1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-03-18 00:19:49 +01:00
Nuno Góis 2025-03-17 08:24:48 +00:00 committed by GitHub
parent e38a58d635
commit 76b3e06fe5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 96 additions and 50 deletions

View File

@ -12,6 +12,12 @@ import useProjects from 'hooks/api/getters/useProjects/useProjects';
import { AccessOverviewSelect } from './AccessOverviewSelect';
import { useUserAccessOverview } from 'hooks/api/getters/useUserAccessOverview/useUserAccessOverview';
import { AccessOverviewAccordion } from './AccessOverviewAccordion/AccessOverviewAccordion';
import {
getCategorizedProjectPermissions,
getCategorizedRootPermissions,
} from 'utils/permissions';
import type { IAccessOverviewPermissionCategory } from './AccessOverviewAccordion/AccessOverviewList';
import { createProjectPermissionsStructure } from 'component/admin/roles/RoleForm/RolePermissionCategories/createProjectPermissionsStructure';
const StyledActionsContainer = styled('div')(({ theme }) => ({
display: 'flex',
@ -86,6 +92,21 @@ export const AccessOverview = () => {
</StyledActionsContainer>
);
const rootCategories = getCategorizedRootPermissions(
overview?.root ?? [],
) as IAccessOverviewPermissionCategory[];
const projectCategories = createProjectPermissionsStructure(
overview?.project ?? [],
).map(({ label, permissions }) => ({
label,
permissions: permissions.map(([permission]) => permission),
})) as IAccessOverviewPermissionCategory[];
const environmentCategories = getCategorizedProjectPermissions(
overview?.environment ?? [],
) as IAccessOverviewPermissionCategory[];
return (
<PageContent
isLoading={loading}
@ -107,19 +128,17 @@ export const AccessOverview = () => {
}
>
<StyledAccessOverviewContainer>
<AccessOverviewAccordion permissions={overview?.root ?? []}>
<AccessOverviewAccordion categories={rootCategories}>
Root permissions for role {rootRole?.name}
</AccessOverviewAccordion>
<AccessOverviewAccordion permissions={overview?.project ?? []}>
<AccessOverviewAccordion categories={projectCategories}>
Project permissions
{project
? ` for project ${project}${projectRoles?.length ? ` with project role${projectRoles.length !== 1 ? 's' : ''} ${projectRoles?.map((role: any) => role.name).join(', ')}` : ''}`
: ''}
</AccessOverviewAccordion>
{environment && (
<AccessOverviewAccordion
permissions={overview?.environment ?? []}
>
<AccessOverviewAccordion categories={environmentCategories}>
Environment permissions for {environment}
</AccessOverviewAccordion>
)}

View File

@ -5,8 +5,10 @@ import {
AccordionSummary,
styled,
} from '@mui/material';
import type { IAccessOverviewPermission } from 'interfaces/permissions';
import { AccessOverviewList } from './AccessOverviewList';
import {
AccessOverviewList,
type IAccessOverviewPermissionCategory,
} from './AccessOverviewList';
const StyledAccordion = styled(Accordion)(({ theme }) => ({
border: `1px solid ${theme.palette.divider}`,
@ -50,29 +52,33 @@ const StyledAccordionDetails = styled(AccordionDetails)(({ theme }) => ({
}));
interface IAccessAccordionProps {
permissions: IAccessOverviewPermission[];
categories: IAccessOverviewPermissionCategory[];
children: React.ReactNode;
}
export const AccessOverviewAccordion = ({
permissions,
categories,
children,
}: IAccessAccordionProps) => (
<StyledAccordion>
<StyledAccordionSummary expandIcon={<ExpandMore />}>
<StyledTitleContainer>
<StyledTitle>{children}</StyledTitle>
</StyledTitleContainer>
<StyledSecondaryLabel>
{
permissions.filter(({ hasPermission }) => hasPermission)
.length
}
/{permissions.length} permissions
</StyledSecondaryLabel>
</StyledAccordionSummary>
<StyledAccordionDetails>
<AccessOverviewList permissions={permissions} />
</StyledAccordionDetails>
</StyledAccordion>
);
}: IAccessAccordionProps) => {
const permissions = categories.flatMap(({ permissions }) => permissions);
return (
<StyledAccordion>
<StyledAccordionSummary expandIcon={<ExpandMore />}>
<StyledTitleContainer>
<StyledTitle>{children}</StyledTitle>
</StyledTitleContainer>
<StyledSecondaryLabel>
{
permissions.filter(({ hasPermission }) => hasPermission)
.length
}
/{permissions.length} permissions
</StyledSecondaryLabel>
</StyledAccordionSummary>
<StyledAccordionDetails>
<AccessOverviewList categories={categories} />
</StyledAccordionDetails>
</StyledAccordion>
);
};

View File

@ -1,20 +1,34 @@
import Check from '@mui/icons-material/Check';
import Close from '@mui/icons-material/Close';
import { Box, styled } from '@mui/material';
import type { IAccessOverviewPermission } from 'interfaces/permissions';
import type {
IAccessOverviewPermission,
IPermissionCategory,
} from 'interfaces/permissions';
export type IAccessOverviewPermissionCategory = Omit<
IPermissionCategory,
'permissions'
> & {
permissions: IAccessOverviewPermission[];
};
const StyledList = styled('ul')(({ theme }) => ({
listStyle: 'none',
padding: 0,
margin: 0,
fontSize: theme.fontSizes.smallBody,
'& li': {
'& > li': {
display: 'flex',
justifyContent: 'space-between',
padding: theme.spacing(2),
'&:not(:last-child)': {
borderBottom: `1px solid ${theme.palette.divider}`,
},
borderBottom: `1px solid ${theme.palette.divider}`,
},
'& ul li': {
paddingLeft: theme.spacing(4),
},
'& ul:last-of-type > li:last-child': {
borderBottom: 'none',
},
}));
@ -36,25 +50,32 @@ const StyledPermissionStatus = styled('div', {
}));
export const AccessOverviewList = ({
permissions,
categories,
}: {
permissions: IAccessOverviewPermission[];
}) => {
return (
<Box sx={{ maxHeight: 500, overflow: 'auto' }}>
<StyledList>
{permissions.map((permission) => (
<li key={permission.name}>
<div>{permission.displayName}</div>
<PermissionStatus
hasPermission={permission.hasPermission}
/>
categories: IAccessOverviewPermissionCategory[];
}) => (
<Box sx={{ maxHeight: 500, overflow: 'auto' }}>
<StyledList>
{categories.map((category) => (
<>
<li key={category.label}>
<strong>{category.label}</strong>
</li>
))}
</StyledList>
</Box>
);
};
<StyledList>
{category.permissions.map((permission) => (
<li key={permission.name}>
<div>{permission.displayName}</div>
<PermissionStatus
hasPermission={permission.hasPermission}
/>
</li>
))}
</StyledList>
</>
))}
</StyledList>
</Box>
);
const PermissionStatus = ({ hasPermission }: { hasPermission: boolean }) => (
<StyledPermissionStatus hasPermission={hasPermission}>