fix: mutation error on issue details

This commit is contained in:
Dakshesh Jain 2022-12-20 13:16:40 +05:30
parent 010d98c40d
commit a0e7475ce8
3 changed files with 86 additions and 88 deletions

View File

@ -99,13 +99,15 @@ const IssueDetailSidebar: React.FC<Props> = ({
const handleCycleChange = (cycleId: string) => { const handleCycleChange = (cycleId: string) => {
if (activeWorkspace && activeProject && issueDetail) if (activeWorkspace && activeProject && issueDetail)
issuesServices.addIssueToCycle(activeWorkspace.slug, activeProject.id, cycleId, { issuesServices
issue: issueDetail.id, .addIssueToCycle(activeWorkspace.slug, activeProject.id, cycleId, {
}); issue: issueDetail.id,
})
.then(() => {
submitChanges({});
});
}; };
console.log(issueDetail?.labels, issueDetail?.labels_list);
return ( return (
<> <>
<div className="h-full w-full divide-y-2 divide-gray-100"> <div className="h-full w-full divide-y-2 divide-gray-100">
@ -141,7 +143,7 @@ const IssueDetailSidebar: React.FC<Props> = ({
type="button" type="button"
className="p-2 hover:bg-gray-100 border rounded-md shadow-sm focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 duration-300" className="p-2 hover:bg-gray-100 border rounded-md shadow-sm focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 duration-300"
onClick={() => onClick={() =>
copyTextToClipboard(`${issueDetail?.id}`) copyTextToClipboard(issueDetail?.id ?? "")
.then(() => { .then(() => {
setToastAlert({ setToastAlert({
type: "success", type: "success",
@ -249,7 +251,7 @@ const IssueDetailSidebar: React.FC<Props> = ({
</div> </div>
<div className="basis-1/2"> <div className="basis-1/2">
<div className="flex gap-1 flex-wrap"> <div className="flex gap-1 flex-wrap">
{issueDetail?.labels.map((label) => { {watchIssue("labels_list")?.map((label) => {
const singleLabel = issueLabels?.find((l) => l.id === label); const singleLabel = issueLabels?.find((l) => l.id === label);
if (!singleLabel) return null; if (!singleLabel) return null;
@ -259,11 +261,10 @@ const IssueDetailSidebar: React.FC<Props> = ({
key={singleLabel.id} key={singleLabel.id}
className="group flex items-center gap-1 border rounded-2xl text-xs px-1 py-0.5 hover:bg-red-50 hover:border-red-500 cursor-pointer" className="group flex items-center gap-1 border rounded-2xl text-xs px-1 py-0.5 hover:bg-red-50 hover:border-red-500 cursor-pointer"
onClick={() => { onClick={() => {
const updatedLabels = issueDetail?.labels.filter((l) => l !== label); const updatedLabels = watchIssue("labels_list")?.filter((l) => l !== label);
// submitChanges({ submitChanges({
// labels_list: updatedLabels, labels_list: updatedLabels,
// }); });
console.log(updatedLabels);
}} }}
> >
<span <span

View File

@ -551,6 +551,10 @@ const ListView: React.FC<Props> = ({
[selectedGroup]: singleGroup, [selectedGroup]: singleGroup,
actionType: "createIssue", actionType: "createIssue",
}); });
} else {
setPreloadedData({
actionType: "createIssue",
});
} }
}} }}
> >

View File

@ -1,16 +1,25 @@
import React, { useCallback, useEffect, useState } from "react";
// next // next
import Link from "next/link"; import Link from "next/link";
import type { NextPage } from "next"; import type { NextPage } from "next";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
// react
import React, { useCallback, useEffect, useState } from "react";
// swr // swr
import useSWR, { mutate } from "swr"; import useSWR, { mutate } from "swr";
// react hook form // react hook form
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
// headless ui
import { Disclosure, Menu, Tab, Transition } from "@headlessui/react";
// fetch keys
import {
PROJECT_ISSUES_ACTIVITY,
PROJECT_ISSUES_COMMENTS,
PROJECT_ISSUES_LIST,
} from "constants/fetch-keys";
// services // services
import issuesServices from "lib/services/issues.service"; import issuesServices from "lib/services/issues.service";
// common
import { debounce } from "constants/common";
// hooks // hooks
import useUser from "lib/hooks/useUser"; import useUser from "lib/hooks/useUser";
// hoc // hoc
@ -24,12 +33,8 @@ import AddAsSubIssue from "components/project/issues/issue-detail/add-as-sub-iss
import ConfirmIssueDeletion from "components/project/issues/confirm-issue-deletion"; import ConfirmIssueDeletion from "components/project/issues/confirm-issue-deletion";
import IssueDetailSidebar from "components/project/issues/issue-detail/issue-detail-sidebar"; import IssueDetailSidebar from "components/project/issues/issue-detail/issue-detail-sidebar";
import IssueActivitySection from "components/project/issues/issue-detail/activity"; import IssueActivitySection from "components/project/issues/issue-detail/activity";
// headless ui
import { Disclosure, Menu, Tab, Transition } from "@headlessui/react";
// ui // ui
import { Spinner, TextArea } from "ui"; import { Spinner, TextArea, HeaderButton, Breadcrumbs, BreadcrumbItem } from "ui";
import HeaderButton from "ui/HeaderButton";
import { BreadcrumbItem, Breadcrumbs } from "ui/Breadcrumbs";
// icons // icons
import { import {
ChevronLeftIcon, ChevronLeftIcon,
@ -39,14 +44,6 @@ import {
} from "@heroicons/react/24/outline"; } from "@heroicons/react/24/outline";
// types // types
import { IIssue, IIssueComment, IssueResponse } from "types"; import { IIssue, IIssueComment, IssueResponse } from "types";
// fetch keys
import {
PROJECT_ISSUES_ACTIVITY,
PROJECT_ISSUES_COMMENTS,
PROJECT_ISSUES_LIST,
} from "constants/fetch-keys";
// common
import { debounce } from "constants/common";
const RichTextEditor = dynamic(() => import("components/lexical/editor"), { const RichTextEditor = dynamic(() => import("components/lexical/editor"), {
ssr: false, ssr: false,
@ -148,7 +145,15 @@ const IssueDetail: NextPage = () => {
issuesServices issuesServices
.patchIssue(activeWorkspace.slug, projectId as string, issueId as string, payload) .patchIssue(activeWorkspace.slug, projectId as string, issueId as string, payload)
.then((response) => { .then((response) => {
console.log(response); mutateIssues((prevData) => ({
...(prevData as IssueResponse),
results: (prevData?.results ?? []).map((issue) => {
if (issue.id === issueId) {
return { ...issue, ...response };
}
return issue;
}),
}));
}) })
.catch((error) => { .catch((error) => {
console.log(error); console.log(error);
@ -170,25 +175,23 @@ const IssueDetail: NextPage = () => {
issueDetail.blocked_issues?.map((issue) => issue.blocked_issue_detail?.id), issueDetail.blocked_issues?.map((issue) => issue.blocked_issue_detail?.id),
assignees_list: assignees_list:
issueDetail.assignees_list ?? issueDetail.assignee_details?.map((user) => user.id), issueDetail.assignees_list ?? issueDetail.assignee_details?.map((user) => user.id),
labels_list: issueDetail.labels_list ?? issueDetail.labels?.map((label) => label), labels_list: issueDetail.labels_list ?? issueDetail.labels,
labels: issueDetail.labels_list ?? issueDetail.labels?.map((label) => label), labels: issueDetail.labels_list ?? issueDetail.labels,
}); });
}, [issueDetail, reset]); }, [issueDetail, reset]);
useEffect(() => { useEffect(() => {
const issueIndex = issues?.results.findIndex((issue) => issue.id === issueId); const issueDetail = issues?.results.find((issue) => issue.id === issueId);
if (issueIndex === undefined) return;
const issueDetail = issues?.results[issueIndex];
setIssueDetail(issueDetail); setIssueDetail(issueDetail);
}, [issues, issueId]); }, [issueId, issues]);
const prevIssue = issues?.results[issues?.results.findIndex((issue) => issue.id === issueId) - 1]; const prevIssue = issues?.results[issues?.results.findIndex((issue) => issue.id === issueId) - 1];
const nextIssue = issues?.results[issues?.results.findIndex((issue) => issue.id === issueId) + 1]; const nextIssue = issues?.results[issues?.results.findIndex((issue) => issue.id === issueId) + 1];
const subIssues = (issues && issues.results.filter((i) => i.parent === issueDetail?.id)) ?? []; const subIssues = (issues && issues.results.filter((i) => i.parent === issueId)) ?? [];
const siblingIssues = const siblingIssues =
issueDetail && issueDetail &&
issues?.results.filter((i) => i.parent === issueDetail.parent && i.id !== issueDetail.id); issues?.results.filter((i) => i.parent === issueDetail.parent && i.id !== issueId);
const handleSubIssueRemove = (issueId: string) => { const handleSubIssueRemove = (issueId: string) => {
if (activeWorkspace && activeProject) { if (activeWorkspace && activeProject) {
@ -212,8 +215,6 @@ const IssueDetail: NextPage = () => {
} }
}; };
console.log(issueDetail);
return ( return (
<AppLayout <AppLayout
noPadding={true} noPadding={true}
@ -236,7 +237,7 @@ const IssueDetail: NextPage = () => {
<HeaderButton <HeaderButton
Icon={ChevronLeftIcon} Icon={ChevronLeftIcon}
label="Previous" label="Previous"
className={`${!prevIssue ? "cursor-not-allowed opacity-70" : ""}`} className={!prevIssue ? "cursor-not-allowed opacity-70" : ""}
onClick={() => { onClick={() => {
if (!prevIssue) return; if (!prevIssue) return;
router.push(`/projects/${prevIssue.project}/issues/${prevIssue.id}`); router.push(`/projects/${prevIssue.project}/issues/${prevIssue.id}`);
@ -246,7 +247,7 @@ const IssueDetail: NextPage = () => {
Icon={ChevronRightIcon} Icon={ChevronRightIcon}
disabled={!nextIssue} disabled={!nextIssue}
label="Next" label="Next"
className={`${!nextIssue ? "cursor-not-allowed opacity-70" : ""}`} className={!nextIssue ? "cursor-not-allowed opacity-70" : ""}
onClick={() => { onClick={() => {
if (!nextIssue) return; if (!nextIssue) return;
router.push(`/projects/${nextIssue.project}/issues/${nextIssue?.id}`); router.push(`/projects/${nextIssue.project}/issues/${nextIssue?.id}`);
@ -284,7 +285,7 @@ const IssueDetail: NextPage = () => {
<Link href={`/projects/${activeProject.id}/issues/${issueDetail.parent}`}> <Link href={`/projects/${activeProject.id}/issues/${issueDetail.parent}`}>
<a className="flex items-center gap-2"> <a className="flex items-center gap-2">
<span <span
className={`h-1.5 w-1.5 block rounded-full`} className="h-1.5 w-1.5 block rounded-full"
style={{ style={{
backgroundColor: issueDetail.state_detail.color, backgroundColor: issueDetail.state_detail.color,
}} }}
@ -432,15 +433,13 @@ const IssueDetail: NextPage = () => {
<Menu.Items className="origin-top-right absolute right-0 mt-2 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none z-50"> <Menu.Items className="origin-top-right absolute right-0 mt-2 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none z-50">
<div className="p-1"> <div className="p-1">
<Menu.Item as="div"> <Menu.Item as="div">
{(active) => ( <button
<button type="button"
type="button" className="flex items-center gap-2 p-2 text-left text-gray-900 hover:bg-theme hover:text-white rounded-md text-xs whitespace-nowrap"
className="flex items-center gap-2 p-2 text-left text-gray-900 hover:bg-theme hover:text-white rounded-md text-xs whitespace-nowrap" onClick={() => setIsAddAsSubIssueOpen(true)}
onClick={() => setIsAddAsSubIssueOpen(true)} >
> Add an existing issue
Add an existing issue </button>
</button>
)}
</Menu.Item> </Menu.Item>
</div> </div>
</Menu.Items> </Menu.Items>
@ -497,14 +496,12 @@ const IssueDetail: NextPage = () => {
<Menu.Items className="origin-top-right absolute right-0 mt-2 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none z-50"> <Menu.Items className="origin-top-right absolute right-0 mt-2 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none z-50">
<div className="p-1"> <div className="p-1">
<Menu.Item as="div"> <Menu.Item as="div">
{(active) => ( <button
<button className="flex items-center gap-2 p-2 text-left text-gray-900 hover:bg-theme hover:text-white rounded-md text-xs whitespace-nowrap"
className="flex items-center gap-2 p-2 text-left text-gray-900 hover:bg-theme hover:text-white rounded-md text-xs whitespace-nowrap" onClick={() => handleSubIssueRemove(subIssue.id)}
onClick={() => handleSubIssueRemove(subIssue.id)} >
> Remove as sub-issue
Remove as sub-issue </button>
</button>
)}
</Menu.Item> </Menu.Item>
</div> </div>
</Menu.Items> </Menu.Items>
@ -537,38 +534,34 @@ const IssueDetail: NextPage = () => {
<Menu.Items className="absolute origin-top-right left-0 mt-2 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none z-10"> <Menu.Items className="absolute origin-top-right left-0 mt-2 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none z-10">
<div className="p-1"> <div className="p-1">
<Menu.Item as="div"> <Menu.Item as="div">
{(active) => ( <button
<button type="button"
type="button" className="text-left p-2 text-gray-900 hover:bg-theme hover:text-white rounded-md text-xs whitespace-nowrap w-full"
className="text-left p-2 text-gray-900 hover:bg-theme hover:text-white rounded-md text-xs whitespace-nowrap w-full" onClick={() => {
onClick={() => { setIsOpen(true);
setIsOpen(true); setPreloadedData({
setPreloadedData({ parent: issueDetail.id,
parent: issueDetail.id, actionType: "createIssue",
actionType: "createIssue", });
}); }}
}} >
> Create new
Create new </button>
</button>
)}
</Menu.Item> </Menu.Item>
<Menu.Item as="div"> <Menu.Item as="div">
{(active) => ( <button
<button type="button"
type="button" className="p-2 text-left text-gray-900 hover:bg-theme hover:text-white rounded-md text-xs whitespace-nowrap"
className="p-2 text-left text-gray-900 hover:bg-theme hover:text-white rounded-md text-xs whitespace-nowrap" onClick={() => {
onClick={() => { setIsAddAsSubIssueOpen(true);
setIsAddAsSubIssueOpen(true); setPreloadedData({
setPreloadedData({ parent: issueDetail.id,
parent: issueDetail.id, actionType: "createIssue",
actionType: "createIssue", });
}); }}
}} >
> Add an existing issue
Add an existing issue </button>
</button>
)}
</Menu.Item> </Menu.Item>
</div> </div>
</Menu.Items> </Menu.Items>