fix: resolve z-index and peek overview component bug (#2624)

* fix: resolved z-index issue on peek overview component

* fix: fix issue with peekover view in spreadsheet view

---------

Co-authored-by: gurusainath <gurusainath007@gmail.com>
This commit is contained in:
Anmol Singh Bhatia 2023-11-03 17:20:14 +05:30 committed by GitHub
parent 1352c200dd
commit 4c1aee0cfc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 140 additions and 103 deletions

View File

@ -5,7 +5,6 @@ import { MoreHorizontal, Pencil, Trash2, ChevronRight, Link } from "lucide-react
// hooks // hooks
import useToast from "hooks/use-toast"; import useToast from "hooks/use-toast";
// components // components
import { IssuePeekOverview } from "components/issues/issue-peek-overview";
import { Tooltip } from "@plane/ui"; import { Tooltip } from "@plane/ui";
// helpers // helpers
import { copyUrlToClipboard } from "helpers/string.helper"; import { copyUrlToClipboard } from "helpers/string.helper";
@ -16,10 +15,16 @@ type Props = {
issue: IIssue; issue: IIssue;
expanded: boolean; expanded: boolean;
handleToggleExpand: (issueId: string) => void; handleToggleExpand: (issueId: string) => void;
handleUpdateIssue: (issue: IIssue, data: Partial<IIssue>) => void;
properties: IIssueDisplayProperties; properties: IIssueDisplayProperties;
handleEditIssue: (issue: IIssue) => void; handleEditIssue: (issue: IIssue) => void;
handleDeleteIssue: (issue: IIssue) => void; handleDeleteIssue: (issue: IIssue) => void;
setIssuePeekOverView: React.Dispatch<
React.SetStateAction<{
workspaceSlug: string;
projectId: string;
issueId: string;
} | null>
>;
disableUserActions: boolean; disableUserActions: boolean;
nestingLevel: number; nestingLevel: number;
}; };
@ -28,7 +33,7 @@ export const IssueColumn: React.FC<Props> = ({
issue, issue,
expanded, expanded,
handleToggleExpand, handleToggleExpand,
handleUpdateIssue, setIssuePeekOverView,
properties, properties,
handleEditIssue, handleEditIssue,
handleDeleteIssue, handleDeleteIssue,
@ -53,105 +58,116 @@ export const IssueColumn: React.FC<Props> = ({
}); });
}; };
const handleIssuePeekOverview = (issue: IIssue) => {
const { query } = router;
setIssuePeekOverView({
workspaceSlug: issue?.workspace_detail?.slug,
projectId: issue?.project_detail?.id,
issueId: issue?.id,
});
router.push({
pathname: router.pathname,
query: { ...query, peekIssueId: issue?.id },
});
};
const paddingLeft = `${nestingLevel * 54}px`; const paddingLeft = `${nestingLevel * 54}px`;
return ( return (
<div className="group flex items-center w-[28rem] text-sm h-11 sticky top-0 bg-custom-background-100 truncate border-b border-custom-border-100"> <>
{properties.key && ( <div className="group flex items-center w-[28rem] text-sm h-11 sticky top-0 bg-custom-background-100 truncate border-b border-custom-border-100">
<div {properties.key && (
className="flex gap-1.5 px-4 pr-0 py-2.5 items-center min-w-[96px]" <div
style={issue.parent && nestingLevel !== 0 ? { paddingLeft } : {}} className="flex gap-1.5 px-4 pr-0 py-2.5 items-center min-w-[96px]"
> style={issue.parent && nestingLevel !== 0 ? { paddingLeft } : {}}
<div className="relative flex items-center cursor-pointer text-xs text-center hover:text-custom-text-100"> >
<span className="flex items-center justify-center font-medium opacity-100 group-hover:opacity-0 "> <div className="relative flex items-center cursor-pointer text-xs text-center hover:text-custom-text-100">
{issue.project_detail?.identifier}-{issue.sequence_id} <span className="flex items-center justify-center font-medium opacity-100 group-hover:opacity-0 ">
</span> {issue.project_detail?.identifier}-{issue.sequence_id}
</span>
{!disableUserActions && ( {!disableUserActions && (
<div className="absolute top-0 left-2.5 opacity-0 group-hover:opacity-100"> <div className="absolute top-0 left-2.5 opacity-0 group-hover:opacity-100">
<Popover2 <Popover2
isOpen={isOpen} isOpen={isOpen}
canEscapeKeyClose canEscapeKeyClose
onInteraction={(nextOpenState) => setIsOpen(nextOpenState)} onInteraction={(nextOpenState) => setIsOpen(nextOpenState)}
content={ content={
<div className="flex flex-col whitespace-nowrap rounded-md border border-custom-border-100 p-1 text-xs shadow-lg focus:outline-none min-w-full bg-custom-background-100 space-y-0.5"> <div className="flex flex-col whitespace-nowrap rounded-md border border-custom-border-100 p-1 text-xs shadow-lg focus:outline-none min-w-full bg-custom-background-100 space-y-0.5">
<button <button
type="button" type="button"
className="hover:text-custom-text-200 w-full select-none gap-2 rounded p-1 text-left text-custom-text-200 hover:bg-custom-background-80" className="hover:text-custom-text-200 w-full select-none gap-2 rounded p-1 text-left text-custom-text-200 hover:bg-custom-background-80"
onClick={() => { onClick={() => {
handleCopyText(); handleCopyText();
setIsOpen(false); setIsOpen(false);
}} }}
> >
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Link className="h-3 w-3" /> <Link className="h-3 w-3" />
<span>Copy link</span> <span>Copy link</span>
</div> </div>
</button> </button>
<button <button
type="button" type="button"
className="hover:text-custom-text-200 w-full select-none gap-2 rounded p-1 text-left text-custom-text-200 hover:bg-custom-background-80" className="hover:text-custom-text-200 w-full select-none gap-2 rounded p-1 text-left text-custom-text-200 hover:bg-custom-background-80"
onClick={() => { onClick={() => {
handleEditIssue(issue); handleEditIssue(issue);
setIsOpen(false); setIsOpen(false);
}} }}
> >
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Pencil className="h-3 w-3" /> <Pencil className="h-3 w-3" />
<span>Edit issue</span> <span>Edit issue</span>
</div> </div>
</button> </button>
<button <button
type="button" type="button"
className="w-full select-none gap-2 rounded p-1 text-left text-red-500 hover:bg-custom-background-80" className="w-full select-none gap-2 rounded p-1 text-left text-red-500 hover:bg-custom-background-80"
onClick={() => { onClick={() => {
handleDeleteIssue(issue); handleDeleteIssue(issue);
setIsOpen(false); setIsOpen(false);
}} }}
> >
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Trash2 className="h-3 w-3" /> <Trash2 className="h-3 w-3" />
<span>Delete issue</span> <span>Delete issue</span>
</div> </div>
</button> </button>
</div> </div>
} }
placement="bottom-start" placement="bottom-start"
>
<MoreHorizontal className="h-5 w-5 text-custom-text-200" />
</Popover2>
</div>
)}
</div>
{issue.sub_issues_count > 0 && (
<div className="h-6 w-6 flex justify-center items-center">
<button
className="h-5 w-5 hover:bg-custom-background-90 hover:text-custom-text-100 rounded-sm cursor-pointer"
onClick={() => handleToggleExpand(issue.id)}
> >
<MoreHorizontal className="h-5 w-5 text-custom-text-200" /> <ChevronRight className={`h-3.5 w-3.5 ${expanded ? "rotate-90" : ""}`} />
</Popover2> </button>
</div> </div>
)} )}
</div> </div>
)}
{issue.sub_issues_count > 0 && ( <div className="w-full overflow-hidden">
<div className="h-6 w-6 flex justify-center items-center"> <Tooltip tooltipHeading="Title" tooltipContent={issue.name}>
<button <div
className="h-5 w-5 hover:bg-custom-background-90 hover:text-custom-text-100 rounded-sm cursor-pointer" className="px-4 py-2.5 h-full w-full truncate text-custom-text-100 text-left cursor-pointer text-[0.825rem]"
onClick={() => handleToggleExpand(issue.id)} onClick={() => handleIssuePeekOverview(issue)}
> >
<ChevronRight className={`h-3.5 w-3.5 ${expanded ? "rotate-90" : ""}`} />
</button>
</div>
)}
</div>
)}
<IssuePeekOverview
workspaceSlug={issue?.workspace_detail?.slug}
projectId={issue?.project_detail?.id}
issueId={issue?.id}
handleIssue={(issueToUpdate) => handleUpdateIssue(issueToUpdate as IIssue, issueToUpdate)}
>
<Tooltip tooltipHeading="Title" tooltipContent={issue.name}>
<span className="flex items-center px-4 py-2.5 h-full truncate flex-grow">
<div className="truncate text-custom-text-100 text-left cursor-pointer w-full text-[0.825rem]">
{issue.name} {issue.name}
</div> </div>
</span> </Tooltip>
</Tooltip> </div>
</IssuePeekOverview> </div>
</div> </>
); );
}; };

View File

@ -11,9 +11,15 @@ type Props = {
issue: IIssue; issue: IIssue;
expandedIssues: string[]; expandedIssues: string[];
setExpandedIssues: React.Dispatch<React.SetStateAction<string[]>>; setExpandedIssues: React.Dispatch<React.SetStateAction<string[]>>;
handleUpdateIssue: (issue: IIssue, data: Partial<IIssue>) => void;
properties: IIssueDisplayProperties; properties: IIssueDisplayProperties;
handleIssueAction: (issue: IIssue, action: "copy" | "delete" | "edit") => void; handleIssueAction: (issue: IIssue, action: "copy" | "delete" | "edit") => void;
setIssuePeekOverView: React.Dispatch<
React.SetStateAction<{
workspaceSlug: string;
projectId: string;
issueId: string;
} | null>
>;
disableUserActions: boolean; disableUserActions: boolean;
nestingLevel?: number; nestingLevel?: number;
}; };
@ -22,7 +28,7 @@ export const SpreadsheetIssuesColumn: React.FC<Props> = ({
issue, issue,
expandedIssues, expandedIssues,
setExpandedIssues, setExpandedIssues,
handleUpdateIssue, setIssuePeekOverView,
properties, properties,
handleIssueAction, handleIssueAction,
disableUserActions, disableUserActions,
@ -51,9 +57,9 @@ export const SpreadsheetIssuesColumn: React.FC<Props> = ({
expanded={isExpanded} expanded={isExpanded}
handleToggleExpand={handleToggleExpand} handleToggleExpand={handleToggleExpand}
properties={properties} properties={properties}
handleUpdateIssue={handleUpdateIssue}
handleEditIssue={() => handleIssueAction(issue, "edit")} handleEditIssue={() => handleIssueAction(issue, "edit")}
handleDeleteIssue={() => handleIssueAction(issue, "delete")} handleDeleteIssue={() => handleIssueAction(issue, "delete")}
setIssuePeekOverView={setIssuePeekOverView}
disableUserActions={disableUserActions} disableUserActions={disableUserActions}
nestingLevel={nestingLevel} nestingLevel={nestingLevel}
/> />
@ -67,10 +73,10 @@ export const SpreadsheetIssuesColumn: React.FC<Props> = ({
key={subIssue.id} key={subIssue.id}
issue={subIssue} issue={subIssue}
expandedIssues={expandedIssues} expandedIssues={expandedIssues}
handleUpdateIssue={handleUpdateIssue}
setExpandedIssues={setExpandedIssues} setExpandedIssues={setExpandedIssues}
properties={properties} properties={properties}
handleIssueAction={handleIssueAction} handleIssueAction={handleIssueAction}
setIssuePeekOverView={setIssuePeekOverView}
disableUserActions={disableUserActions} disableUserActions={disableUserActions}
nestingLevel={nestingLevel + 1} nestingLevel={nestingLevel + 1}
/> />

View File

@ -1,10 +1,10 @@
import React, { useEffect, useRef, useState } from "react"; import React, { useEffect, useRef, useState } from "react";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { PlusIcon } from "lucide-react";
// components // components
import { SpreadsheetColumnsList, SpreadsheetIssuesColumn, SpreadsheetInlineCreateIssueForm } from "components/issues"; import { SpreadsheetColumnsList, SpreadsheetIssuesColumn, SpreadsheetInlineCreateIssueForm } from "components/issues";
import { CustomMenu, Spinner } from "@plane/ui"; import { IssuePeekOverview } from "components/issues/issue-peek-overview";
import { Spinner } from "@plane/ui";
// types // types
import { import {
IIssue, IIssue,
@ -47,6 +47,11 @@ export const SpreadsheetView: React.FC<Props> = observer((props) => {
} = props; } = props;
const [expandedIssues, setExpandedIssues] = useState<string[]>([]); const [expandedIssues, setExpandedIssues] = useState<string[]>([]);
const [issuePeekOverview, setIssuePeekOverView] = useState<{
workspaceSlug: string;
projectId: string;
issueId: string;
} | null>(null);
const [isInlineCreateIssueFormOpen, setIsInlineCreateIssueFormOpen] = useState(false); const [isInlineCreateIssueFormOpen, setIsInlineCreateIssueFormOpen] = useState(false);
@ -104,11 +109,11 @@ export const SpreadsheetView: React.FC<Props> = observer((props) => {
key={`${issue.id}_${index}`} key={`${issue.id}_${index}`}
issue={issue} issue={issue}
expandedIssues={expandedIssues} expandedIssues={expandedIssues}
handleUpdateIssue={handleUpdateIssue}
setExpandedIssues={setExpandedIssues} setExpandedIssues={setExpandedIssues}
properties={displayProperties} properties={displayProperties}
handleIssueAction={handleIssueAction} handleIssueAction={handleIssueAction}
disableUserActions={disableUserActions} disableUserActions={disableUserActions}
setIssuePeekOverView={setIssuePeekOverView}
/> />
))} ))}
</div> </div>
@ -174,6 +179,14 @@ export const SpreadsheetView: React.FC<Props> = observer((props) => {
))} */} ))} */}
</div> </div>
</div> </div>
{issuePeekOverview && (
<IssuePeekOverview
workspaceSlug={issuePeekOverview?.workspaceSlug}
projectId={issuePeekOverview?.projectId}
issueId={issuePeekOverview?.issueId}
handleIssue={(issueToUpdate: any) => handleUpdateIssue(issueToUpdate as IIssue, issueToUpdate)}
/>
)}
</div> </div>
); );
}); });

View File

@ -13,7 +13,7 @@ interface IIssuePeekOverview {
projectId: string; projectId: string;
issueId: string; issueId: string;
handleIssue: (issue: Partial<IIssue>) => void; handleIssue: (issue: Partial<IIssue>) => void;
children: ReactNode; children?: ReactNode;
} }
export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => { export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {

View File

@ -1,6 +1,6 @@
import { FC, ReactNode, useState } from "react"; import { FC, ReactNode, useState } from "react";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { PanelRightOpen, Square, SquareCode, MoveRight, MoveDiagonal, Bell, Link2, Trash2 } from "lucide-react"; import { MoveRight, MoveDiagonal, Bell, Link2, Trash2 } from "lucide-react";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import useSWR from "swr"; import useSWR from "swr";
// components // components
@ -165,9 +165,11 @@ export const IssueView: FC<IIssueView> = observer((props) => {
/> />
)} )}
<div className="w-full !text-base"> <div className="w-full !text-base">
<div onClick={updateRoutePeekId} className="w-full cursor-pointer"> {children && (
{children} <div onClick={updateRoutePeekId} className="w-full cursor-pointer">
</div> {children}
</div>
)}
{issueId === peekIssueId && ( {issueId === peekIssueId && (
<div <div