From ce67f73b9a820d21d0f73be4e62f77c0d354b02e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20G=C3=B3is?= Date: Thu, 7 Sep 2023 19:59:27 +0100 Subject: [PATCH 1/2] fix: misc UI improvements for multi proj roles --- .../admin/groups/GroupForm/GroupForm.tsx | 2 +- .../admin/groups/GroupsList/GroupsList.tsx | 2 +- .../ProjectAccessTable/ProjectAccessTable.tsx | 30 +++++++++++-------- .../ProjectGroupView/ProjectGroupView.tsx | 4 ++- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/frontend/src/component/admin/groups/GroupForm/GroupForm.tsx b/frontend/src/component/admin/groups/GroupForm/GroupForm.tsx index 9fa4765986a1..1d80b6ad334a 100644 --- a/frontend/src/component/admin/groups/GroupForm/GroupForm.tsx +++ b/frontend/src/component/admin/groups/GroupForm/GroupForm.tsx @@ -179,7 +179,7 @@ export const GroupForm: FC = ({ Do you want to associate a root role with this group? - + diff --git a/frontend/src/component/admin/groups/GroupsList/GroupsList.tsx b/frontend/src/component/admin/groups/GroupsList/GroupsList.tsx index 11b1ff1594d6..025f920fb270 100644 --- a/frontend/src/component/admin/groups/GroupsList/GroupsList.tsx +++ b/frontend/src/component/admin/groups/GroupsList/GroupsList.tsx @@ -30,7 +30,7 @@ const groupsSearch = (group: IGroup, searchValue: string) => { }; return ( group.name.toLowerCase().includes(search) || - group.description.toLowerCase().includes(search) || + group.description?.toLowerCase().includes(search) || users.names?.some(name => name.includes(search)) || users.usernames?.some(username => username.includes(search)) || users.emails?.some(email => email.includes(search)) diff --git a/frontend/src/component/project/ProjectAccess/ProjectAccessTable/ProjectAccessTable.tsx b/frontend/src/component/project/ProjectAccess/ProjectAccessTable/ProjectAccessTable.tsx index a30a9174b81b..c2202d5db5f4 100644 --- a/frontend/src/component/project/ProjectAccess/ProjectAccessTable/ProjectAccessTable.tsx +++ b/frontend/src/component/project/ProjectAccess/ProjectAccessTable/ProjectAccessTable.tsx @@ -98,6 +98,11 @@ export const ProjectAccessTable: VFC = () => { const [groupOpen, setGroupOpen] = useState(false); const [selectedRow, setSelectedRow] = useState(); + const roleText = (roles: number[]): string => + roles.length > 1 + ? `${roles.length} roles` + : access?.roles.find(({ id }) => id === roles[0])?.name || ''; + const columns = useMemo( () => [ { @@ -150,14 +155,7 @@ export const ProjectAccessTable: VFC = () => { { id: 'role', Header: 'Role', - accessor: (row: IProjectAccess) => - row.entity.roles - ? row.entity.roles.length > 1 - ? `${row.entity.roles.length} roles` - : access?.roles.find( - ({ id }) => id === row.entity.roleId - )?.name - : 'No Roles!', + accessor: (row: IProjectAccess) => roleText(row.entity.roles), Cell: ({ value, row: { original: row }, @@ -490,11 +488,17 @@ export const ProjectAccessTable: VFC = () => { setOpen={setGroupOpen} group={selectedRow?.entity as IGroup} projectId={projectId} - subtitle={`Role: ${ - access?.roles.find( - ({ id }) => id === selectedRow?.entity.roleId - )?.name - }`} + subtitle={ + <> + {selectedRow && selectedRow.entity.roles.length > 1 + ? 'Roles:' + : 'Role:'} + + + } onEdit={() => { navigate(`edit/group/${selectedRow?.entity.id}`); }} diff --git a/frontend/src/component/project/ProjectAccess/ProjectGroupView/ProjectGroupView.tsx b/frontend/src/component/project/ProjectAccess/ProjectGroupView/ProjectGroupView.tsx index f9b2c66ba1d6..b7eef3f289c3 100644 --- a/frontend/src/component/project/ProjectAccess/ProjectGroupView/ProjectGroupView.tsx +++ b/frontend/src/component/project/ProjectAccess/ProjectGroupView/ProjectGroupView.tsx @@ -41,6 +41,8 @@ const StyledTitle = styled('div')(({ theme }) => ({ display: 'flex', flexDirection: 'column', '& > span': { + display: 'flex', + alignItems: 'center', color: theme.palette.text.secondary, fontSize: theme.fontSizes.bodySize, }, @@ -113,7 +115,7 @@ interface IProjectGroupViewProps { setOpen: React.Dispatch>; group: IGroup; projectId: string; - subtitle: string; + subtitle: React.ReactNode; onEdit: () => void; onRemove: () => void; } From 965cc12935ddc80e8a1e9253442eb8526859d0d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20G=C3=B3is?= Date: Fri, 8 Sep 2023 11:18:18 +0100 Subject: [PATCH 2/2] fix: improve design for role description --- .../RoleDescription/RoleDescription.tsx | 78 ++++++++++++++----- 1 file changed, 57 insertions(+), 21 deletions(-) diff --git a/frontend/src/component/common/RoleDescription/RoleDescription.tsx b/frontend/src/component/common/RoleDescription/RoleDescription.tsx index 2ace95f1f4fc..34c9c6267bae 100644 --- a/frontend/src/component/common/RoleDescription/RoleDescription.tsx +++ b/frontend/src/component/common/RoleDescription/RoleDescription.tsx @@ -1,4 +1,5 @@ import { SxProps, Theme, styled } from '@mui/material'; +import { SupervisedUserCircle } from '@mui/icons-material'; import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender'; import { useRole } from 'hooks/api/getters/useRole/useRole'; import { @@ -24,20 +25,45 @@ const StyledDescription = styled('div', { borderRadius: tooltip ? 0 : theme.shape.borderRadiusMedium, })); -const StyledDescriptionBlock = styled('div')(({ theme }) => ({ +const StyledPermissionsLabel = styled('p')(({ theme }) => ({ + color: theme.palette.text.primary, marginTop: theme.spacing(2), + marginBottom: theme.spacing(0.5), })); -const StyledDescriptionHeader = styled('p')(({ theme }) => ({ +const StyledPermissions = styled('div')(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(1), +})); + +const StyledRoleHeader = styled('p')(({ theme }) => ({ + display: 'flex', + alignItems: 'center', + gap: theme.spacing(0.5), color: theme.palette.text.primary, - fontSize: theme.fontSizes.smallBody, + fontSize: theme.fontSizes.bodySize, + fontWeight: theme.fontWeight.bold, +})); + +const StyledSupervisedUserCircle = styled(SupervisedUserCircle)( + ({ theme }) => ({ + fontSize: theme.fontSizes.mainHeader, + }) +); + +const StyledDescriptionHeader = styled('p')(({ theme }) => ({ + color: theme.palette.text.secondary, fontWeight: theme.fontWeight.bold, - marginBottom: theme.spacing(1), })); const StyledDescriptionSubHeader = styled('p')(({ theme }) => ({ - fontSize: theme.fontSizes.smallBody, - marginTop: theme.spacing(1), + marginTop: theme.spacing(0.5), +})); + +const StyledPermissionsList = styled('ul')(({ theme }) => ({ + margin: 0, + paddingLeft: theme.spacing(2), })); interface IRoleDescriptionProps { @@ -66,28 +92,38 @@ export const RoleDescription = ({ return ( - + + {name} - + {description} - categories.map(({ label, permissions }) => ( - - - {label} - - {permissions.map(permission => ( -

- {permission.displayName} -

+ show={() => ( + <> + + Role permissions: + + + {categories.map(({ label, permissions }) => ( +
+ + {label} + + + {permissions.map(permission => ( +
  • + {permission.displayName} +
  • + ))} +
    +
    ))} -
    - )) - } + + + )} />
    );