Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: code splitting for workspace delete modal #6581

Merged
merged 3 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions packages/i18n/src/locales/en/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -1253,9 +1253,19 @@
"company_size": "Company size",
"url": "Workspace URL",
"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_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": {
"name": {
"required": "Name is required",
Expand Down
16 changes: 13 additions & 3 deletions packages/i18n/src/locales/es/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -1422,9 +1422,19 @@
"company_size": "Tamaño de la empresa",
"url": "URL del espacio de trabajo",
"update_workspace": "Actualizar espacio de trabajo",
"delete_workspace": "Eliminar 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_btn": "Eliminar mi 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 se eliminarán permanentemente y no podrán recuperarse.",
"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": {
"name": {
"required": "El nombre es obligatorio",
Expand Down
16 changes: 13 additions & 3 deletions packages/i18n/src/locales/fr/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -1422,9 +1422,19 @@
"company_size": "Taille de l'entreprise",
"url": "URL de l'espace de travail",
"update_workspace": "Mettre à jour l'espace de travail",
"delete_workspace": "Supprimer l'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_btn": "Supprimer mon 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 seront définitivement supprimées et ne pourront pas être récupérées.",
"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": {
"name": {
"required": "Le nom est requis",
Expand Down
16 changes: 13 additions & 3 deletions packages/i18n/src/locales/ja/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -1422,9 +1422,19 @@
"company_size": "会社の規模",
"url": "ワークスペースURL",
"update_workspace": "ワークスペースを更新",
"delete_workspace": "ワークスペースを削除",
"delete_workspace_description": "ワークスペースを削除すると、そのワークスペース内のすべてのデータとリソースが永久に削除され、復元できなくなります。",
"delete_btn": "ワークスペースを削除",
"delete_workspace": "このワークスペースを削除",
"delete_workspace_description": "ワークスペースを削除すると、そのワークスペース内のすべてのデータとリソースが完全に削除され、復元することはできません。",
"delete_btn": "このワークスペースを削除",
"delete_modal": {
"title": "このワークスペースを削除してもよろしいですか?",
"description": "有料プランの無料トライアルが有効です。続行するには、まずトライアルをキャンセルしてください。",
"dismiss": "閉じる",
"cancel": "トライアルをキャンセル",
"success_title": "ワークスペースが削除されました。",
"success_message": "まもなくプロフィールページに移動します。",
"error_title": "操作に失敗しました。",
"error_message": "もう一度お試しください。"
},
"errors": {
"name": {
"required": "名前は必須です",
Expand Down
16 changes: 13 additions & 3 deletions packages/i18n/src/locales/zh-CN/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -1422,9 +1422,19 @@
"company_size": "公司规模",
"url": "工作区网址",
"update_workspace": "更新工作区",
"delete_workspace": "删除工作区",
"delete_workspace_description": "删除工作区时,该工作区内的所有数据和资源将被永久删除且无法恢复。",
"delete_btn": "删除我的工作区",
"delete_workspace": "删除此工作区",
"delete_workspace_description": "删除工作区时,该工作区内的所有数据和资源将被永久删除,且无法恢复。",
"delete_btn": "删除此工作区",
"delete_modal": {
"title": "确定要删除此工作区吗?",
"description": "您目前正在试用我们的付费方案。请先取消试用后再继续。",
"dismiss": "关闭",
"cancel": "取消试用",
"success_title": "工作区已删除。",
"success_message": "即将跳转到您的个人资料页面。",
"error_title": "操作失败。",
"error_message": "请重试。"
},
"errors": {
"name": {
"required": "名称为必填项",
Expand Down
27 changes: 27 additions & 0 deletions web/ce/components/workspace/delete-workspace-modal.tsx
Original file line number Diff line number Diff line change
@@ -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>
);
});
2 changes: 1 addition & 1 deletion web/ce/components/workspace/delete-workspace-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { useTranslation } from "@plane/i18n";
import { IWorkspace } from "@plane/types";
// ui
import { Button, Collapsible } from "@plane/ui";
import { DeleteWorkspaceModal } from "./delete-workspace-modal";
// components
import { DeleteWorkspaceModal } from "@/components/workspace";

type TDeleteWorkspace = {
workspace: IWorkspace | null;
Expand Down
171 changes: 171 additions & 0 deletions web/core/components/workspace/delete-workspace-form.tsx
Original file line number Diff line number Diff line change
@@ -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&apos;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>
);
});
Loading
Loading