mirror of
https://github.com/docmost/docmost.git
synced 2026-05-07 14:43:06 +08:00
6ccb2bb872
* feat(export): add metadata file to preserve page icons and ordering on import - Export includes `docmost-metadata.json` - Import reads metadata to restore icons and sort siblings by original position * cleanup * bonus fixes * handle unknown prosemirror nodes * add docmost app version
95 lines
2.8 KiB
TypeScript
95 lines
2.8 KiB
TypeScript
import { Button, Divider, Group, Modal, Text, TextInput } from "@mantine/core";
|
|
import { useDisclosure } from "@mantine/hooks";
|
|
import { useDeleteSpaceMutation } from "../queries/space-query";
|
|
import { useField } from "@mantine/form";
|
|
import { ISpace } from "../types/space.types";
|
|
import { useNavigate } from "react-router-dom";
|
|
import APP_ROUTE from "@/lib/app-route";
|
|
import { Trans, useTranslation } from "react-i18next";
|
|
import { useState } from "react";
|
|
|
|
interface DeleteSpaceModalProps {
|
|
space: ISpace;
|
|
}
|
|
|
|
export default function DeleteSpaceModal({ space }: DeleteSpaceModalProps) {
|
|
const { t } = useTranslation();
|
|
const [opened, { open, close }] = useDisclosure(false);
|
|
const [isDeleting, setIsDeleting] = useState(false);
|
|
const deleteSpaceMutation = useDeleteSpaceMutation();
|
|
const navigate = useNavigate();
|
|
|
|
const confirmNameField = useField({
|
|
initialValue: "",
|
|
validateOnChange: true,
|
|
validate: (value) =>
|
|
value.trim().toLowerCase() === space.name.trim().toLocaleLowerCase()
|
|
? null
|
|
: t("Names do not match"),
|
|
});
|
|
|
|
const handleDelete = async () => {
|
|
if (
|
|
confirmNameField.getValue().trim().toLowerCase() !==
|
|
space.name.trim().toLowerCase()
|
|
) {
|
|
confirmNameField.validate();
|
|
return;
|
|
}
|
|
|
|
setIsDeleting(true);
|
|
try {
|
|
// pass slug too so we can clear the local cache
|
|
await deleteSpaceMutation.mutateAsync({ id: space.id, slug: space.slug });
|
|
navigate(APP_ROUTE.HOME);
|
|
} catch (error) {
|
|
console.error("Failed to delete space", error);
|
|
} finally {
|
|
setIsDeleting(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Button onClick={open} variant="light" color="red">
|
|
{t("Delete")}
|
|
</Button>
|
|
|
|
<Modal
|
|
opened={opened}
|
|
onClose={close}
|
|
title={t("Are you sure you want to delete this space?")}
|
|
>
|
|
<Divider size="xs" mb="xs" />
|
|
<Text>
|
|
{t(
|
|
"All pages, comments, attachments and permissions in this space will be deleted irreversibly.",
|
|
)}
|
|
</Text>
|
|
<Text mt="sm">
|
|
<Trans
|
|
defaults="Type the space name <b>{{spaceName}}</b> to confirm your action."
|
|
values={{ spaceName: space.name }}
|
|
components={{ b: <Text span fw={500} /> }}
|
|
/>
|
|
</Text>
|
|
<TextInput
|
|
{...confirmNameField.getInputProps()}
|
|
variant="filled"
|
|
placeholder={t("Confirm space name")}
|
|
py="sm"
|
|
data-autofocus
|
|
/>
|
|
<Group justify="flex-end" mt="md">
|
|
<Button onClick={close} variant="default">
|
|
{t("Cancel")}
|
|
</Button>
|
|
<Button onClick={handleDelete} color="red" loading={isDeleting}>
|
|
{t("Confirm")}
|
|
</Button>
|
|
</Group>
|
|
</Modal>
|
|
</>
|
|
);
|
|
}
|