Skip to content

Commit e06d6b1

Browse files
committed
chore: categorize access overview
1 parent 14512c7 commit e06d6b1

File tree

3 files changed

+96
-50
lines changed

3 files changed

+96
-50
lines changed

frontend/src/component/admin/users/AccessOverview/AccessOverview.tsx

+24-5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ import useProjects from 'hooks/api/getters/useProjects/useProjects';
1212
import { AccessOverviewSelect } from './AccessOverviewSelect';
1313
import { useUserAccessOverview } from 'hooks/api/getters/useUserAccessOverview/useUserAccessOverview';
1414
import { AccessOverviewAccordion } from './AccessOverviewAccordion/AccessOverviewAccordion';
15+
import {
16+
getCategorizedProjectPermissions,
17+
getCategorizedRootPermissions,
18+
} from 'utils/permissions';
19+
import type { IAccessOverviewPermissionCategory } from './AccessOverviewAccordion/AccessOverviewList';
20+
import { createProjectPermissionsStructure } from 'component/admin/roles/RoleForm/RolePermissionCategories/createProjectPermissionsStructure';
1521

1622
const StyledActionsContainer = styled('div')(({ theme }) => ({
1723
display: 'flex',
@@ -86,6 +92,21 @@ export const AccessOverview = () => {
8692
</StyledActionsContainer>
8793
);
8894

95+
const rootCategories = getCategorizedRootPermissions(
96+
overview?.root ?? [],
97+
) as IAccessOverviewPermissionCategory[];
98+
99+
const projectCategories = createProjectPermissionsStructure(
100+
overview?.project ?? [],
101+
).map(({ label, permissions }) => ({
102+
label,
103+
permissions: permissions.map(([permission]) => permission),
104+
})) as IAccessOverviewPermissionCategory[];
105+
106+
const environmentCategories = getCategorizedProjectPermissions(
107+
overview?.environment ?? [],
108+
) as IAccessOverviewPermissionCategory[];
109+
89110
return (
90111
<PageContent
91112
isLoading={loading}
@@ -107,19 +128,17 @@ export const AccessOverview = () => {
107128
}
108129
>
109130
<StyledAccessOverviewContainer>
110-
<AccessOverviewAccordion permissions={overview?.root ?? []}>
131+
<AccessOverviewAccordion categories={rootCategories}>
111132
Root permissions for role {rootRole?.name}
112133
</AccessOverviewAccordion>
113-
<AccessOverviewAccordion permissions={overview?.project ?? []}>
134+
<AccessOverviewAccordion categories={projectCategories}>
114135
Project permissions
115136
{project
116137
? ` for project ${project}${projectRoles?.length ? ` with project role${projectRoles.length !== 1 ? 's' : ''} ${projectRoles?.map((role: any) => role.name).join(', ')}` : ''}`
117138
: ''}
118139
</AccessOverviewAccordion>
119140
{environment && (
120-
<AccessOverviewAccordion
121-
permissions={overview?.environment ?? []}
122-
>
141+
<AccessOverviewAccordion categories={environmentCategories}>
123142
Environment permissions for {environment}
124143
</AccessOverviewAccordion>
125144
)}

frontend/src/component/admin/users/AccessOverview/AccessOverviewAccordion/AccessOverviewAccordion.tsx

+29-23
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import {
55
AccordionSummary,
66
styled,
77
} from '@mui/material';
8-
import type { IAccessOverviewPermission } from 'interfaces/permissions';
9-
import { AccessOverviewList } from './AccessOverviewList';
8+
import {
9+
AccessOverviewList,
10+
type IAccessOverviewPermissionCategory,
11+
} from './AccessOverviewList';
1012

1113
const StyledAccordion = styled(Accordion)(({ theme }) => ({
1214
border: `1px solid ${theme.palette.divider}`,
@@ -50,29 +52,33 @@ const StyledAccordionDetails = styled(AccordionDetails)(({ theme }) => ({
5052
}));
5153

5254
interface IAccessAccordionProps {
53-
permissions: IAccessOverviewPermission[];
55+
categories: IAccessOverviewPermissionCategory[];
5456
children: React.ReactNode;
5557
}
5658

5759
export const AccessOverviewAccordion = ({
58-
permissions,
60+
categories,
5961
children,
60-
}: IAccessAccordionProps) => (
61-
<StyledAccordion>
62-
<StyledAccordionSummary expandIcon={<ExpandMore />}>
63-
<StyledTitleContainer>
64-
<StyledTitle>{children}</StyledTitle>
65-
</StyledTitleContainer>
66-
<StyledSecondaryLabel>
67-
{
68-
permissions.filter(({ hasPermission }) => hasPermission)
69-
.length
70-
}
71-
/{permissions.length} permissions
72-
</StyledSecondaryLabel>
73-
</StyledAccordionSummary>
74-
<StyledAccordionDetails>
75-
<AccessOverviewList permissions={permissions} />
76-
</StyledAccordionDetails>
77-
</StyledAccordion>
78-
);
62+
}: IAccessAccordionProps) => {
63+
const permissions = categories.flatMap(({ permissions }) => permissions);
64+
65+
return (
66+
<StyledAccordion>
67+
<StyledAccordionSummary expandIcon={<ExpandMore />}>
68+
<StyledTitleContainer>
69+
<StyledTitle>{children}</StyledTitle>
70+
</StyledTitleContainer>
71+
<StyledSecondaryLabel>
72+
{
73+
permissions.filter(({ hasPermission }) => hasPermission)
74+
.length
75+
}
76+
/{permissions.length} permissions
77+
</StyledSecondaryLabel>
78+
</StyledAccordionSummary>
79+
<StyledAccordionDetails>
80+
<AccessOverviewList categories={categories} />
81+
</StyledAccordionDetails>
82+
</StyledAccordion>
83+
);
84+
};

frontend/src/component/admin/users/AccessOverview/AccessOverviewAccordion/AccessOverviewList.tsx

+43-22
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,34 @@
11
import Check from '@mui/icons-material/Check';
22
import Close from '@mui/icons-material/Close';
33
import { Box, styled } from '@mui/material';
4-
import type { IAccessOverviewPermission } from 'interfaces/permissions';
4+
import type {
5+
IAccessOverviewPermission,
6+
IPermissionCategory,
7+
} from 'interfaces/permissions';
8+
9+
export type IAccessOverviewPermissionCategory = Omit<
10+
IPermissionCategory,
11+
'permissions'
12+
> & {
13+
permissions: IAccessOverviewPermission[];
14+
};
515

616
const StyledList = styled('ul')(({ theme }) => ({
717
listStyle: 'none',
818
padding: 0,
919
margin: 0,
1020
fontSize: theme.fontSizes.smallBody,
11-
'& li': {
21+
'& > li': {
1222
display: 'flex',
1323
justifyContent: 'space-between',
1424
padding: theme.spacing(2),
15-
'&:not(:last-child)': {
16-
borderBottom: `1px solid ${theme.palette.divider}`,
17-
},
25+
borderBottom: `1px solid ${theme.palette.divider}`,
26+
},
27+
'& ul li': {
28+
paddingLeft: theme.spacing(4),
29+
},
30+
'& ul:last-of-type > li:last-child': {
31+
borderBottom: 'none',
1832
},
1933
}));
2034

@@ -36,25 +50,32 @@ const StyledPermissionStatus = styled('div', {
3650
}));
3751

3852
export const AccessOverviewList = ({
39-
permissions,
53+
categories,
4054
}: {
41-
permissions: IAccessOverviewPermission[];
42-
}) => {
43-
return (
44-
<Box sx={{ maxHeight: 500, overflow: 'auto' }}>
45-
<StyledList>
46-
{permissions.map((permission) => (
47-
<li key={permission.name}>
48-
<div>{permission.displayName}</div>
49-
<PermissionStatus
50-
hasPermission={permission.hasPermission}
51-
/>
55+
categories: IAccessOverviewPermissionCategory[];
56+
}) => (
57+
<Box sx={{ maxHeight: 500, overflow: 'auto' }}>
58+
<StyledList>
59+
{categories.map((category) => (
60+
<>
61+
<li key={category.label}>
62+
<strong>{category.label}</strong>
5263
</li>
53-
))}
54-
</StyledList>
55-
</Box>
56-
);
57-
};
64+
<StyledList>
65+
{category.permissions.map((permission) => (
66+
<li key={permission.name}>
67+
<div>{permission.displayName}</div>
68+
<PermissionStatus
69+
hasPermission={permission.hasPermission}
70+
/>
71+
</li>
72+
))}
73+
</StyledList>
74+
</>
75+
))}
76+
</StyledList>
77+
</Box>
78+
);
5879

5980
const PermissionStatus = ({ hasPermission }: { hasPermission: boolean }) => (
6081
<StyledPermissionStatus hasPermission={hasPermission}>

0 commit comments

Comments
 (0)