fix: code splitting for workspace delete modal (#6581)
* fix: code splitting for delete modal * fix: redirected to profile post deletion * fix: translations
This commit is contained in:
parent
cc9b448a9b
commit
6a3ccafe35
11 changed files with 264 additions and 221 deletions
|
|
@ -1253,9 +1253,19 @@
|
||||||
"company_size": "Company size",
|
"company_size": "Company size",
|
||||||
"url": "Workspace URL",
|
"url": "Workspace URL",
|
||||||
"update_workspace": "Update workspace",
|
"update_workspace": "Update workspace",
|
||||||
"delete_workspace": "Delete workspace",
|
"delete_workspace": "Delete this workspace",
|
||||||
"delete_workspace_description": "When deleting a workspace, all of the data and resources within that workspace will be permanently removed and cannot be recovered.",
|
"delete_workspace_description": "When deleting a workspace, all of the data and resources within that workspace will be permanently removed and cannot be recovered.",
|
||||||
"delete_btn": "Delete my workspace",
|
"delete_btn": "Delete this workspace",
|
||||||
|
"delete_modal": {
|
||||||
|
"title": "Are you sure you want to delete this workspace?",
|
||||||
|
"description": "You have an active trial to one of our paid plans. Please cancel it first to proceed.",
|
||||||
|
"dismiss": "Dismiss",
|
||||||
|
"cancel": "Cancel trial",
|
||||||
|
"success_title": "Workspace deleted.",
|
||||||
|
"success_message": "You will soon go to your profile page.",
|
||||||
|
"error_title": "That didn't work.",
|
||||||
|
"error_message": "Try again, please."
|
||||||
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"name": {
|
"name": {
|
||||||
"required": "Name is required",
|
"required": "Name is required",
|
||||||
|
|
|
||||||
|
|
@ -1422,9 +1422,19 @@
|
||||||
"company_size": "Tamaño de la empresa",
|
"company_size": "Tamaño de la empresa",
|
||||||
"url": "URL del espacio de trabajo",
|
"url": "URL del espacio de trabajo",
|
||||||
"update_workspace": "Actualizar espacio de trabajo",
|
"update_workspace": "Actualizar espacio de trabajo",
|
||||||
"delete_workspace": "Eliminar espacio de trabajo",
|
"delete_workspace": "Eliminar este espacio de trabajo",
|
||||||
"delete_workspace_description": "Al eliminar un espacio de trabajo, todos los datos y recursos dentro de ese espacio de trabajo se eliminarán permanentemente y no se podrán recuperar.",
|
"delete_workspace_description": "Al eliminar un espacio de trabajo, todos los datos y recursos dentro de ese espacio se eliminarán permanentemente y no podrán recuperarse.",
|
||||||
"delete_btn": "Eliminar mi espacio de trabajo",
|
"delete_btn": "Eliminar este espacio de trabajo",
|
||||||
|
"delete_modal": {
|
||||||
|
"title": "¿Está seguro de que desea eliminar este espacio de trabajo?",
|
||||||
|
"description": "Tiene una prueba activa de uno de nuestros planes de pago. Por favor, cancelela primero para continuar.",
|
||||||
|
"dismiss": "Descartar",
|
||||||
|
"cancel": "Cancelar prueba",
|
||||||
|
"success_title": "Espacio de trabajo eliminado.",
|
||||||
|
"success_message": "Pronto irá a su página de perfil.",
|
||||||
|
"error_title": "Eso no funcionó.",
|
||||||
|
"error_message": "Por favor, inténtelo de nuevo."
|
||||||
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"name": {
|
"name": {
|
||||||
"required": "El nombre es obligatorio",
|
"required": "El nombre es obligatorio",
|
||||||
|
|
|
||||||
|
|
@ -1422,9 +1422,19 @@
|
||||||
"company_size": "Taille de l'entreprise",
|
"company_size": "Taille de l'entreprise",
|
||||||
"url": "URL de l'espace de travail",
|
"url": "URL de l'espace de travail",
|
||||||
"update_workspace": "Mettre à jour l'espace de travail",
|
"update_workspace": "Mettre à jour l'espace de travail",
|
||||||
"delete_workspace": "Supprimer l'espace de travail",
|
"delete_workspace": "Supprimer cet espace de travail",
|
||||||
"delete_workspace_description": "Lors de la suppression d'un espace de travail, toutes les données et ressources au sein de cet espace de travail seront définitivement supprimées et ne pourront pas être récupérées.",
|
"delete_workspace_description": "Lors de la suppression d'un espace de travail, toutes les données et ressources au sein de cet espace seront définitivement supprimées et ne pourront pas être récupérées.",
|
||||||
"delete_btn": "Supprimer mon espace de travail",
|
"delete_btn": "Supprimer cet espace de travail",
|
||||||
|
"delete_modal": {
|
||||||
|
"title": "Êtes-vous sûr de vouloir supprimer cet espace de travail ?",
|
||||||
|
"description": "Vous avez un essai actif sur l'un de nos forfaits payants. Veuillez d'abord l'annuler pour continuer.",
|
||||||
|
"dismiss": "Fermer",
|
||||||
|
"cancel": "Annuler l'essai",
|
||||||
|
"success_title": "Espace de travail supprimé.",
|
||||||
|
"success_message": "Vous serez bientôt redirigé vers votre page de profil.",
|
||||||
|
"error_title": "Cela n'a pas fonctionné.",
|
||||||
|
"error_message": "Veuillez réessayer."
|
||||||
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"name": {
|
"name": {
|
||||||
"required": "Le nom est requis",
|
"required": "Le nom est requis",
|
||||||
|
|
|
||||||
|
|
@ -1422,9 +1422,19 @@
|
||||||
"company_size": "会社の規模",
|
"company_size": "会社の規模",
|
||||||
"url": "ワークスペースURL",
|
"url": "ワークスペースURL",
|
||||||
"update_workspace": "ワークスペースを更新",
|
"update_workspace": "ワークスペースを更新",
|
||||||
"delete_workspace": "ワークスペースを削除",
|
"delete_workspace": "このワークスペースを削除",
|
||||||
"delete_workspace_description": "ワークスペースを削除すると、そのワークスペース内のすべてのデータとリソースが永久に削除され、復元できなくなります。",
|
"delete_workspace_description": "ワークスペースを削除すると、そのワークスペース内のすべてのデータとリソースが完全に削除され、復元することはできません。",
|
||||||
"delete_btn": "ワークスペースを削除",
|
"delete_btn": "このワークスペースを削除",
|
||||||
|
"delete_modal": {
|
||||||
|
"title": "このワークスペースを削除してもよろしいですか?",
|
||||||
|
"description": "有料プランの無料トライアルが有効です。続行するには、まずトライアルをキャンセルしてください。",
|
||||||
|
"dismiss": "閉じる",
|
||||||
|
"cancel": "トライアルをキャンセル",
|
||||||
|
"success_title": "ワークスペースが削除されました。",
|
||||||
|
"success_message": "まもなくプロフィールページに移動します。",
|
||||||
|
"error_title": "操作に失敗しました。",
|
||||||
|
"error_message": "もう一度お試しください。"
|
||||||
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"name": {
|
"name": {
|
||||||
"required": "名前は必須です",
|
"required": "名前は必須です",
|
||||||
|
|
|
||||||
|
|
@ -1422,9 +1422,19 @@
|
||||||
"company_size": "公司规模",
|
"company_size": "公司规模",
|
||||||
"url": "工作区网址",
|
"url": "工作区网址",
|
||||||
"update_workspace": "更新工作区",
|
"update_workspace": "更新工作区",
|
||||||
"delete_workspace": "删除工作区",
|
"delete_workspace": "删除此工作区",
|
||||||
"delete_workspace_description": "删除工作区时,该工作区内的所有数据和资源将被永久删除且无法恢复。",
|
"delete_workspace_description": "删除工作区时,该工作区内的所有数据和资源将被永久删除,且无法恢复。",
|
||||||
"delete_btn": "删除我的工作区",
|
"delete_btn": "删除此工作区",
|
||||||
|
"delete_modal": {
|
||||||
|
"title": "确定要删除此工作区吗?",
|
||||||
|
"description": "您目前正在试用我们的付费方案。请先取消试用后再继续。",
|
||||||
|
"dismiss": "关闭",
|
||||||
|
"cancel": "取消试用",
|
||||||
|
"success_title": "工作区已删除。",
|
||||||
|
"success_message": "即将跳转到您的个人资料页面。",
|
||||||
|
"error_title": "操作失败。",
|
||||||
|
"error_message": "请重试。"
|
||||||
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"name": {
|
"name": {
|
||||||
"required": "名称为必填项",
|
"required": "名称为必填项",
|
||||||
|
|
|
||||||
27
web/ce/components/workspace/delete-workspace-modal.tsx
Normal file
27
web/ce/components/workspace/delete-workspace-modal.tsx
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
import type { IWorkspace } from "@plane/types";
|
||||||
|
// ui
|
||||||
|
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||||
|
// constants
|
||||||
|
// hooks
|
||||||
|
|
||||||
|
import { DeleteWorkspaceForm } from "@/components/workspace/delete-workspace-form";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
isOpen: boolean;
|
||||||
|
data: IWorkspace | null;
|
||||||
|
onClose: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DeleteWorkspaceModal: React.FC<Props> = observer((props) => {
|
||||||
|
const { isOpen, data, onClose } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ModalCore isOpen={isOpen} handleClose={() => onClose()} position={EModalPosition.CENTER} width={EModalWidth.XL}>
|
||||||
|
<DeleteWorkspaceForm data={data} onClose={onClose} />
|
||||||
|
</ModalCore>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
@ -6,8 +6,8 @@ import { useTranslation } from "@plane/i18n";
|
||||||
import { IWorkspace } from "@plane/types";
|
import { IWorkspace } from "@plane/types";
|
||||||
// ui
|
// ui
|
||||||
import { Button, Collapsible } from "@plane/ui";
|
import { Button, Collapsible } from "@plane/ui";
|
||||||
|
import { DeleteWorkspaceModal } from "./delete-workspace-modal";
|
||||||
// components
|
// components
|
||||||
import { DeleteWorkspaceModal } from "@/components/workspace";
|
|
||||||
|
|
||||||
type TDeleteWorkspace = {
|
type TDeleteWorkspace = {
|
||||||
workspace: IWorkspace | null;
|
workspace: IWorkspace | null;
|
||||||
|
|
|
||||||
171
web/core/components/workspace/delete-workspace-form.tsx
Normal file
171
web/core/components/workspace/delete-workspace-form.tsx
Normal file
|
|
@ -0,0 +1,171 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
import { Controller, useForm } from "react-hook-form";
|
||||||
|
import { AlertTriangle } from "lucide-react";
|
||||||
|
// types
|
||||||
|
import { WORKSPACE_DELETED } from "@plane/constants";
|
||||||
|
import { useTranslation } from "@plane/i18n";
|
||||||
|
import type { IWorkspace } from "@plane/types";
|
||||||
|
// ui
|
||||||
|
import { Button, Input, TOAST_TYPE, setToast } from "@plane/ui";
|
||||||
|
// constants
|
||||||
|
// hooks
|
||||||
|
import { cn } from "@plane/utils";
|
||||||
|
import { useEventTracker, useWorkspace } from "@/hooks/store";
|
||||||
|
import { useAppRouter } from "@/hooks/use-app-router";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
data: IWorkspace | null;
|
||||||
|
onClose: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultValues = {
|
||||||
|
workspaceName: "",
|
||||||
|
confirmDelete: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DeleteWorkspaceForm: React.FC<Props> = observer((props) => {
|
||||||
|
const { data, onClose } = props;
|
||||||
|
// router
|
||||||
|
const router = useAppRouter();
|
||||||
|
// store hooks
|
||||||
|
const { captureWorkspaceEvent } = useEventTracker();
|
||||||
|
const { deleteWorkspace } = useWorkspace();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
// form info
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
formState: { errors, isSubmitting },
|
||||||
|
handleSubmit,
|
||||||
|
reset,
|
||||||
|
watch,
|
||||||
|
} = useForm({ defaultValues });
|
||||||
|
|
||||||
|
const canDelete = watch("workspaceName") === data?.name && watch("confirmDelete") === "delete my workspace";
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
onClose();
|
||||||
|
reset(defaultValues);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSubmit = async () => {
|
||||||
|
if (!data || !canDelete) return;
|
||||||
|
|
||||||
|
await deleteWorkspace(data.slug)
|
||||||
|
.then(() => {
|
||||||
|
handleClose();
|
||||||
|
router.push("/profile");
|
||||||
|
captureWorkspaceEvent({
|
||||||
|
eventName: WORKSPACE_DELETED,
|
||||||
|
payload: {
|
||||||
|
...data,
|
||||||
|
state: "SUCCESS",
|
||||||
|
element: "Workspace general settings page",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
setToast({
|
||||||
|
type: TOAST_TYPE.SUCCESS,
|
||||||
|
title: t("workspace_settings.settings.general.delete_modal.success_title"),
|
||||||
|
message: t("workspace_settings.settings.general.delete_modal.success_message"),
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setToast({
|
||||||
|
type: TOAST_TYPE.ERROR,
|
||||||
|
title: t("workspace_settings.settings.general.delete_modal.error_title"),
|
||||||
|
message: t("workspace_settings.settings.general.delete_modal.error_message"),
|
||||||
|
});
|
||||||
|
captureWorkspaceEvent({
|
||||||
|
eventName: WORKSPACE_DELETED,
|
||||||
|
payload: {
|
||||||
|
...data,
|
||||||
|
state: "FAILED",
|
||||||
|
element: "Workspace general settings page",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)} className="flex flex-col gap-6 p-6">
|
||||||
|
<div className="flex flex-col sm:flex-row items-center sm:items-start gap-4">
|
||||||
|
<span
|
||||||
|
className={cn(
|
||||||
|
"flex-shrink-0 grid place-items-center rounded-full size-12 sm:size-10 bg-red-500/20 text-red-100"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<AlertTriangle className="size-5 text-red-600" aria-hidden="true" />
|
||||||
|
</span>
|
||||||
|
<div>
|
||||||
|
<div className="text-center sm:text-left">
|
||||||
|
<h3 className="text-lg font-medium">{t("workspace_settings.settings.general.delete_modal.title")}</h3>
|
||||||
|
<p className="mt-1 text-sm text-custom-text-200">
|
||||||
|
You are about to delete the workspace <span className="break-words font-semibold">{data?.name}</span>. If
|
||||||
|
you confirm, you will lose access to all your work data in this workspace without any way to restore it.
|
||||||
|
Tread very carefully.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="text-custom-text-200 mt-4">
|
||||||
|
<p className="break-words text-sm ">Type in this workspace's name to continue.</p>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="workspaceName"
|
||||||
|
render={({ field: { value, onChange, ref } }) => (
|
||||||
|
<Input
|
||||||
|
id="workspaceName"
|
||||||
|
name="workspaceName"
|
||||||
|
type="text"
|
||||||
|
value={value}
|
||||||
|
onChange={onChange}
|
||||||
|
ref={ref}
|
||||||
|
hasError={Boolean(errors.workspaceName)}
|
||||||
|
placeholder={data?.name}
|
||||||
|
className="mt-2 w-full"
|
||||||
|
autoComplete="off"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="text-custom-text-200 mt-4">
|
||||||
|
<p className="text-sm">
|
||||||
|
For final confirmation, type{" "}
|
||||||
|
<span className="font-medium text-custom-text-100">delete my workspace </span>
|
||||||
|
below.
|
||||||
|
</p>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="confirmDelete"
|
||||||
|
render={({ field: { value, onChange, ref } }) => (
|
||||||
|
<Input
|
||||||
|
id="confirmDelete"
|
||||||
|
name="confirmDelete"
|
||||||
|
type="text"
|
||||||
|
value={value}
|
||||||
|
onChange={onChange}
|
||||||
|
ref={ref}
|
||||||
|
hasError={Boolean(errors.confirmDelete)}
|
||||||
|
placeholder=""
|
||||||
|
className="mt-2 w-full"
|
||||||
|
autoComplete="off"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex justify-end gap-2">
|
||||||
|
<Button variant="neutral-primary" size="sm" onClick={handleClose}>
|
||||||
|
{t("cancel")}
|
||||||
|
</Button>
|
||||||
|
<Button variant="danger" size="sm" type="submit" disabled={!canDelete} loading={isSubmitting}>
|
||||||
|
{isSubmitting ? t("deleting") : t("confirm")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
@ -1,205 +0,0 @@
|
||||||
"use client";
|
|
||||||
|
|
||||||
import React from "react";
|
|
||||||
import { observer } from "mobx-react";
|
|
||||||
import { Controller, useForm } from "react-hook-form";
|
|
||||||
import { AlertTriangle } from "lucide-react";
|
|
||||||
import { Dialog, Transition } from "@headlessui/react";
|
|
||||||
// types
|
|
||||||
import { WORKSPACE_DELETED } from "@plane/constants";
|
|
||||||
import type { IWorkspace } from "@plane/types";
|
|
||||||
// ui
|
|
||||||
import { Button, Input, TOAST_TYPE, setToast } from "@plane/ui";
|
|
||||||
// constants
|
|
||||||
// hooks
|
|
||||||
import { useEventTracker, useWorkspace } from "@/hooks/store";
|
|
||||||
import { useAppRouter } from "@/hooks/use-app-router";
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
isOpen: boolean;
|
|
||||||
data: IWorkspace | null;
|
|
||||||
onClose: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultValues = {
|
|
||||||
workspaceName: "",
|
|
||||||
confirmDelete: "",
|
|
||||||
};
|
|
||||||
|
|
||||||
export const DeleteWorkspaceModal: React.FC<Props> = observer((props) => {
|
|
||||||
const { isOpen, data, onClose } = props;
|
|
||||||
// router
|
|
||||||
const router = useAppRouter();
|
|
||||||
// store hooks
|
|
||||||
const { captureWorkspaceEvent } = useEventTracker();
|
|
||||||
const { deleteWorkspace } = useWorkspace();
|
|
||||||
// form info
|
|
||||||
const {
|
|
||||||
control,
|
|
||||||
formState: { errors, isSubmitting },
|
|
||||||
handleSubmit,
|
|
||||||
reset,
|
|
||||||
watch,
|
|
||||||
} = useForm({ defaultValues });
|
|
||||||
|
|
||||||
const canDelete = watch("workspaceName") === data?.name && watch("confirmDelete") === "delete my workspace";
|
|
||||||
|
|
||||||
const handleClose = () => {
|
|
||||||
const timer = setTimeout(() => {
|
|
||||||
reset(defaultValues);
|
|
||||||
clearTimeout(timer);
|
|
||||||
}, 350);
|
|
||||||
|
|
||||||
onClose();
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSubmit = async () => {
|
|
||||||
if (!data || !canDelete) return;
|
|
||||||
|
|
||||||
await deleteWorkspace(data.slug)
|
|
||||||
.then(() => {
|
|
||||||
handleClose();
|
|
||||||
router.push("/");
|
|
||||||
captureWorkspaceEvent({
|
|
||||||
eventName: WORKSPACE_DELETED,
|
|
||||||
payload: {
|
|
||||||
...data,
|
|
||||||
state: "SUCCESS",
|
|
||||||
element: "Workspace general settings page",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
setToast({
|
|
||||||
type: TOAST_TYPE.SUCCESS,
|
|
||||||
title: "Success!",
|
|
||||||
message: "Workspace deleted successfully.",
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
setToast({
|
|
||||||
type: TOAST_TYPE.ERROR,
|
|
||||||
title: "Error!",
|
|
||||||
message: "Something went wrong. Please try again later.",
|
|
||||||
});
|
|
||||||
captureWorkspaceEvent({
|
|
||||||
eventName: WORKSPACE_DELETED,
|
|
||||||
payload: {
|
|
||||||
...data,
|
|
||||||
state: "FAILED",
|
|
||||||
element: "Workspace general settings page",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
|
||||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
|
||||||
<Transition.Child
|
|
||||||
as={React.Fragment}
|
|
||||||
enter="ease-out duration-300"
|
|
||||||
enterFrom="opacity-0"
|
|
||||||
enterTo="opacity-100"
|
|
||||||
leave="ease-in duration-200"
|
|
||||||
leaveFrom="opacity-100"
|
|
||||||
leaveTo="opacity-0"
|
|
||||||
>
|
|
||||||
<div className="fixed inset-0 bg-custom-backdrop transition-opacity" />
|
|
||||||
</Transition.Child>
|
|
||||||
|
|
||||||
<div className="fixed inset-0 z-20 overflow-y-auto">
|
|
||||||
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
|
||||||
<Transition.Child
|
|
||||||
as={React.Fragment}
|
|
||||||
enter="ease-out duration-300"
|
|
||||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
|
||||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
|
||||||
leave="ease-in duration-200"
|
|
||||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
|
||||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
|
||||||
>
|
|
||||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-custom-background-100 text-left shadow-custom-shadow-md transition-all sm:my-8 sm:w-full sm:max-w-2xl">
|
|
||||||
<form onSubmit={handleSubmit(onSubmit)} className="flex flex-col gap-6 p-6">
|
|
||||||
<div className="flex w-full items-center justify-start gap-6">
|
|
||||||
<span className="place-items-center rounded-full bg-red-500/20 p-4">
|
|
||||||
<AlertTriangle className="h-6 w-6 text-red-600" aria-hidden="true" />
|
|
||||||
</span>
|
|
||||||
<span className="flex items-center justify-start">
|
|
||||||
<h3 className="text-xl font-medium 2xl:text-2xl">Delete workspace</h3>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<span>
|
|
||||||
<p className="text-sm leading-7 text-custom-text-200">
|
|
||||||
Are you sure you want to delete workspace{" "}
|
|
||||||
<span className="break-words font-semibold">{data?.name}</span>? All of the data related to the
|
|
||||||
workspace will be permanently removed. This action cannot be undone.
|
|
||||||
</p>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<div className="text-custom-text-200">
|
|
||||||
<p className="break-words text-sm ">
|
|
||||||
Enter the workspace name <span className="font-medium text-custom-text-100">{data?.name}</span> to
|
|
||||||
continue:
|
|
||||||
</p>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name="workspaceName"
|
|
||||||
render={({ field: { value, onChange, ref } }) => (
|
|
||||||
<Input
|
|
||||||
id="workspaceName"
|
|
||||||
name="workspaceName"
|
|
||||||
type="text"
|
|
||||||
value={value}
|
|
||||||
onChange={onChange}
|
|
||||||
ref={ref}
|
|
||||||
hasError={Boolean(errors.workspaceName)}
|
|
||||||
placeholder="Workspace name"
|
|
||||||
className="mt-2 w-full"
|
|
||||||
autoComplete="off"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="text-custom-text-200">
|
|
||||||
<p className="text-sm">
|
|
||||||
To confirm, type <span className="font-medium text-custom-text-100">delete my workspace</span>{" "}
|
|
||||||
below:
|
|
||||||
</p>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name="confirmDelete"
|
|
||||||
render={({ field: { value, onChange, ref } }) => (
|
|
||||||
<Input
|
|
||||||
id="confirmDelete"
|
|
||||||
name="confirmDelete"
|
|
||||||
type="text"
|
|
||||||
value={value}
|
|
||||||
onChange={onChange}
|
|
||||||
ref={ref}
|
|
||||||
hasError={Boolean(errors.confirmDelete)}
|
|
||||||
placeholder="Enter 'delete my workspace'"
|
|
||||||
className="mt-2 w-full"
|
|
||||||
autoComplete="off"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex justify-end gap-2">
|
|
||||||
<Button variant="neutral-primary" size="sm" onClick={handleClose}>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
<Button variant="danger" size="sm" type="submit" disabled={!canDelete} loading={isSubmitting}>
|
|
||||||
{isSubmitting ? "Deleting" : "Delete workspace"}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Dialog.Panel>
|
|
||||||
</Transition.Child>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Dialog>
|
|
||||||
</Transition.Root>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
@ -3,6 +3,5 @@ export * from "./sidebar";
|
||||||
export * from "./views";
|
export * from "./views";
|
||||||
export * from "./confirm-workspace-member-remove";
|
export * from "./confirm-workspace-member-remove";
|
||||||
export * from "./create-workspace-form";
|
export * from "./create-workspace-form";
|
||||||
export * from "./delete-workspace-modal";
|
|
||||||
export * from "./logo";
|
export * from "./logo";
|
||||||
export * from "./invite-modal";
|
export * from "./invite-modal";
|
||||||
|
|
|
||||||
1
web/ee/components/workspace/delete-workspace-modal.tsx
Normal file
1
web/ee/components/workspace/delete-workspace-modal.tsx
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "ce/components/workspace/delete-workspace-modal";
|
||||||
Loading…
Add table
Add a link
Reference in a new issue