diff --git a/src/i18n/de.ts b/src/i18n/de.ts
index 9fd96ff..2917b9d 100644
--- a/src/i18n/de.ts
+++ b/src/i18n/de.ts
@@ -142,6 +142,7 @@ const de: SynapseTranslationMessages = {
password: "Durch die Änderung des Passworts wird der Benutzer von allen Sitzungen abgemeldet.",
deactivate: "Sie müssen ein Passwort angeben, um ein Konto wieder zu aktivieren.",
erase: "DSGVO konformes Löschen der Benutzerdaten",
+ erase_admin_error: "Das Löschen des eigenen Benutzers ist nicht erlaubt",
},
action: {
erase: "Lösche Benutzerdaten",
diff --git a/src/i18n/en.ts b/src/i18n/en.ts
index 7577342..c6ef695 100644
--- a/src/i18n/en.ts
+++ b/src/i18n/en.ts
@@ -141,6 +141,7 @@ const en: SynapseTranslationMessages = {
password: "Changing password will log user out of all sessions.",
deactivate: "You must provide a password to re-activate an account.",
erase: "Mark the user as GDPR-erased",
+ erase_admin_error: "Deleting own user is not allowed.",
},
action: {
erase: "Erase user data",
diff --git a/src/i18n/fr.ts b/src/i18n/fr.ts
index af54bd6..b973061 100644
--- a/src/i18n/fr.ts
+++ b/src/i18n/fr.ts
@@ -139,6 +139,7 @@ const fr: SynapseTranslationMessages = {
helper: {
deactivate: "Vous devrez fournir un mot de passe pour réactiver le compte.",
erase: "Marquer l'utilisateur comme effacé conformément au RGPD",
+ erase_admin_error: "La suppression de son propre utilisateur n'est pas autorisée.",
},
action: {
erase: "Effacer les données de l'utilisateur",
diff --git a/src/i18n/index.d.ts b/src/i18n/index.d.ts
index 38635ad..8a2abb5 100644
--- a/src/i18n/index.d.ts
+++ b/src/i18n/index.d.ts
@@ -137,6 +137,7 @@ interface SynapseTranslationMessages extends TranslationMessages {
password?: string;
deactivate: string;
erase: string;
+ erase_admin_error: string;
};
action: {
erase: string;
diff --git a/src/i18n/it.ts b/src/i18n/it.ts
index bb813c5..3eedd85 100644
--- a/src/i18n/it.ts
+++ b/src/i18n/it.ts
@@ -141,6 +141,7 @@ const it: SynapseTranslationMessages = {
},
action: {
erase: "Cancella i dati dell'utente",
+ erase_admin_error: "Non è consentito eliminare il proprio utente.",
},
},
rooms: {
diff --git a/src/i18n/ru.ts b/src/i18n/ru.ts
index 5976e11..055479a 100644
--- a/src/i18n/ru.ts
+++ b/src/i18n/ru.ts
@@ -150,6 +150,7 @@ const ru: SynapseTranslationMessages = {
password: "Смена пароля завершит все сессии пользователя.",
deactivate: "Вы должны предоставить пароль для реактивации учётной записи.",
erase: "Пометить пользователя как удалённого в соответствии с GDPR",
+ erase_admin_error: "Удаление собственного пользователя запрещено.",
},
action: {
erase: "Удалить данные пользователя",
diff --git a/src/i18n/zh.ts b/src/i18n/zh.ts
index 86ca9df..eabe806 100644
--- a/src/i18n/zh.ts
+++ b/src/i18n/zh.ts
@@ -134,6 +134,7 @@ const zh: SynapseTranslationMessages = {
helper: {
deactivate: "您必须提供一串密码来激活账户。",
erase: "将用户标记为根据 GDPR 的要求抹除了",
+ erase_admin_error: "不允许删除自己的用户",
},
action: {
erase: "抹除用户信息",
diff --git a/src/resources/users.tsx b/src/resources/users.tsx
index 2e33df4..eb80dc6 100644
--- a/src/resources/users.tsx
+++ b/src/resources/users.tsx
@@ -8,6 +8,8 @@ import PermMediaIcon from "@mui/icons-material/PermMedia";
import PersonPinIcon from "@mui/icons-material/PersonPin";
import SettingsInputComponentIcon from "@mui/icons-material/SettingsInputComponent";
import ViewListIcon from "@mui/icons-material/ViewList";
+import { useEffect, useState } from "react";
+import { Alert, ownerDocument } from "@mui/material";
import {
ArrayInput,
ArrayField,
@@ -42,11 +44,15 @@ import {
useRecordContext,
useTranslate,
Pagination,
+ SaveButton,
CreateButton,
ExportButton,
TopToolbar,
+ Toolbar,
NumberField,
useListContext,
+ useNotify,
+ ToolbarClasses,
} from "react-admin";
import { Link } from "react-router-dom";
@@ -92,16 +98,47 @@ const userFilters = [
,
];
-const UserBulkActionButtons = () => (
- <>
+const UserPreventSelfDelete: React.FC<{ children: React.ReactNode, ownUserIsSelected: boolean }> = (props) => {
+ const ownUserIsSelected = props.ownUserIsSelected;
+ const notify = useNotify();
+ const translate = useTranslate();
+
+ const handleDeleteClick = (ev: React.MouseEvent) => {
+ if (ownUserIsSelected) {
+ notify({translate("resources.users.helper.erase_admin_error")})
+ ev.stopPropagation();
+ }
+ };
+
+ return
+ {props.children}
+
+};
+
+const UserBulkActionButtons = () => {
+ const record = useListContext();
+ const [ ownUserIsSelected, setOwnUserIsSelected ] = useState(false);
+ const selectedIds = record.selectedIds;
+ const ownUserId = localStorage.getItem("user_id");
+ const notify = useNotify();
+ const translate = useTranslate();
+
+ useEffect(() => {
+ setOwnUserIsSelected(selectedIds.includes(ownUserId));
+ }, [ selectedIds ]);
+
+
+ return <>
-
+
+
+
>
-);
+};
export const UserList = (props: ListProps) => (
{
const record = useRecordContext();
const translate = useTranslate();
+ const ownUserId = localStorage.getItem("user_id");
+ let ownUserIsSelected = false;
+ if (record && record.id) {
+ ownUserIsSelected = record.id === ownUserId;
+ }
return (
{!record?.deactivated && }
-
+
+
+
);
};
@@ -189,11 +233,44 @@ const UserTitle = () => {
);
};
+const UserEditToolbar = () => {
+ const record = useRecordContext();
+ const ownUserId = localStorage.getItem("user_id");
+ let ownUserIsSelected = false;
+ if (record && record.id) {
+ ownUserIsSelected = record.id === ownUserId;
+ }
+
+ return <>
+
+
+
+
+
+
+
+
+ >
+};
+
+const UserBooleanInput = (props) => {
+ const record = useRecordContext();
+ const ownUserId = localStorage.getItem("user_id");
+ const isOwnUser = false;
+ let ownUserIsSelected = false;
+ if (record && (record.id === ownUserId)) {
+ ownUserIsSelected = true;
+ }
+
+ return
+}
+
export const UserEdit = (props: EditProps) => {
const translate = useTranslate();
+
return (
} actions={}>
-
+ }>
}>
@@ -202,7 +279,7 @@ export const UserEdit = (props: EditProps) => {
-
+