diff --git a/frontend/bun.lockb b/frontend/bun.lockb index 7b36f43..eccbf47 100755 Binary files a/frontend/bun.lockb and b/frontend/bun.lockb differ diff --git a/frontend/package.json b/frontend/package.json index 0451b01..470c566 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -11,6 +11,9 @@ "preview": "vite preview" }, "dependencies": { + "@dnd-kit/core": "^6.1.0", + "@dnd-kit/sortable": "^8.0.0", + "@dnd-kit/utilities": "^3.2.2", "@fontsource/inter": "^5.0.19", "@hookform/resolvers": "^3.9.0", "@it-incubator/prettier-config": "^0.1.2", diff --git a/frontend/src/components/db-table-view/columns-dropdown.tsx b/frontend/src/components/db-table-view/columns-dropdown.tsx index 9b64861..b9d4eb8 100644 --- a/frontend/src/components/db-table-view/columns-dropdown.tsx +++ b/frontend/src/components/db-table-view/columns-dropdown.tsx @@ -5,13 +5,42 @@ import { DropdownMenuContent, DropdownMenuTrigger, } from "@/components/ui"; -import type { Table } from "@tanstack/react-table"; +import { + DndContext, + type DragEndEvent, + KeyboardSensor, + PointerSensor, + closestCenter, + useSensor, + useSensors, +} from "@dnd-kit/core"; +import { + SortableContext, + arrayMove, + sortableKeyboardCoordinates, + useSortable, + verticalListSortingStrategy, +} from "@dnd-kit/sortable"; +import { CSS } from "@dnd-kit/utilities"; +import type { Column, Table } from "@tanstack/react-table"; +import { GripVertical } from "lucide-react"; +import type { Dispatch, SetStateAction } from "react"; export function ColumnsDropdown({ table, + columnOrder, + setColumnOrder, }: { table: Table; + columnOrder: string[]; + setColumnOrder: Dispatch>; }) { + const sensors = useSensors( + useSensor(PointerSensor), + useSensor(KeyboardSensor, { + coordinateGetter: sortableKeyboardCoordinates, + }), + ); return ( @@ -20,22 +49,69 @@ export function ColumnsDropdown({ - {table - .getAllColumns() - .filter((column) => column.getCanHide()) - .map((column) => { - return ( - e.preventDefault()} - checked={column.getIsVisible()} - onCheckedChange={column.toggleVisibility} - > - {column.id} - - ); - })} + + + {columnOrder.map((columnId) => { + const column = table.getColumn(columnId); + if (!column) return null; + return ; + })} + + ); + function handleDragEnd(event: DragEndEvent) { + const { active, over } = event; + if (active.id !== over?.id) { + setColumnOrder((items) => { + const oldIndex = items.findIndex((id) => id === active.id); + const newIndex = items.findIndex((id) => id === over.id); + + return arrayMove(items, oldIndex, newIndex); + }); + } + } } + +const SortableItem = ({ column }: { column: Column }) => { + const { + attributes, + listeners, + setNodeRef, + setActivatorNodeRef, + transform, + transition, + } = useSortable({ id: column.id }); + + const style = { + transform: CSS.Transform.toString(transform), + transition, + }; + + return ( + e.preventDefault()} + checked={column.getIsVisible()} + onCheckedChange={column.toggleVisibility} + > +
+ {column.id} + +
+
+ ); +}; diff --git a/frontend/src/components/db-table-view/columns.tsx b/frontend/src/components/db-table-view/columns.tsx index 8a7ef85..abd96ff 100644 --- a/frontend/src/components/db-table-view/columns.tsx +++ b/frontend/src/components/db-table-view/columns.tsx @@ -20,6 +20,7 @@ const buildColumns = ({ accessorKey: column_name, title: column_name, size: 300, + id: column_name, header: () => { return (
( @@ -64,7 +65,13 @@ function Component() { const sortingState = useMemo(() => sortByToState(filters), [filters]); const columns = useColumns({ dbName, tableName }); - + const [columnOrder, setColumnOrder] = useState(() => + columns.map((c) => c.id ?? ""), + ); + useEffect(() => { + if (columnOrder.length !== 0) return; + setColumnOrder(columns.map((c) => c.id ?? "")); + }, [columns, columnOrder.length]); const { data, refetch } = useTableDataQuery({ whereQuery, tableName, @@ -115,12 +122,14 @@ function Component() { getCoreRowModel: getCoreRowModel(), manualPagination: true, manualSorting: true, + onColumnOrderChange: setColumnOrder, onColumnSizingChange: setColumnSizing, onColumnVisibilityChange: setColumnVisibility, onPaginationChange: handlePaginationChange, onSortingChange: handleSortingChange, rowCount: data?.count ?? 0, state: { + columnOrder, sorting: sortingState, columnSizing: columnSizing, columnVisibility, @@ -136,7 +145,11 @@ function Component() { {tableName} - +

Rows: {data?.count}