|
|
@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
|
|
|
|
|
|
## ListPage
|
|
|
|
|
|
-<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/page/list-page.tsx" sourceLine="165" packageName="@vendure/dashboard" since="3.3.0" />
|
|
|
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/page/list-page.tsx" sourceLine="452" packageName="@vendure/dashboard" since="3.3.0" />
|
|
|
|
|
|
Auto-generates a list page with columns generated based on the provided query document fields.
|
|
|
|
|
|
@@ -113,7 +113,7 @@ Parameters
|
|
|
|
|
|
## ListPageProps
|
|
|
|
|
|
-<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/page/list-page.tsx" sourceLine="31" packageName="@vendure/dashboard" since="3.3.0" />
|
|
|
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/page/list-page.tsx" sourceLine="30" packageName="@vendure/dashboard" since="3.3.0" />
|
|
|
|
|
|
Props to configure the <a href='/reference/dashboard/list-views/list-page#listpage'>ListPage</a> component.
|
|
|
|
|
|
@@ -149,22 +149,60 @@ interface ListPageProps<T extends TypedDocumentNode<U, V>, U extends ListQuerySh
|
|
|
|
|
|
<MemberInfo kind="property" type={`string`} />
|
|
|
|
|
|
-
|
|
|
+A unique identifier for the list page. This is important to support
|
|
|
+customization functionality that relies on page IDs and makes your
|
|
|
+component extensible.
|
|
|
### route
|
|
|
|
|
|
<MemberInfo kind="property" type={`AnyRoute | (() => AnyRoute)`} />
|
|
|
|
|
|
-
|
|
|
+* The Tanstack Router `Route` object, which will be defined in the component file.
|
|
|
### title
|
|
|
|
|
|
<MemberInfo kind="property" type={`string | React.ReactElement`} />
|
|
|
|
|
|
-
|
|
|
+* The page title, which will display in the header area.
|
|
|
### listQuery
|
|
|
|
|
|
<MemberInfo kind="property" type={`T`} />
|
|
|
|
|
|
+This DocumentNode of the list query, i.e. a query that fetches
|
|
|
+PaginatedList data with "items" and "totalItems", such as:
|
|
|
|
|
|
+*Example*
|
|
|
+
|
|
|
+```tsx
|
|
|
+export const collectionListDocument = graphql(`
|
|
|
+ query CollectionList($options: CollectionListOptions) {
|
|
|
+ collections(options: $options) {
|
|
|
+ items {
|
|
|
+ id
|
|
|
+ createdAt
|
|
|
+ updatedAt
|
|
|
+ name
|
|
|
+ slug
|
|
|
+ breadcrumbs {
|
|
|
+ id
|
|
|
+ name
|
|
|
+ slug
|
|
|
+ }
|
|
|
+ children {
|
|
|
+ id
|
|
|
+ name
|
|
|
+ }
|
|
|
+ # ... etc
|
|
|
+ }
|
|
|
+ totalItems
|
|
|
+ }
|
|
|
+ }
|
|
|
+`);
|
|
|
+// ...
|
|
|
+<ListPage
|
|
|
+ pageId="collection-list"
|
|
|
+ listQuery={collectionListDocument}
|
|
|
+ // ...
|
|
|
+/>
|
|
|
+```
|
|
|
### deleteMutation
|
|
|
|
|
|
<MemberInfo kind="property" type={`TypedDocumentNode<any, { id: string }>`} />
|
|
|
@@ -177,37 +215,179 @@ will be added to the action column dropdown already.
|
|
|
|
|
|
<MemberInfo kind="property" type={`(variables: V) => V`} />
|
|
|
|
|
|
+This prop can be used to intercept and transform the list query variables before they are
|
|
|
+sent to the Admin API.
|
|
|
+
|
|
|
+This allows you to implement specific logic that differs from the standard filter/sort
|
|
|
+handling.
|
|
|
+
|
|
|
+*Example*
|
|
|
|
|
|
+```tsx
|
|
|
+<ListPage
|
|
|
+ pageId="collection-list"
|
|
|
+ title="Collections"
|
|
|
+ listQuery={collectionListDocument}
|
|
|
+ transformVariables={input => {
|
|
|
+ const filterTerm = input.options?.filter?.name?.contains;
|
|
|
+ // If there is a filter term set
|
|
|
+ // we want to return all results. Else
|
|
|
+ // we only want top-level Collections
|
|
|
+ const isFiltering = !!filterTerm;
|
|
|
+ return {
|
|
|
+ options: {
|
|
|
+ ...input.options,
|
|
|
+ topLevelOnly: !isFiltering,
|
|
|
+ },
|
|
|
+ };
|
|
|
+ }}
|
|
|
+/>
|
|
|
+```
|
|
|
### onSearchTermChange
|
|
|
|
|
|
<MemberInfo kind="property" type={`(searchTerm: string) => NonNullable<V['options']>['filter']`} />
|
|
|
|
|
|
+Allows you to customize how the search term is used in the list query options.
|
|
|
+For instance, when you want the term to filter on specific fields.
|
|
|
+
|
|
|
+*Example*
|
|
|
|
|
|
+```tsx
|
|
|
+ <ListPage
|
|
|
+ pageId="administrator-list"
|
|
|
+ title="Administrators"
|
|
|
+ listQuery={administratorListDocument}
|
|
|
+ onSearchTermChange={searchTerm => {
|
|
|
+ return {
|
|
|
+ firstName: { contains: searchTerm },
|
|
|
+ lastName: { contains: searchTerm },
|
|
|
+ emailAddress: { contains: searchTerm },
|
|
|
+ };
|
|
|
+ }}
|
|
|
+ />
|
|
|
### customizeColumns
|
|
|
|
|
|
<MemberInfo kind="property" type={`CustomizeColumnConfig<T>`} />
|
|
|
|
|
|
+Allows you to customize the rendering and other aspects of individual columns.
|
|
|
+
|
|
|
+By default, an appropriate component will be chosen to render the column data
|
|
|
+based on the data type of the field. However, in many cases you want to have
|
|
|
+more control over how the column data is rendered.
|
|
|
|
|
|
+*Example*
|
|
|
+
|
|
|
+```tsx
|
|
|
+<ListPage
|
|
|
+ pageId="collection-list"
|
|
|
+ listQuery={collectionListDocument}
|
|
|
+ customizeColumns={{
|
|
|
+ // The key "name" matches one of the top-level fields of the
|
|
|
+ // list query type (Collection, in this example)
|
|
|
+ name: {
|
|
|
+ meta: {
|
|
|
+ // The Dashboard optimizes the list query `collectionListDocument` to
|
|
|
+ // only select field that are actually visible in the ListPage table.
|
|
|
+ // However, sometimes you want to render data from other fields, i.e.
|
|
|
+ // this column has a data dependency on the "children" and "breadcrumbs"
|
|
|
+ // fields in order to correctly render the "name" field.
|
|
|
+ // In this case, we can declare those data dependencies which means whenever
|
|
|
+ // the "name" column is visible, it will ensure the "children" and "breadcrumbs"
|
|
|
+ // fields are also selected in the query.
|
|
|
+ dependencies: ['children', 'breadcrumbs'],
|
|
|
+ },
|
|
|
+ header: 'Collection Name',
|
|
|
+ cell: ({ row }) => {
|
|
|
+ const isExpanded = row.getIsExpanded();
|
|
|
+ const hasChildren = !!row.original.children?.length;
|
|
|
+ return (
|
|
|
+ <div
|
|
|
+ style={{ marginLeft: (row.original.breadcrumbs?.length - 2) * 20 + 'px' }}
|
|
|
+ className="flex gap-2 items-center"
|
|
|
+ >
|
|
|
+ <Button
|
|
|
+ size="icon"
|
|
|
+ variant="secondary"
|
|
|
+ onClick={row.getToggleExpandedHandler()}
|
|
|
+ disabled={!hasChildren}
|
|
|
+ className={!hasChildren ? 'opacity-20' : ''}
|
|
|
+ >
|
|
|
+ {isExpanded ? <FolderOpen /> : <Folder />}
|
|
|
+ </Button>
|
|
|
+ <DetailPageButton id={row.original.id} label={row.original.name} />
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ },
|
|
|
+ },
|
|
|
+```
|
|
|
### additionalColumns
|
|
|
|
|
|
<MemberInfo kind="property" type={`AC`} />
|
|
|
|
|
|
+Allows you to define extra columns that are not related to actual fields returned in
|
|
|
+the query result.
|
|
|
+
|
|
|
+For example, in the Administrator list, we define an additional "name" column composed
|
|
|
+of the `firstName` and `lastName` fields.
|
|
|
+
|
|
|
+*Example*
|
|
|
|
|
|
+```tsx
|
|
|
+<ListPage
|
|
|
+ pageId="administrator-list"
|
|
|
+ title="Administrators"
|
|
|
+ listQuery={administratorListDocument}
|
|
|
+ additionalColumns={{
|
|
|
+ name: {
|
|
|
+ header: 'Name',
|
|
|
+ cell: ({ row }) => (
|
|
|
+ <DetailPageButton
|
|
|
+ id={row.original.id}
|
|
|
+ label={`${row.original.firstName} ${row.original.lastName}`}
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+/>
|
|
|
+```
|
|
|
### defaultColumnOrder
|
|
|
|
|
|
<MemberInfo kind="property" type={`(keyof ListQueryFields<T> | keyof AC | CustomFieldKeysOfItem<ListQueryFields<T>>)[]`} />
|
|
|
|
|
|
-
|
|
|
+Allows you to specify the default order of columns in the table. When not defined, the
|
|
|
+order of fields in the list query document will be used.
|
|
|
### defaultSort
|
|
|
|
|
|
<MemberInfo kind="property" type={`SortingState`} />
|
|
|
|
|
|
+Allows you to specify the default sorting applied to the table.
|
|
|
|
|
|
+*Example*
|
|
|
+
|
|
|
+```tsx
|
|
|
+defaultSort={[{ id: 'orderPlacedAt', desc: true }]}
|
|
|
+```
|
|
|
### defaultVisibility
|
|
|
|
|
|
<MemberInfo kind="property" type={`Partial< Record<keyof ListQueryFields<T> | keyof AC | CustomFieldKeysOfItem<ListQueryFields<T>>, boolean> >`} />
|
|
|
|
|
|
+Allows you to specify the default columns that are visible in the table.
|
|
|
+If you set them to `true`, then only those will show by default. If you set them to `false`,
|
|
|
+then _all other_ columns will be visible by default.
|
|
|
+
|
|
|
+*Example*
|
|
|
|
|
|
+```tsx
|
|
|
+ <ListPage
|
|
|
+ pageId="country-list"
|
|
|
+ listQuery={countriesListQuery}
|
|
|
+ title="Countries"
|
|
|
+ defaultVisibility={{
|
|
|
+ name: true,
|
|
|
+ code: true,
|
|
|
+ enabled: true,
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ ```
|
|
|
### children
|
|
|
|
|
|
<MemberInfo kind="property" type={`React.ReactNode`} />
|
|
|
@@ -217,27 +397,79 @@ will be added to the action column dropdown already.
|
|
|
|
|
|
<MemberInfo kind="property" type={`FacetedFilterConfig<T>`} />
|
|
|
|
|
|
+Allows you to define pre-set filters based on an array of possible selections
|
|
|
|
|
|
+*Example*
|
|
|
+
|
|
|
+```tsx
|
|
|
+<ListPage
|
|
|
+ pageId="payment-method-list"
|
|
|
+ listQuery={paymentMethodListQuery}
|
|
|
+ title="Payment Methods"
|
|
|
+ facetedFilters={{
|
|
|
+ enabled: {
|
|
|
+ title: 'Enabled',
|
|
|
+ options: [
|
|
|
+ { label: 'Enabled', value: true },
|
|
|
+ { label: 'Disabled', value: false },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ }}
|
|
|
+/>
|
|
|
+```
|
|
|
### rowActions
|
|
|
|
|
|
<MemberInfo kind="property" type={`RowAction<ListQueryFields<T>>[]`} />
|
|
|
|
|
|
-
|
|
|
+Allows you to specify additional "actions" that will be made available in the "actions" column.
|
|
|
+By default, the actions column includes all bulk actions defined in the `bulkActions` prop.
|
|
|
### transformData
|
|
|
|
|
|
<MemberInfo kind="property" type={`(data: any[]) => any[]`} />
|
|
|
|
|
|
-
|
|
|
+Allows the returned list query data to be transformed in some way. This is an advanced feature
|
|
|
+that is not often required.
|
|
|
### setTableOptions
|
|
|
|
|
|
<MemberInfo kind="property" type={`(table: TableOptions<any>) => TableOptions<any>`} />
|
|
|
|
|
|
-
|
|
|
+Allows you to directly manipulate the Tanstack Table `TableOptions` object before the
|
|
|
+table is created. And advanced option that is not often required.
|
|
|
### bulkActions
|
|
|
|
|
|
-<MemberInfo kind="property" type={`<a href='/reference/dashboard/list-views/data-table#bulkaction'>BulkAction</a>[]`} />
|
|
|
+<MemberInfo kind="property" type={`<a href='/reference/dashboard/list-views/bulk-actions#bulkaction'>BulkAction</a>[]`} />
|
|
|
|
|
|
+Bulk actions are actions that can be applied to one or more table rows, and include things like
|
|
|
|
|
|
+- Deleting the rows
|
|
|
+- Assigning the rows to another channel
|
|
|
+- Bulk editing some aspect of the rows
|
|
|
+
|
|
|
+See the <a href='/reference/dashboard/list-views/bulk-actions#bulkaction'>BulkAction</a> docs for an example of how to build the component.
|
|
|
+
|
|
|
+*Example*
|
|
|
+
|
|
|
+```tsx
|
|
|
+<ListPage
|
|
|
+ pageId="product-list"
|
|
|
+ listQuery={productListDocument}
|
|
|
+ title="Products"
|
|
|
+ bulkActions={[
|
|
|
+ {
|
|
|
+ component: AssignProductsToChannelBulkAction,
|
|
|
+ order: 100,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ component: RemoveProductsFromChannelBulkAction,
|
|
|
+ order: 200,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ component: DeleteProductsBulkAction,
|
|
|
+ order: 300,
|
|
|
+ },
|
|
|
+ ]}
|
|
|
+/>
|
|
|
+```
|
|
|
### registerRefresher
|
|
|
|
|
|
<MemberInfo kind="property" type={`PaginatedListRefresherRegisterFn`} />
|