forked from github/plane
fix: spreadsheet quick action menu fix (#1404)
This commit is contained in:
parent
5914240290
commit
b01afdf300
@ -1,4 +1,4 @@
|
|||||||
import React, { useCallback } from "react";
|
import React, { useCallback, useState } from "react";
|
||||||
|
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
@ -14,9 +14,15 @@ import {
|
|||||||
ViewPrioritySelect,
|
ViewPrioritySelect,
|
||||||
ViewStateSelect,
|
ViewStateSelect,
|
||||||
} from "components/issues";
|
} from "components/issues";
|
||||||
|
import { Popover2 } from "@blueprintjs/popover2";
|
||||||
// icons
|
// icons
|
||||||
import { CustomMenu, Icon } from "components/ui";
|
import { Icon } from "components/ui";
|
||||||
import { LinkIcon, PencilIcon, TrashIcon, XMarkIcon } from "@heroicons/react/24/outline";
|
import {
|
||||||
|
EllipsisHorizontalIcon,
|
||||||
|
LinkIcon,
|
||||||
|
PencilIcon,
|
||||||
|
TrashIcon,
|
||||||
|
} from "@heroicons/react/24/outline";
|
||||||
// hooks
|
// hooks
|
||||||
import useSpreadsheetIssuesView from "hooks/use-spreadsheet-issues-view";
|
import useSpreadsheetIssuesView from "hooks/use-spreadsheet-issues-view";
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
@ -60,6 +66,7 @@ export const SingleSpreadsheetIssue: React.FC<Props> = ({
|
|||||||
userAuth,
|
userAuth,
|
||||||
nestingLevel,
|
nestingLevel,
|
||||||
}) => {
|
}) => {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const { workspaceSlug, projectId, cycleId, moduleId, viewId } = router.query;
|
const { workspaceSlug, projectId, cycleId, moduleId, viewId } = router.query;
|
||||||
@ -163,27 +170,87 @@ export const SingleSpreadsheetIssue: React.FC<Props> = ({
|
|||||||
className="relative group grid auto-rows-[minmax(44px,1fr)] hover:rounded-sm hover:bg-brand-surface-2 border-b border-brand-base w-full min-w-max"
|
className="relative group grid auto-rows-[minmax(44px,1fr)] hover:rounded-sm hover:bg-brand-surface-2 border-b border-brand-base w-full min-w-max"
|
||||||
style={{ gridTemplateColumns }}
|
style={{ gridTemplateColumns }}
|
||||||
>
|
>
|
||||||
<div className="flex gap-1.5 items-center px-4 sticky left-0 z-[1] text-brand-secondary bg-brand-base group-hover:text-brand-base group-hover:bg-brand-surface-2 border-brand-base w-full">
|
<div className="flex gap-1.5 items-center px-4 sticky z-10 left-0 text-brand-secondary bg-brand-base group-hover:text-brand-base group-hover:bg-brand-surface-2 border-brand-base w-full">
|
||||||
<span className="flex gap-1 items-center" style={issue.parent ? { paddingLeft } : {}}>
|
<div className="flex gap-1.5 items-center" style={issue.parent ? { paddingLeft } : {}}>
|
||||||
<div className="flex items-center cursor-pointer text-xs text-center hover:text-brand-base w-14 opacity-100 group-hover:opacity-0">
|
<div className="relative flex items-center cursor-pointer text-xs text-center hover:text-brand-base w-14">
|
||||||
{properties.key && (
|
{properties.key && (
|
||||||
<span>
|
<span className="flex items-center justify-center opacity-100 group-hover:opacity-0">
|
||||||
{issue.project_detail?.identifier}-{issue.sequence_id}
|
{issue.project_detail?.identifier}-{issue.sequence_id}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
{!isNotAllowed && (
|
||||||
|
<div className="absolute top-0 left-2.5 opacity-0 group-hover:opacity-100">
|
||||||
|
<Popover2
|
||||||
|
isOpen={isOpen}
|
||||||
|
canEscapeKeyClose
|
||||||
|
onInteraction={(nextOpenState) => setIsOpen(nextOpenState)}
|
||||||
|
content={
|
||||||
|
<div
|
||||||
|
className={`flex flex-col gap-1.5 overflow-y-scroll whitespace-nowrap rounded-md border p-1 text-xs shadow-lg focus:outline-none max-h-44 min-w-full border-brand-base bg-brand-surface-1`}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="hover:text-brand-muted-1 w-full select-none gap-2 truncate rounded px-1 py-1.5 text-left text-brand-secondary hover:bg-brand-surface-2"
|
||||||
|
onClick={() => {
|
||||||
|
handleEditIssue(issue);
|
||||||
|
setIsOpen(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-start gap-2">
|
||||||
|
<PencilIcon className="h-4 w-4" />
|
||||||
|
<span>Edit issue</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="hover:text-brand-muted-1 w-full select-none gap-2 truncate rounded px-1 py-1.5 text-left text-brand-secondary hover:bg-brand-surface-2"
|
||||||
|
onClick={() => {
|
||||||
|
handleDeleteIssue(issue);
|
||||||
|
setIsOpen(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-start gap-2">
|
||||||
|
<TrashIcon className="h-4 w-4" />
|
||||||
|
<span>Delete issue</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="hover:text-brand-muted-1 w-full select-none gap-2 truncate rounded px-1 py-1.5 text-left text-brand-secondary hover:bg-brand-surface-2"
|
||||||
|
onClick={() => {
|
||||||
|
handleCopyText();
|
||||||
|
setIsOpen(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-start gap-2">
|
||||||
|
<LinkIcon className="h-4 w-4" />
|
||||||
|
<span>Copy issue link</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
placement="bottom-start"
|
||||||
|
>
|
||||||
|
<EllipsisHorizontalIcon className="h-5 w-5 text-brand-secondary" />
|
||||||
|
</Popover2>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="h-5 w-5">
|
<div className="h-6 w-6 flex justify-center items-center">
|
||||||
{issue.sub_issues_count > 0 && (
|
{issue.sub_issues_count > 0 && (
|
||||||
<button
|
<button
|
||||||
className="h-5 w-5 hover:bg-brand-surface-1 hover:text-brand-base rounded-sm"
|
className="h-5 w-5 hover:bg-brand-surface-1 hover:text-brand-base rounded-sm cursor-pointer"
|
||||||
onClick={() => handleToggleExpand(issue.id)}
|
onClick={() => handleToggleExpand(issue.id)}
|
||||||
>
|
>
|
||||||
<Icon iconName="chevron_right" className={`${expanded ? "rotate-90" : ""}`} />
|
<Icon iconName="chevron_right" className={`${expanded ? "rotate-90" : ""}`} />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</div>
|
||||||
|
|
||||||
<Link href={`/${workspaceSlug}/projects/${issue?.project_detail?.id}/issues/${issue.id}`}>
|
<Link href={`/${workspaceSlug}/projects/${issue?.project_detail?.id}/issues/${issue.id}`}>
|
||||||
<a className="truncate text-brand-base cursor-pointer w-full text-[0.825rem]">
|
<a className="truncate text-brand-base cursor-pointer w-full text-[0.825rem]">
|
||||||
{issue.name}
|
{issue.name}
|
||||||
@ -261,35 +328,6 @@ export const SingleSpreadsheetIssue: React.FC<Props> = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div
|
|
||||||
className="absolute top-2.5 z-10 cursor-pointer opacity-0 group-hover:opacity-100"
|
|
||||||
style={{
|
|
||||||
left: `${nestingLevel * 68 + 24}px`,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{!isNotAllowed && (
|
|
||||||
<CustomMenu width="auto" position="left" ellipsis>
|
|
||||||
<CustomMenu.MenuItem onClick={() => handleEditIssue(issue)}>
|
|
||||||
<div className="flex items-center justify-start gap-2">
|
|
||||||
<PencilIcon className="h-4 w-4" />
|
|
||||||
<span>Edit issue</span>
|
|
||||||
</div>
|
|
||||||
</CustomMenu.MenuItem>
|
|
||||||
<CustomMenu.MenuItem onClick={() => handleDeleteIssue(issue)}>
|
|
||||||
<div className="flex items-center justify-start gap-2">
|
|
||||||
<TrashIcon className="h-4 w-4" />
|
|
||||||
<span>Delete issue</span>
|
|
||||||
</div>
|
|
||||||
</CustomMenu.MenuItem>
|
|
||||||
<CustomMenu.MenuItem onClick={handleCopyText}>
|
|
||||||
<div className="flex items-center justify-start gap-2">
|
|
||||||
<LinkIcon className="h-4 w-4" />
|
|
||||||
<span>Copy issue link</span>
|
|
||||||
</div>
|
|
||||||
</CustomMenu.MenuItem>
|
|
||||||
</CustomMenu>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -40,7 +40,7 @@ export const SpreadsheetColumns: React.FC<Props> = ({ columnData, gridTemplateCo
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`bg-brand-surface-1 w-full ${
|
className={`bg-brand-surface-1 w-full ${
|
||||||
col.propertyName === "title" ? "sticky left-0 z-[2] bg-brand-surface-1 pl-24" : ""
|
col.propertyName === "title" ? "sticky left-0 z-20 bg-brand-surface-1 pl-24" : ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{col.propertyName === "title" ? (
|
{col.propertyName === "title" ? (
|
||||||
|
@ -62,7 +62,7 @@ export const SpreadsheetView: React.FC<Props> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full rounded-lg text-brand-secondary overflow-x-auto whitespace-nowrap bg-brand-base">
|
<div className="h-full rounded-lg text-brand-secondary overflow-x-auto whitespace-nowrap bg-brand-base">
|
||||||
<div className="sticky z-[2] top-0 border-b border-brand-base bg-brand-surface-1 w-full min-w-max">
|
<div className="sticky z-20 top-0 border-b border-brand-base bg-brand-surface-1 w-full min-w-max">
|
||||||
<SpreadsheetColumns columnData={columnData} gridTemplateColumns={gridTemplateColumns} />
|
<SpreadsheetColumns columnData={columnData} gridTemplateColumns={gridTemplateColumns} />
|
||||||
</div>
|
</div>
|
||||||
{spreadsheetIssues ? (
|
{spreadsheetIssues ? (
|
||||||
|
@ -225,3 +225,8 @@ body {
|
|||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
-webkit-line-clamp: 1;
|
-webkit-line-clamp: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* popover2 styling */
|
||||||
|
.bp4-popover2-transition-container {
|
||||||
|
z-index: 20 !important;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user