mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
refactor: issue details page (#211)
This commit is contained in:
parent
60a35e6af1
commit
7278b5727f
@ -18,27 +18,17 @@ import AddAsSubIssue from "components/project/issues/issue-detail/add-as-sub-iss
|
|||||||
import IssueDetailSidebar from "components/project/issues/issue-detail/issue-detail-sidebar";
|
import IssueDetailSidebar from "components/project/issues/issue-detail/issue-detail-sidebar";
|
||||||
import AddIssueComment from "components/project/issues/issue-detail/comment/issue-comment-section";
|
import AddIssueComment from "components/project/issues/issue-detail/comment/issue-comment-section";
|
||||||
import IssueActivitySection from "components/project/issues/issue-detail/activity";
|
import IssueActivitySection from "components/project/issues/issue-detail/activity";
|
||||||
import {
|
import { IssueDescriptionForm, SubIssueList, CreateUpdateIssueModal } from "components/issues";
|
||||||
IssueDescriptionForm,
|
|
||||||
IssueDescriptionFormValues,
|
|
||||||
SubIssueList,
|
|
||||||
CreateUpdateIssueModal,
|
|
||||||
} from "components/issues";
|
|
||||||
// ui
|
// ui
|
||||||
import { Loader, HeaderButton, CustomMenu } from "components/ui";
|
import { Loader, CustomMenu } from "components/ui";
|
||||||
import { Breadcrumbs } from "components/breadcrumbs";
|
import { Breadcrumbs } from "components/breadcrumbs";
|
||||||
// icons
|
// icons
|
||||||
import { ChevronLeftIcon, ChevronRightIcon, PlusIcon } from "@heroicons/react/24/outline";
|
import { PlusIcon } from "@heroicons/react/24/outline";
|
||||||
// types
|
// types
|
||||||
import { IIssue } from "types";
|
import { IIssue } from "types";
|
||||||
import type { NextPage, NextPageContext } from "next";
|
import type { NextPage, NextPageContext } from "next";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import {
|
import { PROJECT_ISSUES_ACTIVITY, ISSUE_DETAILS, SUB_ISSUES } from "constants/fetch-keys";
|
||||||
PROJECT_ISSUES_LIST,
|
|
||||||
PROJECT_ISSUES_ACTIVITY,
|
|
||||||
ISSUE_DETAILS,
|
|
||||||
SUB_ISSUES,
|
|
||||||
} from "constants/fetch-keys";
|
|
||||||
|
|
||||||
const defaultValues = {
|
const defaultValues = {
|
||||||
name: "",
|
name: "",
|
||||||
@ -81,15 +71,6 @@ const IssueDetailsPage: NextPage = () => {
|
|||||||
: null
|
: null
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data: issues } = useSWR(
|
|
||||||
workspaceSlug && projectId
|
|
||||||
? PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string)
|
|
||||||
: null,
|
|
||||||
workspaceSlug && projectId
|
|
||||||
? () => issuesService.getIssues(workspaceSlug as string, projectId as string)
|
|
||||||
: null
|
|
||||||
);
|
|
||||||
|
|
||||||
const { data: issueActivities, mutate: mutateIssueActivities } = useSWR(
|
const { data: issueActivities, mutate: mutateIssueActivities } = useSWR(
|
||||||
workspaceSlug && projectId && issueId ? PROJECT_ISSUES_ACTIVITY(issueId as string) : null,
|
workspaceSlug && projectId && issueId ? PROJECT_ISSUES_ACTIVITY(issueId as string) : null,
|
||||||
workspaceSlug && projectId && issueId
|
workspaceSlug && projectId && issueId
|
||||||
@ -102,17 +83,22 @@ const IssueDetailsPage: NextPage = () => {
|
|||||||
: null
|
: null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { data: siblingIssues } = useSWR(
|
||||||
|
workspaceSlug && projectId && issueDetails?.parent ? SUB_ISSUES(issueDetails.parent) : null,
|
||||||
|
workspaceSlug && projectId && issueDetails?.parent
|
||||||
|
? () =>
|
||||||
|
issuesService.subIssues(
|
||||||
|
workspaceSlug as string,
|
||||||
|
projectId as string,
|
||||||
|
issueDetails.parent ?? ""
|
||||||
|
)
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
|
||||||
const { reset, control, watch } = useForm<IIssue>({
|
const { reset, control, watch } = useForm<IIssue>({
|
||||||
defaultValues,
|
defaultValues,
|
||||||
});
|
});
|
||||||
|
|
||||||
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 siblingIssues =
|
|
||||||
issueDetails &&
|
|
||||||
issues?.results.filter((i) => i.parent === issueDetails.parent && i.id !== issueId);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (issueDetails) {
|
if (issueDetails) {
|
||||||
mutateIssueActivities();
|
mutateIssueActivities();
|
||||||
@ -191,32 +177,6 @@ const IssueDetailsPage: NextPage = () => {
|
|||||||
/>
|
/>
|
||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
}
|
}
|
||||||
right={
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<HeaderButton
|
|
||||||
Icon={ChevronLeftIcon}
|
|
||||||
label="Previous"
|
|
||||||
className={!prevIssue ? "cursor-not-allowed opacity-70" : ""}
|
|
||||||
onClick={() => {
|
|
||||||
if (!prevIssue) return;
|
|
||||||
router.push(`/${workspaceSlug}/projects/${prevIssue.project}/issues/${prevIssue.id}`);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<HeaderButton
|
|
||||||
Icon={ChevronRightIcon}
|
|
||||||
disabled={!nextIssue}
|
|
||||||
label="Next"
|
|
||||||
className={!nextIssue ? "cursor-not-allowed opacity-70" : ""}
|
|
||||||
onClick={() => {
|
|
||||||
if (!nextIssue) return;
|
|
||||||
router.push(
|
|
||||||
`/${workspaceSlug}/projects/${nextIssue.project}/issues/${nextIssue?.id}`
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
position="reverse"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
{isOpen && (
|
{isOpen && (
|
||||||
<CreateUpdateIssueModal
|
<CreateUpdateIssueModal
|
||||||
@ -254,19 +214,17 @@ const IssueDetailsPage: NextPage = () => {
|
|||||||
/>
|
/>
|
||||||
<span className="flex-shrink-0 text-gray-600">
|
<span className="flex-shrink-0 text-gray-600">
|
||||||
{issueDetails.project_detail.identifier}-
|
{issueDetails.project_detail.identifier}-
|
||||||
{issues?.results.find((i) => i.id === issueDetails.parent)?.sequence_id}
|
{issueDetails.parent_detail?.sequence_id}
|
||||||
</span>
|
</span>
|
||||||
<span className="truncate font-medium">
|
<span className="truncate font-medium">
|
||||||
{issues?.results
|
{issueDetails.parent_detail?.name.substring(0, 50)}
|
||||||
.find((i) => i.id === issueDetails.parent)
|
|
||||||
?.name.substring(0, 50)}
|
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<CustomMenu ellipsis optionsPosition="left">
|
<CustomMenu ellipsis optionsPosition="left">
|
||||||
{siblingIssues && siblingIssues.length > 0 ? (
|
{siblingIssues && siblingIssues.length > 0 ? (
|
||||||
siblingIssues.map((issue) => (
|
siblingIssues.map((issue: IIssue) => (
|
||||||
<CustomMenu.MenuItem key={issue.id}>
|
<CustomMenu.MenuItem key={issue.id}>
|
||||||
<Link
|
<Link
|
||||||
href={`/${workspaceSlug}/projects/${projectId as string}/issues/${
|
href={`/${workspaceSlug}/projects/${projectId as string}/issues/${
|
||||||
|
12
apps/app/types/issues.d.ts
vendored
12
apps/app/types/issues.d.ts
vendored
@ -50,6 +50,16 @@ export interface IIssueCycle {
|
|||||||
workspace: string;
|
workspace: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IIssueParent {
|
||||||
|
description: any;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
priority: string | null;
|
||||||
|
sequence_id: number;
|
||||||
|
start_date: string | null;
|
||||||
|
target_date: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IIssue {
|
export interface IIssue {
|
||||||
assignees: any[] | null;
|
assignees: any[] | null;
|
||||||
assignee_details: IUser[];
|
assignee_details: IUser[];
|
||||||
@ -77,7 +87,7 @@ export interface IIssue {
|
|||||||
module: string | null;
|
module: string | null;
|
||||||
name: string;
|
name: string;
|
||||||
parent: string | null;
|
parent: string | null;
|
||||||
parent_detail: IProject | null;
|
parent_detail: IIssueParent | null;
|
||||||
priority: string | null;
|
priority: string | null;
|
||||||
project: string;
|
project: string;
|
||||||
project_detail: IProject;
|
project_detail: IProject;
|
||||||
|
Loading…
Reference in New Issue
Block a user