From aace0b1e7f78fd3956e85ead225e9c336f072f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mih=C3=A1ly=20Gy=C3=B6ngy=C3=B6si?= Date: Thu, 25 Aug 2022 13:30:11 +0200 Subject: [PATCH] Admin: Create/Edit Team/ServiceAccount UI changes (#53889) * RolePicker: Handle inherited with * Small ammendment to Create Service Account layout * RolePicker: introduce maxWidth prop * Clean up * Change VerticalGroup spacing to large on Team Settings page * Introduce constant for submenu width * Update public/app/core/components/RolePicker/RolePicker.tsx Simplify style parameter Co-authored-by: Alex Khomenko * Add description to the improved calculation Co-authored-by: Alex Khomenko --- .../core/components/RolePicker/RolePicker.tsx | 27 +++++- .../components/RolePicker/RolePickerInput.tsx | 2 +- .../components/RolePicker/RolePickerMenu.tsx | 6 +- .../components/RolePicker/TeamRolePicker.tsx | 3 + .../components/RolePicker/UserRolePicker.tsx | 3 + .../core/components/RolePicker/constants.ts | 1 + .../ServiceAccountCreatePage.tsx | 1 + .../components/ServiceAccountRoleRow.tsx | 2 +- public/app/features/teams/CreateTeam.tsx | 5 +- public/app/features/teams/TeamSettings.tsx | 97 +++++++++---------- 10 files changed, 87 insertions(+), 60 deletions(-) diff --git a/public/app/core/components/RolePicker/RolePicker.tsx b/public/app/core/components/RolePicker/RolePicker.tsx index d12a01b36f5..9c9406ef6fc 100644 --- a/public/app/core/components/RolePicker/RolePicker.tsx +++ b/public/app/core/components/RolePicker/RolePicker.tsx @@ -5,7 +5,7 @@ import { Role, OrgRole } from 'app/types'; import { RolePickerInput } from './RolePickerInput'; import { RolePickerMenu } from './RolePickerMenu'; -import { MENU_MAX_HEIGHT, ROLE_PICKER_WIDTH } from './constants'; +import { MENU_MAX_HEIGHT, ROLE_PICKER_SUBMENU_MIN_WIDTH, ROLE_PICKER_WIDTH } from './constants'; export interface Props { basicRole?: OrgRole; @@ -22,6 +22,7 @@ export interface Props { * Set {@link RolePickerMenu}'s button to display either `Apply` (apply=true) or `Update` (apply=false) */ apply?: boolean; + maxWidth?: string | number; } export const RolePicker = ({ @@ -36,6 +37,7 @@ export const RolePicker = ({ onBasicRoleChange, canUpdateRoles = true, apply = false, + maxWidth = ROLE_PICKER_WIDTH, }: Props): JSX.Element | null => { const [isOpen, setOpen] = useState(false); const [selectedRoles, setSelectedRoles] = useState(appliedRoles); @@ -54,7 +56,7 @@ export const RolePicker = ({ if (!dimensions || !isOpen) { return; } - const { bottom, top, left, right } = dimensions; + const { bottom, top, left, right, width: currentRolePickerWidth } = dimensions; const distance = window.innerHeight - bottom; const offsetVertical = bottom - top + 10; // Add extra 10px to offset to account for border and outline const offsetHorizontal = right - left; @@ -65,7 +67,17 @@ export const RolePicker = ({ vertical = offsetVertical; } - if (window.innerWidth - right < ROLE_PICKER_WIDTH) { + /* + * This expression calculates whether there is enough place + * on the right of the RolePicker input to show/fit the role picker menu and its sub menu AND + * 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 ( + window.innerWidth - right < currentRolePickerWidth && + currentRolePickerWidth < 2 * ROLE_PICKER_SUBMENU_MIN_WIDTH + ) { horizontal = offsetHorizontal; } @@ -140,7 +152,14 @@ export const RolePicker = ({ } return ( -
+
{ min-width: auto; `, menu: css` - min-width: 260px; + min-width: ${ROLE_PICKER_SUBMENU_MIN_WIDTH}px; & > div { padding-top: ${theme.spacing(1)}; @@ -600,7 +600,7 @@ export const getStyles = (theme: GrafanaTheme2) => { `, subMenu: css` height: 100%; - min-width: 260px; + min-width: ${ROLE_PICKER_SUBMENU_MIN_WIDTH}px; display: flex; flex-direction: column; border-left: 1px solid ${theme.components.input.borderColor}; diff --git a/public/app/core/components/RolePicker/TeamRolePicker.tsx b/public/app/core/components/RolePicker/TeamRolePicker.tsx index de92e711c26..73e0b7f0aa8 100644 --- a/public/app/core/components/RolePicker/TeamRolePicker.tsx +++ b/public/app/core/components/RolePicker/TeamRolePicker.tsx @@ -26,6 +26,7 @@ export interface Props { * @default false */ apply?: boolean; + maxWidth?: string | number; } export const TeamRolePicker: FC = ({ @@ -35,6 +36,7 @@ export const TeamRolePicker: FC = ({ onApplyRoles, pendingRoles, apply = false, + maxWidth, }) => { const [{ loading, value: appliedRoles = [] }, getTeamRoles] = useAsyncFn(async () => { try { @@ -78,6 +80,7 @@ export const TeamRolePicker: FC = ({ disabled={disabled} basicRoleDisabled={true} canUpdateRoles={canUpdateRoles} + maxWidth={maxWidth} /> ); }; diff --git a/public/app/core/components/RolePicker/UserRolePicker.tsx b/public/app/core/components/RolePicker/UserRolePicker.tsx index 11c5aa68e67..ede86b99f3f 100644 --- a/public/app/core/components/RolePicker/UserRolePicker.tsx +++ b/public/app/core/components/RolePicker/UserRolePicker.tsx @@ -29,6 +29,7 @@ export interface Props { apply?: boolean; onApplyRoles?: (newRoles: Role[], userId: number, orgId: number | undefined) => void; pendingRoles?: Role[]; + maxWidth?: string | number; } export const UserRolePicker: FC = ({ @@ -42,6 +43,7 @@ export const UserRolePicker: FC = ({ apply = false, onApplyRoles, pendingRoles, + maxWidth, }) => { const [{ loading, value: appliedRoles = [] }, getUserRoles] = useAsyncFn(async () => { try { @@ -92,6 +94,7 @@ export const UserRolePicker: FC = ({ showBasicRole apply={apply} canUpdateRoles={canUpdateRoles} + maxWidth={maxWidth} /> ); }; diff --git a/public/app/core/components/RolePicker/constants.ts b/public/app/core/components/RolePicker/constants.ts index 80beb4e0d43..3b6c35447da 100644 --- a/public/app/core/components/RolePicker/constants.ts +++ b/public/app/core/components/RolePicker/constants.ts @@ -1,2 +1,3 @@ export const MENU_MAX_HEIGHT = 300; // max height for the picker's dropdown menu export const ROLE_PICKER_WIDTH = 360; +export const ROLE_PICKER_SUBMENU_MIN_WIDTH = 260; diff --git a/public/app/features/serviceaccounts/ServiceAccountCreatePage.tsx b/public/app/features/serviceaccounts/ServiceAccountCreatePage.tsx index 2286a9d18f1..23f073c7a64 100644 --- a/public/app/features/serviceaccounts/ServiceAccountCreatePage.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountCreatePage.tsx @@ -127,6 +127,7 @@ export const ServiceAccountCreatePage = ({}: Props): JSX.Element => { roleOptions={roleOptions} onApplyRoles={onPendingRolesUpdate} pendingRoles={pendingRoles} + maxWidth="100%" /> ) : ( diff --git a/public/app/features/serviceaccounts/components/ServiceAccountRoleRow.tsx b/public/app/features/serviceaccounts/components/ServiceAccountRoleRow.tsx index 7ece92c41de..6d62e7216cb 100644 --- a/public/app/features/serviceaccounts/components/ServiceAccountRoleRow.tsx +++ b/public/app/features/serviceaccounts/components/ServiceAccountRoleRow.tsx @@ -23,7 +23,7 @@ export const ServiceAccountRoleRow = ({ label, serviceAccount, roleOptions, onRo {contextSrv.licensedAccessControlEnabled() ? ( - + { {({ register, errors }) => (
- + {contextSrv.licensedAccessControlEnabled() && ( @@ -56,6 +56,7 @@ export const CreateTeam = (): JSX.Element => { apply={true} onApplyRoles={setPendingRoles} pendingRoles={pendingRoles} + maxWidth="100%" /> )} @@ -63,7 +64,7 @@ export const CreateTeam = (): JSX.Element => { label={'Email'} description={'This is optional and is primarily used for allowing custom team avatars.'} > - +
- - )} - -
+ )} + + + + + + + )} + );