Browse Source

feat(dashboard): Implement column visibility control

Michael Bromley 11 months ago
parent
commit
6817a90534

+ 9 - 1
packages/dashboard/src/framework/internal/data-table/data-table.tsx

@@ -10,9 +10,10 @@ import {
     getCoreRowModel,
     getPaginationRowModel,
     PaginationState,
+    VisibilityState,
     SortingState,
-    useReactTable,
     Table as TableType,
+    useReactTable,
 } from '@tanstack/react-table';
 import React, { useEffect } from 'react';
 
@@ -24,6 +25,7 @@ interface DataTableProps<TData, TValue> {
     itemsPerPage?: number;
     onPageChange?: (table: TableType<TData>, page: number, itemsPerPage: number) => void;
     onSortChange?: (table: TableType<TData>, sorting: SortingState) => void;
+    defaultColumnVisibility?: VisibilityState;
 }
 
 export function DataTable<TData, TValue>({
@@ -34,12 +36,16 @@ export function DataTable<TData, TValue>({
     itemsPerPage,
     onPageChange,
     onSortChange,
+    defaultColumnVisibility,
 }: DataTableProps<TData, TValue>) {
     const [sorting, setSorting] = React.useState<SortingState>([]);
     const [pagination, setPagination] = React.useState<PaginationState>({
         pageIndex: (page ?? 1) - 1,
         pageSize: itemsPerPage ?? 10,
     });
+    const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>(
+        defaultColumnVisibility ?? {},
+    );
     const table = useReactTable({
         data,
         columns,
@@ -50,9 +56,11 @@ export function DataTable<TData, TValue>({
         rowCount: totalItems,
         onPaginationChange: setPagination,
         onSortingChange: setSorting,
+        onColumnVisibilityChange: setColumnVisibility,
         state: {
             pagination,
             sorting,
+            columnVisibility,
         },
     });
 

+ 11 - 0
packages/dashboard/src/framework/internal/page/list-page.tsx

@@ -39,6 +39,8 @@ export interface ListPageProps<T extends TypedDocumentNode<U>, U extends ListQue
     title: string;
     listQuery: T;
     customizeColumns?: CustomizeColumnConfig<T>;
+    defaultColumnOrder?: (keyof ListQueryFields<T>)[];
+    defaultVisibility?: Partial<Record<keyof ListQueryFields<T>, boolean>>;
     route: AnyRoute;
 }
 
@@ -47,6 +49,7 @@ export function ListPage<T extends TypedDocumentNode<U>, U extends Record<string
     listQuery,
     customizeColumns,
     route,
+    defaultVisibility,
 }: ListPageProps<T, U>) {
     const { getComponent } = useComponentRegistry();
     const routeSearch = route.useSearch();
@@ -143,6 +146,13 @@ export function ListPage<T extends TypedDocumentNode<U>, U extends Record<string
         });
     });
 
+    const columnVisibility = {
+        id: false,
+        createdAt: false,
+        updatedAt: false,
+        ...(defaultVisibility ?? {}),
+    };
+
     function persistListStateToUrl(
         table: Table<any>,
         listState: {
@@ -180,6 +190,7 @@ export function ListPage<T extends TypedDocumentNode<U>, U extends Record<string
                 onSortChange={(table, sorting) => {
                     persistListStateToUrl(table, { sort: sorting });
                 }}
+                defaultColumnVisibility={columnVisibility}
             ></DataTable>
         </div>
     );

+ 7 - 1
packages/dashboard/src/routes/_authenticated/products.tsx

@@ -12,7 +12,6 @@ const productFragment = graphql(`
         id
         createdAt
         updatedAt
-        name
         featuredAsset {
             id
             preview
@@ -21,6 +20,8 @@ const productFragment = graphql(`
                 y
             }
         }
+        name
+        slug
         enabled
     }
 `);
@@ -45,12 +46,17 @@ export function ProductListPage() {
             title="Products"
             listQuery={productListDocument}
             customizeColumns={{
+                id: { enableHiding: true },
                 name: { header: 'Product Name' },
                 featuredAsset: {
                     header: 'Image',
                     enableSorting: false,
                 },
             }}
+            defaultColumnOrder={['id', 'featuredAsset', 'name']}
+            defaultVisibility={{
+                id: true,
+            }}
             route={Route}
         />
     );