diff --git a/src/components/accessories/admin/users/editGroup/EditGroup.tsx b/src/components/accessories/admin/users/editGroup/EditGroup.tsx
index c9ac20d9a..a5b77b261 100644
--- a/src/components/accessories/admin/users/editGroup/EditGroup.tsx
+++ b/src/components/accessories/admin/users/editGroup/EditGroup.tsx
@@ -22,13 +22,13 @@ import {
updateUserGroup,
updateUserGroupReset,
} from "../../../../../state/usergroups";
+import { TabOptions } from "../Users";
import { GroupPermissionsEditor } from "../editPermissions/GroupPermissionsEditor";
import {
PermissionActionEnum,
PermissionActionType,
comparePermissions,
} from "../editPermissions/permission.utils";
-import { TabOptions } from "../Users";
import "./styles.scss";
import { userGroupSchema } from "./validation";
@@ -58,18 +58,18 @@ export const EditGroup = () => {
>([]);
const handleUpdatePermissions = ({
- permission,
+ permissions: perms,
action,
}: PermissionActionType) => {
const otherPermissions = groupPermissions.filter(
- (p) => p.id !== permission.id
+ (p) => !perms.some((item) => item.id === p.id)
);
if (action === PermissionActionEnum.REVOKE) {
setGroupPermissions(otherPermissions);
}
if (action === PermissionActionEnum.ASSIGN) {
- setGroupPermissions([...otherPermissions, permission]);
+ setGroupPermissions([...otherPermissions, ...perms]);
}
};
@@ -197,13 +197,15 @@ export const EditGroup = () => {
Editing permissions:{" "}
{updatedPermissionsStack
- .map(
- (p) =>
- `${p.permission.name}: ${
- p.action === PermissionActionEnum.ASSIGN
- ? "assign"
- : "revoked"
- }`
+ .flatMap((p) =>
+ p.permissions.map(
+ (item) =>
+ `${item.name}: ${
+ p.action === PermissionActionEnum.ASSIGN
+ ? "assign"
+ : "revoked"
+ }`
+ )
)
.join(",")}
diff --git a/src/components/accessories/admin/users/editPermissions/AclPermissionCheckbox.tsx b/src/components/accessories/admin/users/editPermissions/AclPermissionCheckbox.tsx
index 6c38dd86f..eb9e0d812 100644
--- a/src/components/accessories/admin/users/editPermissions/AclPermissionCheckbox.tsx
+++ b/src/components/accessories/admin/users/editPermissions/AclPermissionCheckbox.tsx
@@ -1,12 +1,16 @@
-import { Checkbox, Popper } from "@mui/material";
+import { Checkbox, Tooltip } from "@mui/material";
import React from "react";
+import { useTranslation } from "react-i18next";
import { PermissionDTO } from "../../../../../generated";
import { PermissionActionEnum } from "./permission.utils";
interface IProps {
permission: PermissionDTO;
groupPermissions: Array;
- onChange: (permission: PermissionDTO, action: PermissionActionEnum) => void;
+ onChange: (
+ permissions: [PermissionDTO],
+ action: PermissionActionEnum
+ ) => void;
}
export const AclPermissionCheckbox = ({
@@ -14,46 +18,22 @@ export const AclPermissionCheckbox = ({
groupPermissions,
onChange,
}: IProps) => {
- const [anchorEl, setAnchorEl] = React.useState(null);
- const open = Boolean(anchorEl);
- const id = open ? "simple-popper" : undefined;
+ const { t } = useTranslation();
const checked =
groupPermissions?.some((p) => p.id === permission.id) || false;
return (
- <>
+
onChange(
- permission,
+ [permission],
checked ? PermissionActionEnum.REVOKE : PermissionActionEnum.ASSIGN
)
}
name={permission.id.toString()}
- onMouseEnter={(event: React.MouseEvent) => {
- setAnchorEl(anchorEl ? null : event.currentTarget);
- }}
- onMouseLeave={() => setAnchorEl(null)}
/>
-
-
- {permission.name || "unknown"}
-
-
- >
+
);
};
diff --git a/src/components/accessories/admin/users/editPermissions/AclTable.tsx b/src/components/accessories/admin/users/editPermissions/AclTable.tsx
index 42eb72d3b..1b511d00d 100644
--- a/src/components/accessories/admin/users/editPermissions/AclTable.tsx
+++ b/src/components/accessories/admin/users/editPermissions/AclTable.tsx
@@ -1,5 +1,6 @@
-import React, { useMemo } from "react";
+import React, { ChangeEvent, useCallback, useMemo } from "react";
+import { Checkbox, Tooltip } from "@mui/material";
import { useTranslation } from "react-i18next";
import { PermissionDTO } from "../../../../../generated";
import { AclPermissionCheckbox } from "./AclPermissionCheckbox";
@@ -13,7 +14,10 @@ import {
interface IProps {
permissions: PermissionDTO[];
groupPermissions: PermissionDTO[];
- onChange: (permission: PermissionDTO, action: PermissionActionEnum) => void;
+ onChange: (
+ permissions: PermissionDTO[],
+ action: PermissionActionEnum
+ ) => void;
}
export const AclTable = ({
@@ -29,22 +33,111 @@ export const AclTable = ({
const crudKeys = Array.from(crudPermissions.keys());
+ const allColumnsChecked = useCallback(
+ (crudKey: string) => {
+ return (
+ [Crud.CREATE, Crud.READ, Crud.UPDATE, Crud.DELETE].filter((item) =>
+ groupPermissions.some((p) => p.name === `${crudKey}.${item}`)
+ ).length ===
+ [Crud.CREATE, Crud.READ, Crud.UPDATE, Crud.DELETE].filter((item) =>
+ permissions.some((p) => p.name === `${crudKey}.${item}`)
+ ).length
+ );
+ },
+ [groupPermissions, permissions]
+ );
+
+ const allRowsChecked = useCallback(() => {
+ return (
+ crudKeys.filter((crudKey) => allColumnsChecked(crudKey)).length ===
+ crudKeys.length
+ );
+ }, [groupPermissions, permissions, allColumnsChecked]);
+
+ const toggleCheckAllColumns = useCallback(
+ (crudKey: string) => (event: ChangeEvent) => {
+ const crudPermNames = [
+ Crud.CREATE,
+ Crud.READ,
+ Crud.UPDATE,
+ Crud.DELETE,
+ ].map((item) => `${crudKey}.${item}`);
+ const crudPerms = permissions.filter((p) =>
+ crudPermNames.includes(p.name!)
+ );
+ if (event.target.checked) {
+ onChange(
+ crudPerms.filter(
+ (item) => !groupPermissions.some((p) => p.id === item.id)
+ ),
+ PermissionActionEnum.ASSIGN
+ );
+ } else {
+ onChange(crudPerms, PermissionActionEnum.REVOKE);
+ }
+ },
+ [groupPermissions, permissions, onChange]
+ );
+
+ const toggleCheckAllRows = useCallback(
+ (event: ChangeEvent) => {
+ const crudPermNames = [
+ Crud.CREATE,
+ Crud.READ,
+ Crud.UPDATE,
+ Crud.DELETE,
+ ].flatMap((item) => crudKeys.map((crudKey) => `${crudKey}.${item}`));
+ const crudPerms = permissions.filter((p) =>
+ crudPermNames.includes(p.name!)
+ );
+ if (event.target.checked) {
+ onChange(
+ crudPerms.filter(
+ (item) => !groupPermissions.some((p) => p.id === item.id)
+ ),
+ PermissionActionEnum.ASSIGN
+ );
+ } else {
+ onChange(crudPerms, PermissionActionEnum.REVOKE);
+ }
+ },
+ [groupPermissions, permissions]
+ );
+
return (
+
+
+
+
+ |
{t("permission.name")} |
{t("permission.create")} |
{t("permission.read")} |
{t("permission.update")} |
- {t("permission.deleted")} |
+ {t("permission.delete")} |
{Array.from(crudPermissions.values()).map((crudPermission, index) => {
return (
+
+
+
+
+ |
{crudKeys[index]} |
{[Crud.CREATE, Crud.READ, Crud.UPDATE, Crud.DELETE].map(
(access: Crud, index: number) => {
diff --git a/src/components/accessories/admin/users/editPermissions/AreaAccess.tsx b/src/components/accessories/admin/users/editPermissions/AreaAccess.tsx
index ec90d1dbc..cdf822740 100644
--- a/src/components/accessories/admin/users/editPermissions/AreaAccess.tsx
+++ b/src/components/accessories/admin/users/editPermissions/AreaAccess.tsx
@@ -7,7 +7,10 @@ import { PermissionActionEnum } from "./permission.utils";
interface IProps {
permissions: PermissionDTO[];
groupPermissions: PermissionDTO[];
- onChange: (permission: PermissionDTO, action: PermissionActionEnum) => void;
+ onChange: (
+ permissions: PermissionDTO[],
+ action: PermissionActionEnum
+ ) => void;
}
export const AreaAccess = ({
permissions,
diff --git a/src/components/accessories/admin/users/editPermissions/GroupPermissionsEditor.tsx b/src/components/accessories/admin/users/editPermissions/GroupPermissionsEditor.tsx
index ee15e53f9..f73a5aa0d 100644
--- a/src/components/accessories/admin/users/editPermissions/GroupPermissionsEditor.tsx
+++ b/src/components/accessories/admin/users/editPermissions/GroupPermissionsEditor.tsx
@@ -19,11 +19,11 @@ export const GroupPermissionsEditor = ({
update,
}: IProps) => {
const handleChange = (
- newPermission: PermissionDTO,
+ newPermissions: PermissionDTO[],
action: PermissionActionEnum
) => {
setDirty(true);
- update({ permission: newPermission, action });
+ update({ permissions: newPermissions, action });
};
const { t } = useTranslation();
diff --git a/src/components/accessories/admin/users/editPermissions/PermissionCheckbox.tsx b/src/components/accessories/admin/users/editPermissions/PermissionCheckbox.tsx
index 3ac90792c..b5547d822 100644
--- a/src/components/accessories/admin/users/editPermissions/PermissionCheckbox.tsx
+++ b/src/components/accessories/admin/users/editPermissions/PermissionCheckbox.tsx
@@ -6,7 +6,10 @@ import { PermissionActionEnum } from "./permission.utils";
interface IProps {
permission: PermissionDTO;
groupPermissions: Array;
- onChange: (permission: PermissionDTO, action: PermissionActionEnum) => void;
+ onChange: (
+ permissions: PermissionDTO[],
+ action: PermissionActionEnum
+ ) => void;
}
export const PermissionCheckbox = ({
@@ -23,7 +26,7 @@ export const PermissionCheckbox = ({
checked={checked}
onChange={(_ev, val) =>
onChange(
- permission,
+ [permission],
checked
? PermissionActionEnum.REVOKE
: PermissionActionEnum.ASSIGN
diff --git a/src/components/accessories/admin/users/editPermissions/permission.utils.ts b/src/components/accessories/admin/users/editPermissions/permission.utils.ts
index efd8d53ac..da29cdc52 100644
--- a/src/components/accessories/admin/users/editPermissions/permission.utils.ts
+++ b/src/components/accessories/admin/users/editPermissions/permission.utils.ts
@@ -7,7 +7,7 @@ export enum PermissionActionEnum {
export type PermissionActionType = {
action: PermissionActionEnum;
- permission: PermissionDTO;
+ permissions: PermissionDTO[];
};
export enum Crud {
@@ -79,7 +79,7 @@ export const comparePermissions = (
action: stackedPermission
? PermissionActionEnum.ASSIGN
: PermissionActionEnum.REVOKE,
- permission,
+ permissions: [permission],
},
];
}
diff --git a/src/resources/i18n/en.json b/src/resources/i18n/en.json
index e580cb747..b2271af58 100644
--- a/src/resources/i18n/en.json
+++ b/src/resources/i18n/en.json
@@ -576,8 +576,11 @@
"read": "Read",
"update": "Update",
"deleted": "Deleted",
+ "delete": "Delete",
"accessarea": "Access area",
- "accesscontrollist": "Access control list"
+ "accesscontrollist": "Access control list",
+ "toggle-check-all": "Toggle check all",
+ "all": "All"
},
"therapy": {
"newtherapy": "New Therapy",