Browse Source

docs(dashboard): Add list / table docs, generate docs

Michael Bromley 3 months ago
parent
commit
baecf1c62e
52 changed files with 1404 additions and 97 deletions
  1. 61 0
      docs/docs/reference/dashboard/form-components/slug-input.md
  2. 1 1
      docs/docs/reference/dashboard/hooks/use-paginated-list.md
  3. 196 0
      docs/docs/reference/dashboard/list-views/bulk-actions.md
  4. 5 38
      docs/docs/reference/dashboard/list-views/data-table.md
  5. 242 10
      docs/docs/reference/dashboard/list-views/list-page.md
  6. 3 3
      docs/docs/reference/dashboard/list-views/paginated-list-data-table.md
  7. 95 0
      docs/docs/reference/graphql-api/admin/input-types.md
  8. 52 0
      docs/docs/reference/graphql-api/admin/object-types.md
  9. 30 0
      docs/docs/reference/graphql-api/admin/queries.md
  10. 40 0
      docs/docs/reference/graphql-api/shop/object-types.md
  11. 1 1
      docs/docs/reference/typescript-api/assets/asset-options.md
  12. 1 1
      docs/docs/reference/typescript-api/auth/auth-options.md
  13. 1 1
      docs/docs/reference/typescript-api/auth/cookie-options.md
  14. 74 0
      docs/docs/reference/typescript-api/auth/permission-definition.md
  15. 1 1
      docs/docs/reference/typescript-api/auth/superadmin-credentials.md
  16. 1 1
      docs/docs/reference/typescript-api/common/currency-code.md
  17. 1 1
      docs/docs/reference/typescript-api/common/job-state.md
  18. 1 1
      docs/docs/reference/typescript-api/common/language-code.md
  19. 1 1
      docs/docs/reference/typescript-api/common/permission.md
  20. 1 1
      docs/docs/reference/typescript-api/configuration/api-options.md
  21. 1 1
      docs/docs/reference/typescript-api/configuration/default-config.md
  22. 50 0
      docs/docs/reference/typescript-api/configuration/default-slug-strategy.md
  23. 8 1
      docs/docs/reference/typescript-api/configuration/entity-options.md
  24. 1 1
      docs/docs/reference/typescript-api/configuration/runtime-vendure-config.md
  25. 1 1
      docs/docs/reference/typescript-api/configuration/settings-store-fields.md
  26. 51 0
      docs/docs/reference/typescript-api/configuration/slug-strategy.md
  27. 1 1
      docs/docs/reference/typescript-api/configuration/system-options.md
  28. 1 1
      docs/docs/reference/typescript-api/configuration/trust-proxy-options.md
  29. 1 1
      docs/docs/reference/typescript-api/configuration/vendure-config.md
  30. 1 1
      docs/docs/reference/typescript-api/import-export/import-export-options.md
  31. 1 1
      docs/docs/reference/typescript-api/job-queue/job-queue-options.md
  32. 1 1
      docs/docs/reference/typescript-api/orders/order-options.md
  33. 1 1
      docs/docs/reference/typescript-api/payment/payment-options.md
  34. 1 1
      docs/docs/reference/typescript-api/products-stock/catalog-options.md
  35. 1 1
      docs/docs/reference/typescript-api/promotions/promotion-options.md
  36. 1 1
      docs/docs/reference/typescript-api/scheduled-tasks/scheduler-options.md
  37. 41 0
      docs/docs/reference/typescript-api/services/entity-slug-service.md
  38. 7 7
      docs/docs/reference/typescript-api/services/product-option-service.md
  39. 12 0
      docs/docs/reference/typescript-api/services/settings-store-service.md
  40. 39 0
      docs/docs/reference/typescript-api/services/slug-service.md
  41. 1 1
      docs/docs/reference/typescript-api/settings-store/cleanup-orphaned-settings-store-entries-options.md
  42. 1 1
      docs/docs/reference/typescript-api/settings-store/cleanup-orphaned-settings-store-entries-result.md
  43. 1 1
      docs/docs/reference/typescript-api/settings-store/orphaned-settings-store-entry.md
  44. 1 1
      docs/docs/reference/typescript-api/settings-store/set-settings-store-value-result.md
  45. 32 2
      docs/docs/reference/typescript-api/settings-store/settings-store-field-config.md
  46. 1 1
      docs/docs/reference/typescript-api/settings-store/settings-store-registration.md
  47. 1 1
      docs/docs/reference/typescript-api/settings-store/settings-store-scopes.md
  48. 1 1
      docs/docs/reference/typescript-api/shipping/shipping-options.md
  49. 1 1
      docs/docs/reference/typescript-api/tax/tax-options.md
  50. 38 1
      packages/dashboard/src/lib/components/data-table/data-table-bulk-action-item.tsx
  51. 62 4
      packages/dashboard/src/lib/framework/extension-api/types/data-table.ts
  52. 235 0
      packages/dashboard/src/lib/framework/page/list-page.tsx

+ 61 - 0
docs/docs/reference/dashboard/form-components/slug-input.md

@@ -0,0 +1,61 @@
+---
+title: "SlugInput"
+isDefaultIndex: false
+generated: true
+---
+<!-- This file was generated from the Vendure source. Do not modify. Instead, re-run the "docs:build" script -->
+import MemberInfo from '@site/src/components/MemberInfo';
+import GenerationInfo from '@site/src/components/GenerationInfo';
+import MemberDescription from '@site/src/components/MemberDescription';
+
+
+## SlugInput
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/components/data-input/slug-input.tsx" sourceLine="137" packageName="@vendure/dashboard" />
+
+A component for generating and displaying slugs based on a watched field.
+The component watches a source field for changes, debounces the input,
+and generates a unique slug via the Admin API. The slug is only auto-generated
+when it's empty. For existing slugs, a regenerate button allows manual regeneration.
+The input is readonly by default but can be made editable with a toggle button.
+
+*Example*
+
+```tsx
+// In a TranslatableFormFieldWrapper context with translatable field
+<SlugInput
+    {...field}
+    entityName="Product"
+    fieldName="slug"
+    watchFieldName="name" // Automatically resolves to "translations.X.name"
+    entityId={productId}
+/>
+
+// In a TranslatableFormFieldWrapper context with non-translatable field
+<SlugInput
+    {...field}
+    entityName="Product"
+    fieldName="slug"
+    watchFieldName="enabled" // Uses "enabled" directly (base entity field)
+    entityId={productId}
+/>
+
+// For non-translatable entities
+<SlugInput
+    {...field}
+    entityName="Channel"
+    fieldName="code"
+    watchFieldName="name" // Uses "name" directly
+    entityId={channelId}
+/>
+```
+
+```ts title="Signature"
+function SlugInput(props: SlugInputProps): void
+```
+Parameters
+
+### props
+
+<MemberInfo kind="parameter" type={`SlugInputProps`} />
+

+ 1 - 1
docs/docs/reference/dashboard/hooks/use-paginated-list.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## usePaginatedList
 
-<GenerationInfo sourceFile="packages/dashboard/src/lib/components/shared/paginated-list-data-table.tsx" sourceLine="162" packageName="@vendure/dashboard" since="3.4.0" />
+<GenerationInfo sourceFile="packages/dashboard/src/lib/components/shared/paginated-list-data-table.tsx" sourceLine="175" packageName="@vendure/dashboard" since="3.4.0" />
 
 Returns the context for the paginated list data table. Must be used within a PaginatedListDataTable.
 

+ 196 - 0
docs/docs/reference/dashboard/list-views/bulk-actions.md

@@ -0,0 +1,196 @@
+---
+title: "Bulk Actions"
+isDefaultIndex: false
+generated: true
+---
+<!-- This file was generated from the Vendure source. Do not modify. Instead, re-run the "docs:build" script -->
+import MemberInfo from '@site/src/components/MemberInfo';
+import GenerationInfo from '@site/src/components/GenerationInfo';
+import MemberDescription from '@site/src/components/MemberDescription';
+
+
+## DataTableBulkActionItemProps
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/components/data-table/data-table-bulk-action-item.tsx" sourceLine="26" packageName="@vendure/dashboard" since="3.4.0" />
+
+
+
+```ts title="Signature"
+interface DataTableBulkActionItemProps {
+    label: React.ReactNode;
+    icon?: LucideIcon;
+    confirmationText?: React.ReactNode;
+    onClick: () => void;
+    className?: string;
+    requiresPermission?: string[];
+}
+```
+
+<div className="members-wrapper">
+
+### label
+
+<MemberInfo kind="property" type={`React.ReactNode`}   />
+
+
+### icon
+
+<MemberInfo kind="property" type={`LucideIcon`}   />
+
+
+### confirmationText
+
+<MemberInfo kind="property" type={`React.ReactNode`}   />
+
+
+### onClick
+
+<MemberInfo kind="property" type={`() =&#62; void`}   />
+
+
+### className
+
+<MemberInfo kind="property" type={`string`}   />
+
+
+### requiresPermission
+
+<MemberInfo kind="property" type={`string[]`}   />
+
+
+
+
+</div>
+
+
+## DataTableBulkActionItem
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/components/data-table/data-table-bulk-action-item.tsx" sourceLine="65" packageName="@vendure/dashboard" since="3.4.0" />
+
+A component that should be used to implement any bulk actions for list pages & data tables.
+
+*Example*
+
+```tsx
+import { DataTableBulkActionItem, Trans } from '@vendure/dashboard';
+import { Check } from 'lucide-react';
+
+export const MyBulkAction: BulkActionComponent<any> = ({ selection, table }) => {
+
+  return (
+    <DataTableBulkActionItem
+      requiresPermission={['ReadMyCustomEntity']}
+      onClick={() => {
+        console.log('Selected items:', selection);
+      }}
+      label={<Trans>Delete</Trans>}
+      confirmationText={<Trans>Are you sure?</Trans>}
+      icon={Check}
+      className="text-destructive"
+    />
+  );
+}
+```
+
+```ts title="Signature"
+function DataTableBulkActionItem(props: Readonly<DataTableBulkActionItemProps>): void
+```
+Parameters
+
+### props
+
+<MemberInfo kind="parameter" type={`Readonly&#60;<a href='/reference/dashboard/list-views/bulk-actions#datatablebulkactionitemprops'>DataTableBulkActionItemProps</a>&#62;`} />
+
+
+
+## BulkAction
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/extension-api/types/data-table.ts" sourceLine="104" packageName="@vendure/dashboard" since="3.4.0" />
+
+A bulk action is a component that will be rendered in the bulk actions dropdown.
+
+The component receives the following props:
+
+- `selection`: The selected row or rows
+- `table`: A reference to the Tanstack table instance powering the list
+
+The `table` object has
+
+*Example*
+
+```tsx
+import { BulkActionComponent, DataTableBulkActionItem, usePaginatedList } from '@vendure/dashboard';
+
+// This is an example of a bulk action that shows some typical
+// uses of the provided props
+export const MyBulkAction: BulkActionComponent<any> = ({ selection, table }) => {
+  const { refetchPaginatedList } = usePaginatedList();
+
+  const doTheAction = async () => {
+    // Actual logic of the action
+    // goes here...
+
+    // On success, we refresh the list
+    refetchPaginatedList();
+    // and un-select any selected rows in the table
+    table.resetRowSelection();
+  };
+
+ return (
+   <DataTableBulkActionItem
+     onClick={doTheAction}
+     label={<Trans>Delete</Trans>}
+     confirmationText={<Trans>Are you sure?</Trans>}
+     icon={Check}
+     className="text-destructive"
+   />
+ );
+}
+```
+
+For the common action of deletion, we provide a ready-made helper component:
+
+*Example*
+
+```tsx
+import { BulkActionComponent, DeleteProductsBulkAction } from '@vendure/dashboard';
+
+// Define the BulkAction component. This one uses
+// a built-in wrapper for "delete" actions, which includes
+// a confirmation dialog.
+export const DeleteProductsBulkAction: BulkActionComponent<any> = ({ selection, table }) => {
+    return (
+        <DeleteBulkAction
+            mutationDocument={deleteProductsDocument}
+            entityName="products"
+            requiredPermissions={['DeleteCatalog', 'DeleteProduct']}
+            selection={selection}
+            table={table}
+        />
+    );
+};
+```
+
+```ts title="Signature"
+type BulkAction = {
+    order?: number;
+    component: BulkActionComponent<any>;
+}
+```
+
+<div className="members-wrapper">
+
+### order
+
+<MemberInfo kind="property" type={`number`}   />
+
+Optional order number to control the position of this bulk action in the dropdown.
+A larger number will appear lower in the list.
+### component
+
+<MemberInfo kind="property" type={`BulkActionComponent&#60;any&#62;`}   />
+
+The React component that will be rendered as the bulk action item.
+
+
+</div>

+ 5 - 38
docs/docs/reference/dashboard/list-views/data-table.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## DataTable
 
-<GenerationInfo sourceFile="packages/dashboard/src/lib/components/data-table/data-table.tsx" sourceLine="85" packageName="@vendure/dashboard" since="3.4.0" />
+<GenerationInfo sourceFile="packages/dashboard/src/lib/components/data-table/data-table.tsx" sourceLine="93" packageName="@vendure/dashboard" since="3.4.0" />
 
 A data table which includes sorting, filtering, pagination, bulk actions, column controls etc.
 
@@ -30,7 +30,7 @@ Parameters
 
 ## DataTableProps
 
-<GenerationInfo sourceFile="packages/dashboard/src/lib/components/data-table/data-table.tsx" sourceLine="46" packageName="@vendure/dashboard" since="3.4.0" />
+<GenerationInfo sourceFile="packages/dashboard/src/lib/components/data-table/data-table.tsx" sourceLine="54" packageName="@vendure/dashboard" since="3.4.0" />
 
 Props for configuring the <a href='/reference/dashboard/list-views/data-table#datatable'>DataTable</a>.
 
@@ -148,7 +148,7 @@ interface DataTableProps<TData> {
 
 ### 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>[]`}   />
 
 
 ### setTableOptions
@@ -199,42 +199,9 @@ It should accept `value` and other standard display props.
 </div>
 
 
-## BulkAction
-
-<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/extension-api/types/data-table.ts" sourceLine="46" packageName="@vendure/dashboard" since="3.4.0" />
-
-**Status: Developer Preview**
-
-A bulk action is a component that will be rendered in the bulk actions dropdown.
-
-```ts title="Signature"
-type BulkAction = {
-    order?: number;
-    component: BulkActionComponent<any>;
-}
-```
-
-<div className="members-wrapper">
-
-### order
-
-<MemberInfo kind="property" type={`number`}   />
-
-Optional order number to control the position of this bulk action in the dropdown.
-A larger number will appear lower in the list.
-### component
-
-<MemberInfo kind="property" type={`BulkActionComponent&#60;any&#62;`}   />
-
-The React component that will be rendered as the bulk action item.
-
-
-</div>
-
-
 ## DashboardDataTableExtensionDefinition
 
-<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/extension-api/types/data-table.ts" sourceLine="68" packageName="@vendure/dashboard" since="3.4.0" />
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/extension-api/types/data-table.ts" sourceLine="126" packageName="@vendure/dashboard" since="3.4.0" />
 
 This allows you to customize aspects of existing data tables in the dashboard.
 
@@ -264,7 +231,7 @@ for the standard list pages. However, some other pages may use a different block
 such as `'product-variants-table'` on the `'product-detail'` page.
 ### 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>[]`}   />
 
 An array of additional bulk actions that will be available on the data table.
 ### extendListDocument

+ 242 - 10
docs/docs/reference/dashboard/list-views/list-page.md

@@ -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 | (() =&#62; 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&#60;any, { id: string }&#62;`}   />
@@ -177,37 +215,179 @@ will be added to the action column dropdown already.
 
 <MemberInfo kind="property" type={`(variables: V) =&#62; 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) =&#62; NonNullable&#60;V['options']&#62;['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&#60;T&#62;`}   />
 
+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&#60;T&#62; | keyof AC | CustomFieldKeysOfItem&#60;ListQueryFields&#60;T&#62;&#62;)[]`}   />
 
-
+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&#60;         Record&#60;keyof ListQueryFields&#60;T&#62; | keyof AC | CustomFieldKeysOfItem&#60;ListQueryFields&#60;T&#62;&#62;, boolean&#62;     &#62;`}   />
 
+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&#60;T&#62;`}   />
 
+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&#60;ListQueryFields&#60;T&#62;&#62;[]`}   />
 
-
+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[]) =&#62; 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&#60;any&#62;) =&#62; TableOptions&#60;any&#62;`}   />
 
-
+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`}   />

+ 3 - 3
docs/docs/reference/dashboard/list-views/paginated-list-data-table.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## PaginatedListDataTable
 
-<GenerationInfo sourceFile="packages/dashboard/src/lib/components/shared/paginated-list-data-table.tsx" sourceLine="334" packageName="@vendure/dashboard" since="3.4.0" />
+<GenerationInfo sourceFile="packages/dashboard/src/lib/components/shared/paginated-list-data-table.tsx" sourceLine="347" packageName="@vendure/dashboard" since="3.4.0" />
 
 A wrapper around the <a href='/reference/dashboard/list-views/data-table#datatable'>DataTable</a> component, which automatically configures functionality common to
 list queries that implement the `PaginatedList` interface, which is the common way of representing lists
@@ -130,7 +130,7 @@ Parameters
 
 ## PaginatedListDataTableProps
 
-<GenerationInfo sourceFile="packages/dashboard/src/lib/components/shared/paginated-list-data-table.tsx" sourceLine="185" packageName="@vendure/dashboard" since="3.4.0" />
+<GenerationInfo sourceFile="packages/dashboard/src/lib/components/shared/paginated-list-data-table.tsx" sourceLine="198" packageName="@vendure/dashboard" since="3.4.0" />
 
 Props to configure the <a href='/reference/dashboard/list-views/paginated-list-data-table#paginatedlistdatatable'>PaginatedListDataTable</a> component.
 
@@ -262,7 +262,7 @@ interface PaginatedListDataTableProps<T extends TypedDocumentNode<U, V>, U exten
 
 ### 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>[]`}   />
 
 
 ### disableViewOptions

+ 95 - 0
docs/docs/reference/graphql-api/admin/input-types.md

@@ -2494,6 +2494,32 @@ import MemberDescription from '@site/src/components/MemberDescription';
 <div class="graphql-code-line ">filterOperator: <a href="/reference/graphql-api/admin/enums#logicaloperator">LogicalOperator</a></div>
 
 
+<div class="graphql-code-line top-level">&#125;</div>
+</div>
+
+## ProductOptionFilterParameter
+
+<div class="graphql-code-block">
+<div class="graphql-code-line top-level">input <span class="graphql-code-identifier">ProductOptionFilterParameter</span> &#123;</div>
+<div class="graphql-code-line ">id: <a href="/reference/graphql-api/admin/input-types#idoperators">IDOperators</a></div>
+
+<div class="graphql-code-line ">createdAt: <a href="/reference/graphql-api/admin/input-types#dateoperators">DateOperators</a></div>
+
+<div class="graphql-code-line ">updatedAt: <a href="/reference/graphql-api/admin/input-types#dateoperators">DateOperators</a></div>
+
+<div class="graphql-code-line ">languageCode: <a href="/reference/graphql-api/admin/input-types#stringoperators">StringOperators</a></div>
+
+<div class="graphql-code-line ">code: <a href="/reference/graphql-api/admin/input-types#stringoperators">StringOperators</a></div>
+
+<div class="graphql-code-line ">name: <a href="/reference/graphql-api/admin/input-types#stringoperators">StringOperators</a></div>
+
+<div class="graphql-code-line ">groupId: <a href="/reference/graphql-api/admin/input-types#idoperators">IDOperators</a></div>
+
+<div class="graphql-code-line ">_and: [<a href="/reference/graphql-api/admin/input-types#productoptionfilterparameter">ProductOptionFilterParameter</a>!]</div>
+
+<div class="graphql-code-line ">_or: [<a href="/reference/graphql-api/admin/input-types#productoptionfilterparameter">ProductOptionFilterParameter</a>!]</div>
+
+
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 
@@ -2510,6 +2536,59 @@ import MemberDescription from '@site/src/components/MemberDescription';
 <div class="graphql-code-line ">customFields: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
 
 
+<div class="graphql-code-line top-level">&#125;</div>
+</div>
+
+## ProductOptionListOptions
+
+<div class="graphql-code-block">
+<div class="graphql-code-line top-level">input <span class="graphql-code-identifier">ProductOptionListOptions</span> &#123;</div>
+<div class="graphql-code-line comment">"""</div>
+<div class="graphql-code-line comment">Skips the first n results, for use in pagination</div>
+<div class="graphql-code-line comment">"""</div>
+<div class="graphql-code-line ">skip: <a href="/reference/graphql-api/admin/object-types#int">Int</a></div>
+
+<div class="graphql-code-line comment">"""</div>
+<div class="graphql-code-line comment">Takes n results, for use in pagination</div>
+<div class="graphql-code-line comment">"""</div>
+<div class="graphql-code-line ">take: <a href="/reference/graphql-api/admin/object-types#int">Int</a></div>
+
+<div class="graphql-code-line comment">"""</div>
+<div class="graphql-code-line comment">Specifies which properties to sort the results by</div>
+<div class="graphql-code-line comment">"""</div>
+<div class="graphql-code-line ">sort: <a href="/reference/graphql-api/admin/input-types#productoptionsortparameter">ProductOptionSortParameter</a></div>
+
+<div class="graphql-code-line comment">"""</div>
+<div class="graphql-code-line comment">Allows the results to be filtered</div>
+<div class="graphql-code-line comment">"""</div>
+<div class="graphql-code-line ">filter: <a href="/reference/graphql-api/admin/input-types#productoptionfilterparameter">ProductOptionFilterParameter</a></div>
+
+<div class="graphql-code-line comment">"""</div>
+<div class="graphql-code-line comment">Specifies whether multiple top-level "filter" fields should be combined with a logical AND or OR operation. Defaults to AND.</div>
+<div class="graphql-code-line comment">"""</div>
+<div class="graphql-code-line ">filterOperator: <a href="/reference/graphql-api/admin/enums#logicaloperator">LogicalOperator</a></div>
+
+
+<div class="graphql-code-line top-level">&#125;</div>
+</div>
+
+## ProductOptionSortParameter
+
+<div class="graphql-code-block">
+<div class="graphql-code-line top-level">input <span class="graphql-code-identifier">ProductOptionSortParameter</span> &#123;</div>
+<div class="graphql-code-line ">id: <a href="/reference/graphql-api/admin/enums#sortorder">SortOrder</a></div>
+
+<div class="graphql-code-line ">createdAt: <a href="/reference/graphql-api/admin/enums#sortorder">SortOrder</a></div>
+
+<div class="graphql-code-line ">updatedAt: <a href="/reference/graphql-api/admin/enums#sortorder">SortOrder</a></div>
+
+<div class="graphql-code-line ">code: <a href="/reference/graphql-api/admin/enums#sortorder">SortOrder</a></div>
+
+<div class="graphql-code-line ">name: <a href="/reference/graphql-api/admin/enums#sortorder">SortOrder</a></div>
+
+<div class="graphql-code-line ">groupId: <a href="/reference/graphql-api/admin/enums#sortorder">SortOrder</a></div>
+
+
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 
@@ -3353,6 +3432,22 @@ import MemberDescription from '@site/src/components/MemberDescription';
 <div class="graphql-code-line ">customFields: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
 
 
+<div class="graphql-code-line top-level">&#125;</div>
+</div>
+
+## SlugForEntityInput
+
+<div class="graphql-code-block">
+<div class="graphql-code-line top-level">input <span class="graphql-code-identifier">SlugForEntityInput</span> &#123;</div>
+<div class="graphql-code-line ">entityName: <a href="/reference/graphql-api/admin/object-types#string">String</a>!</div>
+
+<div class="graphql-code-line ">fieldName: <a href="/reference/graphql-api/admin/object-types#string">String</a>!</div>
+
+<div class="graphql-code-line ">inputValue: <a href="/reference/graphql-api/admin/object-types#string">String</a>!</div>
+
+<div class="graphql-code-line ">entityId: <a href="/reference/graphql-api/admin/object-types#id">ID</a></div>
+
+
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 

+ 52 - 0
docs/docs/reference/graphql-api/admin/object-types.md

@@ -266,6 +266,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/admin/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/admin/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/admin/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">ui: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
 
 
@@ -1019,6 +1023,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/admin/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/admin/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/admin/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">min: <a href="/reference/graphql-api/admin/object-types#string">String</a></div>
 
 <div class="graphql-code-line ">max: <a href="/reference/graphql-api/admin/object-types#string">String</a></div>
@@ -1370,6 +1378,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/admin/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/admin/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/admin/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">min: <a href="/reference/graphql-api/admin/object-types#float">Float</a></div>
 
 <div class="graphql-code-line ">max: <a href="/reference/graphql-api/admin/object-types#float">Float</a></div>
@@ -1663,6 +1675,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/admin/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/admin/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/admin/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">min: <a href="/reference/graphql-api/admin/object-types#int">Int</a></div>
 
 <div class="graphql-code-line ">max: <a href="/reference/graphql-api/admin/object-types#int">Int</a></div>
@@ -1870,6 +1886,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/admin/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/admin/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/admin/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">pattern: <a href="/reference/graphql-api/admin/object-types#string">String</a></div>
 
 <div class="graphql-code-line ">ui: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
@@ -1900,6 +1920,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/admin/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/admin/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/admin/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">ui: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
 
 
@@ -2932,6 +2956,18 @@ import MemberDescription from '@site/src/components/MemberDescription';
 <div class="graphql-code-line ">productVariantCount: <a href="/reference/graphql-api/admin/object-types#int">Int</a>!</div>
 
 
+<div class="graphql-code-line top-level">&#125;</div>
+</div>
+
+## ProductOptionList
+
+<div class="graphql-code-block">
+<div class="graphql-code-line top-level">type <span class="graphql-code-identifier">ProductOptionList</span> &#123;</div>
+<div class="graphql-code-line ">totalItems: <a href="/reference/graphql-api/admin/object-types#int">Int</a>!</div>
+
+<div class="graphql-code-line ">items: [<a href="/reference/graphql-api/admin/object-types#productoption">ProductOption</a>!]!</div>
+
+
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 
@@ -3391,6 +3427,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/admin/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/admin/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/admin/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">entity: <a href="/reference/graphql-api/admin/object-types#string">String</a>!</div>
 
 <div class="graphql-code-line ">scalarFields: [<a href="/reference/graphql-api/admin/object-types#string">String</a>!]!</div>
@@ -4023,6 +4063,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/admin/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/admin/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/admin/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">pattern: <a href="/reference/graphql-api/admin/object-types#string">String</a></div>
 
 <div class="graphql-code-line ">options: [<a href="/reference/graphql-api/admin/object-types#stringfieldoption">StringFieldOption</a>!]</div>
@@ -4095,6 +4139,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/admin/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/admin/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/admin/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">ui: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
 
 
@@ -4307,6 +4355,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/admin/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/admin/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/admin/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">ui: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
 
 

+ 30 - 0
docs/docs/reference/graphql-api/admin/queries.md

@@ -424,6 +424,15 @@ import MemberDescription from '@site/src/components/MemberDescription';
 <div class="graphql-code-line ">product(id: <a href="/reference/graphql-api/admin/object-types#id">ID</a>, slug: <a href="/reference/graphql-api/admin/object-types#string">String</a>): <a href="/reference/graphql-api/admin/object-types#product">Product</a></div>
 
 
+<div class="graphql-code-line top-level">&#125;</div>
+</div>
+
+## productOption
+<div class="graphql-code-block">
+<div class="graphql-code-line top-level">type <span class="graphql-code-identifier">Query</span> &#123;</div>
+<div class="graphql-code-line ">productOption(id: <a href="/reference/graphql-api/admin/object-types#id">ID</a>!): <a href="/reference/graphql-api/admin/object-types#productoption">ProductOption</a></div>
+
+
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 
@@ -442,6 +451,15 @@ import MemberDescription from '@site/src/components/MemberDescription';
 <div class="graphql-code-line ">productOptionGroups(filterTerm: <a href="/reference/graphql-api/admin/object-types#string">String</a>): [<a href="/reference/graphql-api/admin/object-types#productoptiongroup">ProductOptionGroup</a>!]!</div>
 
 
+<div class="graphql-code-line top-level">&#125;</div>
+</div>
+
+## productOptions
+<div class="graphql-code-block">
+<div class="graphql-code-line top-level">type <span class="graphql-code-identifier">Query</span> &#123;</div>
+<div class="graphql-code-line ">productOptions(options: <a href="/reference/graphql-api/admin/input-types#productoptionlistoptions">ProductOptionListOptions</a>, groupId: <a href="/reference/graphql-api/admin/object-types#id">ID</a>): <a href="/reference/graphql-api/admin/object-types#productoptionlist">ProductOptionList</a>!</div>
+
+
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 
@@ -622,6 +640,18 @@ import MemberDescription from '@site/src/components/MemberDescription';
 <div class="graphql-code-line ">shippingMethods(options: <a href="/reference/graphql-api/admin/input-types#shippingmethodlistoptions">ShippingMethodListOptions</a>): <a href="/reference/graphql-api/admin/object-types#shippingmethodlist">ShippingMethodList</a>!</div>
 
 
+<div class="graphql-code-line top-level">&#125;</div>
+</div>
+
+## slugForEntity
+<div class="graphql-code-block">
+<div class="graphql-code-line top-level comment">"""</div>
+<div class="graphql-code-line top-level comment">Generate slug for entity</div>
+<div class="graphql-code-line top-level comment">"""</div>
+<div class="graphql-code-line top-level">type <span class="graphql-code-identifier">Query</span> &#123;</div>
+<div class="graphql-code-line ">slugForEntity(input: <a href="/reference/graphql-api/admin/input-types#slugforentityinput">SlugForEntityInput</a>!): <a href="/reference/graphql-api/admin/object-types#string">String</a>!</div>
+
+
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 

+ 40 - 0
docs/docs/reference/graphql-api/shop/object-types.md

@@ -204,6 +204,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/shop/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/shop/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/shop/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">ui: <a href="/reference/graphql-api/shop/object-types#json">JSON</a></div>
 
 
@@ -704,6 +708,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/shop/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/shop/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/shop/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">min: <a href="/reference/graphql-api/shop/object-types#string">String</a></div>
 
 <div class="graphql-code-line ">max: <a href="/reference/graphql-api/shop/object-types#string">String</a></div>
@@ -959,6 +967,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/shop/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/shop/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/shop/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">min: <a href="/reference/graphql-api/shop/object-types#float">Float</a></div>
 
 <div class="graphql-code-line ">max: <a href="/reference/graphql-api/shop/object-types#float">Float</a></div>
@@ -1215,6 +1227,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/shop/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/shop/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/shop/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">min: <a href="/reference/graphql-api/shop/object-types#int">Int</a></div>
 
 <div class="graphql-code-line ">max: <a href="/reference/graphql-api/shop/object-types#int">Int</a></div>
@@ -1303,6 +1319,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/shop/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/shop/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/shop/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">pattern: <a href="/reference/graphql-api/shop/object-types#string">String</a></div>
 
 <div class="graphql-code-line ">ui: <a href="/reference/graphql-api/shop/object-types#json">JSON</a></div>
@@ -1333,6 +1353,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/shop/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/shop/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/shop/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">ui: <a href="/reference/graphql-api/shop/object-types#json">JSON</a></div>
 
 
@@ -2585,6 +2609,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/shop/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/shop/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/shop/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">entity: <a href="/reference/graphql-api/shop/object-types#string">String</a>!</div>
 
 <div class="graphql-code-line ">scalarFields: [<a href="/reference/graphql-api/shop/object-types#string">String</a>!]!</div>
@@ -2946,6 +2974,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/shop/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/shop/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/shop/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">pattern: <a href="/reference/graphql-api/shop/object-types#string">String</a></div>
 
 <div class="graphql-code-line ">options: [<a href="/reference/graphql-api/shop/object-types#stringfieldoption">StringFieldOption</a>!]</div>
@@ -3018,6 +3050,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/shop/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/shop/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/shop/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">ui: <a href="/reference/graphql-api/shop/object-types#json">JSON</a></div>
 
 
@@ -3192,6 +3228,10 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <div class="graphql-code-line ">requiresPermission: [<a href="/reference/graphql-api/shop/enums#permission">Permission</a>!]</div>
 
+<div class="graphql-code-line ">deprecated: <a href="/reference/graphql-api/shop/object-types#boolean">Boolean</a></div>
+
+<div class="graphql-code-line ">deprecationReason: <a href="/reference/graphql-api/shop/object-types#string">String</a></div>
+
 <div class="graphql-code-line ">ui: <a href="/reference/graphql-api/shop/object-types#json">JSON</a></div>
 
 

+ 1 - 1
docs/docs/reference/typescript-api/assets/asset-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## AssetOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="674" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="675" packageName="@vendure/core" />
 
 The AssetOptions define how assets (images and other files) are named and stored, and how preview images are generated.
 

+ 1 - 1
docs/docs/reference/typescript-api/auth/auth-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## AuthOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="359" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="360" packageName="@vendure/core" />
 
 The AuthOptions define how authentication and authorization is managed.
 

+ 1 - 1
docs/docs/reference/typescript-api/auth/cookie-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## CookieOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="254" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="255" packageName="@vendure/core" />
 
 Options for the handling of the cookies used to track sessions (only applicable if
 `authOptions.tokenMethod` is set to `'cookie'`). These options are passed directly

+ 74 - 0
docs/docs/reference/typescript-api/auth/permission-definition.md

@@ -154,6 +154,80 @@ Returns the 'Delete' CRUD permission defined by this definition, for use in the
 </div>
 
 
+## RwPermissionDefinition
+
+<GenerationInfo sourceFile="packages/core/src/common/permission-definition.ts" sourceLine="245" packageName="@vendure/core" since="3.5.0" />
+
+Defines a set of Read-Write Permissions for the given name, i.e. a `name` of 'DashboardSavedViews' will create
+2 Permissions: 'ReadDashboardSavedViews' and 'WriteDashboardSavedViews'.
+
+*Example*
+
+```ts
+export const dashboardSavedViews = new RwPermissionDefinition('DashboardSavedViews');
+```
+
+```ts
+const config: VendureConfig = {
+  authOptions: {
+    customPermissions: [dashboardSavedViews],
+  },
+}
+```
+
+```ts
+@Resolver()
+export class DashboardResolver {
+
+  @Allow(dashboardSavedViews.Read)
+  @Query()
+  getDashboardSavedViews() {
+    // ...
+  }
+
+  @Allow(dashboardSavedViews.Write)
+  @Mutation()
+  saveDashboardView() {
+    // ...
+  }
+}
+```
+
+```ts title="Signature"
+class RwPermissionDefinition extends PermissionDefinition {
+    constructor(name: string, descriptionFn?: (operation: 'read' | 'write') => string)
+    Read: Permission
+    Write: Permission
+}
+```
+* Extends: <code><a href='/reference/typescript-api/auth/permission-definition#permissiondefinition'>PermissionDefinition</a></code>
+
+
+
+<div className="members-wrapper">
+
+### constructor
+
+<MemberInfo kind="method" type={`(name: string, descriptionFn?: (operation: 'read' | 'write') =&#62; string) => RwPermissionDefinition`}   />
+
+
+### Read
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/common/permission#permission'>Permission</a>`}   />
+
+Returns the 'Read' permission defined by this definition, for use in the
+<a href='/reference/typescript-api/request/allow-decorator#allow'>Allow</a> decorator.
+### Write
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/common/permission#permission'>Permission</a>`}   />
+
+Returns the 'Write' permission defined by this definition, for use in the
+<a href='/reference/typescript-api/request/allow-decorator#allow'>Allow</a> decorator.
+
+
+</div>
+
+
 ## PermissionDefinitionConfig
 
 <GenerationInfo sourceFile="packages/core/src/common/permission-definition.ts" sourceLine="10" packageName="@vendure/core" />

+ 1 - 1
docs/docs/reference/typescript-api/auth/superadmin-credentials.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## SuperadminCredentials
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="850" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="851" packageName="@vendure/core" />
 
 These credentials will be used to create the Superadmin user & administrator
 when Vendure first bootstraps.

+ 1 - 1
docs/docs/reference/typescript-api/common/currency-code.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## CurrencyCode
 
-<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="1002" packageName="@vendure/common" />
+<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="1004" packageName="@vendure/common" />
 
 ISO 4217 currency code
 

+ 1 - 1
docs/docs/reference/typescript-api/common/job-state.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## JobState
 
-<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="2246" packageName="@vendure/common" />
+<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="2256" packageName="@vendure/common" />
 
 The state of a Job in the JobQueue
 

+ 1 - 1
docs/docs/reference/typescript-api/common/language-code.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## LanguageCode
 
-<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="2264" packageName="@vendure/common" />
+<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="2274" packageName="@vendure/common" />
 
 Languages in the form of a ISO 639-1 language code with optional
 region or script modifier (e.g. de_AT). The selection available is based

+ 1 - 1
docs/docs/reference/typescript-api/common/permission.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## Permission
 
-<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="4477" packageName="@vendure/common" />
+<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="4491" packageName="@vendure/common" />
 
 Permissions for administrators and customers. Used to control access to
 GraphQL resolvers via the <a href='/reference/typescript-api/request/allow-decorator#allow'>Allow</a> decorator.

+ 1 - 1
docs/docs/reference/typescript-api/configuration/api-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ApiOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="75" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="76" packageName="@vendure/core" />
 
 The ApiOptions define how the Vendure GraphQL APIs are exposed, as well as allowing the API layer
 to be extended with middleware.

+ 1 - 1
docs/docs/reference/typescript-api/configuration/default-config.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## defaultConfig
 
-<GenerationInfo sourceFile="packages/core/src/config/default-config.ts" sourceLine="68" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/default-config.ts" sourceLine="69" packageName="@vendure/core" />
 
 The default configuration settings which are used if not explicitly overridden in the bootstrap() call.
 

+ 50 - 0
docs/docs/reference/typescript-api/configuration/default-slug-strategy.md

@@ -0,0 +1,50 @@
+---
+title: "DefaultSlugStrategy"
+isDefaultIndex: false
+generated: true
+---
+<!-- This file was generated from the Vendure source. Do not modify. Instead, re-run the "docs:build" script -->
+import MemberInfo from '@site/src/components/MemberInfo';
+import GenerationInfo from '@site/src/components/GenerationInfo';
+import MemberDescription from '@site/src/components/MemberDescription';
+
+
+## DefaultSlugStrategy
+
+<GenerationInfo sourceFile="packages/core/src/config/entity/default-slug-strategy.ts" sourceLine="25" packageName="@vendure/core" since="3.5.0" />
+
+The default strategy for generating slugs. This strategy:
+- Converts to lowercase
+- Replaces spaces and special characters with hyphens
+- Removes non-alphanumeric characters (except hyphens)
+- Removes leading and trailing hyphens
+- Collapses multiple hyphens into one
+
+*Example*
+
+```ts
+const strategy = new DefaultSlugStrategy();
+strategy.generate(ctx, { value: "Hello World!" }); // "hello-world"
+strategy.generate(ctx, { value: "Café Français" }); // "cafe-francais"
+strategy.generate(ctx, { value: "100% Natural" }); // "100-natural"
+```
+
+```ts title="Signature"
+class DefaultSlugStrategy implements SlugStrategy {
+    generate(ctx: RequestContext, params: SlugGenerateParams) => string;
+}
+```
+* Implements: <code><a href='/reference/typescript-api/configuration/slug-strategy#slugstrategy'>SlugStrategy</a></code>
+
+
+
+<div className="members-wrapper">
+
+### generate
+
+<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, params: SlugGenerateParams) => string`}   />
+
+
+
+
+</div>

+ 8 - 1
docs/docs/reference/typescript-api/configuration/entity-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## EntityOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="1035" packageName="@vendure/core" since="1.3.0" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="1036" packageName="@vendure/core" since="1.3.0" />
 
 Options relating to the internal handling of entities.
 
@@ -24,6 +24,7 @@ interface EntityOptions {
     zoneCacheTtl?: number;
     taxRateCacheTtl?: number;
     metadataModifiers?: EntityMetadataModifier[];
+    slugStrategy?: SlugStrategy;
 }
 ```
 
@@ -87,6 +88,12 @@ Allows the metadata of the built-in TypeORM entities to be manipulated. This all
 to do things like altering data types, adding indices etc. This is an advanced feature
 which should be used with some caution as it will result in DB schema changes. For examples
 see <a href='/reference/typescript-api/configuration/entity-options#entitymetadatamodifier'>EntityMetadataModifier</a>.
+### slugStrategy
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/configuration/slug-strategy#slugstrategy'>SlugStrategy</a>`} default={`<a href='/reference/typescript-api/configuration/default-slug-strategy#defaultslugstrategy'>DefaultSlugStrategy</a>`}  since="3.5.0"  />
+
+Defines the strategy for generating slugs from input strings.
+Slugs are URL-friendly versions of text commonly used for entity identifiers in URLs.
 
 
 </div>

+ 1 - 1
docs/docs/reference/typescript-api/configuration/runtime-vendure-config.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## RuntimeVendureConfig
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="1309" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="1319" packageName="@vendure/core" />
 
 This interface represents the VendureConfig object available at run-time, i.e. the user-supplied
 config values have been merged with the <a href='/reference/typescript-api/configuration/default-config#defaultconfig'>defaultConfig</a> values.

+ 1 - 1
docs/docs/reference/typescript-api/configuration/settings-store-fields.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## SettingsStoreFields
 
-<GenerationInfo sourceFile="packages/core/src/config/settings-store/settings-store-types.ts" sourceLine="111" packageName="@vendure/core" since="3.4.0" />
+<GenerationInfo sourceFile="packages/core/src/config/settings-store/settings-store-types.ts" sourceLine="141" packageName="@vendure/core" since="3.4.0" />
 
 This is how SettingsStoreFields are defined in the <a href='/reference/typescript-api/configuration/vendure-config#vendureconfig'>VendureConfig</a> object.
 

+ 51 - 0
docs/docs/reference/typescript-api/configuration/slug-strategy.md

@@ -0,0 +1,51 @@
+---
+title: "SlugStrategy"
+isDefaultIndex: false
+generated: true
+---
+<!-- This file was generated from the Vendure source. Do not modify. Instead, re-run the "docs:build" script -->
+import MemberInfo from '@site/src/components/MemberInfo';
+import GenerationInfo from '@site/src/components/GenerationInfo';
+import MemberDescription from '@site/src/components/MemberDescription';
+
+
+## SlugStrategy
+
+<GenerationInfo sourceFile="packages/core/src/config/entity/slug-strategy.ts" sourceLine="44" packageName="@vendure/core" since="3.5.0" />
+
+Defines the strategy for generating slugs from input strings.
+Slugs are URL-friendly versions of text that are commonly used for
+entity identifiers in URLs.
+
+*Example*
+
+```ts
+export class CustomSlugStrategy implements SlugStrategy {
+  generate(ctx: RequestContext, params: SlugGenerateParams): string {
+    return params.value
+      .toLowerCase()
+      .replace(/[^a-z0-9]+/g, '-')
+      .replace(/^-+|-+$/g, '');
+  }
+}
+```
+
+```ts title="Signature"
+interface SlugStrategy extends InjectableStrategy {
+    generate(ctx: RequestContext, params: SlugGenerateParams): string | Promise<string>;
+}
+```
+* Extends: <code><a href='/reference/typescript-api/common/injectable-strategy#injectablestrategy'>InjectableStrategy</a></code>
+
+
+
+<div className="members-wrapper">
+
+### generate
+
+<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, params: SlugGenerateParams) => string | Promise&#60;string&#62;`}   />
+
+Generates a slug from the input string.
+
+
+</div>

+ 1 - 1
docs/docs/reference/typescript-api/configuration/system-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## SystemOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="1124" packageName="@vendure/core" since="1.6.0" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="1134" packageName="@vendure/core" since="1.6.0" />
 
 Options relating to system functions.
 

+ 1 - 1
docs/docs/reference/typescript-api/configuration/trust-proxy-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## TrustProxyOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="244" packageName="@vendure/core" since="3.4.0" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="245" packageName="@vendure/core" since="3.4.0" />
 
 Configures Express trust proxy settings when running behind a reverse proxy (usually the case with most hosting services).
 Setting `trustProxy` allows you to retrieve the original IP address from the `X-Forwarded-For` header.

+ 1 - 1
docs/docs/reference/typescript-api/configuration/vendure-config.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## VendureConfig
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="1162" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="1172" packageName="@vendure/core" />
 
 All possible configuration options are defined by the
 [`VendureConfig`](https://github.com/vendure-ecommerce/vendure/blob/master/packages/core/src/config/vendure-config.ts) interface.

+ 1 - 1
docs/docs/reference/typescript-api/import-export/import-export-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ImportExportOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="935" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="936" packageName="@vendure/core" />
 
 Options related to importing & exporting data.
 

+ 1 - 1
docs/docs/reference/typescript-api/job-queue/job-queue-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## JobQueueOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="959" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="960" packageName="@vendure/core" />
 
 Options related to the built-in job queue.
 

+ 1 - 1
docs/docs/reference/typescript-api/orders/order-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## OrderOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="520" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="521" packageName="@vendure/core" />
 
 
 

+ 1 - 1
docs/docs/reference/typescript-api/payment/payment-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## PaymentOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="872" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="873" packageName="@vendure/core" />
 
 Defines payment-related options in the <a href='/reference/typescript-api/configuration/vendure-config#vendureconfig'>VendureConfig</a>.
 

+ 1 - 1
docs/docs/reference/typescript-api/products-stock/catalog-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## CatalogOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="721" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="722" packageName="@vendure/core" />
 
 Options related to products and collections.
 

+ 1 - 1
docs/docs/reference/typescript-api/promotions/promotion-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## PromotionOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="783" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="784" packageName="@vendure/core" />
 
 
 

+ 1 - 1
docs/docs/reference/typescript-api/scheduled-tasks/scheduler-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## SchedulerOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="998" packageName="@vendure/core" since="3.3.0" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="999" packageName="@vendure/core" since="3.3.0" />
 
 Options related to scheduled tasks..
 

+ 41 - 0
docs/docs/reference/typescript-api/services/entity-slug-service.md

@@ -0,0 +1,41 @@
+---
+title: "EntitySlugService"
+isDefaultIndex: false
+generated: true
+---
+<!-- This file was generated from the Vendure source. Do not modify. Instead, re-run the "docs:build" script -->
+import MemberInfo from '@site/src/components/MemberInfo';
+import GenerationInfo from '@site/src/components/GenerationInfo';
+import MemberDescription from '@site/src/components/MemberDescription';
+
+
+## EntitySlugService
+
+<GenerationInfo sourceFile="packages/core/src/service/helpers/entity-slug.service.ts" sourceLine="41" packageName="@vendure/core" since="3.5.0" />
+
+A service that handles slug generation for entities, ensuring uniqueness
+and handling conflicts by appending numbers.
+
+```ts title="Signature"
+class EntitySlugService {
+    constructor(slugService: SlugService, connection: TransactionalConnection)
+    generateSlugFromInput(ctx: RequestContext, params: GenerateSlugFromInputParams) => Promise<string>;
+}
+```
+
+<div className="members-wrapper">
+
+### constructor
+
+<MemberInfo kind="method" type={`(slugService: <a href='/reference/typescript-api/services/slug-service#slugservice'>SlugService</a>, connection: <a href='/reference/typescript-api/data-access/transactional-connection#transactionalconnection'>TransactionalConnection</a>) => EntitySlugService`}   />
+
+
+### generateSlugFromInput
+
+<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, params: GenerateSlugFromInputParams) => Promise&#60;string&#62;`}   />
+
+Generates a slug from input value for an entity, ensuring uniqueness.
+Automatically detects if the field exists on the base entity or its translation entity.
+
+
+</div>

+ 7 - 7
docs/docs/reference/typescript-api/services/product-option-service.md

@@ -11,15 +11,15 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ProductOptionService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/product-option.service.ts" sourceLine="34" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/product-option.service.ts" sourceLine="37" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/product-option#productoption'>ProductOption</a> entities.
 
 ```ts title="Signature"
 class ProductOptionService {
-    constructor(connection: TransactionalConnection, translatableSaver: TranslatableSaver, customFieldRelationService: CustomFieldRelationService, eventBus: EventBus, translator: TranslatorService)
-    findAll(ctx: RequestContext) => Promise<Array<Translated<ProductOption>>>;
-    findOne(ctx: RequestContext, id: ID) => Promise<Translated<ProductOption> | undefined>;
+    constructor(connection: TransactionalConnection, translatableSaver: TranslatableSaver, customFieldRelationService: CustomFieldRelationService, eventBus: EventBus, translator: TranslatorService, listQueryBuilder: ListQueryBuilder)
+    findAll(ctx: RequestContext, options?: ListQueryOptions<ProductOption>, groupId?: ID, relations?: RelationPaths<ProductOption>) => Promise<PaginatedList<Translated<ProductOption>>>;
+    findOne(ctx: RequestContext, id: ID, relations?: RelationPaths<ProductOption>) => Promise<Translated<ProductOption> | undefined>;
     create(ctx: RequestContext, group: ProductOptionGroup | ID, input: CreateGroupOptionInput | CreateProductOptionInput) => Promise<Translated<ProductOption>>;
     update(ctx: RequestContext, input: UpdateProductOptionInput) => Promise<Translated<ProductOption>>;
     delete(ctx: RequestContext, id: ID) => Promise<DeletionResponse>;
@@ -30,17 +30,17 @@ class ProductOptionService {
 
 ### constructor
 
-<MemberInfo kind="method" type={`(connection: <a href='/reference/typescript-api/data-access/transactional-connection#transactionalconnection'>TransactionalConnection</a>, translatableSaver: <a href='/reference/typescript-api/service-helpers/translatable-saver#translatablesaver'>TranslatableSaver</a>, customFieldRelationService: CustomFieldRelationService, eventBus: <a href='/reference/typescript-api/events/event-bus#eventbus'>EventBus</a>, translator: <a href='/reference/typescript-api/service-helpers/translator-service#translatorservice'>TranslatorService</a>) => ProductOptionService`}   />
+<MemberInfo kind="method" type={`(connection: <a href='/reference/typescript-api/data-access/transactional-connection#transactionalconnection'>TransactionalConnection</a>, translatableSaver: <a href='/reference/typescript-api/service-helpers/translatable-saver#translatablesaver'>TranslatableSaver</a>, customFieldRelationService: CustomFieldRelationService, eventBus: <a href='/reference/typescript-api/events/event-bus#eventbus'>EventBus</a>, translator: <a href='/reference/typescript-api/service-helpers/translator-service#translatorservice'>TranslatorService</a>, listQueryBuilder: <a href='/reference/typescript-api/data-access/list-query-builder#listquerybuilder'>ListQueryBuilder</a>) => ProductOptionService`}   />
 
 
 ### findAll
 
-<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>) => Promise&#60;Array&#60;Translated&#60;<a href='/reference/typescript-api/entities/product-option#productoption'>ProductOption</a>&#62;&#62;&#62;`}   />
+<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, options?: ListQueryOptions&#60;<a href='/reference/typescript-api/entities/product-option#productoption'>ProductOption</a>&#62;, groupId?: <a href='/reference/typescript-api/common/id#id'>ID</a>, relations?: RelationPaths&#60;<a href='/reference/typescript-api/entities/product-option#productoption'>ProductOption</a>&#62;) => Promise&#60;<a href='/reference/typescript-api/common/paginated-list#paginatedlist'>PaginatedList</a>&#60;Translated&#60;<a href='/reference/typescript-api/entities/product-option#productoption'>ProductOption</a>&#62;&#62;&#62;`}   />
 
 
 ### findOne
 
-<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, id: <a href='/reference/typescript-api/common/id#id'>ID</a>) => Promise&#60;Translated&#60;<a href='/reference/typescript-api/entities/product-option#productoption'>ProductOption</a>&#62; | undefined&#62;`}   />
+<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, id: <a href='/reference/typescript-api/common/id#id'>ID</a>, relations?: RelationPaths&#60;<a href='/reference/typescript-api/entities/product-option#productoption'>ProductOption</a>&#62;) => Promise&#60;Translated&#60;<a href='/reference/typescript-api/entities/product-option#productoption'>ProductOption</a>&#62; | undefined&#62;`}   />
 
 
 ### create

+ 12 - 0
docs/docs/reference/typescript-api/services/settings-store-service.md

@@ -57,6 +57,8 @@ class SettingsStoreService implements OnModuleInit {
     findOrphanedEntries(options: CleanupOrphanedSettingsStoreEntriesOptions = {}) => Promise<OrphanedSettingsStoreEntry[]>;
     cleanupOrphanedEntries(options: CleanupOrphanedSettingsStoreEntriesOptions = {}) => Promise<CleanupOrphanedSettingsStoreEntriesResult>;
     hasPermission(ctx: RequestContext, key: string) => boolean;
+    hasReadPermission(ctx: RequestContext, key: string) => boolean;
+    hasWritePermission(ctx: RequestContext, key: string) => boolean;
     isReadonly(key: string) => boolean;
 }
 ```
@@ -176,6 +178,16 @@ Check if the current user has permission to access a field.
 This is not called internally in the get and set methods, so should
 be used by any methods which are exposing these methods via the GraphQL
 APIs.
+### hasReadPermission
+
+<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, key: string) => boolean`}  since="3.5.0"  />
+
+Check if the current user has permission to read a field.
+### hasWritePermission
+
+<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, key: string) => boolean`}  since="3.5.0"  />
+
+Check if the current user has permission to write a field.
 ### isReadonly
 
 <MemberInfo kind="method" type={`(key: string) => boolean`}   />

+ 39 - 0
docs/docs/reference/typescript-api/services/slug-service.md

@@ -0,0 +1,39 @@
+---
+title: "SlugService"
+isDefaultIndex: false
+generated: true
+---
+<!-- This file was generated from the Vendure source. Do not modify. Instead, re-run the "docs:build" script -->
+import MemberInfo from '@site/src/components/MemberInfo';
+import GenerationInfo from '@site/src/components/GenerationInfo';
+import MemberDescription from '@site/src/components/MemberDescription';
+
+
+## SlugService
+
+<GenerationInfo sourceFile="packages/core/src/service/helpers/slug.service.ts" sourceLine="13" packageName="@vendure/core" since="3.5.0" />
+
+A service that handles slug generation using the configured SlugStrategy.
+
+```ts title="Signature"
+class SlugService {
+    constructor(configService: ConfigService)
+    generate(ctx: RequestContext, params: SlugGenerateParams) => Promise<string>;
+}
+```
+
+<div className="members-wrapper">
+
+### constructor
+
+<MemberInfo kind="method" type={`(configService: ConfigService) => SlugService`}   />
+
+
+### generate
+
+<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, params: SlugGenerateParams) => Promise&#60;string&#62;`}   />
+
+Generates a slug from the input string using the configured SlugStrategy.
+
+
+</div>

+ 1 - 1
docs/docs/reference/typescript-api/settings-store/cleanup-orphaned-settings-store-entries-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## CleanupOrphanedSettingsStoreEntriesOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/settings-store/settings-store-types.ts" sourceLine="240" packageName="@vendure/core" since="3.4.0" />
+<GenerationInfo sourceFile="packages/core/src/config/settings-store/settings-store-types.ts" sourceLine="270" packageName="@vendure/core" since="3.4.0" />
 
 Options for cleaning up orphaned settings store entries.
 

+ 1 - 1
docs/docs/reference/typescript-api/settings-store/cleanup-orphaned-settings-store-entries-result.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## CleanupOrphanedSettingsStoreEntriesResult
 
-<GenerationInfo sourceFile="packages/core/src/config/settings-store/settings-store-types.ts" sourceLine="278" packageName="@vendure/core" since="3.4.0" />
+<GenerationInfo sourceFile="packages/core/src/config/settings-store/settings-store-types.ts" sourceLine="308" packageName="@vendure/core" since="3.4.0" />
 
 Result of a cleanup operation for orphaned settings store entries.
 

+ 1 - 1
docs/docs/reference/typescript-api/settings-store/orphaned-settings-store-entry.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## OrphanedSettingsStoreEntry
 
-<GenerationInfo sourceFile="packages/core/src/config/settings-store/settings-store-types.ts" sourceLine="207" packageName="@vendure/core" since="3.4.0" />
+<GenerationInfo sourceFile="packages/core/src/config/settings-store/settings-store-types.ts" sourceLine="237" packageName="@vendure/core" since="3.4.0" />
 
 Represents an orphaned settings store entry that no longer has a corresponding
 field definition in the configuration.

+ 1 - 1
docs/docs/reference/typescript-api/settings-store/set-settings-store-value-result.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## SetSettingsStoreValueResult
 
-<GenerationInfo sourceFile="packages/core/src/config/settings-store/settings-store-types.ts" sourceLine="179" packageName="@vendure/core" since="3.4.0" />
+<GenerationInfo sourceFile="packages/core/src/config/settings-store/settings-store-types.ts" sourceLine="209" packageName="@vendure/core" since="3.4.0" />
 
 Result type for settings store set operations, providing detailed feedback
 about the success or failure of each operation.

+ 32 - 2
docs/docs/reference/typescript-api/settings-store/settings-store-field-config.md

@@ -21,7 +21,14 @@ interface SettingsStoreFieldConfig {
     name: string;
     scope?: SettingsStoreScopeFunction;
     readonly?: boolean;
-    requiresPermission?: Array<Permission | string> | Permission | string;
+    requiresPermission?:
+        | Array<Permission | string>
+        | Permission
+        | string
+        | {
+              read?: Array<Permission | string> | Permission | string;
+              write?: Array<Permission | string> | Permission | string;
+          };
     validate?: (
         value: any,
         injector: Injector,
@@ -52,10 +59,33 @@ Whether this field is readonly via the GraphQL API.
 Readonly fields can still be modified programmatically via a service.
 ### requiresPermission
 
-<MemberInfo kind="property" type={`Array&#60;<a href='/reference/typescript-api/common/permission#permission'>Permission</a> | string&#62; | <a href='/reference/typescript-api/common/permission#permission'>Permission</a> | string`}   />
+<MemberInfo kind="property" type={`| Array&#60;<a href='/reference/typescript-api/common/permission#permission'>Permission</a> | string&#62;         | <a href='/reference/typescript-api/common/permission#permission'>Permission</a>         | string         | {               read?: Array&#60;<a href='/reference/typescript-api/common/permission#permission'>Permission</a> | string&#62; | <a href='/reference/typescript-api/common/permission#permission'>Permission</a> | string;               write?: Array&#60;<a href='/reference/typescript-api/common/permission#permission'>Permission</a> | string&#62; | <a href='/reference/typescript-api/common/permission#permission'>Permission</a> | string;           }`}  since="3.5.0 - Added support for object with read/write properties"  />
 
 Permissions required to access this field. If not specified,
 basic authentication is required for admin API access.
+
+Can be either:
+- A single permission or array of permissions (applies to both read and write)
+- An object with `read` and `write` properties for granular control
+
+*Example*
+
+```ts
+// Single permission for both read and write
+requiresPermission: Permission.UpdateSettings
+
+// Separate read and write permissions
+requiresPermission: {
+  read: Permission.ReadSettings,
+  write: Permission.UpdateSettings
+}
+
+// Using custom RwPermissionDefinition
+requiresPermission: {
+  read: dashboardSavedViews.Read,
+  write: dashboardSavedViews.Write
+}
+```
 ### validate
 
 <MemberInfo kind="property" type={`(         value: any,         injector: <a href='/reference/typescript-api/common/injector#injector'>Injector</a>,         ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>,     ) =&#62; string | LocalizedString[] | void | Promise&#60;string | LocalizedString[] | void&#62;`}   />

+ 1 - 1
docs/docs/reference/typescript-api/settings-store/settings-store-registration.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## SettingsStoreRegistration
 
-<GenerationInfo sourceFile="packages/core/src/config/settings-store/settings-store-types.ts" sourceLine="89" packageName="@vendure/core" since="3.4.0" />
+<GenerationInfo sourceFile="packages/core/src/config/settings-store/settings-store-types.ts" sourceLine="119" packageName="@vendure/core" since="3.4.0" />
 
 Configuration for registering a namespace of settings store fields.
 

+ 1 - 1
docs/docs/reference/typescript-api/settings-store/settings-store-scopes.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## SettingsStoreScopes
 
-<GenerationInfo sourceFile="packages/core/src/config/settings-store/settings-store-types.ts" sourceLine="144" packageName="@vendure/core" since="3.4.0" />
+<GenerationInfo sourceFile="packages/core/src/config/settings-store/settings-store-types.ts" sourceLine="174" packageName="@vendure/core" since="3.4.0" />
 
 Pre-built scope functions for common scoping patterns.
 

+ 1 - 1
docs/docs/reference/typescript-api/shipping/shipping-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ShippingOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="799" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="800" packageName="@vendure/core" />
 
 
 

+ 1 - 1
docs/docs/reference/typescript-api/tax/tax-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## TaxOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="912" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="913" packageName="@vendure/core" />
 
 
 

+ 38 - 1
packages/dashboard/src/lib/components/data-table/data-table-bulk-action-item.tsx

@@ -16,6 +16,13 @@ import {
 } from '../ui/alert-dialog.js';
 import { DropdownMenuItem } from '../ui/dropdown-menu.js';
 
+/**
+ * @description
+ *
+ * @docsCategory list-views
+ * @docsPage bulk-actions
+ * @since 3.4.0
+ */
 export interface DataTableBulkActionItemProps {
     label: React.ReactNode;
     icon?: LucideIcon;
@@ -25,6 +32,36 @@ export interface DataTableBulkActionItemProps {
     requiresPermission?: string[];
 }
 
+/**
+ * @description
+ * A component that should be used to implement any bulk actions for list pages & data tables.
+ *
+ * @example
+ * ```tsx
+ * import { DataTableBulkActionItem, Trans } from '\@vendure/dashboard';
+ * import { Check } from 'lucide-react';
+ *
+ * export const MyBulkAction: BulkActionComponent<any> = ({ selection, table }) => {
+ *
+ *   return (
+ *     <DataTableBulkActionItem
+ *       requiresPermission={['ReadMyCustomEntity']}
+ *       onClick={() => {
+ *         console.log('Selected items:', selection);
+ *       }}
+ *       label={<Trans>Delete</Trans>}
+ *       confirmationText={<Trans>Are you sure?</Trans>}
+ *       icon={Check}
+ *       className="text-destructive"
+ *     />
+ *   );
+ * }
+ * ```
+ *
+ * @docsCategory list-views
+ * @docsPage bulk-actions
+ * @since 3.4.0
+ */
 export function DataTableBulkActionItem({
     label,
     icon: Icon,
@@ -32,7 +69,7 @@ export function DataTableBulkActionItem({
     className,
     onClick,
     requiresPermission,
-}: DataTableBulkActionItemProps) {
+}: Readonly<DataTableBulkActionItemProps>) {
     const [isOpen, setIsOpen] = useState(false);
     const { hasPermissions } = usePermissions();
     const userHasPermission = hasPermissions(requiresPermission ?? []);

+ 62 - 4
packages/dashboard/src/lib/framework/extension-api/types/data-table.ts

@@ -35,12 +35,70 @@ export type BulkActionComponent<Item extends { id: string } & Record<string, any
 
 /**
  * @description
- * **Status: Developer Preview**
- *
  * A bulk action is a component that will be rendered in the bulk actions dropdown.
  *
- * @docsCategory components
- * @docsPage DataTable
+ * The component receives the following props:
+ *
+ * - `selection`: The selected row or rows
+ * - `table`: A reference to the Tanstack table instance powering the list
+ *
+ * The `table` object has
+ *
+ * @example
+ * ```tsx
+ * import { BulkActionComponent, DataTableBulkActionItem, usePaginatedList } from '\@vendure/dashboard';
+ *
+ * // This is an example of a bulk action that shows some typical
+ * // uses of the provided props
+ * export const MyBulkAction: BulkActionComponent<any> = ({ selection, table }) => {
+ *   const { refetchPaginatedList } = usePaginatedList();
+ *
+ *   const doTheAction = async () => {
+ *     // Actual logic of the action
+ *     // goes here...
+ *
+ *     // On success, we refresh the list
+ *     refetchPaginatedList();
+ *     // and un-select any selected rows in the table
+ *     table.resetRowSelection();
+ *   };
+ *
+ *  return (
+ *    <DataTableBulkActionItem
+ *      onClick={doTheAction}
+ *      label={<Trans>Delete</Trans>}
+ *      confirmationText={<Trans>Are you sure?</Trans>}
+ *      icon={Check}
+ *      className="text-destructive"
+ *    />
+ *  );
+ * }
+ * ```
+ *
+ * For the common action of deletion, we provide a ready-made helper component:
+ *
+ * @example
+ * ```tsx
+ * import { BulkActionComponent, DeleteProductsBulkAction } from '\@vendure/dashboard';
+ *
+ * // Define the BulkAction component. This one uses
+ * // a built-in wrapper for "delete" actions, which includes
+ * // a confirmation dialog.
+ * export const DeleteProductsBulkAction: BulkActionComponent<any> = ({ selection, table }) => {
+ *     return (
+ *         <DeleteBulkAction
+ *             mutationDocument={deleteProductsDocument}
+ *             entityName="products"
+ *             requiredPermissions={['DeleteCatalog', 'DeleteProduct']}
+ *             selection={selection}
+ *             table={table}
+ *         />
+ *     );
+ * };
+ * ```
+ *
+ * @docsCategory list-views
+ * @docsPage bulk-actions
  * @since 3.4.0
  */
 export type BulkAction = {

+ 235 - 0
packages/dashboard/src/lib/framework/page/list-page.tsx

@@ -33,9 +33,62 @@ export interface ListPageProps<
     V extends ListQueryOptionsShape,
     AC extends AdditionalColumns<T>,
 > {
+    /**
+     * @description
+     * A unique identifier for the list page. This is important to support
+     * customization functionality that relies on page IDs and makes your
+     * component extensible.
+     */
     pageId?: string;
+    /**
+     @description
+     * The Tanstack Router `Route` object, which will be defined in the component file.
+     */
     route: AnyRoute | (() => AnyRoute);
+    /**
+     @description
+     * The page title, which will display in the header area.
+     */
     title: string | React.ReactElement;
+    /**
+     * @description
+     * 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}
+     *   // ...
+     * />
+     * ```
+     */
     listQuery: T;
     /**
      * @description
@@ -45,7 +98,58 @@ export interface ListPageProps<
      * will be added to the action column dropdown already.
      */
     deleteMutation?: TypedDocumentNode<any, { id: string }>;
+    /**
+     * @description
+     * 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,
+     *           },
+     *       };
+     *   }}
+     * />
+     * ```
+     */
     transformVariables?: (variables: V) => V;
+    /**
+     * @description
+     * 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 },
+     *      };
+     *    }}
+     *  />
+     * @param searchTerm
+     */
     onSearchTermChange?: (searchTerm: string) => NonNullable<V['options']>['filter'];
     /**
      * @description
@@ -101,17 +205,148 @@ export interface ListPageProps<
      * ```
      */
     customizeColumns?: CustomizeColumnConfig<T>;
+    /**
+     * @description
+     * 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}`}
+     *             />
+     *         ),
+     *   },
+     * />
+     * ```
+     */
     additionalColumns?: AC;
+    /**
+     * @description
+     * 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.
+     */
     defaultColumnOrder?: (keyof ListQueryFields<T> | keyof AC | CustomFieldKeysOfItem<ListQueryFields<T>>)[];
+    /**
+     * @description
+     * Allows you to specify the default sorting applied to the table.
+     *
+     * @example
+     * ```tsx
+     * defaultSort={[{ id: 'orderPlacedAt', desc: true }]}
+     * ```
+     */
     defaultSort?: SortingState;
+    /**
+     * @description
+     * 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,
+     *    }}
+     *  />
+     *  ```
+     */
     defaultVisibility?: Partial<
         Record<keyof ListQueryFields<T> | keyof AC | CustomFieldKeysOfItem<ListQueryFields<T>>, boolean>
     >;
     children?: React.ReactNode;
+    /**
+     * @description
+     * 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 },
+     *           ],
+     *       },
+     *   }}
+     * />
+     * ```
+     */
     facetedFilters?: FacetedFilterConfig<T>;
+    /**
+     * @description
+     * 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.
+     */
     rowActions?: RowAction<ListQueryFields<T>>[];
+    /**
+     * @description
+     * Allows the returned list query data to be transformed in some way. This is an advanced feature
+     * that is not often required.
+     */
     transformData?: (data: any[]) => any[];
+    /**
+     * @description
+     * Allows you to directly manipulate the Tanstack Table `TableOptions` object before the
+     * table is created. And advanced option that is not often required.
+     */
     setTableOptions?: (table: TableOptions<any>) => TableOptions<any>;
+    /**
+     * @description
+     * 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 {@link BulkAction} 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,
+     *     },
+     *   ]}
+     * />
+     * ```
+     */
     bulkActions?: BulkAction[];
     /**
      * @description