From e0dfb55c5457aec489fc084c4567e791b4c65eb1 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Wed, 26 Mar 2025 00:37:41 +0000 Subject: 3/25 까지의 대표님 작업사항 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client-data-table/data-table-sort-list.tsx | 272 +++++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 components/client-data-table/data-table-sort-list.tsx (limited to 'components/client-data-table/data-table-sort-list.tsx') diff --git a/components/client-data-table/data-table-sort-list.tsx b/components/client-data-table/data-table-sort-list.tsx new file mode 100644 index 00000000..b67fdde3 --- /dev/null +++ b/components/client-data-table/data-table-sort-list.tsx @@ -0,0 +1,272 @@ +"use client" + +import * as React from "react" +import { type SortingState, type Table } from "@tanstack/react-table" +import { + ArrowDownUp, + ChevronsUpDown, + GripVertical, + Trash2, +} from "lucide-react" + +import { Badge } from "@/components/ui/badge" +import { Button } from "@/components/ui/button" +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select" +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, +} from "@/components/ui/command" +import { + Sortable, + SortableItem, + SortableDragHandle, +} from "@/components/ui/sortable" +import { cn, toSentenceCase } from "@/lib/utils" + + +/** + * A simpler, local-state version of the column "sort list". + * - No `useQueryState` or URL sync + * - We store a local `sorting: SortingState` and whenever it changes, we do `table.setSorting(sorting)`. + */ +interface DataTableSortListLocalProps { + /** TanStack Table instance */ + table: Table +} + +export function ClientDataTableSortList({ table }: DataTableSortListLocalProps) { + + + // 2) local SortingState + const [sorting, setSorting] = React.useState([]) + + // 3) Keep the table in sync + React.useEffect(() => { + table.setSorting(sorting) + }, [sorting, table]) + + // 4) columns that can be sorted + const sortableColumns = React.useMemo(() => { + return table + .getAllColumns() + .filter((col) => col.getCanSort()) + .map((col) => ({ + id: col.id, + // excelHeader 를 사용 중이면 label이 없을 수 있으니 fallback + label: (col.columnDef.meta?.excelHeader as string) || toSentenceCase(col.id), + })) + }, [table]) + + // 5) "Add sort" → pick first unsorted column + function addSort() { + const used = new Set(sorting.map((s) => s.id)) + const firstUnused = sortableColumns.find((col) => !used.has(col.id)) + if (!firstUnused) return + setSorting((prev) => [...prev, { id: firstUnused.id, desc: false }]) + } + + // 6) update sort item by column id + function updateSort( + columnId: string, + patch: Partial<{ id: string; desc: boolean }> + ) { + setSorting((prev) => + prev.map((s) => (s.id === columnId ? { ...s, ...patch } : s)) + ) + } + + // 7) remove a sort item + function removeSort(columnId: string) { + setSorting((prev) => prev.filter((s) => s.id !== columnId)) + } + + // 8) reorder sorting items via drag + function moveSort(activeIndex: number, overIndex: number) { + setSorting((prev) => { + const arr = [...prev] + const [removed] = arr.splice(activeIndex, 1) + if (!removed) return prev + arr.splice(overIndex, 0, removed) + return arr + }) + } + + const isSortingEmpty = sorting.length === 0 + + return ( + moveSort(activeIndex, overIndex)} + overlay={ +
+
+
+
+
+
+ } + > + + + + + + 0 ? "gap-3.5" : "gap-2" + )} + > + {isSortingEmpty ? ( +
+

+ { "No sorting applied"} +

+

+ { "Add sorting to organize your results."} +

+
+ ) : ( +

+ { "Sort by"} +

+ )} + + {/* Sorting items */} + {sorting.length > 0 && ( +
+ {sorting.map((sortItem) => { + const col = sortableColumns.find((c) => c.id === sortItem.id) + const columnLabel = col ? col.label : toSentenceCase(sortItem.id) + + return ( + +
+ {/* Column name selector */} + + + + + + + + + + { "No columns found."} + + + {sortableColumns.map((col) => ( + { + // change the ID of the sort item + updateSort(sortItem.id, { id: val, desc: false }) + }} + > + {col.label} + + ))} + + + + + + + {/* Sort direction */} + + + {/* remove sort */} + + + {/* drag handle */} + + +
+
+ ) + })} +
+ )} + + {/* Footer: "Add sort" & "Reset" */} +
+ + {sorting.length > 0 && ( + + )} +
+
+
+ + ) +} \ No newline at end of file -- cgit v1.2.3