|
|
@ -5,7 +5,12 @@ import { Role, OrgRole } from 'app/types'; |
|
|
|
|
|
|
|
|
|
|
|
import { RolePickerInput } from './RolePickerInput'; |
|
|
|
import { RolePickerInput } from './RolePickerInput'; |
|
|
|
import { RolePickerMenu } from './RolePickerMenu'; |
|
|
|
import { RolePickerMenu } from './RolePickerMenu'; |
|
|
|
import { MENU_MAX_HEIGHT, ROLE_PICKER_MAX_MENU_WIDTH, ROLE_PICKER_WIDTH } from './constants'; |
|
|
|
import { |
|
|
|
|
|
|
|
MENU_MAX_HEIGHT, |
|
|
|
|
|
|
|
ROLE_PICKER_MAX_MENU_WIDTH, |
|
|
|
|
|
|
|
ROLE_PICKER_MENU_MAX_WIDTH, |
|
|
|
|
|
|
|
ROLE_PICKER_WIDTH, |
|
|
|
|
|
|
|
} from './constants'; |
|
|
|
|
|
|
|
|
|
|
|
export interface Props { |
|
|
|
export interface Props { |
|
|
|
basicRole?: OrgRole; |
|
|
|
basicRole?: OrgRole; |
|
|
@ -79,39 +84,38 @@ export const RolePicker = ({ |
|
|
|
return {}; |
|
|
|
return {}; |
|
|
|
} |
|
|
|
} |
|
|
|
const { bottom, top, left, right } = dimensions; |
|
|
|
const { bottom, top, left, right } = dimensions; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const spaceBelow = window.innerHeight - bottom; |
|
|
|
|
|
|
|
const spaceAbove = top; |
|
|
|
|
|
|
|
const spaceRight = window.innerWidth - right; |
|
|
|
|
|
|
|
const spaceLeft = left; |
|
|
|
|
|
|
|
|
|
|
|
let horizontal = left; |
|
|
|
let horizontal = left; |
|
|
|
|
|
|
|
let vertical = bottom; |
|
|
|
let menuToLeft = false; |
|
|
|
let menuToLeft = false; |
|
|
|
|
|
|
|
let menuToTop = false; |
|
|
|
|
|
|
|
|
|
|
|
const distance = window.innerHeight - bottom; |
|
|
|
// Check vertical space
|
|
|
|
let vertical = bottom + 5; |
|
|
|
if (spaceBelow < MENU_MAX_HEIGHT && spaceAbove > spaceBelow) { |
|
|
|
let ToTheSide = false; |
|
|
|
vertical = top - MENU_MAX_HEIGHT; |
|
|
|
if (distance < MENU_MAX_HEIGHT + 20) { |
|
|
|
menuToTop = true; |
|
|
|
// move the menu above the input if there is not enough space below
|
|
|
|
|
|
|
|
vertical = top - MENU_MAX_HEIGHT - 50; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check if there is enough space above the input field
|
|
|
|
|
|
|
|
if (top < MENU_MAX_HEIGHT + 50) { |
|
|
|
|
|
|
|
// if not, reset the vertical position
|
|
|
|
|
|
|
|
vertical = top; |
|
|
|
|
|
|
|
// move the menu to the right edge of the input field
|
|
|
|
|
|
|
|
horizontal = right + 5; |
|
|
|
|
|
|
|
// flag to align the menu to the right or left edge of the input field
|
|
|
|
|
|
|
|
ToTheSide = true; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
// Check horizontal space
|
|
|
|
* This expression calculates whether there is enough place |
|
|
|
if (spaceRight < ROLE_PICKER_MENU_MAX_WIDTH && spaceLeft < ROLE_PICKER_MENU_MAX_WIDTH) { |
|
|
|
* on the right of the RolePicker input to show/fit the role picker menu and its sub menu AND |
|
|
|
horizontal = right - ROLE_PICKER_MENU_MAX_WIDTH; |
|
|
|
* whether there is enough place under the RolePicker input to show/fit |
|
|
|
|
|
|
|
* both (the role picker menu and its sub menu) aligned to the left edge of the input. |
|
|
|
|
|
|
|
* Otherwise, it aligns the role picker menu to the right. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
if (horizontal + ROLE_PICKER_MAX_MENU_WIDTH > window.innerWidth) { |
|
|
|
|
|
|
|
horizontal = window.innerWidth - (ToTheSide ? left : right); |
|
|
|
|
|
|
|
menuToLeft = true; |
|
|
|
menuToLeft = true; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
horizontal = Math.max(0, left + (dimensions.width - ROLE_PICKER_MENU_MAX_WIDTH) / 2); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Ensure the menu stays within the viewport
|
|
|
|
|
|
|
|
horizontal = Math.max(0, Math.min(horizontal, window.innerWidth - ROLE_PICKER_MAX_MENU_WIDTH)); |
|
|
|
|
|
|
|
vertical = Math.max(0, Math.min(vertical, window.innerHeight - MENU_MAX_HEIGHT)); |
|
|
|
|
|
|
|
if (menuToTop) { |
|
|
|
|
|
|
|
// Adjust vertical position to align with the input
|
|
|
|
|
|
|
|
vertical -= 48; |
|
|
|
|
|
|
|
} |
|
|
|
return { horizontal, vertical, menuToLeft }; |
|
|
|
return { horizontal, vertical, menuToLeft }; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|