From 7de9166648aafbc9b6d71e2f5b31de2ecbf1f347 Mon Sep 17 00:00:00 2001 From: Borislav Pantaleev Date: Sat, 14 Sep 2024 11:03:51 +0300 Subject: [PATCH] Add UI option to block deleted rooms from being rejoined (#26) Add UI option to block deleted rooms from being rejoined This is almost a copy of https://github.com/Awesome-Technologies/synapse-admin/pull/166 PR, authored by @jkanefendt --- .github/workflows/workflow.yml | 2 +- README.md | 1 + src/components/DeleteRoomButton.tsx | 105 ++++++++++++++++++++++++++++ src/i18n/de.ts | 5 ++ src/i18n/en.ts | 5 ++ src/i18n/fr.ts | 5 ++ src/i18n/index.d.ts | 5 ++ src/i18n/ru.ts | 5 ++ src/resources/rooms.tsx | 31 ++++---- src/synapse/authProvider.test.ts | 3 +- src/synapse/dataProvider.ts | 2 +- 11 files changed, 153 insertions(+), 16 deletions(-) create mode 100644 src/components/DeleteRoomButton.tsx diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 11f55ed..33c6545 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -4,7 +4,7 @@ on: branches: [ "main" ] env: upstream_version: v0.10.3 - etke_version: etke12 + etke_version: etke13 bunny_version: v0.1.0 base_path: ./ permissions: diff --git a/README.md b/README.md index b0d6339..fc90ac3 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ The following changes are already implemented: * [Fix base_url being undefined on unsuccessful login](https://github.com/etkecc/synapse-admin/pull/18) * [Put the version into manifest.json](https://github.com/Awesome-Technologies/synapse-admin/issues/507) (CI only) * [Federation page improvements](https://github.com/Awesome-Technologies/synapse-admin/pull/583) (using theme colors) +* [Add UI option to block deleted rooms from being rejoined](https://github.com/etkecc/synapse-admin/pull/26) _the list will be updated as new changes are added_ diff --git a/src/components/DeleteRoomButton.tsx b/src/components/DeleteRoomButton.tsx new file mode 100644 index 0000000..e21c2f2 --- /dev/null +++ b/src/components/DeleteRoomButton.tsx @@ -0,0 +1,105 @@ +import { Button, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material"; +import { Fragment, useState } from "react"; +import { SimpleForm, BooleanInput, useTranslate, RaRecord, useNotify, useRedirect, useDelete, NotificationType, useDeleteMany, Identifier, useUnselectAll } from "react-admin"; +import ActionDelete from "@mui/icons-material/Delete"; +import ActionCheck from "@mui/icons-material/CheckCircle"; +import AlertError from "@mui/icons-material/ErrorOutline"; + +interface DeleteRoomButtonProps { + selectedIds: Identifier[]; + confirmTitle: string; + confirmContent: string; +} + +const resourceName = "rooms"; + +const DeleteRoomButton: React.FC = (props) => { + const translate = useTranslate(); + const [open, setOpen] = useState(false); + const [block, setBlock] = useState(true); + + const notify = useNotify(); + const redirect = useRedirect(); + + const [deleteMany, { isLoading }] = useDeleteMany(); + const unselectAll = useUnselectAll(resourceName); + const recordIds = props.selectedIds; + + const handleDialogOpen = () => setOpen(true); + const handleDialogClose = () => setOpen(false); + + const handleDelete = (values: {block: boolean}) => { + deleteMany( + resourceName, + { ids: recordIds, meta: values }, + { + onSuccess: () => { + notify("resources.rooms.action.erase.success"); + handleDialogClose(); + unselectAll(); + redirect("/rooms"); + }, + onError: (error) => + notify("resources.rooms.action.erase.failure", { type: 'error' as NotificationType }), + } + ); + }; + + const handleConfirm = () => { + setOpen(false); + handleDelete({ block: block }); + }; + + return ( + + + + {translate(props.confirmTitle)} + + {translate(props.confirmContent)} + + ) => setBlock(event.target.checked)} + label="resources.rooms.action.erase.fields.block" + defaultValue={true} + /> + + + + + + + + + ); +}; + +export default DeleteRoomButton; diff --git a/src/i18n/de.ts b/src/i18n/de.ts index 51e4fd5..d5034f8 100644 --- a/src/i18n/de.ts +++ b/src/i18n/de.ts @@ -199,6 +199,11 @@ const de: SynapseTranslationMessages = { title: "Raum löschen", content: "Sind Sie sicher dass Sie den Raum löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden. Alle Nachrichten und Medien, die der Raum beinhaltet werden vom Server gelöscht!", + fields: { + block: "Benutzer blockieren und daran hindern, dem Raum beizutreten", + }, + success: "Raum/Räume erfolgreich gelöscht.", + failure: "Der/die Raum/Räume konnten nicht gelöscht werden.", }, }, }, diff --git a/src/i18n/en.ts b/src/i18n/en.ts index 5fa1dda..a44d405 100644 --- a/src/i18n/en.ts +++ b/src/i18n/en.ts @@ -198,6 +198,11 @@ const en: SynapseTranslationMessages = { title: "Delete room", content: "Are you sure you want to delete the room? This cannot be undone. All messages and shared media in the room will be deleted from the server!", + fields: { + block: "Block and prevent users from joining the room", + }, + success: "Room/s successfully deleted.", + failure: "The room/s could not be deleted.", }, }, }, diff --git a/src/i18n/fr.ts b/src/i18n/fr.ts index fff036f..50ac6d0 100644 --- a/src/i18n/fr.ts +++ b/src/i18n/fr.ts @@ -196,6 +196,11 @@ const fr: SynapseTranslationMessages = { title: "Supprimer le salon", content: "Voulez-vous vraiment supprimer le salon ? Cette opération ne peut être annulée. Tous les messages et médias partagés du salon seront supprimés du serveur !", + fields: { + block: "Bloquer et empêcher les utilisateurs de rejoindre la salle", + }, + success: "Salle/s supprimées avec succès.", + failure: "La/les salle/s n'ont pas pu être supprimées.", }, }, }, diff --git a/src/i18n/index.d.ts b/src/i18n/index.d.ts index c3662f1..325fe21 100644 --- a/src/i18n/index.d.ts +++ b/src/i18n/index.d.ts @@ -192,6 +192,11 @@ interface SynapseTranslationMessages extends TranslationMessages { erase: { title: string; content: string; + fields: { + block: string; + }, + success: string; + failure: string; }; }; }; diff --git a/src/i18n/ru.ts b/src/i18n/ru.ts index 67e2db1..d5380ec 100644 --- a/src/i18n/ru.ts +++ b/src/i18n/ru.ts @@ -210,6 +210,11 @@ const ru: SynapseTranslationMessages = { title: "Удалить комнату", content: "Действительно удалить эту комнату? Это действие будет невозможно отменить. Все сообщения и файлы в комнате будут удалены с сервера!", + fields: { + block: "Заблокировать и запретить пользователям присоединяться к комнате", + }, + success: "Комната/ы успешно удалены", + failure: "Комната/ы не могут быть удалены.", }, }, }, diff --git a/src/resources/rooms.tsx b/src/resources/rooms.tsx index 9e974af..43f1228 100644 --- a/src/resources/rooms.tsx +++ b/src/resources/rooms.tsx @@ -36,6 +36,7 @@ import { TopToolbar, useRecordContext, useTranslate, + useListContext, } from "react-admin"; import { @@ -45,6 +46,7 @@ import { RoomDirectoryPublishButton, } from "./room_directory"; import { DATE_FORMAT } from "../components/date"; +import DeleteRoomButton from "../components/DeleteRoomButton"; const RoomPagination = () => ; @@ -70,8 +72,8 @@ const RoomShowActions = () => { return ( {publishButton} - @@ -207,17 +209,20 @@ export const RoomShow = (props: ShowProps) => { ); }; -const RoomBulkActionButtons = () => ( - <> - - - - -); +const RoomBulkActionButtons = () => { + const record = useListContext(); + return ( + <> + + + + + ); +}; const roomFilters = []; diff --git a/src/synapse/authProvider.test.ts b/src/synapse/authProvider.test.ts index ad61500..340f5c3 100644 --- a/src/synapse/authProvider.test.ts +++ b/src/synapse/authProvider.test.ts @@ -2,6 +2,7 @@ import fetchMock from "jest-fetch-mock"; import authProvider from "./authProvider"; import storage from "../storage"; +import { HttpError } from "ra-core"; fetchMock.enableMocks(); @@ -104,7 +105,7 @@ describe("authProvider", () => { }); it("should reject if error.status is 403", async () => { - await expect(authProvider.checkError({ status: 403 })).rejects.toBeUndefined(); + await expect(authProvider.checkError(new HttpError("test-error", 403, {errcode: "test-errcode", error: "test-error"}))).rejects.toBeDefined(); }); }); diff --git a/src/synapse/dataProvider.ts b/src/synapse/dataProvider.ts index 05adec0..d69a760 100644 --- a/src/synapse/dataProvider.ts +++ b/src/synapse/dataProvider.ts @@ -270,7 +270,7 @@ const resourceMap = { total: json => json.total_rooms, delete: (params: DeleteParams) => ({ endpoint: `/_synapse/admin/v2/rooms/${params.id}`, - body: { block: false }, + body: { block: params.meta?.block ?? false }, }), }, reports: {