chore: issue relation modal and issue peek overview mutation fix (#3482)

* fix: resolve addtocycle and addtomodule mutation in peek overview and issue sidebar

* fix: issue relation modal fix for all issues peek overview

* fix: cycle and module mutation in issue detail and issue peek overview

* fix: updated the issue actions for cycle and module mutation in peek overview

* chore: module issue store updated

* chore: existing isssue modal improvement and build error fix

---------

Co-authored-by: gurusainath <gurusainath007@gmail.com>
This commit is contained in:
Anmol Singh Bhatia 2024-01-27 15:20:36 +05:30 committed by GitHub
parent 9ecdcc6fde
commit 212f2b54f8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 59 additions and 81 deletions

View File

@ -1,5 +1,4 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { useRouter } from "next/router";
import { Combobox, Dialog, Transition } from "@headlessui/react"; import { Combobox, Dialog, Transition } from "@headlessui/react";
import { Rocket, Search, X } from "lucide-react"; import { Rocket, Search, X } from "lucide-react";
// services // services
@ -13,6 +12,8 @@ import { Button, LayersIcon, Loader, ToggleSwitch, Tooltip } from "@plane/ui";
import { ISearchIssueResponse, TProjectIssuesSearchParams } from "@plane/types"; import { ISearchIssueResponse, TProjectIssuesSearchParams } from "@plane/types";
type Props = { type Props = {
workspaceSlug: string | undefined;
projectId: string | undefined;
isOpen: boolean; isOpen: boolean;
handleClose: () => void; handleClose: () => void;
searchParams: Partial<TProjectIssuesSearchParams>; searchParams: Partial<TProjectIssuesSearchParams>;
@ -23,7 +24,15 @@ type Props = {
const projectService = new ProjectService(); const projectService = new ProjectService();
export const ExistingIssuesListModal: React.FC<Props> = (props) => { export const ExistingIssuesListModal: React.FC<Props> = (props) => {
const { isOpen, handleClose: onClose, searchParams, handleOnSubmit, workspaceLevelToggle = false } = props; const {
workspaceSlug,
projectId,
isOpen,
handleClose: onClose,
searchParams,
handleOnSubmit,
workspaceLevelToggle = false,
} = props;
// states // states
const [searchTerm, setSearchTerm] = useState(""); const [searchTerm, setSearchTerm] = useState("");
const [issues, setIssues] = useState<ISearchIssueResponse[]>([]); const [issues, setIssues] = useState<ISearchIssueResponse[]>([]);
@ -34,9 +43,6 @@ export const ExistingIssuesListModal: React.FC<Props> = (props) => {
const debouncedSearchTerm: string = useDebounce(searchTerm, 500); const debouncedSearchTerm: string = useDebounce(searchTerm, 500);
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
const { setToastAlert } = useToast(); const { setToastAlert } = useToast();
const handleClose = () => { const handleClose = () => {

View File

@ -90,6 +90,8 @@ export const IssueRelationSelect: React.FC<TIssueRelationSelect> = observer((pro
return ( return (
<> <>
<ExistingIssuesListModal <ExistingIssuesListModal
workspaceSlug={workspaceSlug}
projectId={projectId}
isOpen={isRelationModalOpen === relationKey} isOpen={isRelationModalOpen === relationKey}
handleClose={() => toggleRelationModal(null)} handleClose={() => toggleRelationModal(null)}
searchParams={{ issue_relation: true, issue_id: issueId }} searchParams={{ issue_relation: true, issue_id: issueId }}

View File

@ -120,23 +120,12 @@ export const IssueDetailRoot: FC<TIssueDetailRoot> = (props) => {
}, },
addIssueToCycle: async (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => { addIssueToCycle: async (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => {
try { try {
await addIssueToCycle(workspaceSlug, projectId, cycleId, issueIds) await addIssueToCycle(workspaceSlug, projectId, cycleId, issueIds);
.then((res) => { setToastAlert({
updateIssue(workspaceSlug, projectId, res.id, res); title: "Cycle added to issue successfully",
fetchIssue(workspaceSlug, projectId, res.id); type: "success",
setToastAlert({ message: "Issue added to issue successfully",
title: "Cycle added to issue successfully", });
type: "success",
message: "Issue added to issue successfully",
});
})
.catch(() => {
setToastAlert({
type: "error",
title: "Error!",
message: "Selected issues could not be added to the cycle. Please try again.",
});
});
} catch (error) { } catch (error) {
setToastAlert({ setToastAlert({
title: "Cycle add to issue failed", title: "Cycle add to issue failed",
@ -163,23 +152,12 @@ export const IssueDetailRoot: FC<TIssueDetailRoot> = (props) => {
}, },
addIssueToModule: async (workspaceSlug: string, projectId: string, moduleId: string, issueIds: string[]) => { addIssueToModule: async (workspaceSlug: string, projectId: string, moduleId: string, issueIds: string[]) => {
try { try {
await addIssueToModule(workspaceSlug, projectId, moduleId, issueIds) await addIssueToModule(workspaceSlug, projectId, moduleId, issueIds);
.then((res) => { setToastAlert({
updateIssue(workspaceSlug, projectId, res.id, res); title: "Module added to issue successfully",
fetchIssue(workspaceSlug, projectId, res.id); type: "success",
setToastAlert({ message: "Module added to issue successfully",
title: "Module added to issue successfully", });
type: "success",
message: "Module added to issue successfully",
});
})
.catch(() =>
setToastAlert({
type: "error",
title: "Error!",
message: "Selected issues could not be added to the module. Please try again.",
})
);
} catch (error) { } catch (error) {
setToastAlert({ setToastAlert({
title: "Module add to issue failed", title: "Module add to issue failed",

View File

@ -65,6 +65,8 @@ export const CycleEmptyState: React.FC<Props> = observer((props) => {
return ( return (
<> <>
<ExistingIssuesListModal <ExistingIssuesListModal
workspaceSlug={workspaceSlug}
projectId={projectId}
isOpen={cycleIssuesListModal} isOpen={cycleIssuesListModal}
handleClose={() => setCycleIssuesListModal(false)} handleClose={() => setCycleIssuesListModal(false)}
searchParams={{ cycle: true }} searchParams={{ cycle: true }}

View File

@ -65,6 +65,8 @@ export const ModuleEmptyState: React.FC<Props> = observer((props) => {
return ( return (
<> <>
<ExistingIssuesListModal <ExistingIssuesListModal
workspaceSlug={workspaceSlug}
projectId={projectId}
isOpen={moduleIssuesListModal} isOpen={moduleIssuesListModal}
handleClose={() => setModuleIssuesListModal(false)} handleClose={() => setModuleIssuesListModal(false)}
searchParams={{ module: true }} searchParams={{ module: true }}

View File

@ -93,6 +93,8 @@ export const HeaderGroupByCard: FC<IHeaderGroupByCard> = observer((props) => {
)} )}
{renderExistingIssueModal && ( {renderExistingIssueModal && (
<ExistingIssuesListModal <ExistingIssuesListModal
workspaceSlug={workspaceSlug?.toString()}
projectId={projectId?.toString()}
isOpen={openExistingIssueListModal} isOpen={openExistingIssueListModal}
handleClose={() => setOpenExistingIssueListModal(false)} handleClose={() => setOpenExistingIssueListModal(false)}
searchParams={ExistingIssuesListModalPayload} searchParams={ExistingIssuesListModalPayload}

View File

@ -110,6 +110,8 @@ export const HeaderGroupByCard = observer(
{renderExistingIssueModal && ( {renderExistingIssueModal && (
<ExistingIssuesListModal <ExistingIssuesListModal
workspaceSlug={workspaceSlug?.toString()}
projectId={projectId?.toString()}
isOpen={openExistingIssueListModal} isOpen={openExistingIssueListModal}
handleClose={() => setOpenExistingIssueListModal(false)} handleClose={() => setOpenExistingIssueListModal(false)}
searchParams={ExistingIssuesListModalPayload} searchParams={ExistingIssuesListModalPayload}

View File

@ -113,23 +113,12 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
}, },
addIssueToCycle: async (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => { addIssueToCycle: async (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => {
try { try {
await addIssueToCycle(workspaceSlug, projectId, cycleId, issueIds) await addIssueToCycle(workspaceSlug, projectId, cycleId, issueIds);
.then((res) => { setToastAlert({
updateIssue(workspaceSlug, projectId, res.id, res); title: "Cycle added to issue successfully",
fetchIssue(workspaceSlug, projectId, res.id); type: "success",
setToastAlert({ message: "Issue added to issue successfully",
title: "Cycle added to issue successfully", });
type: "success",
message: "Issue added to issue successfully",
});
})
.catch(() => {
setToastAlert({
type: "error",
title: "Error!",
message: "Selected issues could not be added to the cycle. Please try again.",
});
});
} catch (error) { } catch (error) {
setToastAlert({ setToastAlert({
title: "Cycle add to issue failed", title: "Cycle add to issue failed",
@ -156,23 +145,12 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
}, },
addIssueToModule: async (workspaceSlug: string, projectId: string, moduleId: string, issueIds: string[]) => { addIssueToModule: async (workspaceSlug: string, projectId: string, moduleId: string, issueIds: string[]) => {
try { try {
await addIssueToModule(workspaceSlug, projectId, moduleId, issueIds) await addIssueToModule(workspaceSlug, projectId, moduleId, issueIds);
.then((res) => { setToastAlert({
updateIssue(workspaceSlug, projectId, res.id, res); title: "Module added to issue successfully",
fetchIssue(workspaceSlug, projectId, res.id); type: "success",
setToastAlert({ message: "Module added to issue successfully",
title: "Module added to issue successfully", });
type: "success",
message: "Module added to issue successfully",
});
})
.catch(() =>
setToastAlert({
type: "error",
title: "Error!",
message: "Selected issues could not be added to the module. Please try again.",
})
);
} catch (error) { } catch (error) {
setToastAlert({ setToastAlert({
title: "Module add to issue failed", title: "Module add to issue failed",

View File

@ -369,6 +369,8 @@ export const SubIssuesRoot: FC<ISubIssuesRoot> = observer((props) => {
{issueCrudState?.existing?.toggle && issueCrudState?.existing?.parentIssueId && ( {issueCrudState?.existing?.toggle && issueCrudState?.existing?.parentIssueId && (
<ExistingIssuesListModal <ExistingIssuesListModal
workspaceSlug={workspaceSlug}
projectId={projectId}
isOpen={issueCrudState?.existing?.toggle} isOpen={issueCrudState?.existing?.toggle}
handleClose={() => handleIssueCrudState("existing", null, null)} handleClose={() => handleIssueCrudState("existing", null, null)}
searchParams={{ sub_issue: true, issue_id: issueCrudState?.existing?.parentIssueId }} searchParams={{ sub_issue: true, issue_id: issueCrudState?.existing?.parentIssueId }}

View File

@ -3,6 +3,7 @@ import set from "lodash/set";
import update from "lodash/update"; import update from "lodash/update";
import concat from "lodash/concat"; import concat from "lodash/concat";
import pull from "lodash/pull"; import pull from "lodash/pull";
import uniq from "lodash/uniq";
// base class // base class
import { IssueHelperStore } from "../helpers/issue-helper.store"; import { IssueHelperStore } from "../helpers/issue-helper.store";
// services // services
@ -165,7 +166,6 @@ export class CycleIssues extends IssueHelperStore implements ICycleIssues {
return response; return response;
} catch (error) { } catch (error) {
console.log(error);
this.loader = undefined; this.loader = undefined;
throw error; throw error;
} }
@ -267,11 +267,13 @@ export class CycleIssues extends IssueHelperStore implements ICycleIssues {
}); });
runInAction(() => { runInAction(() => {
update(this.issues, cycleId, (cycleIssueIds) => { update(this.issues, cycleId, (cycleIssueIds = []) => {
if (!cycleIssueIds) return [...issueIds]; uniq(concat(cycleIssueIds, issueIds));
else return concat(cycleIssueIds, [...issueIds]);
}); });
}); });
issueIds.forEach((issueId) => {
this.rootStore.issues.updateIssue(issueId, { cycle_id: cycleId });
});
return issueToCycle; return issueToCycle;
} catch (error) { } catch (error) {
@ -332,7 +334,6 @@ export class CycleIssues extends IssueHelperStore implements ICycleIssues {
return response; return response;
} catch (error) { } catch (error) {
console.log(error);
this.loader = undefined; this.loader = undefined;
throw error; throw error;
} }

View File

@ -3,6 +3,7 @@ import set from "lodash/set";
import update from "lodash/update"; import update from "lodash/update";
import concat from "lodash/concat"; import concat from "lodash/concat";
import pull from "lodash/pull"; import pull from "lodash/pull";
import uniq from "lodash/uniq";
// base class // base class
import { IssueHelperStore } from "../helpers/issue-helper.store"; import { IssueHelperStore } from "../helpers/issue-helper.store";
// services // services
@ -259,11 +260,13 @@ export class ModuleIssues extends IssueHelperStore implements IModuleIssues {
}); });
runInAction(() => { runInAction(() => {
update(this.issues, moduleId, (moduleIssueIds) => { update(this.issues, moduleId, (moduleIssueIds = []) => {
if (!moduleIssueIds) return [...issueIds]; uniq(concat(moduleIssueIds, issueIds));
else return concat(moduleIssueIds, [...issueIds]);
}); });
}); });
issueIds.forEach((issueId) => {
this.rootStore.issues.updateIssue(issueId, { module_id: moduleId });
});
return issueToModule; return issueToModule;
} catch (error) { } catch (error) {