mirror of
https://github.com/Unleash/unleash.git
synced 2025-09-15 17:50:48 +02:00
refactor: address custom root roles PR comments (#3994)
https://linear.app/unleash/issue/2-1135/address-3975-pr-comments-by-refactoring-some-of-the-new-custom-root This pull request addresses the majority of the comments raised in issue #3975 and lays the groundwork for unifying roles. The idea is for project roles to also be managed in the "Roles" tab, and several components, such as `RoleForm` and the `useRoleForm` can potentially be reused. I'll leave the further investigation and implementation of unifying roles to be addressed in a separate task. As a mostly unrelated UI fix, this also adds an arrow to the tooltip in the `RoleBadge` component.
This commit is contained in:
parent
c7ff3b472e
commit
58607f7f48
@ -48,7 +48,7 @@ export const PermissionAccordion: VFC<IEnvironmentPermissionAccordionProps> = ({
|
|||||||
permissions,
|
permissions,
|
||||||
checkedPermissions,
|
checkedPermissions,
|
||||||
Icon,
|
Icon,
|
||||||
isInitiallyExpanded,
|
isInitiallyExpanded = false,
|
||||||
context,
|
context,
|
||||||
onPermissionChange,
|
onPermissionChange,
|
||||||
onCheckAll,
|
onCheckAll,
|
||||||
|
@ -5,7 +5,7 @@ import { Person as UserIcon } from '@mui/icons-material';
|
|||||||
import { ICheckedPermissions, IPermission } from 'interfaces/permissions';
|
import { ICheckedPermissions, IPermission } from 'interfaces/permissions';
|
||||||
import { IRoleFormErrors } from './useRoleForm';
|
import { IRoleFormErrors } from './useRoleForm';
|
||||||
import { ROOT_PERMISSION_CATEGORIES } from '@server/types/permissions';
|
import { ROOT_PERMISSION_CATEGORIES } from '@server/types/permissions';
|
||||||
import cloneDeep from 'lodash.clonedeep';
|
import { toggleAllPermissions, togglePermission } from 'utils/permissions';
|
||||||
|
|
||||||
const StyledInputDescription = styled('p')(({ theme }) => ({
|
const StyledInputDescription = styled('p')(({ theme }) => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@ -30,7 +30,6 @@ interface IRoleFormProps {
|
|||||||
setCheckedPermissions: React.Dispatch<
|
setCheckedPermissions: React.Dispatch<
|
||||||
React.SetStateAction<ICheckedPermissions>
|
React.SetStateAction<ICheckedPermissions>
|
||||||
>;
|
>;
|
||||||
handlePermissionChange: (permission: IPermission) => void;
|
|
||||||
permissions: IPermission[];
|
permissions: IPermission[];
|
||||||
errors: IRoleFormErrors;
|
errors: IRoleFormErrors;
|
||||||
}
|
}
|
||||||
@ -42,7 +41,6 @@ export const RoleForm = ({
|
|||||||
setDescription,
|
setDescription,
|
||||||
checkedPermissions,
|
checkedPermissions,
|
||||||
setCheckedPermissions,
|
setCheckedPermissions,
|
||||||
handlePermissionChange,
|
|
||||||
permissions,
|
permissions,
|
||||||
errors,
|
errors,
|
||||||
}: IRoleFormProps) => {
|
}: IRoleFormProps) => {
|
||||||
@ -61,30 +59,25 @@ export const RoleForm = ({
|
|||||||
categorizedPermissions.map(({ category }) => category).sort()
|
categorizedPermissions.map(({ category }) => category).sort()
|
||||||
);
|
);
|
||||||
|
|
||||||
const onToggleAllPermissions = (category: string) => {
|
const onPermissionChange = (permission: IPermission) => {
|
||||||
let checkedPermissionsCopy = cloneDeep(checkedPermissions);
|
const newCheckedPermissions = togglePermission(
|
||||||
|
checkedPermissions,
|
||||||
|
permission
|
||||||
|
);
|
||||||
|
setCheckedPermissions(newCheckedPermissions);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCheckAll = (category: string) => {
|
||||||
const categoryPermissions = categorizedPermissions
|
const categoryPermissions = categorizedPermissions
|
||||||
.filter(({ category: pCategory }) => pCategory === category)
|
.filter(({ category: pCategory }) => pCategory === category)
|
||||||
.map(({ permission }) => permission);
|
.map(({ permission }) => permission);
|
||||||
|
|
||||||
const allChecked = categoryPermissions.every(
|
const newCheckedPermissions = toggleAllPermissions(
|
||||||
(permission: IPermission) => checkedPermissionsCopy[permission.id]
|
checkedPermissions,
|
||||||
|
categoryPermissions
|
||||||
);
|
);
|
||||||
|
|
||||||
if (allChecked) {
|
setCheckedPermissions(newCheckedPermissions);
|
||||||
categoryPermissions.forEach((permission: IPermission) => {
|
|
||||||
delete checkedPermissionsCopy[permission.id];
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
categoryPermissions.forEach((permission: IPermission) => {
|
|
||||||
checkedPermissionsCopy[permission.id] = {
|
|
||||||
...permission,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setCheckedPermissions(checkedPermissionsCopy);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -128,9 +121,9 @@ export const RoleForm = ({
|
|||||||
.map(({ permission }) => permission)}
|
.map(({ permission }) => permission)}
|
||||||
checkedPermissions={checkedPermissions}
|
checkedPermissions={checkedPermissions}
|
||||||
onPermissionChange={(permission: IPermission) =>
|
onPermissionChange={(permission: IPermission) =>
|
||||||
handlePermissionChange(permission)
|
onPermissionChange(permission)
|
||||||
}
|
}
|
||||||
onCheckAll={() => onToggleAllPermissions(category)}
|
onCheckAll={() => onCheckAll(category)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { IPermission, ICheckedPermissions } from 'interfaces/permissions';
|
import { IPermission, ICheckedPermissions } from 'interfaces/permissions';
|
||||||
import cloneDeep from 'lodash.clonedeep';
|
|
||||||
import usePermissions from 'hooks/api/getters/usePermissions/usePermissions';
|
|
||||||
import IRole from 'interfaces/role';
|
import IRole from 'interfaces/role';
|
||||||
import { useRoles } from 'hooks/api/getters/useRoles/useRoles';
|
import { useRoles } from 'hooks/api/getters/useRoles/useRoles';
|
||||||
|
import { permissionsToCheckedPermissions } from 'utils/permissions';
|
||||||
|
|
||||||
enum ErrorField {
|
enum ErrorField {
|
||||||
NAME = 'name',
|
NAME = 'name',
|
||||||
@ -19,33 +18,11 @@ export const useRoleForm = (
|
|||||||
initialPermissions: IPermission[] = []
|
initialPermissions: IPermission[] = []
|
||||||
) => {
|
) => {
|
||||||
const { roles } = useRoles();
|
const { roles } = useRoles();
|
||||||
const { permissions } = usePermissions({
|
|
||||||
revalidateIfStale: false,
|
|
||||||
revalidateOnReconnect: false,
|
|
||||||
revalidateOnFocus: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const rootPermissions = permissions.root.filter(
|
|
||||||
({ name }) => name !== 'ADMIN'
|
|
||||||
);
|
|
||||||
|
|
||||||
const [name, setName] = useState(initialName);
|
const [name, setName] = useState(initialName);
|
||||||
const [description, setDescription] = useState(initialDescription);
|
const [description, setDescription] = useState(initialDescription);
|
||||||
const [checkedPermissions, setCheckedPermissions] =
|
const [checkedPermissions, setCheckedPermissions] =
|
||||||
useState<ICheckedPermissions>({});
|
useState<ICheckedPermissions>({});
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setCheckedPermissions(
|
|
||||||
initialPermissions.reduce(
|
|
||||||
(acc: { [key: string]: IPermission }, curr: IPermission) => {
|
|
||||||
acc[curr.id] = curr;
|
|
||||||
return acc;
|
|
||||||
},
|
|
||||||
{}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}, [initialPermissions.length]);
|
|
||||||
|
|
||||||
const [errors, setErrors] = useState<IRoleFormErrors>({});
|
const [errors, setErrors] = useState<IRoleFormErrors>({});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -56,44 +33,16 @@ export const useRoleForm = (
|
|||||||
setDescription(initialDescription);
|
setDescription(initialDescription);
|
||||||
}, [initialDescription]);
|
}, [initialDescription]);
|
||||||
|
|
||||||
const handlePermissionChange = (permission: IPermission) => {
|
useEffect(() => {
|
||||||
let checkedPermissionsCopy = cloneDeep(checkedPermissions);
|
const newCheckedPermissions =
|
||||||
|
permissionsToCheckedPermissions(initialPermissions);
|
||||||
|
setCheckedPermissions(newCheckedPermissions);
|
||||||
|
}, [initialPermissions.length]);
|
||||||
|
|
||||||
if (checkedPermissionsCopy[permission.id]) {
|
const getRolePayload = (type: 'root-custom' | 'custom' = 'custom') => ({
|
||||||
delete checkedPermissionsCopy[permission.id];
|
|
||||||
} else {
|
|
||||||
checkedPermissionsCopy[permission.id] = { ...permission };
|
|
||||||
}
|
|
||||||
|
|
||||||
setCheckedPermissions(checkedPermissionsCopy);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onToggleAllPermissions = () => {
|
|
||||||
let checkedPermissionsCopy = cloneDeep(checkedPermissions);
|
|
||||||
|
|
||||||
const allChecked = rootPermissions.every(
|
|
||||||
(permission: IPermission) => checkedPermissionsCopy[permission.id]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (allChecked) {
|
|
||||||
rootPermissions.forEach((permission: IPermission) => {
|
|
||||||
delete checkedPermissionsCopy[permission.id];
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
rootPermissions.forEach((permission: IPermission) => {
|
|
||||||
checkedPermissionsCopy[permission.id] = {
|
|
||||||
...permission,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setCheckedPermissions(checkedPermissionsCopy);
|
|
||||||
};
|
|
||||||
|
|
||||||
const getRolePayload = () => ({
|
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
type: 'root-custom',
|
type,
|
||||||
permissions: Object.values(checkedPermissions),
|
permissions: Object.values(checkedPermissions),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -121,14 +70,11 @@ export const useRoleForm = (
|
|||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
errors,
|
|
||||||
checkedPermissions,
|
checkedPermissions,
|
||||||
rootPermissions,
|
errors,
|
||||||
setName,
|
setName,
|
||||||
setDescription,
|
setDescription,
|
||||||
setCheckedPermissions,
|
setCheckedPermissions,
|
||||||
handlePermissionChange,
|
|
||||||
onToggleAllPermissions,
|
|
||||||
getRolePayload,
|
getRolePayload,
|
||||||
clearError,
|
clearError,
|
||||||
setError,
|
setError,
|
||||||
|
@ -10,6 +10,7 @@ import { formatUnknownError } from 'utils/formatUnknownError';
|
|||||||
import { FormEvent } from 'react';
|
import { FormEvent } from 'react';
|
||||||
import { useRolesApi } from 'hooks/api/actions/useRolesApi/useRolesApi';
|
import { useRolesApi } from 'hooks/api/actions/useRolesApi/useRolesApi';
|
||||||
import { useRole } from 'hooks/api/getters/useRole/useRole';
|
import { useRole } from 'hooks/api/getters/useRole/useRole';
|
||||||
|
import usePermissions from 'hooks/api/getters/usePermissions/usePermissions';
|
||||||
|
|
||||||
const StyledForm = styled('form')(() => ({
|
const StyledForm = styled('form')(() => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@ -44,12 +45,10 @@ export const RoleModal = ({ roleId, open, setOpen }: IRoleModalProps) => {
|
|||||||
setDescription,
|
setDescription,
|
||||||
checkedPermissions,
|
checkedPermissions,
|
||||||
setCheckedPermissions,
|
setCheckedPermissions,
|
||||||
handlePermissionChange,
|
|
||||||
getRolePayload,
|
getRolePayload,
|
||||||
isNameUnique,
|
isNameUnique,
|
||||||
isNotEmpty,
|
isNotEmpty,
|
||||||
hasPermissions,
|
hasPermissions,
|
||||||
rootPermissions,
|
|
||||||
errors,
|
errors,
|
||||||
setError,
|
setError,
|
||||||
clearError,
|
clearError,
|
||||||
@ -57,9 +56,18 @@ export const RoleModal = ({ roleId, open, setOpen }: IRoleModalProps) => {
|
|||||||
} = useRoleForm(role?.name, role?.description, role?.permissions);
|
} = useRoleForm(role?.name, role?.description, role?.permissions);
|
||||||
const { refetch: refetchRoles } = useRoles();
|
const { refetch: refetchRoles } = useRoles();
|
||||||
const { addRole, updateRole, loading } = useRolesApi();
|
const { addRole, updateRole, loading } = useRolesApi();
|
||||||
|
const { permissions } = usePermissions({
|
||||||
|
revalidateIfStale: false,
|
||||||
|
revalidateOnReconnect: false,
|
||||||
|
revalidateOnFocus: false,
|
||||||
|
});
|
||||||
const { setToastData, setToastApiError } = useToast();
|
const { setToastData, setToastApiError } = useToast();
|
||||||
const { uiConfig } = useUiConfig();
|
const { uiConfig } = useUiConfig();
|
||||||
|
|
||||||
|
const rootPermissions = permissions.root.filter(
|
||||||
|
({ name }) => name !== 'ADMIN'
|
||||||
|
);
|
||||||
|
|
||||||
const editing = role !== undefined;
|
const editing = role !== undefined;
|
||||||
const isValid =
|
const isValid =
|
||||||
isNameUnique(name) &&
|
isNameUnique(name) &&
|
||||||
@ -67,13 +75,15 @@ export const RoleModal = ({ roleId, open, setOpen }: IRoleModalProps) => {
|
|||||||
isNotEmpty(description) &&
|
isNotEmpty(description) &&
|
||||||
hasPermissions(checkedPermissions);
|
hasPermissions(checkedPermissions);
|
||||||
|
|
||||||
|
const payload = getRolePayload('root-custom');
|
||||||
|
|
||||||
const formatApiCode = () => {
|
const formatApiCode = () => {
|
||||||
return `curl --location --request ${editing ? 'PUT' : 'POST'} '${
|
return `curl --location --request ${editing ? 'PUT' : 'POST'} '${
|
||||||
uiConfig.unleashUrl
|
uiConfig.unleashUrl
|
||||||
}/api/admin/roles${editing ? `/${role.id}` : ''}' \\
|
}/api/admin/roles${editing ? `/${role.id}` : ''}' \\
|
||||||
--header 'Authorization: INSERT_API_KEY' \\
|
--header 'Authorization: INSERT_API_KEY' \\
|
||||||
--header 'Content-Type: application/json' \\
|
--header 'Content-Type: application/json' \\
|
||||||
--data-raw '${JSON.stringify(getRolePayload(), undefined, 2)}'`;
|
--data-raw '${JSON.stringify(payload, undefined, 2)}'`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSetName = (name: string) => {
|
const onSetName = (name: string) => {
|
||||||
@ -96,9 +106,9 @@ export const RoleModal = ({ roleId, open, setOpen }: IRoleModalProps) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (editing) {
|
if (editing) {
|
||||||
await updateRole(role.id, getRolePayload());
|
await updateRole(role.id, payload);
|
||||||
} else {
|
} else {
|
||||||
await addRole(getRolePayload());
|
await addRole(payload);
|
||||||
}
|
}
|
||||||
setToastData({
|
setToastData({
|
||||||
title: `Role ${editing ? 'updated' : 'added'} successfully`,
|
title: `Role ${editing ? 'updated' : 'added'} successfully`,
|
||||||
@ -136,7 +146,6 @@ export const RoleModal = ({ roleId, open, setOpen }: IRoleModalProps) => {
|
|||||||
setDescription={setDescription}
|
setDescription={setDescription}
|
||||||
checkedPermissions={checkedPermissions}
|
checkedPermissions={checkedPermissions}
|
||||||
setCheckedPermissions={setCheckedPermissions}
|
setCheckedPermissions={setCheckedPermissions}
|
||||||
handlePermissionChange={handlePermissionChange}
|
|
||||||
permissions={rootPermissions}
|
permissions={rootPermissions}
|
||||||
errors={errors}
|
errors={errors}
|
||||||
/>
|
/>
|
||||||
|
@ -14,7 +14,7 @@ export const RoleBadge = ({ roleId }: IRoleBadgeProps) => {
|
|||||||
if (!role) return null;
|
if (!role) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HtmlTooltip title={<RoleDescription roleId={roleId} tooltip />}>
|
<HtmlTooltip title={<RoleDescription roleId={roleId} tooltip />} arrow>
|
||||||
<Badge
|
<Badge
|
||||||
color="success"
|
color="success"
|
||||||
icon={<UserIcon />}
|
icon={<UserIcon />}
|
||||||
|
@ -2,21 +2,11 @@ import useSWR, { mutate, SWRConfiguration } from 'swr';
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { formatApiPath } from 'utils/formatPath';
|
import { formatApiPath } from 'utils/formatPath';
|
||||||
|
|
||||||
import {
|
import { IPermissions } from 'interfaces/permissions';
|
||||||
IProjectEnvironmentPermissions,
|
|
||||||
IPermissions,
|
|
||||||
IPermission,
|
|
||||||
} from 'interfaces/permissions';
|
|
||||||
import handleErrorResponses from '../httpErrorResponseHandler';
|
import handleErrorResponses from '../httpErrorResponseHandler';
|
||||||
|
|
||||||
interface IUsePermissions {
|
interface IUsePermissions {
|
||||||
permissions:
|
permissions: IPermissions;
|
||||||
| IPermissions
|
|
||||||
| {
|
|
||||||
root: IPermission[];
|
|
||||||
project: IPermission[];
|
|
||||||
environments: IProjectEnvironmentPermissions[];
|
|
||||||
};
|
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
refetch: () => void;
|
refetch: () => void;
|
||||||
error: any;
|
error: any;
|
||||||
|
@ -2,12 +2,12 @@ import { SWRConfiguration } from 'swr';
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { formatApiPath } from 'utils/formatPath';
|
import { formatApiPath } from 'utils/formatPath';
|
||||||
import handleErrorResponses from '../httpErrorResponseHandler';
|
import handleErrorResponses from '../httpErrorResponseHandler';
|
||||||
import IRole from 'interfaces/role';
|
import IRole, { IRoleWithPermissions } from 'interfaces/role';
|
||||||
import useUiConfig from '../useUiConfig/useUiConfig';
|
import useUiConfig from '../useUiConfig/useUiConfig';
|
||||||
import { useConditionalSWR } from '../useConditionalSWR/useConditionalSWR';
|
import { useConditionalSWR } from '../useConditionalSWR/useConditionalSWR';
|
||||||
|
|
||||||
export interface IUseRoleOutput {
|
export interface IUseRoleOutput {
|
||||||
role?: IRole;
|
role?: IRoleWithPermissions;
|
||||||
refetch: () => void;
|
refetch: () => void;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
error?: Error;
|
error?: Error;
|
||||||
@ -42,16 +42,19 @@ export const useRole = (
|
|||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
if (!isEnterprise()) {
|
if (!isEnterprise()) {
|
||||||
return {
|
return {
|
||||||
role: ((ossData?.rootRoles ?? []) as IRole[]).find(
|
role: {
|
||||||
({ id: rId }) => rId === +id!
|
...((ossData?.rootRoles ?? []) as IRole[]).find(
|
||||||
),
|
({ id: rId }) => rId === +id!
|
||||||
|
),
|
||||||
|
permissions: [],
|
||||||
|
} as IRoleWithPermissions,
|
||||||
loading: !ossError && !ossData,
|
loading: !ossError && !ossData,
|
||||||
refetch: () => ossMutate(),
|
refetch: () => ossMutate(),
|
||||||
error: ossError,
|
error: ossError,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
role: data as IRole,
|
role: data as IRoleWithPermissions,
|
||||||
loading: !error && !data,
|
loading: !error && !data,
|
||||||
refetch: () => mutate(),
|
refetch: () => mutate(),
|
||||||
error,
|
error,
|
||||||
|
@ -6,7 +6,10 @@ interface IRole {
|
|||||||
project: string | null;
|
project: string | null;
|
||||||
description: string;
|
description: string;
|
||||||
type: string;
|
type: string;
|
||||||
permissions?: IPermission[];
|
}
|
||||||
|
|
||||||
|
export interface IRoleWithPermissions extends IRole {
|
||||||
|
permissions: IPermission[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IProjectRole {
|
export interface IProjectRole {
|
||||||
|
63
frontend/src/utils/permissions.ts
Normal file
63
frontend/src/utils/permissions.ts
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import { IPermission, ICheckedPermissions } from 'interfaces/permissions';
|
||||||
|
import cloneDeep from 'lodash.clonedeep';
|
||||||
|
|
||||||
|
const getRoleKey = (permission: IPermission): string => {
|
||||||
|
return permission.environment
|
||||||
|
? `${permission.id}-${permission.environment}`
|
||||||
|
: `${permission.id}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const permissionsToCheckedPermissions = (
|
||||||
|
permissions: IPermission[]
|
||||||
|
): ICheckedPermissions =>
|
||||||
|
permissions.reduce(
|
||||||
|
(
|
||||||
|
checkedPermissions: { [key: string]: IPermission },
|
||||||
|
permission: IPermission
|
||||||
|
) => {
|
||||||
|
checkedPermissions[getRoleKey(permission)] = permission;
|
||||||
|
return checkedPermissions;
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
export const togglePermission = (
|
||||||
|
checkedPermissions: ICheckedPermissions,
|
||||||
|
permission: IPermission
|
||||||
|
): ICheckedPermissions => {
|
||||||
|
let checkedPermissionsCopy = cloneDeep(checkedPermissions);
|
||||||
|
|
||||||
|
if (checkedPermissionsCopy[getRoleKey(permission)]) {
|
||||||
|
delete checkedPermissionsCopy[getRoleKey(permission)];
|
||||||
|
} else {
|
||||||
|
checkedPermissionsCopy[getRoleKey(permission)] = { ...permission };
|
||||||
|
}
|
||||||
|
|
||||||
|
return checkedPermissionsCopy;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const toggleAllPermissions = (
|
||||||
|
checkedPermissions: ICheckedPermissions,
|
||||||
|
toggledPermissions: IPermission[]
|
||||||
|
): ICheckedPermissions => {
|
||||||
|
let checkedPermissionsCopy = cloneDeep(checkedPermissions);
|
||||||
|
|
||||||
|
const allChecked = toggledPermissions.every(
|
||||||
|
(permission: IPermission) =>
|
||||||
|
checkedPermissionsCopy[getRoleKey(permission)]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (allChecked) {
|
||||||
|
toggledPermissions.forEach((permission: IPermission) => {
|
||||||
|
delete checkedPermissionsCopy[getRoleKey(permission)];
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
toggledPermissions.forEach((permission: IPermission) => {
|
||||||
|
checkedPermissionsCopy[getRoleKey(permission)] = {
|
||||||
|
...permission,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return checkedPermissionsCopy;
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user