From 66d07e340b6bb2a0c915434afa64c0dd2d7e748f Mon Sep 17 00:00:00 2001
From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com>
Date: Fri, 31 Mar 2023 02:17:35 +0530
Subject: [PATCH] fix: delete mutations for issues, cycles and modules (#634)
---
.../core/list-view/single-issue.tsx | 19 ++--
.../components/cycles/delete-cycle-modal.tsx | 89 ++++++++++++++++---
.../components/issues/delete-issue-modal.tsx | 53 +++++------
.../modules/delete-module-modal.tsx | 43 ++++-----
apps/app/hooks/use-issues-view.tsx | 2 +-
5 files changed, 131 insertions(+), 75 deletions(-)
diff --git a/apps/app/components/core/list-view/single-issue.tsx b/apps/app/components/core/list-view/single-issue.tsx
index 0dc66996c..4da844645 100644
--- a/apps/app/components/core/list-view/single-issue.tsx
+++ b/apps/app/components/core/list-view/single-issue.tsx
@@ -26,6 +26,7 @@ import {
LinkIcon,
PencilIcon,
TrashIcon,
+ XMarkIcon,
} from "@heroicons/react/24/outline";
// helpers
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
@@ -38,6 +39,7 @@ import {
MODULE_ISSUES_WITH_PARAMS,
PROJECT_ISSUES_LIST_WITH_PARAMS,
} from "constants/fetch-keys";
+import { DIVIDER } from "@blueprintjs/core/lib/esm/common/classes";
type Props = {
type?: string;
@@ -258,27 +260,30 @@ export const SingleListIssue: React.FC = ({
{type && !isNotAllowed && (
-
+
{type !== "issue" && removeIssue && (
- <>Remove from {type}>
+
+
+ Remove from {type}
+
)}
handleDeleteIssue(issue)}>
-
+
Delete issue
-
+
-
+
Copy issue link
-
+
)}
diff --git a/apps/app/components/cycles/delete-cycle-modal.tsx b/apps/app/components/cycles/delete-cycle-modal.tsx
index 4464c54d9..c43d34d68 100644
--- a/apps/app/components/cycles/delete-cycle-modal.tsx
+++ b/apps/app/components/cycles/delete-cycle-modal.tsx
@@ -14,14 +14,25 @@ import { DangerButton, SecondaryButton } from "components/ui";
// icons
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
// types
-import type { ICycle } from "types";
+import type {
+ CompletedCyclesResponse,
+ CurrentAndUpcomingCyclesResponse,
+ DraftCyclesResponse,
+ ICycle,
+} from "types";
type TConfirmCycleDeletionProps = {
isOpen: boolean;
setIsOpen: React.Dispatch>;
data?: ICycle;
};
// fetch-keys
-import { CYCLE_LIST } from "constants/fetch-keys";
+import {
+ CYCLE_COMPLETE_LIST,
+ CYCLE_CURRENT_AND_UPCOMING_LIST,
+ CYCLE_DRAFT_LIST,
+ CYCLE_LIST,
+} from "constants/fetch-keys";
+import { getDateRangeStatus } from "helpers/date-time.helper";
export const DeleteCycleModal: React.FC = ({
isOpen,
@@ -31,7 +42,7 @@ export const DeleteCycleModal: React.FC = ({
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
const router = useRouter();
- const { workspaceSlug } = router.query;
+ const { workspaceSlug, projectId } = router.query;
const { setToastAlert } = useToast();
@@ -41,16 +52,68 @@ export const DeleteCycleModal: React.FC = ({
};
const handleDeletion = async () => {
- setIsDeleteLoading(true);
if (!data || !workspaceSlug) return;
+
+ setIsDeleteLoading(true);
+
await cycleService
.deleteCycle(workspaceSlug as string, data.project, data.id)
.then(() => {
- mutate(
- CYCLE_LIST(data.project),
- (prevData) => prevData?.filter((cycle) => cycle.id !== data?.id),
- false
- );
+ switch (getDateRangeStatus(data.start_date, data.end_date)) {
+ case "completed":
+ mutate(
+ CYCLE_COMPLETE_LIST(projectId as string),
+ (prevData) => {
+ if (!prevData) return;
+
+ return {
+ completed_cycles: prevData.completed_cycles?.filter(
+ (cycle) => cycle.id !== data?.id
+ ),
+ };
+ },
+ false
+ );
+ break;
+ case "current":
+ mutate(
+ CYCLE_CURRENT_AND_UPCOMING_LIST(projectId as string),
+ (prevData) => {
+ if (!prevData) return;
+ return {
+ current_cycle: prevData.current_cycle?.filter((c) => c.id !== data?.id),
+ upcoming_cycle: prevData.upcoming_cycle,
+ };
+ },
+ false
+ );
+ break;
+ case "upcoming":
+ mutate(
+ CYCLE_CURRENT_AND_UPCOMING_LIST(projectId as string),
+ (prevData) => {
+ if (!prevData) return;
+
+ return {
+ current_cycle: prevData.current_cycle,
+ upcoming_cycle: prevData.upcoming_cycle?.filter((c) => c.id !== data?.id),
+ };
+ },
+ false
+ );
+ break;
+ default:
+ mutate(
+ CYCLE_DRAFT_LIST(projectId as string),
+ (prevData) => {
+ if (!prevData) return;
+ return {
+ draft_cycles: prevData.draft_cycles?.filter((cycle) => cycle.id !== data?.id),
+ };
+ },
+ false
+ );
+ }
handleClose();
setToastAlert({
@@ -59,8 +122,7 @@ export const DeleteCycleModal: React.FC = ({
message: "Cycle deleted successfully",
});
})
- .catch((error) => {
- console.log(error);
+ .catch(() => {
setIsDeleteLoading(false);
});
};
@@ -107,9 +169,8 @@ export const DeleteCycleModal: React.FC = ({
Are you sure you want to delete cycle-{" "}
- {data?.name}
- ? All of the data related to the cycle will be permanently removed.
- This action cannot be undone.
+ {data?.name}? All of the data related
+ to the cycle will be permanently removed. This action cannot be undone.
diff --git a/apps/app/components/issues/delete-issue-modal.tsx b/apps/app/components/issues/delete-issue-modal.tsx
index 0027e6d83..e161e52a1 100644
--- a/apps/app/components/issues/delete-issue-modal.tsx
+++ b/apps/app/components/issues/delete-issue-modal.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useRef, useState } from "react";
+import React, { useEffect, useState } from "react";
import { useRouter } from "next/router";
@@ -17,7 +17,15 @@ import { SecondaryButton, DangerButton } from "components/ui";
// types
import type { CycleIssueResponse, IIssue, ModuleIssueResponse } from "types";
// fetch-keys
-import { CYCLE_ISSUES, PROJECT_ISSUES_LIST, MODULE_ISSUES, USER_ISSUE } from "constants/fetch-keys";
+import {
+ CYCLE_ISSUES,
+ CYCLE_ISSUES_WITH_PARAMS,
+ MODULE_ISSUES,
+ MODULE_ISSUES_WITH_PARAMS,
+ PROJECT_ISSUES_LIST_WITH_PARAMS,
+ USER_ISSUE,
+} from "constants/fetch-keys";
+import useIssuesView from "hooks/use-issues-view";
type Props = {
isOpen: boolean;
@@ -29,7 +37,9 @@ export const DeleteIssueModal: React.FC = ({ isOpen, handleClose, data })
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
const router = useRouter();
- const { workspaceSlug, projectId: queryProjectId } = router.query;
+ const { workspaceSlug, projectId, cycleId, moduleId } = router.query;
+
+ const { params } = useIssuesView();
const { setToastAlert } = useToast();
@@ -44,37 +54,14 @@ export const DeleteIssueModal: React.FC = ({ isOpen, handleClose, data })
const handleDeletion = async () => {
setIsDeleteLoading(true);
- if (!data || !workspaceSlug) return;
+ if (!workspaceSlug || !projectId || !data) return;
- const projectId = data.project;
await issueServices
- .deleteIssue(workspaceSlug as string, projectId, data.id)
+ .deleteIssue(workspaceSlug as string, projectId as string, data.id)
.then(() => {
- const cycleId = data?.cycle;
- const moduleId = data?.module;
-
- if (cycleId) {
- mutate(
- CYCLE_ISSUES(cycleId),
- (prevData) => prevData?.filter((i) => i.issue !== data.id),
- false
- );
- }
-
- if (moduleId) {
- mutate(
- MODULE_ISSUES(moduleId),
- (prevData) => prevData?.filter((i) => i.issue !== data.id),
- false
- );
- }
-
- if (!queryProjectId)
- mutate(
- USER_ISSUE(workspaceSlug as string),
- (prevData) => prevData?.filter((i) => i.id !== data.id),
- false
- );
+ if (cycleId) mutate(CYCLE_ISSUES_WITH_PARAMS(cycleId as string, params));
+ else if (moduleId) mutate(MODULE_ISSUES_WITH_PARAMS(moduleId as string, params));
+ else mutate(PROJECT_ISSUES_LIST_WITH_PARAMS(projectId as string, params));
handleClose();
setToastAlert({
@@ -133,8 +120,8 @@ export const DeleteIssueModal: React.FC = ({ isOpen, handleClose, data })
Are you sure you want to delete issue{" "}
{data?.project_detail.identifier}-{data?.sequence_id}
- {""}
- ? All of the data related to the issue will be permanently removed. This
+
+ {""}? All of the data related to the issue will be permanently removed. This
action cannot be undone.
diff --git a/apps/app/components/modules/delete-module-modal.tsx b/apps/app/components/modules/delete-module-modal.tsx
index 97663b6b9..70fca1916 100644
--- a/apps/app/components/modules/delete-module-modal.tsx
+++ b/apps/app/components/modules/delete-module-modal.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useRef, useState } from "react";
+import React, { useState } from "react";
import { useRouter } from "next/router";
@@ -29,7 +29,7 @@ export const DeleteModuleModal: React.FC = ({ isOpen, setIsOpen, data })
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
const router = useRouter();
- const { workspaceSlug } = router.query;
+ const { workspaceSlug, projectId, moduleId } = router.query;
const { setToastAlert } = useToast();
@@ -41,22 +41,26 @@ export const DeleteModuleModal: React.FC = ({ isOpen, setIsOpen, data })
const handleDeletion = async () => {
setIsDeleteLoading(true);
- if (!workspaceSlug || !data) return;
- await modulesService
- .deleteModule(workspaceSlug as string, data.project, data.id)
- .then(() => {
- mutate(MODULE_LIST(data.project));
- router.push(`/${workspaceSlug}/projects/${data.project}/modules`);
- handleClose();
+ if (!workspaceSlug || !projectId || !data) return;
- setToastAlert({
- title: "Success",
- type: "success",
- message: "Module deleted successfully",
- });
+ mutate(
+ MODULE_LIST(projectId as string),
+ (prevData) => prevData?.filter((m) => m.id !== data.id),
+ false
+ );
+
+ await modulesService
+ .deleteModule(workspaceSlug as string, projectId as string, data.id)
+ .then(() => {
+ if (moduleId) router.push(`/${workspaceSlug}/projects/${data.project}/modules`);
+ handleClose();
})
- .catch((error) => {
- console.log(error);
+ .catch(() => {
+ setToastAlert({
+ type: "error",
+ title: "Error!",
+ message: "Module could not be deleted. Please try again.",
+ });
setIsDeleteLoading(false);
});
};
@@ -102,10 +106,9 @@ export const DeleteModuleModal: React.FC = ({ isOpen, setIsOpen, data })
- Are you sure you want to delete module- {" "}
- {data?.name}
- ? All of the data related to the module will be permanently removed.
- This action cannot be undone.
+ Are you sure you want to delete module-{" "}
+ {data?.name}? All of the data related
+ to the module will be permanently removed. This action cannot be undone.
diff --git a/apps/app/hooks/use-issues-view.tsx b/apps/app/hooks/use-issues-view.tsx
index 789123c58..92e2d695c 100644
--- a/apps/app/hooks/use-issues-view.tsx
+++ b/apps/app/hooks/use-issues-view.tsx
@@ -36,7 +36,7 @@ const useIssuesView = () => {
setFilters,
resetFilterToDefault,
setNewFilterDefaultView,
- setIssueView
+ setIssueView,
} = useContext(issueViewContext);
const router = useRouter();