Pins the roles submenu to the user permission row (#3925)

* Pins the roles submenu to the user permission row

* Fix snapshots
This commit is contained in:
Miguel de la Cruz 2022-10-05 06:52:24 +02:00 committed by GitHub
parent 76b864efe2
commit a69b0a44dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 10 deletions

View File

@ -40,6 +40,7 @@ exports[`src/components/shareBoard/userPermissionsRow should match snapshot 1`]
</button>
<div
class="Menu noselect left "
style="top: 40px;"
>
<div
class="menu-contents"
@ -289,6 +290,7 @@ exports[`src/components/shareBoard/userPermissionsRow should match snapshot in p
</button>
<div
class="Menu noselect left "
style="top: 40px;"
>
<div
class="menu-contents"
@ -538,6 +540,7 @@ exports[`src/components/shareBoard/userPermissionsRow should match snapshot in t
</button>
<div
class="Menu noselect left "
style="top: 40px;"
>
<div
class="menu-contents"

View File

@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react'
import React, {useRef} from 'react'
import {useIntl} from 'react-intl'
import MenuWrapper from '../../widgets/menuWrapper'
@ -46,8 +46,13 @@ const UserPermissionsRow = (props: Props): JSX.Element => {
displayRole = intl.formatMessage({id: 'BoardMember.schemeCommenter', defaultMessage: 'Commenter'})
}
const menuWrapperRef = useRef<HTMLDivElement>(null)
return (
<div className='user-item'>
<div
className='user-item'
ref={menuWrapperRef}
>
<div className='user-item__content'>
{Utils.isFocalboardPlugin() &&
<img
@ -72,7 +77,10 @@ const UserPermissionsRow = (props: Props): JSX.Element => {
className='CompassIcon'
/>
</button>
<Menu position='left'>
<Menu
position='left'
parentRef={menuWrapperRef}
>
{(board.minimumRole === MemberRole.Viewer || board.minimumRole === MemberRole.None) &&
<Menu.Text
id={MemberRole.Viewer}

View File

@ -46,8 +46,9 @@ export default class Menu extends React.PureComponent<Props> {
const {position, fixed, children} = this.props
let style: CSSProperties = {}
if (position === 'auto' && this.props.parentRef) {
style = MenuUtil.openUp(this.props.parentRef).style
if (this.props.parentRef) {
const forceBottom = position ? ['bottom', 'left', 'right'].includes(position) : false
style = MenuUtil.openUp(this.props.parentRef, forceBottom).style
}
return (

View File

@ -3,14 +3,17 @@
import React, {CSSProperties} from 'react'
/**
* Calculates if a menu should open aligned down or up around the `anchorRef` element.
* This should be used to make sure the menues are always fullly visible in cases
* when opening them close to the edges of screen.
* Calculates the position where the menu should be open, aligning it with the
* `anchorRef` and positioning it down or up around the ref.
* This should be used to make sure the menues are always aligned regardless of
* the scroll position and fullly visible in cases when opening them close to
* the edges of screen.
* @param anchorRef ref of the element with respect to which the menu position is to be calculated.
* @param forceBottom forces the element to be aligned at the bottom of the ref
* @param menuMargin a safe margin value to be ensured around the menu in the calculations.
* this ensures the menu stick to the edges of the screen ans has some space around for ease of use.
*/
function openUp(anchorRef: React.RefObject<HTMLElement>, menuMargin = 40): {openUp: boolean, style: CSSProperties} {
function openUp(anchorRef: React.RefObject<HTMLElement>, forceBottom = false, menuMargin = 40): {openUp: boolean, style: CSSProperties} {
const ret = {
openUp: false,
style: {} as CSSProperties,
@ -26,7 +29,7 @@ function openUp(anchorRef: React.RefObject<HTMLElement>, menuMargin = 40): {open
const spaceOnTop = y || 0
const spaceOnBottom = totalSpace - spaceOnTop
ret.openUp = spaceOnTop > spaceOnBottom
if (ret.openUp) {
if (!forceBottom && ret.openUp) {
ret.style.bottom = spaceOnBottom + menuMargin
} else {
ret.style.top = spaceOnTop + menuMargin