From 1ad99873a9458c672c807d4c7716623515a30461 Mon Sep 17 00:00:00 2001 From: guru_sainath Date: Tue, 26 Sep 2023 13:09:08 +0530 Subject: [PATCH] feat: Add peek overview in sub issues and updated UI for empty states. (#2263) --- web/components/issues/sub-issues/issue.tsx | 239 ++++++++++-------- .../issues/sub-issues/issues-list.tsx | 3 + web/components/issues/sub-issues/root.tsx | 57 ++++- 3 files changed, 184 insertions(+), 115 deletions(-) diff --git a/web/components/issues/sub-issues/issue.tsx b/web/components/issues/sub-issues/issue.tsx index 2adb7c6f9..d9c6fd303 100644 --- a/web/components/issues/sub-issues/issue.tsx +++ b/web/components/issues/sub-issues/issue.tsx @@ -1,6 +1,7 @@ import React from "react"; // next imports import Link from "next/link"; +import { useRouter } from "next/router"; // lucide icons import { ChevronDown, @@ -37,6 +38,7 @@ export interface ISubIssues { issueId: string, issue?: IIssue | null ) => void; + setPeekParentId: (id: string) => void; } export const SubIssues: React.FC = ({ @@ -52,38 +54,54 @@ export const SubIssues: React.FC = ({ handleIssuesLoader, copyText, handleIssueCrudOperation, -}) => ( -
- {issue && ( -
-
- {issue?.sub_issues_count > 0 && ( - <> - {issuesLoader.sub_issues.includes(issue?.id) ? ( -
- -
- ) : ( -
handleIssuesLoader({ key: "visibility", issueId: issue?.id })} - > - {issuesLoader && issuesLoader.visibility.includes(issue?.id) ? ( - - ) : ( - - )} -
- )} - - )} -
+ setPeekParentId, +}) => { + const router = useRouter(); - - + const openPeekOverview = (issue_id: string) => { + const { query } = router; + + setPeekParentId(parentIssue?.id); + router.push({ + pathname: router.pathname, + query: { ...query, peekIssue: issue_id }, + }); + }; + + return ( +
+ {issue && ( +
+
+ {issue?.sub_issues_count > 0 && ( + <> + {issuesLoader.sub_issues.includes(issue?.id) ? ( +
+ +
+ ) : ( +
handleIssuesLoader({ key: "visibility", issueId: issue?.id })} + > + {issuesLoader && issuesLoader.visibility.includes(issue?.id) ? ( + + ) : ( + + )} +
+ )} + + )} +
+ +
openPeekOverview(issue?.id)} + > -
- -
+
+ +
+ +
+ + {editable && ( + handleIssueCrudOperation("edit", parentIssue?.id, issue)} + > +
+ + Edit issue +
+
+ )} + + {editable && ( + handleIssueCrudOperation("delete", parentIssue?.id, issue)} + > +
+ + Delete issue +
+
+ )} -
- - {editable && ( handleIssueCrudOperation("edit", parentIssue?.id, issue)} + onClick={() => + copyText(`${workspaceSlug}/projects/${issue.project}/issues/${issue.id}`) + } >
- - Edit issue + + Copy issue link
- )} +
+
- {editable && ( - handleIssueCrudOperation("delete", parentIssue?.id, issue)} - > -
- - Delete issue + {editable && ( + <> + {issuesLoader.delete.includes(issue?.id) ? ( +
+
- - )} - - - copyText(`${workspaceSlug}/projects/${issue.project}/issues/${issue.id}`) - } - > -
- - Copy issue link -
-
- + ) : ( +
{ + handleIssuesLoader({ key: "delete", issueId: issue?.id }); + removeIssueFromSubIssues(parentIssue?.id, issue); + }} + > + +
+ )} + + )}
+ )} - {editable && ( - <> - {issuesLoader.delete.includes(issue?.id) ? ( -
- -
- ) : ( -
{ - handleIssuesLoader({ key: "delete", issueId: issue?.id }); - removeIssueFromSubIssues(parentIssue?.id, issue); - }} - > - -
- )} - - )} -
- )} - - {issuesLoader.visibility.includes(issue?.id) && issue?.sub_issues_count > 0 && ( - - )} -
-); + {issuesLoader.visibility.includes(issue?.id) && issue?.sub_issues_count > 0 && ( + + )} +
+ ); +}; diff --git a/web/components/issues/sub-issues/issues-list.tsx b/web/components/issues/sub-issues/issues-list.tsx index 9fc77992e..a713d6fb8 100644 --- a/web/components/issues/sub-issues/issues-list.tsx +++ b/web/components/issues/sub-issues/issues-list.tsx @@ -27,6 +27,7 @@ export interface ISubIssuesRootList { issueId: string, issue?: IIssue | null ) => void; + setPeekParentId: (id: string) => void; } export const SubIssuesRootList: React.FC = ({ @@ -41,6 +42,7 @@ export const SubIssuesRootList: React.FC = ({ handleIssuesLoader, copyText, handleIssueCrudOperation, + setPeekParentId, }) => { const { data: issues, isLoading } = useSWR( workspaceSlug && projectId && parentIssue && parentIssue?.id @@ -81,6 +83,7 @@ export const SubIssuesRootList: React.FC = ({ handleIssuesLoader={handleIssuesLoader} copyText={copyText} handleIssueCrudOperation={handleIssueCrudOperation} + setPeekParentId={setPeekParentId} /> ))} diff --git a/web/components/issues/sub-issues/root.tsx b/web/components/issues/sub-issues/root.tsx index 305a9150b..352546eab 100644 --- a/web/components/issues/sub-issues/root.tsx +++ b/web/components/issues/sub-issues/root.tsx @@ -10,6 +10,7 @@ import { ExistingIssuesListModal } from "components/core"; import { CreateUpdateIssueModal, DeleteIssueModal } from "components/issues"; import { SubIssuesRootList } from "./issues-list"; import { ProgressBar } from "./progressbar"; +import { IssuePeekOverview } from "components/issues/peek-overview"; // ui import { CustomMenu } from "components/ui"; // hooks @@ -41,7 +42,11 @@ export interface ISubIssuesRootLoadersHandler { export const SubIssuesRoot: React.FC = ({ parentIssue, user }) => { const router = useRouter(); - const { workspaceSlug, projectId } = router.query as { workspaceSlug: string; projectId: string }; + const { workspaceSlug, projectId, peekIssue } = router.query as { + workspaceSlug: string; + projectId: string; + peekIssue: string; + }; const { memberRole } = useProjectMyMembership(); const { setToastAlert } = useToast(); @@ -55,6 +60,8 @@ export const SubIssuesRoot: React.FC = ({ parentIssue, user }) = : null ); + const [peekParentId, setPeekParentId] = React.useState(""); + const [issuesLoader, setIssuesLoader] = React.useState({ visibility: [parentIssue?.id], delete: [], @@ -230,15 +237,48 @@ export const SubIssuesRoot: React.FC = ({ parentIssue, user }) = handleIssuesLoader={handleIssuesLoader} copyText={copyText} handleIssueCrudOperation={handleIssueCrudOperation} + setPeekParentId={setPeekParentId} />
)} + +
+ + + Add sub-issue + + } + buttonClassName="whitespace-nowrap" + position="left" + noBorder + noChevron + > + { + mutateSubIssues(parentIssue?.id); + handleIssueCrudOperation("create", parentIssue?.id); + }} + > + Create new + + { + mutateSubIssues(parentIssue?.id); + handleIssueCrudOperation("existing", parentIssue?.id); + }} + > + Add an existing issue + + +
) : ( isEditable && ( -
-
No sub issues are available
- <> +
+
No Sub-Issues yet
+
@@ -268,7 +308,7 @@ export const SubIssuesRoot: React.FC = ({ parentIssue, user }) = Add an existing issue - +
) )} @@ -323,6 +363,13 @@ export const SubIssuesRoot: React.FC = ({ parentIssue, user }) = )} )} + + peekParentId && peekIssue && mutateSubIssues(peekParentId)} + projectId={projectId ?? ""} + workspaceSlug={workspaceSlug ?? ""} + readOnly={!isEditable} + />
); };