mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
fix: mutation while adding issue to cycle or module (#589)
This commit is contained in:
parent
4e9715a5b2
commit
1509c8611d
@ -1,11 +1,16 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
// headless ui
|
import { useRouter } from "next/router";
|
||||||
import { Combobox, Dialog, Transition } from "@headlessui/react";
|
|
||||||
|
import { mutate } from "swr";
|
||||||
|
|
||||||
// react-hook-form
|
// react-hook-form
|
||||||
import { Controller, SubmitHandler, useForm } from "react-hook-form";
|
import { Controller, SubmitHandler, useForm } from "react-hook-form";
|
||||||
|
// headless ui
|
||||||
|
import { Combobox, Dialog, Transition } from "@headlessui/react";
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
|
import useIssuesView from "hooks/use-issues-view";
|
||||||
// ui
|
// ui
|
||||||
import { PrimaryButton, SecondaryButton } from "components/ui";
|
import { PrimaryButton, SecondaryButton } from "components/ui";
|
||||||
// icons
|
// icons
|
||||||
@ -13,6 +18,8 @@ import { MagnifyingGlassIcon } from "@heroicons/react/24/outline";
|
|||||||
import { LayerDiagonalIcon } from "components/icons";
|
import { LayerDiagonalIcon } from "components/icons";
|
||||||
// types
|
// types
|
||||||
import { IIssue } from "types";
|
import { IIssue } from "types";
|
||||||
|
// fetch-keys
|
||||||
|
import { CYCLE_ISSUES_WITH_PARAMS, MODULE_ISSUES_WITH_PARAMS } from "constants/fetch-keys";
|
||||||
|
|
||||||
type FormInput = {
|
type FormInput = {
|
||||||
issues: string[];
|
issues: string[];
|
||||||
@ -33,8 +40,13 @@ export const ExistingIssuesListModal: React.FC<Props> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const [query, setQuery] = useState("");
|
const [query, setQuery] = useState("");
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const { cycleId, moduleId } = router.query;
|
||||||
|
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
|
const { params } = useIssuesView();
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
onClose();
|
onClose();
|
||||||
setQuery("");
|
setQuery("");
|
||||||
@ -64,6 +76,9 @@ export const ExistingIssuesListModal: React.FC<Props> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
await handleOnSubmit(data);
|
await handleOnSubmit(data);
|
||||||
|
if (cycleId) mutate(CYCLE_ISSUES_WITH_PARAMS(cycleId as string, params));
|
||||||
|
if (moduleId) mutate(MODULE_ISSUES_WITH_PARAMS(moduleId as string, params));
|
||||||
|
|
||||||
handleClose();
|
handleClose();
|
||||||
|
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
|
@ -23,13 +23,12 @@ import type { IIssue } from "types";
|
|||||||
import {
|
import {
|
||||||
PROJECT_ISSUES_DETAILS,
|
PROJECT_ISSUES_DETAILS,
|
||||||
PROJECT_ISSUES_LIST,
|
PROJECT_ISSUES_LIST,
|
||||||
CYCLE_ISSUES,
|
|
||||||
USER_ISSUE,
|
USER_ISSUE,
|
||||||
PROJECTS_LIST,
|
PROJECTS_LIST,
|
||||||
MODULE_ISSUES,
|
|
||||||
SUB_ISSUES,
|
SUB_ISSUES,
|
||||||
PROJECT_ISSUES_LIST_WITH_PARAMS,
|
PROJECT_ISSUES_LIST_WITH_PARAMS,
|
||||||
CYCLE_ISSUES_WITH_PARAMS,
|
CYCLE_ISSUES_WITH_PARAMS,
|
||||||
|
MODULE_ISSUES_WITH_PARAMS,
|
||||||
} from "constants/fetch-keys";
|
} from "constants/fetch-keys";
|
||||||
|
|
||||||
export interface IssuesModalProps {
|
export interface IssuesModalProps {
|
||||||
@ -101,27 +100,8 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = ({
|
|||||||
.addIssueToCycle(workspaceSlug as string, activeProject ?? "", cycleId, {
|
.addIssueToCycle(workspaceSlug as string, activeProject ?? "", cycleId, {
|
||||||
issues: [issueId],
|
issues: [issueId],
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then(() => {
|
||||||
mutate(CYCLE_ISSUES_WITH_PARAMS(cycleId, params));
|
mutate(CYCLE_ISSUES_WITH_PARAMS(cycleId, params));
|
||||||
if (isUpdatingSingleIssue) {
|
|
||||||
mutate<IIssue>(
|
|
||||||
PROJECT_ISSUES_DETAILS,
|
|
||||||
(prevData) => ({ ...(prevData as IIssue), sprints: cycleId }),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
} else
|
|
||||||
mutate<IIssue[]>(
|
|
||||||
PROJECT_ISSUES_LIST_WITH_PARAMS(activeProject ?? "", params),
|
|
||||||
(prevData) =>
|
|
||||||
(prevData ?? []).map((i) => {
|
|
||||||
if (i.id === res.id) return { ...i, sprints: cycleId };
|
|
||||||
return i;
|
|
||||||
}),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log(err);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -132,11 +112,9 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = ({
|
|||||||
.addIssuesToModule(workspaceSlug as string, activeProject ?? "", moduleId as string, {
|
.addIssuesToModule(workspaceSlug as string, activeProject ?? "", moduleId as string, {
|
||||||
issues: [issueId],
|
issues: [issueId],
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then(() => {
|
||||||
console.log(res);
|
mutate(MODULE_ISSUES_WITH_PARAMS(moduleId as string, params));
|
||||||
mutate(MODULE_ISSUES(moduleId as string));
|
});
|
||||||
})
|
|
||||||
.catch((e) => console.log(e));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const createIssue = async (payload: Partial<IIssue>) => {
|
const createIssue = async (payload: Partial<IIssue>) => {
|
||||||
|
@ -20,6 +20,8 @@ import { CycleDetailsSidebar } from "components/cycles";
|
|||||||
import issuesService from "services/issues.service";
|
import issuesService from "services/issues.service";
|
||||||
import cycleServices from "services/cycles.service";
|
import cycleServices from "services/cycles.service";
|
||||||
import projectService from "services/project.service";
|
import projectService from "services/project.service";
|
||||||
|
// hooks
|
||||||
|
import useToast from "hooks/use-toast";
|
||||||
// ui
|
// ui
|
||||||
import { CustomMenu } from "components/ui";
|
import { CustomMenu } from "components/ui";
|
||||||
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
||||||
@ -44,6 +46,8 @@ const SingleCycle: React.FC<UserAuth> = (props) => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId, cycleId } = router.query;
|
const { workspaceSlug, projectId, cycleId } = router.query;
|
||||||
|
|
||||||
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const { data: activeProject } = useSWR(
|
const { data: activeProject } = useSWR(
|
||||||
workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
|
workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
|
||||||
workspaceSlug && projectId
|
workspaceSlug && projectId
|
||||||
@ -93,12 +97,15 @@ const SingleCycle: React.FC<UserAuth> = (props) => {
|
|||||||
|
|
||||||
await issuesService
|
await issuesService
|
||||||
.addIssueToCycle(workspaceSlug as string, projectId as string, cycleId as string, data)
|
.addIssueToCycle(workspaceSlug as string, projectId as string, cycleId as string, data)
|
||||||
.then((res) => {
|
.then(() => {
|
||||||
console.log(res);
|
|
||||||
mutate(CYCLE_ISSUES(cycleId as string));
|
mutate(CYCLE_ISSUES(cycleId as string));
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch(() => {
|
||||||
console.log(e);
|
setToastAlert({
|
||||||
|
type: "error",
|
||||||
|
title: "Error!",
|
||||||
|
message: "Selected issues could not be added to the cycle. Please try again.",
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -107,7 +114,7 @@ const SingleCycle: React.FC<UserAuth> = (props) => {
|
|||||||
<ExistingIssuesListModal
|
<ExistingIssuesListModal
|
||||||
isOpen={cycleIssuesListModal}
|
isOpen={cycleIssuesListModal}
|
||||||
handleClose={() => setCycleIssuesListModal(false)}
|
handleClose={() => setCycleIssuesListModal(false)}
|
||||||
issues={issues?.filter((i) => !i.issue_cycle) ?? []}
|
issues={issues?.filter((i) => !i.cycle_id) ?? []}
|
||||||
handleOnSubmit={handleAddIssuesToCycle}
|
handleOnSubmit={handleAddIssuesToCycle}
|
||||||
/>
|
/>
|
||||||
<AppLayout
|
<AppLayout
|
||||||
|
@ -17,6 +17,8 @@ import { requiredAdmin, requiredAuth } from "lib/auth";
|
|||||||
// services
|
// services
|
||||||
import modulesService from "services/modules.service";
|
import modulesService from "services/modules.service";
|
||||||
import issuesService from "services/issues.service";
|
import issuesService from "services/issues.service";
|
||||||
|
// hooks
|
||||||
|
import useToast from "hooks/use-toast";
|
||||||
// layouts
|
// layouts
|
||||||
import AppLayout from "layouts/app-layout";
|
import AppLayout from "layouts/app-layout";
|
||||||
// contexts
|
// contexts
|
||||||
@ -47,6 +49,8 @@ const SingleModule: React.FC<UserAuth> = (props) => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId, moduleId } = router.query;
|
const { workspaceSlug, projectId, moduleId } = router.query;
|
||||||
|
|
||||||
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const { data: issues } = useSWR(
|
const { data: issues } = useSWR(
|
||||||
workspaceSlug && projectId
|
workspaceSlug && projectId
|
||||||
? PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string)
|
? PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string)
|
||||||
@ -96,7 +100,13 @@ const SingleModule: React.FC<UserAuth> = (props) => {
|
|||||||
console.log(res);
|
console.log(res);
|
||||||
mutate(MODULE_ISSUES(moduleId as string));
|
mutate(MODULE_ISSUES(moduleId as string));
|
||||||
})
|
})
|
||||||
.catch((e) => console.log(e));
|
.catch((e) =>
|
||||||
|
setToastAlert({
|
||||||
|
type: "error",
|
||||||
|
title: "Error!",
|
||||||
|
message: "Selected issues could not be added to the module. Please try again.",
|
||||||
|
})
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const openIssuesListModal = () => {
|
const openIssuesListModal = () => {
|
||||||
@ -108,7 +118,7 @@ const SingleModule: React.FC<UserAuth> = (props) => {
|
|||||||
<ExistingIssuesListModal
|
<ExistingIssuesListModal
|
||||||
isOpen={moduleIssuesListModal}
|
isOpen={moduleIssuesListModal}
|
||||||
handleClose={() => setModuleIssuesListModal(false)}
|
handleClose={() => setModuleIssuesListModal(false)}
|
||||||
issues={issues?.filter((i) => !i.issue_module) ?? []}
|
issues={issues?.filter((i) => !i.module_id) ?? []}
|
||||||
handleOnSubmit={handleAddIssuesToModule}
|
handleOnSubmit={handleAddIssuesToModule}
|
||||||
/>
|
/>
|
||||||
<AppLayout
|
<AppLayout
|
||||||
|
2
apps/app/types/issues.d.ts
vendored
2
apps/app/types/issues.d.ts
vendored
@ -81,6 +81,7 @@ export interface IIssue {
|
|||||||
created_at: Date;
|
created_at: Date;
|
||||||
created_by: string;
|
created_by: string;
|
||||||
cycle: string | null;
|
cycle: string | null;
|
||||||
|
cycle_id: string | null;
|
||||||
cycle_detail: ICycle | null;
|
cycle_detail: ICycle | null;
|
||||||
description: any;
|
description: any;
|
||||||
description_html: any;
|
description_html: any;
|
||||||
@ -100,6 +101,7 @@ export interface IIssue {
|
|||||||
label_details: any[];
|
label_details: any[];
|
||||||
links_list: IIssueLink[];
|
links_list: IIssueLink[];
|
||||||
module: string | null;
|
module: string | null;
|
||||||
|
module_id: string | null;
|
||||||
name: string;
|
name: string;
|
||||||
parent: string | null;
|
parent: string | null;
|
||||||
parent_detail: IIssueParent | null;
|
parent_detail: IIssueParent | null;
|
||||||
|
Loading…
Reference in New Issue
Block a user