mirror of
https://github.com/Unleash/unleash.git
synced 2025-03-18 00:19:49 +01:00
chore: categorize access overview (#9546)
https://linear.app/unleash/issue/2-3346/only-show-description-and-not-permission-first-column-and-group Categorizes the permissions in our Access Overview. 
This commit is contained in:
parent
e38a58d635
commit
76b3e06fe5
@ -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>
|
||||
)}
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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}>
|
||||
|
Loading…
Reference in New Issue
Block a user