forked from github/plane
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:
parent
1352c200dd
commit
4c1aee0cfc
@ -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>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -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}
|
||||||
/>
|
/>
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -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) => {
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user