diff --git a/src/components/devices.js b/src/components/devices.js
new file mode 100644
index 0000000..ee9292c
--- /dev/null
+++ b/src/components/devices.js
@@ -0,0 +1,89 @@
+import React, { Fragment, useState } from "react";
+import {
+ Button,
+ useMutation,
+ useNotify,
+ Confirm,
+ useRefresh,
+} from "react-admin";
+import ActionDelete from "@material-ui/icons/Delete";
+import { makeStyles } from "@material-ui/core/styles";
+import { fade } from "@material-ui/core/styles/colorManipulator";
+import classnames from "classnames";
+
+const useStyles = makeStyles(
+ theme => ({
+ deleteButton: {
+ color: theme.palette.error.main,
+ "&:hover": {
+ backgroundColor: fade(theme.palette.error.main, 0.12),
+ // Reset on mouse devices
+ "@media (hover: none)": {
+ backgroundColor: "transparent",
+ },
+ },
+ },
+ }),
+ { name: "RaDeleteDeviceButton" }
+);
+
+export const DeviceRemoveButton = props => {
+ const { record } = props;
+ const classes = useStyles(props);
+ const [open, setOpen] = useState(false);
+ const refresh = useRefresh();
+ const notify = useNotify();
+
+ const [removeDevice, { loading }] = useMutation();
+
+ if (!record) return null;
+
+ const handleClick = () => setOpen(true);
+ const handleDialogClose = () => setOpen(false);
+
+ const handleConfirm = () => {
+ removeDevice(
+ {
+ type: "delete",
+ resource: "devices",
+ payload: {
+ id: record.id,
+ user_id: record.user_id,
+ },
+ },
+ {
+ onSuccess: () => {
+ notify("resources.devices.action.erase.success");
+ refresh();
+ },
+ onFailure: () =>
+ notify("resources.devices.action.erase.failure", "error"),
+ }
+ );
+ setOpen(false);
+ };
+
+ return (
+
+
+
+
+ );
+};
diff --git a/src/components/users.js b/src/components/users.js
index cb98cd9..a6889b2 100644
--- a/src/components/users.js
+++ b/src/components/users.js
@@ -38,6 +38,7 @@ import {
sanitizeListRestProps,
} from "react-admin";
import { ServerNoticeButton, ServerNoticeBulkButton } from "./ServerNotices";
+import { DeviceRemoveButton } from "./devices";
import { makeStyles } from "@material-ui/core/styles";
const useStyles = makeStyles({
@@ -284,6 +285,7 @@ export const UserEdit = props => {
}}
sortable={false}
/>
+
diff --git a/src/i18n/de.js b/src/i18n/de.js
index 3f95a1d..0243041 100644
--- a/src/i18n/de.js
+++ b/src/i18n/de.js
@@ -114,6 +114,14 @@ export default {
},
devices: {
name: "Gerät |||| Geräte",
+ action: {
+ erase: {
+ title: "Entferne %{id}",
+ content: 'Möchten Sie das Gerät "%{name}" wirklich entfernen?',
+ success: "Gerät erfolgreich entfernt.",
+ failure: "Beim Entfernen ist ein Fehler aufgetreten.",
+ },
+ },
},
servernotices: {
name: "Serverbenachrichtigungen",
diff --git a/src/i18n/en.js b/src/i18n/en.js
index cc98c6b..f6501c9 100644
--- a/src/i18n/en.js
+++ b/src/i18n/en.js
@@ -112,6 +112,14 @@ export default {
},
devices: {
name: "Device |||| Devices",
+ action: {
+ erase: {
+ title: "Removing %{id}",
+ content: 'Are you sure you want to remove the device "%{name}"?',
+ success: "Device successfully removed.",
+ failure: "An error has occurred.",
+ },
+ },
},
servernotices: {
name: "Server Notices",
diff --git a/src/synapse/dataProvider.js b/src/synapse/dataProvider.js
index 674d935..d4c8bcd 100644
--- a/src/synapse/dataProvider.js
+++ b/src/synapse/dataProvider.js
@@ -45,8 +45,8 @@ const resourceMap = {
body: data,
method: "PUT",
}),
- delete: id => ({
- endpoint: `/_synapse/admin/v1/deactivate/${id}`,
+ delete: params => ({
+ endpoint: `/_synapse/admin/v1/deactivate/${params.id}`,
body: { erase: true },
method: "POST",
}),
@@ -76,6 +76,9 @@ const resourceMap = {
reference: id => ({
endpoint: `/_synapse/admin/v2/users/${id}/devices`,
}),
+ delete: params => ({
+ endpoint: `/_synapse/admin/v2/users/${params.user_id}/devices/${params.id}`,
+ }),
},
connections: {
path: "/_synapse/admin/v1/whois",
@@ -274,11 +277,11 @@ const dataProvider = {
const res = resourceMap[resource];
if ("delete" in res) {
- const del = res["delete"](params.id);
+ const del = res["delete"](params);
const endpoint_url = homeserver + del.endpoint;
return jsonClient(endpoint_url, {
- method: del.method,
- body: JSON.stringify(del.body),
+ method: "method" in del ? del.method : "DELETE",
+ body: "body" in del ? JSON.stringify(del.body) : null,
}).then(({ json }) => ({
data: json,
}));
@@ -303,11 +306,11 @@ const dataProvider = {
if ("delete" in res) {
return Promise.all(
params.ids.map(id => {
- const del = res["delete"](id);
+ const del = res["delete"]({ ...params, id: id });
const endpoint_url = homeserver + del.endpoint;
return jsonClient(endpoint_url, {
- method: del.method,
- body: JSON.stringify(del.body),
+ method: "method" in del ? del.method : "DELETE",
+ body: "body" in del ? JSON.stringify(del.body) : null,
});
})
).then(responses => ({