Skip to main content

PaginatedListDataTable

PaginatedListDataTable

A wrapper around the DataTable component, which automatically configures functionality common to list queries that implement the PaginatedList interface, which is the common way of representing lists of data in Vendure.

Given a GraphQL query document node, the component will automatically configure the required columns with sorting & filtering functionality.

The automatic features can be further customized and enhanced using the many options available in the props.

Example

import { Money } from '@/vdb/components/data-display/money.js';
import { PaginatedListDataTable } from '@/vdb/components/shared/paginated-list-data-table.js';
import { Badge } from '@/vdb/components/ui/badge.js';
import { Button } from '@/vdb/components/ui/button.js';
import { Link } from '@tanstack/react-router';
import { ColumnFiltersState, SortingState } from '@tanstack/react-table';
import { useState } from 'react';
import { customerOrderListDocument } from '../customers.graphql.js';

interface CustomerOrderTableProps {
customerId: string;
}

export function CustomerOrderTable({ customerId }: Readonly<CustomerOrderTableProps>) {
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
const [sorting, setSorting] = useState<SortingState>([{ id: 'orderPlacedAt', desc: true }]);
const [filters, setFilters] = useState<ColumnFiltersState>([]);

return (
<PaginatedListDataTable
listQuery={customerOrderListDocument}
transformVariables={variables => {
return {
...variables,
customerId,
};
}}
defaultVisibility={{
id: false,
createdAt: false,
updatedAt: false,
type: false,
currencyCode: false,
total: false,
}}
customizeColumns={{
total: {
header: 'Total',
cell: ({ cell, row }) => {
const value = cell.getValue();
const currencyCode = row.original.currencyCode;
return <Money value={value} currency={currencyCode} />;
},
},
totalWithTax: {
header: 'Total with Tax',
cell: ({ cell, row }) => {
const value = cell.getValue();
const currencyCode = row.original.currencyCode;
return <Money value={value} currency={currencyCode} />;
},
},
state: {
header: 'State',
cell: ({ cell }) => {
const value = cell.getValue() as string;
return <Badge variant="outline">{value}</Badge>;
},
},
code: {
header: 'Code',
cell: ({ cell, row }) => {
const value = cell.getValue() as string;
const id = row.original.id;
return (
<Button asChild variant="ghost">
<Link to={`/orders/${id}`}>{value}</Link>
</Button>
);
},
},
}}
page={page}
itemsPerPage={pageSize}
sorting={sorting}
columnFilters={filters}
onPageChange={(_, page, perPage) => {
setPage(page);
setPageSize(perPage);
}}
onSortChange={(_, sorting) => {
setSorting(sorting);
}}
onFilterChange={(_, filters) => {
setFilters(filters);
}}
/>
);
}
Signature
function PaginatedListDataTable<T extends TypedDocumentNode<U, V>, U extends Record<string, any> = any, V extends ListQueryOptionsShape = any, AC extends AdditionalColumns<T> = AdditionalColumns<T>>(props: Readonly<PaginatedListDataTableProps<T, U, V, AC>>): void

Parameters

props

parameter
Readonly<PaginatedListDataTableProps<T, U, V, AC>>

PaginatedListDataTableProps

Props to configure the PaginatedListDataTable component.

Signature
interface PaginatedListDataTableProps<T extends TypedDocumentNode<U, V>, U extends ListQueryShape, V extends ListQueryOptionsShape, AC extends AdditionalColumns<T>> {
listQuery: T;
deleteMutation?: TypedDocumentNode<any, any>;
transformQueryKey?: (queryKey: any[]) => any[];
transformVariables?: (variables: V) => V;
customizeColumns?: CustomizeColumnConfig<T>;
additionalColumns?: AC;
defaultColumnOrder?: (keyof ListQueryFields<T> | keyof AC | CustomFieldKeysOfItem<ListQueryFields<T>>)[];
defaultVisibility?: Partial<Record<AllItemFieldKeys<T>, boolean>>;
onSearchTermChange?: (searchTerm: string) => NonNullable<V['options']>['filter'];
page: number;
itemsPerPage: number;
sorting: SortingState;
columnFilters?: ColumnFiltersState;
onPageChange: (table: Table<any>, page: number, perPage: number) => void;
onSortChange: (table: Table<any>, sorting: SortingState) => void;
onFilterChange: (table: Table<any>, filters: ColumnFiltersState) => void;
onColumnVisibilityChange?: (table: Table<any>, columnVisibility: VisibilityState) => void;
facetedFilters?: FacetedFilterConfig<T>;
rowActions?: RowAction<PaginatedListItemFields<T>>[];
bulkActions?: BulkAction[];
disableViewOptions?: boolean;
transformData?: (data: PaginatedListItemFields<T>[]) => PaginatedListItemFields<T>[];
setTableOptions?: (table: TableOptions<any>) => TableOptions<any>;
registerRefresher?: PaginatedListRefresherRegisterFn;
}

listQuery

property
T

deleteMutation

property
TypedDocumentNode<any, any>

transformQueryKey

property
(queryKey: any[]) => any[]

transformVariables

property
(variables: V) => V

customizeColumns

property
CustomizeColumnConfig<T>

additionalColumns

property
AC

defaultColumnOrder

property
(keyof ListQueryFields<T> | keyof AC | CustomFieldKeysOfItem<ListQueryFields<T>>)[]

defaultVisibility

property
Partial<Record<AllItemFieldKeys<T>, boolean>>

onSearchTermChange

property
(searchTerm: string) => NonNullable<V['options']>['filter']

page

property
number

itemsPerPage

property
number

sorting

property
SortingState

columnFilters

property
ColumnFiltersState

onPageChange

property
(table: Table<any>, page: number, perPage: number) => void

onSortChange

property
(table: Table<any>, sorting: SortingState) => void

onFilterChange

property
(table: Table<any>, filters: ColumnFiltersState) => void

onColumnVisibilityChange

property
(table: Table<any>, columnVisibility: VisibilityState) => void

facetedFilters

property
FacetedFilterConfig<T>

rowActions

property
RowAction<PaginatedListItemFields<T>>[]

bulkActions

property

disableViewOptions

property
boolean

transformData

property
(data: PaginatedListItemFields<T>[]) => PaginatedListItemFields<T>[]

setTableOptions

property
(table: TableOptions<any>) => TableOptions<any>

registerRefresher

property
PaginatedListRefresherRegisterFn