UI - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: приведение delete-модалок к black-glass канону
This commit is contained in:
@@ -49,8 +49,8 @@ export const CycleDeleteModal = observer(function CycleDeleteModal(props: ICycle
|
||||
if (cycleId || peekCycle) router.push(`/${workspaceSlug}/projects/${projectId}/cycles`);
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Success!",
|
||||
message: "Cycle deleted successfully.",
|
||||
title: t("common.success"),
|
||||
message: t("entity.delete.success", { entity: t("common.cycle").toLowerCase() }),
|
||||
});
|
||||
})
|
||||
.catch((errors) => {
|
||||
@@ -68,8 +68,8 @@ export const CycleDeleteModal = observer(function CycleDeleteModal(props: ICycle
|
||||
} catch {
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Warning!",
|
||||
message: "Something went wrong please try again later.",
|
||||
title: t("common.warning"),
|
||||
message: t("common.something_went_wrong"),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -82,14 +82,11 @@ export const CycleDeleteModal = observer(function CycleDeleteModal(props: ICycle
|
||||
handleSubmit={formSubmit}
|
||||
isSubmitting={loader}
|
||||
isOpen={isOpen}
|
||||
title="Delete cycle"
|
||||
content={
|
||||
<>
|
||||
Are you sure you want to delete cycle{' "'}
|
||||
<span className="font-medium break-words text-primary">{cycle?.name}</span>
|
||||
{'"'}? All of the data related to the cycle will be permanently removed. This action cannot be undone.
|
||||
</>
|
||||
}
|
||||
title={t("entity.delete.label", { entity: t("common.cycle") })}
|
||||
content={t("entity.delete.confirmation", {
|
||||
entity: t("common.cycle").toLowerCase(),
|
||||
identifier: cycle?.name ? `"${cycle.name}"` : "",
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
import { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
// ui
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
import { AlertModalCore } from "@plane/ui";
|
||||
// hooks
|
||||
import { useProjectEstimates } from "@/hooks/store/estimates";
|
||||
import { useEstimate } from "@/hooks/store/estimates/use-estimate";
|
||||
@@ -26,6 +26,7 @@ type TDeleteEstimateModal = {
|
||||
export const DeleteEstimateModal = observer(function DeleteEstimateModal(props: TDeleteEstimateModal) {
|
||||
// props
|
||||
const { workspaceSlug, projectId, estimateId, isOpen, handleClose } = props;
|
||||
const { t } = useTranslation();
|
||||
// hooks
|
||||
const { areEstimateEnabledByProjectId, deleteEstimate } = useProjectEstimates();
|
||||
const { asJson: estimate } = useEstimate(estimateId);
|
||||
@@ -44,46 +45,32 @@ export const DeleteEstimateModal = observer(function DeleteEstimateModal(props:
|
||||
setButtonLoader(false);
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Estimate deleted",
|
||||
message: "Estimate has been removed from your project.",
|
||||
title: t("project_settings.estimates.delete_modal.success_title"),
|
||||
message: t("project_settings.estimates.delete_modal.success_message"),
|
||||
});
|
||||
handleClose();
|
||||
} catch (_error) {
|
||||
setButtonLoader(false);
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Estimate creation failed",
|
||||
message: "We were unable to delete the estimate, please try again.",
|
||||
title: t("project_settings.estimates.delete_modal.error_title"),
|
||||
message: t("project_settings.estimates.delete_modal.error_message"),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ModalCore isOpen={isOpen} position={EModalPosition.TOP} width={EModalWidth.XXL}>
|
||||
<div className="relative space-y-6 py-5">
|
||||
{/* heading */}
|
||||
<div className="relative flex items-center justify-between gap-2 px-5">
|
||||
<div className="text-18 font-medium text-primary">Delete Estimate System</div>
|
||||
</div>
|
||||
|
||||
{/* estimate steps */}
|
||||
<div className="px-5">
|
||||
<div className="text-14 text-secondary">
|
||||
Deleting the estimate <span className="font-bold text-primary">{estimate?.name}</span>
|
||||
system will remove it from all work items permanently. This action cannot be undone. If you add
|
||||
estimates again, you will need to update all the work items.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative flex items-center justify-end gap-3 border-t border-subtle px-5 pt-5">
|
||||
<Button variant="secondary" size="lg" onClick={handleClose} disabled={buttonLoader}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="error-fill" size="lg" onClick={handleDeleteEstimate} disabled={buttonLoader}>
|
||||
{buttonLoader ? "Deleting" : "Delete Estimate"}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</ModalCore>
|
||||
<AlertModalCore
|
||||
handleClose={handleClose}
|
||||
handleSubmit={handleDeleteEstimate}
|
||||
isSubmitting={buttonLoader}
|
||||
isOpen={isOpen}
|
||||
title={t("project_settings.estimates.delete_modal.title")}
|
||||
content={t("project_settings.estimates.delete_modal.description", { value: estimate?.name ?? "" })}
|
||||
primaryButtonText={{
|
||||
loading: t("project_settings.estimates.delete_modal.loading"),
|
||||
default: t("project_settings.estimates.delete_modal.submit"),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -47,16 +47,9 @@ export function DeclineIssueModal(props: Props) {
|
||||
isSubmitting={isDeclining}
|
||||
isOpen={isOpen}
|
||||
title={t("inbox_issue.modals.decline.title")}
|
||||
// TODO: Need to translate the confirmation message
|
||||
content={
|
||||
<>
|
||||
Are you sure you want to decline work item{" "}
|
||||
<span className="font-medium break-words text-primary">
|
||||
{projectDetails?.identifier}-{data?.sequence_id}
|
||||
</span>
|
||||
{""}? This action cannot be undone.
|
||||
</>
|
||||
}
|
||||
content={t("inbox_issue.modals.decline.content", {
|
||||
value: `${projectDetails?.identifier}-${data?.sequence_id}`,
|
||||
})}
|
||||
primaryButtonText={{
|
||||
loading: t("declining"),
|
||||
default: t("decline"),
|
||||
|
||||
@@ -63,14 +63,7 @@ export const IssueAttachmentDeleteModal = observer(function IssueAttachmentDelet
|
||||
isSubmitting={loader}
|
||||
isOpen={isOpen}
|
||||
title={t("attachment.delete")}
|
||||
content={
|
||||
<>
|
||||
{/* TODO: Translate here */}
|
||||
Are you sure you want to delete attachment-{" "}
|
||||
<span className="font-bold">{getFileName(attachment.attributes.name)}</span>? This attachment will be
|
||||
permanently removed. This action cannot be undone.
|
||||
</>
|
||||
}
|
||||
content={t("attachment.delete_confirmation", { value: getFileName(attachment.attributes.name) })}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -8,6 +8,7 @@ import { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
// types
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import type { IIssueLabel } from "@plane/types";
|
||||
// ui
|
||||
@@ -23,6 +24,7 @@ type Props = {
|
||||
|
||||
export const DeleteLabelModal = observer(function DeleteLabelModal(props: Props) {
|
||||
const { isOpen, onClose, data } = props;
|
||||
const { t } = useTranslation();
|
||||
// router
|
||||
const { workspaceSlug, projectId } = useParams();
|
||||
// store hooks
|
||||
@@ -46,10 +48,10 @@ export const DeleteLabelModal = observer(function DeleteLabelModal(props: Props)
|
||||
})
|
||||
.catch((err) => {
|
||||
setIsDeleteLoading(false);
|
||||
const error = err?.error || "Label could not be deleted. Please try again.";
|
||||
const error = err?.error || t("label.delete_error");
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error!",
|
||||
title: t("common.error.label"),
|
||||
message: error,
|
||||
});
|
||||
});
|
||||
@@ -61,13 +63,8 @@ export const DeleteLabelModal = observer(function DeleteLabelModal(props: Props)
|
||||
handleSubmit={handleDeletion}
|
||||
isSubmitting={isDeleteLoading}
|
||||
isOpen={isOpen}
|
||||
title="Delete Label"
|
||||
content={
|
||||
<>
|
||||
Are you sure you want to delete <span className="font-medium text-primary">{data?.name}</span>? This will
|
||||
remove the label from all the work item and from any views where the label is being filtered upon.
|
||||
</>
|
||||
}
|
||||
title={t("entity.delete.label", { entity: t("common.label") })}
|
||||
content={t("label.delete_confirmation", { value: data?.name ?? "" })}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -52,8 +52,8 @@ export const DeleteModuleModal = observer(function DeleteModuleModal(props: Prop
|
||||
handleClose();
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Success!",
|
||||
message: "Module deleted successfully.",
|
||||
title: t("common.success"),
|
||||
message: t("entity.delete.success", { entity: t("common.module").toLowerCase() }),
|
||||
});
|
||||
})
|
||||
.catch((errors) => {
|
||||
@@ -76,14 +76,11 @@ export const DeleteModuleModal = observer(function DeleteModuleModal(props: Prop
|
||||
handleSubmit={handleDeletion}
|
||||
isSubmitting={isDeleteLoading}
|
||||
isOpen={isOpen}
|
||||
title="Delete module"
|
||||
content={
|
||||
<>
|
||||
Are you sure you want to delete module-{" "}
|
||||
<span className="font-medium break-all text-primary">{data?.name}</span>? All of the data related to the
|
||||
module will be permanently removed. This action cannot be undone.
|
||||
</>
|
||||
}
|
||||
title={t("entity.delete.label", { entity: t("common.module") })}
|
||||
content={t("entity.delete.confirmation", {
|
||||
entity: t("common.module").toLowerCase(),
|
||||
identifier: data?.name ? `"${data.name}"` : "",
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -8,6 +8,7 @@ import { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
// ui
|
||||
import { useParams } from "next/navigation";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import { AlertModalCore } from "@plane/ui";
|
||||
import { getPageName } from "@plane/utils";
|
||||
@@ -28,6 +29,7 @@ type TConfirmPageDeletionProps = {
|
||||
|
||||
export const DeletePageModal = observer(function DeletePageModal(props: TConfirmPageDeletionProps) {
|
||||
const { isOpen, onClose, page, storeType } = props;
|
||||
const { t } = useTranslation();
|
||||
// states
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
// store hooks
|
||||
@@ -52,8 +54,8 @@ export const DeletePageModal = observer(function DeletePageModal(props: TConfirm
|
||||
handleClose();
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Success!",
|
||||
message: "Page deleted successfully.",
|
||||
title: t("project_page.delete_modal.success_title"),
|
||||
message: t("project_page.delete_modal.success_message"),
|
||||
});
|
||||
|
||||
if (routePageId) {
|
||||
@@ -63,8 +65,8 @@ export const DeletePageModal = observer(function DeletePageModal(props: TConfirm
|
||||
.catch(() => {
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error!",
|
||||
message: "Page could not be deleted. Please try again.",
|
||||
title: t("project_page.delete_modal.error_title"),
|
||||
message: t("project_page.delete_modal.error_message"),
|
||||
});
|
||||
});
|
||||
|
||||
@@ -79,14 +81,8 @@ export const DeletePageModal = observer(function DeletePageModal(props: TConfirm
|
||||
handleSubmit={handleDelete}
|
||||
isSubmitting={isDeleting}
|
||||
isOpen={isOpen}
|
||||
title="Delete page"
|
||||
content={
|
||||
<>
|
||||
Are you sure you want to delete page-{" "}
|
||||
<span className="font-medium break-words break-all text-primary">{getPageName(name)}</span> ? The Page will be
|
||||
deleted permanently. This action cannot be undone.
|
||||
</>
|
||||
}
|
||||
title={t("project_page.delete_modal.title")}
|
||||
content={t("project_page.delete_modal.content", { value: getPageName(name) })}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Loader } from "lucide-react";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { CloseIcon } from "@plane/propel/icons";
|
||||
// plane imports
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
@@ -26,6 +27,7 @@ type TStateDelete = {
|
||||
|
||||
export const StateDelete = observer(function StateDelete(props: TStateDelete) {
|
||||
const { totalStates, state, deleteStateCallback } = props;
|
||||
const { t } = useTranslation();
|
||||
// hooks
|
||||
const { isMobile } = usePlatformOS();
|
||||
// states
|
||||
@@ -47,15 +49,14 @@ export const StateDelete = observer(function StateDelete(props: TStateDelete) {
|
||||
if (errorStatus.status === 400) {
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error!",
|
||||
message:
|
||||
"This state contains some work items within it, please move them to some other state to delete this state.",
|
||||
title: t("common.error.label"),
|
||||
message: t("project_settings.states.delete.blocked"),
|
||||
});
|
||||
} else {
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error!",
|
||||
message: "State could not be deleted. Please try again.",
|
||||
title: t("common.error.label"),
|
||||
message: t("project_settings.states.delete.error"),
|
||||
});
|
||||
}
|
||||
setIsDelete(false);
|
||||
@@ -69,13 +70,11 @@ export const StateDelete = observer(function StateDelete(props: TStateDelete) {
|
||||
handleSubmit={handleDeleteState}
|
||||
isSubmitting={isDelete}
|
||||
isOpen={isDeleteModal}
|
||||
title="Delete State"
|
||||
content={
|
||||
<>
|
||||
Are you sure you want to delete state- <span className="font-medium text-primary">{state?.name}</span>? All
|
||||
of the data related to the state will be permanently removed. This action cannot be undone.
|
||||
</>
|
||||
}
|
||||
title={t("entity.delete.label", { entity: t("common.state") })}
|
||||
content={t("entity.delete.confirmation", {
|
||||
entity: t("common.state").toLowerCase(),
|
||||
identifier: state?.name ? `"${state.name}"` : "",
|
||||
})}
|
||||
/>
|
||||
|
||||
<button
|
||||
@@ -89,7 +88,11 @@ export const StateDelete = observer(function StateDelete(props: TStateDelete) {
|
||||
>
|
||||
<Tooltip
|
||||
tooltipContent={
|
||||
state.default ? "Cannot delete the default state." : totalStates === 1 ? `Cannot have an empty group.` : ``
|
||||
state.default
|
||||
? t("project_settings.states.delete.disabled_default")
|
||||
: totalStates === 1
|
||||
? t("project_settings.states.delete.disabled_last")
|
||||
: ""
|
||||
}
|
||||
isMobile={isMobile}
|
||||
disabled={!isDeleteDisabled}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
// Plane imports
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import type { IState } from "@plane/types";
|
||||
// ui
|
||||
@@ -23,6 +24,7 @@ type TStateDeleteModal = {
|
||||
|
||||
export const StateDeleteModal = observer(function StateDeleteModal(props: TStateDeleteModal) {
|
||||
const { isOpen, onClose, data } = props;
|
||||
const { t } = useTranslation();
|
||||
// states
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
// router
|
||||
@@ -47,15 +49,14 @@ export const StateDeleteModal = observer(function StateDeleteModal(props: TState
|
||||
if (err.status === 400)
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error!",
|
||||
message:
|
||||
"This state contains some work items within it, please move them to some other state to delete this state.",
|
||||
title: t("common.error.label"),
|
||||
message: t("project_settings.states.delete.blocked"),
|
||||
});
|
||||
else
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error!",
|
||||
message: "State could not be deleted. Please try again.",
|
||||
title: t("common.error.label"),
|
||||
message: t("project_settings.states.delete.error"),
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -69,13 +70,11 @@ export const StateDeleteModal = observer(function StateDeleteModal(props: TState
|
||||
handleSubmit={handleDeletion}
|
||||
isSubmitting={isDeleteLoading}
|
||||
isOpen={isOpen}
|
||||
title="Delete State"
|
||||
content={
|
||||
<>
|
||||
Are you sure you want to delete state- <span className="font-medium text-primary">{data?.name}</span>? All of
|
||||
the data related to the state will be permanently removed. This action cannot be undone.
|
||||
</>
|
||||
}
|
||||
title={t("entity.delete.label", { entity: t("common.state") })}
|
||||
content={t("entity.delete.confirmation", {
|
||||
entity: t("common.state").toLowerCase(),
|
||||
identifier: data?.name ? `"${data.name}"` : "",
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import { useState } from "react";
|
||||
import { useParams } from "next/navigation";
|
||||
// ui
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import { AlertModalCore } from "@plane/ui";
|
||||
// hooks
|
||||
@@ -20,6 +21,7 @@ interface IDeleteWebhook {
|
||||
|
||||
export function DeleteWebhookModal(props: IDeleteWebhook) {
|
||||
const { isOpen, onClose } = props;
|
||||
const { t } = useTranslation();
|
||||
// states
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
// router
|
||||
@@ -41,14 +43,14 @@ export function DeleteWebhookModal(props: IDeleteWebhook) {
|
||||
router.replace(`/${workspaceSlug}/settings/webhooks/`);
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Success!",
|
||||
message: "Webhook deleted successfully.",
|
||||
title: t("workspace_settings.settings.webhooks.toasts.removed.title"),
|
||||
message: t("workspace_settings.settings.webhooks.toasts.removed.message"),
|
||||
});
|
||||
} catch (_error) {
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error!",
|
||||
message: "Webhook could not be deleted. Please try again.",
|
||||
title: t("workspace_settings.settings.webhooks.toasts.not_removed.title"),
|
||||
message: t("workspace_settings.settings.webhooks.toasts.not_removed.message"),
|
||||
});
|
||||
}
|
||||
setIsDeleting(false);
|
||||
@@ -60,13 +62,8 @@ export function DeleteWebhookModal(props: IDeleteWebhook) {
|
||||
handleSubmit={handleDelete}
|
||||
isSubmitting={isDeleting}
|
||||
isOpen={isOpen}
|
||||
title="Delete webhook"
|
||||
content={
|
||||
<>
|
||||
Are you sure you want to delete this webhook? Future events will not be delivered to this webhook. This action
|
||||
cannot be undone.
|
||||
</>
|
||||
}
|
||||
title={t("workspace_settings.settings.webhooks.delete.title")}
|
||||
content={t("workspace_settings.settings.webhooks.delete.description")}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
import { Disclosure, Transition } from "@headlessui/react";
|
||||
import { WORKSPACE_SETTINGS_TRACKER_ELEMENTS } from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { ChevronDownIcon, ChevronUpIcon } from "@plane/propel/icons";
|
||||
|
||||
@@ -15,13 +16,14 @@ type Props = {
|
||||
|
||||
export function WebhookDeleteSection(props: Props) {
|
||||
const { openDeleteModal } = props;
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Disclosure as="div" className="border-t border-subtle">
|
||||
{({ open }) => (
|
||||
<div className="w-full">
|
||||
<Disclosure.Button as="button" type="button" className="flex w-full items-center justify-between py-4">
|
||||
<span className="text-16 tracking-tight">Danger zone</span>
|
||||
<span className="text-16 tracking-tight">{t("workspace_settings.settings.webhooks.delete.title")}</span>
|
||||
{open ? <ChevronUpIcon className="h-5 w-5" /> : <ChevronDownIcon className="h-5 w-5" />}
|
||||
</Disclosure.Button>
|
||||
|
||||
@@ -36,18 +38,16 @@ export function WebhookDeleteSection(props: Props) {
|
||||
>
|
||||
<Disclosure.Panel>
|
||||
<div className="flex flex-col gap-8">
|
||||
<span className="text-13 tracking-tight">
|
||||
Once a webhook is deleted, it cannot be restored. Future events will no longer be delivered to this
|
||||
webhook.
|
||||
</span>
|
||||
<span className="text-13 tracking-tight">{t("workspace_settings.settings.webhooks.delete.description")}</span>
|
||||
<div>
|
||||
<Button
|
||||
variant="error-fill"
|
||||
size="lg"
|
||||
onClick={openDeleteModal}
|
||||
className="nodedc-modal-danger-button"
|
||||
data-ph-element={WORKSPACE_SETTINGS_TRACKER_ELEMENTS.WEBHOOK_DELETE_BUTTON}
|
||||
>
|
||||
Delete webhook
|
||||
{t("workspace_settings.settings.webhooks.delete.title")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user