Skip to content

Commit eafa393

Browse files
[WEB-5726] fix: showing an empty state on deleted work item link #8381
1 parent 9747bff commit eafa393

File tree

2 files changed

+80
-47
lines changed

2 files changed

+80
-47
lines changed

apps/web/app/(all)/[workspaceSlug]/(projects)/browse/[workItem]/page.tsx

Lines changed: 57 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { useTheme } from "next-themes";
44
import useSWR from "swr";
55
// plane imports
66
import { useTranslation } from "@plane/i18n";
7+
import type { TIssue } from "@plane/types";
78
import { EIssueServiceType } from "@plane/types";
89
import { Loader } from "@plane/ui";
910
// assets
@@ -12,7 +13,6 @@ import emptyIssueLight from "@/app/assets/empty-state/search/issues-light.webp?u
1213
// components
1314
import { EmptyState } from "@/components/common/empty-state";
1415
import { PageHead } from "@/components/core/page-title";
15-
import { IssueDetailRoot } from "@/components/issues/issue-detail";
1616
// hooks
1717
import { useAppTheme } from "@/hooks/store/use-app-theme";
1818
import { useIssueDetail } from "@/hooks/store/use-issue-detail";
@@ -21,9 +21,11 @@ import { useAppRouter } from "@/hooks/use-app-router";
2121
// plane web imports
2222
import { useWorkItemProperties } from "@/plane-web/hooks/use-issue-properties";
2323
import { ProjectAuthWrapper } from "@/plane-web/layouts/project-wrapper";
24+
import { WorkItemDetailRoot } from "@/plane-web/components/browse/workItem-detail";
25+
2426
import type { Route } from "./+types/page";
2527

26-
function IssueDetailsPage({ params }: Route.ComponentProps) {
28+
export const IssueDetailsPage = observer(function IssueDetailsPage({ params }: Route.ComponentProps) {
2729
// router
2830
const router = useAppRouter();
2931
const { workspaceSlug, workItem } = params;
@@ -35,18 +37,21 @@ function IssueDetailsPage({ params }: Route.ComponentProps) {
3537
fetchIssueWithIdentifier,
3638
issue: { getIssueById },
3739
} = useIssueDetail();
38-
const { getProjectById } = useProject();
40+
const { getProjectById, getProjectByIdentifier } = useProject();
3941
const { toggleIssueDetailSidebar, issueDetailSidebarCollapsed } = useAppTheme();
4042

4143
const [projectIdentifier, sequence_id] = workItem.split("-");
4244

4345
// fetching issue details
44-
const { data, isLoading, error } = useSWR(`ISSUE_DETAIL_${workspaceSlug}_${projectIdentifier}_${sequence_id}`, () =>
45-
fetchIssueWithIdentifier(workspaceSlug.toString(), projectIdentifier, sequence_id)
46+
const { data, isLoading, error } = useSWR<TIssue, Error>(
47+
`ISSUE_DETAIL_${workspaceSlug}_${projectIdentifier}_${sequence_id}`,
48+
() => fetchIssueWithIdentifier(workspaceSlug.toString(), projectIdentifier, sequence_id)
4649
);
47-
const issueId = data?.id;
48-
const projectId = data?.project_id;
50+
4951
// derived values
52+
const projectDetails = getProjectByIdentifier(projectIdentifier);
53+
const issueId = data?.id;
54+
const projectId = data?.project_id ?? projectDetails?.id ?? "";
5055
const issue = getIssueById(issueId?.toString() || "") || undefined;
5156
const project = (issue?.project_id && getProjectById(issue?.project_id)) || undefined;
5257
const issueLoader = !issue || isLoading;
@@ -77,51 +82,56 @@ function IssueDetailsPage({ params }: Route.ComponentProps) {
7782
if (data?.is_intake) {
7883
router.push(`/${workspaceSlug}/projects/${data.project_id}/intake/?currentTab=open&inboxIssueId=${data?.id}`);
7984
}
80-
}, [workspaceSlug, data]);
85+
}, [workspaceSlug, data, router]);
86+
87+
if (error && !isLoading) {
88+
return (
89+
<EmptyState
90+
image={resolvedTheme === "dark" ? emptyIssueDark : emptyIssueLight}
91+
title={t("issue.empty_state.issue_detail.title")}
92+
description={t("issue.empty_state.issue_detail.description")}
93+
primaryButton={{
94+
text: t("issue.empty_state.issue_detail.primary_button.text"),
95+
onClick: () => router.push(`/${workspaceSlug}/workspace-views/all-issues/`),
96+
}}
97+
/>
98+
);
99+
}
100+
101+
if (issueLoader) {
102+
return (
103+
<Loader className="flex h-full gap-5 p-5">
104+
<div className="basis-2/3 space-y-2">
105+
<Loader.Item height="30px" width="40%" />
106+
<Loader.Item height="15px" width="60%" />
107+
<Loader.Item height="15px" width="60%" />
108+
<Loader.Item height="15px" width="40%" />
109+
</div>
110+
<div className="basis-1/3 space-y-3">
111+
<Loader.Item height="30px" />
112+
<Loader.Item height="30px" />
113+
<Loader.Item height="30px" />
114+
<Loader.Item height="30px" />
115+
</div>
116+
</Loader>
117+
);
118+
}
81119

82120
return (
83121
<>
84122
<PageHead title={pageTitle} />
85-
{error && !issueLoader ? (
86-
<EmptyState
87-
image={resolvedTheme === "dark" ? emptyIssueDark : emptyIssueLight}
88-
title={t("issue.empty_state.issue_detail.title")}
89-
description={t("issue.empty_state.issue_detail.description")}
90-
primaryButton={{
91-
text: t("issue.empty_state.issue_detail.primary_button.text"),
92-
onClick: () => router.push(`/${workspaceSlug}/workspace-views/all-issues/`),
93-
}}
94-
/>
95-
) : issueLoader ? (
96-
<Loader className="flex h-full gap-5 p-5">
97-
<div className="basis-2/3 space-y-2">
98-
<Loader.Item height="30px" width="40%" />
99-
<Loader.Item height="15px" width="60%" />
100-
<Loader.Item height="15px" width="60%" />
101-
<Loader.Item height="15px" width="40%" />
102-
</div>
103-
<div className="basis-1/3 space-y-3">
104-
<Loader.Item height="30px" />
105-
<Loader.Item height="30px" />
106-
<Loader.Item height="30px" />
107-
<Loader.Item height="30px" />
108-
</div>
109-
</Loader>
110-
) : (
111-
projectId &&
112-
issueId && (
113-
<ProjectAuthWrapper workspaceSlug={workspaceSlug} projectId={projectId}>
114-
<IssueDetailRoot
115-
workspaceSlug={workspaceSlug}
116-
projectId={projectId}
117-
issueId={issueId}
118-
is_archived={!!issue?.archived_at}
119-
/>
120-
</ProjectAuthWrapper>
121-
)
123+
{workspaceSlug && projectId && issueId && (
124+
<ProjectAuthWrapper workspaceSlug={workspaceSlug} projectId={projectId}>
125+
<WorkItemDetailRoot
126+
workspaceSlug={workspaceSlug.toString()}
127+
projectId={projectId.toString()}
128+
issueId={issueId.toString()}
129+
issue={issue}
130+
/>
131+
</ProjectAuthWrapper>
122132
)}
123133
</>
124134
);
125-
}
135+
});
126136

127-
export default observer(IssueDetailsPage);
137+
export default IssueDetailsPage;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { observer } from "mobx-react";
2+
import type { TIssue } from "@plane/types";
3+
import { IssueDetailRoot } from "@/components/issues/issue-detail/root";
4+
5+
export type TWorkItemDetailRoot = {
6+
workspaceSlug: string;
7+
projectId: string;
8+
issueId: string;
9+
issue: TIssue | undefined;
10+
};
11+
12+
export const WorkItemDetailRoot = observer(function WorkItemDetailRoot(props: TWorkItemDetailRoot) {
13+
const { workspaceSlug, projectId, issueId, issue } = props;
14+
15+
return (
16+
<IssueDetailRoot
17+
workspaceSlug={workspaceSlug.toString()}
18+
projectId={projectId.toString()}
19+
issueId={issueId.toString()}
20+
is_archived={!!issue?.archived_at}
21+
/>
22+
);
23+
});

0 commit comments

Comments
 (0)