diff --git a/web/core/components/issues/issue-modal/base.tsx b/web/core/components/issues/issue-modal/base.tsx index 0e4e3d6c39..cb638da638 100644 --- a/web/core/components/issues/issue-modal/base.tsx +++ b/web/core/components/issues/issue-modal/base.tsx @@ -3,7 +3,7 @@ import React, { useEffect, useRef, useState } from "react"; import { observer } from "mobx-react"; import { useParams, usePathname } from "next/navigation"; -import { EIssuesStoreType, ISSUE_CREATED, ISSUE_UPDATED } from "@plane/constants"; +import { EIssueServiceType, EIssuesStoreType, ISSUE_CREATED, ISSUE_UPDATED } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; // types import type { TBaseIssue, TIssue } from "@plane/types"; @@ -17,6 +17,7 @@ import { useEventTracker, useCycle, useIssues, useModule, useIssueDetail, useUse import { useIssueStoreType } from "@/hooks/use-issue-layout-store"; import { useIssuesActions } from "@/hooks/use-issues-actions"; // services +import { useIssueTypes } from "@/plane-web/hooks/store"; import { FileService } from "@/services/file.service"; const fileService = new FileService(); // local components @@ -65,8 +66,10 @@ export const CreateUpdateIssueModalBase: React.FC = observer(( const { issues } = useIssues(storeType); const { issues: projectIssues } = useIssues(EIssuesStoreType.PROJECT); const { issues: draftIssues } = useIssues(EIssuesStoreType.WORKSPACE_DRAFT); - const { fetchIssue } = useIssueDetail(); + const { fetchIssue, removeSubIssue } = useIssueDetail(); + const { removeSubIssue: removeEpicSubIssue } = useIssueDetail(EIssueServiceType.EPICS); const { handleCreateUpdatePropertyValues } = useIssueModal(); + const { getIssueTypeById } = useIssueTypes(); // pathname const pathname = usePathname(); // current store details @@ -260,6 +263,14 @@ export const CreateUpdateIssueModalBase: React.FC = observer(( if (!workspaceSlug || !payload.project_id || !data?.id) return; try { + // check for parent change + if (data?.parent_id && payload?.parent_id && payload?.parent_id !== data?.parent_id) { + const isParentEpic = getIssueTypeById(data?.parent_id || "")?.is_epic; + if (isParentEpic) + await removeEpicSubIssue(workspaceSlug?.toString(), payload.project_id, data.parent_id, data.id); + else await removeSubIssue(workspaceSlug?.toString(), payload.project_id, data.parent_id, data.id); + } + if (isDraft) await draftIssues.updateIssue(workspaceSlug.toString(), data.id, payload); else if (updateIssue) await updateIssue(payload.project_id, data.id, payload); diff --git a/web/core/store/issue/issue-details/sub_issues.store.ts b/web/core/store/issue/issue-details/sub_issues.store.ts index c2c160c390..e578057e3a 100644 --- a/web/core/store/issue/issue-details/sub_issues.store.ts +++ b/web/core/store/issue/issue-details/sub_issues.store.ts @@ -282,7 +282,7 @@ export class IssueSubIssuesStore implements IIssueSubIssuesStore { set( this.rootIssueDetailStore.rootIssueStore.issues.issuesMap, [parentIssueId, "sub_issues_count"], - this.subIssues[parentIssueId].length + this.subIssues[parentIssueId]?.length || 0 ); }); @@ -319,7 +319,7 @@ export class IssueSubIssuesStore implements IIssueSubIssuesStore { set( this.rootIssueDetailStore.rootIssueStore.issues.issuesMap, [parentIssueId, "sub_issues_count"], - this.subIssues[parentIssueId].length + this.subIssues[parentIssueId]?.length || 0 ); }); diff --git a/web/ee/components/issues/issue-details/parent-select-root.tsx b/web/ee/components/issues/issue-details/parent-select-root.tsx index 8cc3fff5f6..8b3960c6de 100644 --- a/web/ee/components/issues/issue-details/parent-select-root.tsx +++ b/web/ee/components/issues/issue-details/parent-select-root.tsx @@ -31,11 +31,11 @@ export const IssueParentSelectRoot: React.FC = observer((pro } = useIssueDetail(); const { toggleParentIssueModal, - removeSubIssue, subIssues: { setSubIssueHelpers, fetchSubIssues }, } = useIssueDetail(); const { getIssueTypeById } = useIssueTypes(); - const subIssueOperations = useSubIssueOperations(EIssueServiceType.EPICS); + const subIssueOperations = useSubIssueOperations(); + const epicSubIssueOperations = useSubIssueOperations(EIssueServiceType.EPICS); // derived values const issue = getIssueById(issueId); @@ -47,11 +47,15 @@ export const IssueParentSelectRoot: React.FC = observer((pro const issueBeforeUpdate = { ...issue }; const oldParentDetails = issueBeforeUpdate?.parent_id ? getIssueById(issueBeforeUpdate.parent_id) : undefined; const isOldParentEpic = getIssueTypeById(oldParentDetails?.type_id || "")?.is_epic; + if (oldParentDetails?.id) { + if (isOldParentEpic) + await epicSubIssueOperations.removeSubIssue(workspaceSlug, projectId, oldParentDetails.id, issueId); + else await subIssueOperations.removeSubIssue(workspaceSlug, projectId, oldParentDetails.id, issueId); + } + await issueOperations.update(workspaceSlug, projectId, issueId, { parent_id: _issueId }); await issueOperations.fetch(workspaceSlug, projectId, issueId, false); if (_issueId) await fetchSubIssues(workspaceSlug, projectId, _issueId); - if (isOldParentEpic && oldParentDetails?.id) - await subIssueOperations.removeSubIssue(workspaceSlug, projectId, oldParentDetails.id, issueId); toggleParentIssueModal(null); } catch (error) { console.error("something went wrong while fetching the issue"); @@ -65,14 +69,14 @@ export const IssueParentSelectRoot: React.FC = observer((pro issueId: string ) => { try { - const issueBeforeUpdate = { ...issue }; - const oldParentDetails = issueBeforeUpdate?.parent_id ? getIssueById(issueBeforeUpdate.parent_id) : undefined; - const isOldParentEpic = getIssueTypeById(oldParentDetails?.type_id || "")?.is_epic; + const parentDetails = parentIssueId ? getIssueById(parentIssueId) : undefined; + const isParentEpic = getIssueTypeById(parentDetails?.type_id || "")?.is_epic; setSubIssueHelpers(parentIssueId, "issue_loader", issueId); - await removeSubIssue(workspaceSlug, projectId, parentIssueId, issueId); + + if (isParentEpic) await epicSubIssueOperations.removeSubIssue(workspaceSlug, projectId, parentIssueId, issueId); + else await subIssueOperations.removeSubIssue(workspaceSlug, projectId, parentIssueId, issueId); + await fetchSubIssues(workspaceSlug, projectId, parentIssueId); - if (isOldParentEpic && oldParentDetails?.id) - await subIssueOperations.removeSubIssue(workspaceSlug, projectId, oldParentDetails.id, issueId); setSubIssueHelpers(parentIssueId, "issue_loader", issueId); } catch (error) { setToast({