diff --git a/apps/client/src/ee/base/components/kanban/kanban-column-header.tsx b/apps/client/src/ee/base/components/kanban/kanban-column-header.tsx index 99248e7e9..830a00a16 100644 --- a/apps/client/src/ee/base/components/kanban/kanban-column-header.tsx +++ b/apps/client/src/ee/base/components/kanban/kanban-column-header.tsx @@ -1,13 +1,14 @@ import { useRef } from "react"; import { useTranslation } from "react-i18next"; -import { ActionIcon, Menu, Text } from "@mantine/core"; -import { IconDots, IconPlus, IconGripVertical } from "@tabler/icons-react"; +import { ActionIcon, Text } from "@mantine/core"; +import { IconPlus, IconGripVertical } from "@tabler/icons-react"; import clsx from "clsx"; import { IBaseProperty, KanbanColumn } from "@/ee/base/types/base.types"; import { choiceColor } from "@/ee/base/components/cells/choice-color"; import { useKanbanColumnDnd } from "@/ee/base/hooks/use-kanban-column-dnd"; import { BaseDropEdgeIndicator } from "@/ee/base/components/grid/base-drop-edge-indicator"; import { KanbanColumnTitle } from "@/ee/base/components/kanban/kanban-column-title"; +import { KanbanColumnMenu } from "@/ee/base/components/kanban/kanban-column-menu"; import classes from "@/ee/base/styles/kanban.module.css"; type KanbanColumnHeaderProps = { @@ -55,16 +56,9 @@ export function KanbanColumnHeader({ column, pageId, property, count, canEdit, o {count !== undefined && {count}} {canEdit && ( <> - - - - - - - - {t("Hide group")} - - + {property && ( + + )} diff --git a/apps/client/src/ee/base/components/kanban/kanban-column-menu.tsx b/apps/client/src/ee/base/components/kanban/kanban-column-menu.tsx new file mode 100644 index 000000000..be2e88f76 --- /dev/null +++ b/apps/client/src/ee/base/components/kanban/kanban-column-menu.tsx @@ -0,0 +1,119 @@ +import { useCallback, useEffect, useRef, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { ActionIcon, Popover, Stack } from "@mantine/core"; +import { IconDots, IconEyeOff, IconSettings } from "@tabler/icons-react"; +import { useAtom } from "jotai"; +import { + propertyMenuCloseRequestAtomFamily, + propertyMenuDirtyAtomFamily, +} from "@/ee/base/atoms/base-atoms"; +import { IBaseProperty } from "@/ee/base/types/base.types"; +import { + MenuItem, + PropertyMenuContent, +} from "@/ee/base/components/property/property-menu"; + +type KanbanColumnMenuProps = { + property: IBaseProperty; + pageId: string; + onHide: () => void; +}; + +export function KanbanColumnMenu({ property, pageId, onHide }: KanbanColumnMenuProps) { + const { t } = useTranslation(); + const [opened, setOpened] = useState(false); + const [view, setView] = useState<"menu" | "property">("menu"); + const [dirty, setDirty] = useAtom(propertyMenuDirtyAtomFamily(pageId)) as unknown as [boolean, (val: boolean) => void]; + const [closeRequest, setCloseRequest] = useAtom(propertyMenuCloseRequestAtomFamily(pageId)) as unknown as [number, (val: number) => void]; + + const handleClose = useCallback(() => { + setOpened(false); + setView("menu"); + }, []); + + const wasOpenedRef = useRef(opened); + useEffect(() => { + if (wasOpenedRef.current && !opened) setDirty(false); + wasOpenedRef.current = opened; + }, [opened, setDirty]); + + const handleOpenChange = useCallback( + (next: boolean) => { + if (next) return; + if (dirty) { + setCloseRequest(closeRequest + 1); + } else { + handleClose(); + } + }, + [dirty, closeRequest, setCloseRequest, handleClose], + ); + + const toggle = useCallback(() => { + if (opened) { + handleOpenChange(false); + } else if (!dirty) { + setOpened(true); + } + }, [opened, dirty, handleOpenChange]); + + return ( + + + + + + + e.stopPropagation()} + onKeyDown={(e) => e.stopPropagation()} + > + {view === "menu" ? ( + + } + label={t("Edit property")} + onClick={() => setView("property")} + /> + } + label={t("Hide group")} + onClick={() => { + handleClose(); + onHide(); + }} + /> + + ) : ( + + )} + + + ); +}