"use client" import * as React from "react" import { RowData, type Table } from "@tanstack/react-table" import { Check, ChevronsUpDown, GripVertical, Settings2, } from "lucide-react" import { cn, toSentenceCase } from "@/lib/utils" import { Button } from "@/components/ui/button" import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "@/components/ui/command" import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip" // Sortable import { Sortable, SortableItem, SortableDragHandle, } from "@/components/ui/sortable" import { useTranslation } from '@/i18n/client' import { useParams, usePathname } from "next/navigation"; import deepEqual from "fast-deep-equal" /** * ViewOptionsProps: * - table: TanStack Table instance * - resetAutoSize: Function to reset autosize calculations (optional) */ interface DataTableViewOptionsProps { table: Table resetAutoSize?: () => void } declare module "@tanstack/table-core" { interface ColumnMeta { excelHeader?: string group?: string type?: string // ...anything else you want } } /** * DataTableViewOptions: * - Renders a Popover with hideable columns * - Lets user reorder columns (drag & drop) + toggle visibility */ export function DataTableViewOptions({ table, resetAutoSize, }: DataTableViewOptionsProps) { const triggerRef = React.useRef(null) const params = useParams(); const lng = params?.lng as string; const { t } = useTranslation(lng); // 1) Identify columns that can be hidden const hideableCols = React.useMemo(() => { return table .getAllLeafColumns() .filter((col) => col.getCanHide()) }, [table.getAllLeafColumns().map(c => c.id).join(',')]) // 2) local state for "columnOrder" (just the ID of hideable columns) // We'll reorder these with drag & drop const isInitialized = React.useRef(false) const [columnOrder, setColumnOrder] = React.useState(() => hideableCols.map((c) => c.id) ) // 3) onMove: when user finishes drag // - update local `columnOrder` only (no table.setColumnOrder yet) const handleMove = React.useCallback( ({ activeIndex, overIndex }: { activeIndex: number; overIndex: number }) => { setColumnOrder((prev) => { const newOrder = [...prev] const [removed] = newOrder.splice(activeIndex, 1) newOrder.splice(overIndex, 0, removed) return newOrder }) }, [] ) // 4) After local state changes, reflect in tanstack table // - We do this in useEffect to avoid "update a different component" error React.useEffect(() => { if (!isInitialized.current) { isInitialized.current = true return } const nonHideable = table .getAllColumns() .filter((col) => !hideableCols.some((hc) => hc.id === col.id)) .map((c) => c.id) const finalOrder = [...nonHideable, ...columnOrder] const currentOrder = table.getState().columnOrder if (!deepEqual(currentOrder, finalOrder)) { table.setColumnOrder(finalOrder) resetAutoSize?.() } }, [columnOrder,hideableCols.map(c => c.id).join(','),resetAutoSize]) return ( triggerRef.current?.focus()} > No columns found. {/** * 5) Sortable: we pass an array of { id: string } from `columnOrder`, * so we can reorder them with drag & drop */} ({ id }))} onMove={handleMove} > {columnOrder.map((colId) => { // find column instance const column = hideableCols.find((c) => c.id === colId) if (!column) return null const columnLabel = column?.columnDef?.meta?.excelHeader || column.id return ( { column.toggleVisibility(!column.getIsVisible()) // Reset autosize calculations when toggling columns resetAutoSize?.() }} > {/* Drag handle on the left */} {/* label with tooltip for long names */} {columnLabel} {columnLabel} {/* check if visible */} ) })} ) }