@vendure/dashboard 3.3.6-master-202507021511 → 3.3.6-master-202507030648

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/README.md +41 -4
  2. package/dist/plugin/vite-plugin-config.js +4 -2
  3. package/package.json +4 -4
  4. package/src/app/routes/_authenticated/_administrators/components/administrator-bulk-actions.tsx +1 -1
  5. package/src/app/routes/_authenticated/_administrators/components/role-permissions-display.tsx +1 -1
  6. package/src/app/routes/_authenticated/_channels/components/channel-bulk-actions.tsx +1 -1
  7. package/src/app/routes/_authenticated/_collections/components/collection-bulk-actions.tsx +1 -2
  8. package/src/app/routes/_authenticated/_collections/components/collection-contents-table.tsx +1 -1
  9. package/src/app/routes/_authenticated/_collections/components/collection-filters-selector.tsx +1 -1
  10. package/src/app/routes/_authenticated/_countries/components/country-bulk-actions.tsx +1 -1
  11. package/src/app/routes/_authenticated/_customer-groups/components/customer-group-bulk-actions.tsx +1 -1
  12. package/src/app/routes/_authenticated/_customers/components/customer-address-form.tsx +1 -1
  13. package/src/app/routes/_authenticated/_customers/components/customer-bulk-actions.tsx +1 -1
  14. package/src/app/routes/_authenticated/_customers/components/customer-history/customer-history-container.tsx +1 -1
  15. package/src/app/routes/_authenticated/_customers/components/customer-order-table.tsx +1 -1
  16. package/src/app/routes/_authenticated/_customers/components/customer-status-badge.tsx +1 -1
  17. package/src/app/routes/_authenticated/_facets/components/edit-facet-value.tsx +1 -1
  18. package/src/app/routes/_authenticated/_facets/components/facet-bulk-actions.tsx +1 -2
  19. package/src/app/routes/_authenticated/_facets/components/facet-values-sheet.tsx +1 -1
  20. package/src/app/routes/_authenticated/_facets/components/facet-values-table.tsx +1 -1
  21. package/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsx +1 -1
  22. package/src/app/routes/_authenticated/_orders/components/money-gross-net.tsx +1 -1
  23. package/src/app/routes/_authenticated/_orders/components/order-address.tsx +1 -1
  24. package/src/app/routes/_authenticated/_orders/components/order-history/order-history-container.tsx +1 -1
  25. package/src/app/routes/_authenticated/_orders/components/order-history/order-history.tsx +6 -1
  26. package/src/app/routes/_authenticated/_orders/components/order-line-custom-fields-form.tsx +1 -1
  27. package/src/app/routes/_authenticated/_orders/components/order-table-totals.tsx +3 -3
  28. package/src/app/routes/_authenticated/_orders/components/order-table.tsx +1 -1
  29. package/src/app/routes/_authenticated/_orders/components/order-tax-summary.tsx +2 -2
  30. package/src/app/routes/_authenticated/_orders/components/payment-details.tsx +1 -1
  31. package/src/app/routes/_authenticated/_orders/components/shipping-method-selector.tsx +1 -1
  32. package/src/app/routes/_authenticated/_payment-methods/components/payment-handler-selector.tsx +1 -1
  33. package/src/app/routes/_authenticated/_payment-methods/components/payment-method-bulk-actions.tsx +1 -2
  34. package/src/app/routes/_authenticated/_product-variants/components/product-variant-bulk-actions.tsx +1 -2
  35. package/src/app/routes/_authenticated/_products/components/create-product-variants.tsx +4 -1
  36. package/src/app/routes/_authenticated/_products/components/option-value-input.tsx +5 -1
  37. package/src/app/routes/_authenticated/_products/components/product-bulk-actions.tsx +1 -2
  38. package/src/app/routes/_authenticated/_products/components/product-option-select.tsx +6 -1
  39. package/src/app/routes/_authenticated/_promotions/components/promotion-actions-selector.tsx +1 -1
  40. package/src/app/routes/_authenticated/_promotions/components/promotion-bulk-actions.tsx +1 -2
  41. package/src/app/routes/_authenticated/_promotions/components/promotion-conditions-selector.tsx +1 -1
  42. package/src/app/routes/_authenticated/_roles/components/expandable-permissions.tsx +1 -1
  43. package/src/app/routes/_authenticated/_roles/components/permissions-grid.tsx +1 -1
  44. package/src/app/routes/_authenticated/_roles/components/role-bulk-actions.tsx +1 -1
  45. package/src/app/routes/_authenticated/_sellers/components/seller-bulk-actions.tsx +1 -1
  46. package/src/app/routes/_authenticated/_shipping-methods/components/fulfillment-handler-selector.tsx +1 -1
  47. package/src/app/routes/_authenticated/_shipping-methods/components/shipping-calculator-selector.tsx +1 -1
  48. package/src/app/routes/_authenticated/_shipping-methods/components/shipping-method-bulk-actions.tsx +1 -2
  49. package/src/app/routes/_authenticated/_stock-locations/components/stock-location-bulk-actions.tsx +1 -2
  50. package/src/app/routes/_authenticated/_system/components/payload-dialog.tsx +1 -1
  51. package/src/app/routes/_authenticated/_tax-categories/components/tax-category-bulk-actions.tsx +1 -1
  52. package/src/app/routes/_authenticated/_tax-rates/components/tax-rate-bulk-actions.tsx +1 -1
  53. package/src/app/routes/_authenticated/_zones/components/zone-bulk-actions.tsx +1 -1
  54. package/src/app/routes/_authenticated/_zones/components/zone-countries-sheet.tsx +1 -1
  55. package/src/app/routes/_authenticated/_zones/components/zone-countries-table.tsx +1 -1
  56. package/src/app/routes/_authenticated/index.tsx +1 -1
  57. package/src/lib/components/data-display/boolean.tsx +1 -1
  58. package/src/lib/components/data-display/date-time.tsx +1 -1
  59. package/src/lib/components/data-display/json.tsx +1 -1
  60. package/src/lib/components/data-input/affixed-input.tsx +1 -1
  61. package/src/lib/components/data-input/index.ts +11 -0
  62. package/src/lib/components/data-input/relation-input.tsx +156 -0
  63. package/src/lib/components/data-input/relation-selector.tsx +350 -0
  64. package/src/lib/components/data-input/{richt-text-input.tsx → rich-text-input.tsx} +1 -1
  65. package/src/lib/components/data-table/add-filter-menu.tsx +1 -1
  66. package/src/lib/components/data-table/data-table-bulk-actions.tsx +1 -1
  67. package/src/lib/components/data-table/data-table-column-header.tsx +1 -1
  68. package/src/lib/components/data-table/data-table-filter-dialog.tsx +1 -1
  69. package/src/lib/components/data-table/data-table.tsx +1 -1
  70. package/src/lib/components/data-table/filters/data-table-boolean-filter.tsx +4 -1
  71. package/src/lib/components/data-table/filters/data-table-datetime-filter.tsx +4 -1
  72. package/src/lib/components/data-table/filters/data-table-id-filter.tsx +1 -1
  73. package/src/lib/components/data-table/filters/data-table-number-filter.tsx +5 -1
  74. package/src/lib/components/data-table/filters/data-table-string-filter.tsx +4 -1
  75. package/src/lib/components/data-table/refresh-button.tsx +4 -1
  76. package/src/lib/components/layout/nav-main.tsx +1 -1
  77. package/src/lib/components/shared/asset/asset-bulk-actions.tsx +1 -1
  78. package/src/lib/components/shared/asset/asset-preview-selector.tsx +1 -1
  79. package/src/lib/components/shared/asset/asset-preview.tsx +1 -1
  80. package/src/lib/components/shared/asset/asset-properties.tsx +1 -1
  81. package/src/lib/components/shared/asset/focal-point-control.tsx +1 -1
  82. package/src/lib/components/shared/channel-code-label.tsx +1 -1
  83. package/src/lib/components/shared/copyable-text.tsx +2 -3
  84. package/src/lib/components/shared/custom-fields-form.tsx +1 -1
  85. package/src/lib/components/shared/error-page.tsx +1 -1
  86. package/src/lib/components/shared/history-timeline/history-entry.tsx +7 -1
  87. package/src/lib/components/shared/history-timeline/history-note-checkbox.tsx +1 -1
  88. package/src/lib/components/shared/history-timeline/history-note-input.tsx +1 -1
  89. package/src/lib/components/shared/history-timeline/history-timeline.tsx +1 -1
  90. package/src/lib/components/shared/option-value-input.tsx +1 -1
  91. package/src/lib/components/shared/paginated-list-data-table.tsx +1 -1
  92. package/src/lib/components/shared/permission-guard.tsx +1 -1
  93. package/src/lib/components/shared/product-variant-selector.tsx +1 -1
  94. package/src/lib/components/shared/role-code-label.tsx +1 -1
  95. package/src/lib/components/shared/stock-level-label.tsx +5 -5
  96. package/src/lib/components/shared/tax-category-selector.tsx +1 -1
  97. package/src/lib/components/shared/zone-selector.tsx +1 -1
  98. package/src/lib/framework/alert/alert-extensions.tsx +2 -3
  99. package/src/lib/framework/alert/alert-item.tsx +2 -1
  100. package/src/lib/framework/dashboard-widget/base-widget.tsx +2 -10
  101. package/src/lib/framework/dashboard-widget/widget-extensions.tsx +1 -1
  102. package/src/lib/framework/data-table/data-table-extensions.ts +1 -1
  103. package/src/lib/framework/extension-api/extension-api-types.ts +0 -3
  104. package/src/lib/framework/extension-api/types/data-table.ts +25 -2
  105. package/src/lib/framework/extension-api/types/widgets.ts +7 -4
  106. package/src/lib/framework/layout-engine/location-wrapper.tsx +4 -1
  107. package/src/lib/framework/layout-engine/page-layout.tsx +16 -9
  108. package/src/lib/framework/page/list-page.tsx +2 -8
  109. package/src/lib/framework/registry/registry-types.ts +7 -7
  110. package/src/lib/graphql/graphql-env.d.ts +31 -14
  111. package/src/lib/index.ts +7 -12
  112. package/src/lib/lib/trans.tsx +3 -3
  113. package/src/lib/providers/auth.tsx +1 -1
  114. package/src/lib/providers/channel-provider.tsx +1 -1
  115. package/src/lib/providers/theme-provider.tsx +2 -3
  116. package/vite/vite-plugin-config.ts +2 -1
  117. package/src/lib/framework/alert/types.ts +0 -13
  118. package/src/lib/framework/dashboard-widget/types.ts +0 -22
  119. package/src/lib/framework/data-table/data-table-types.ts +0 -25
@@ -13,7 +13,10 @@ export interface DataTableBooleanFilterProps {
13
13
 
14
14
  export const BOOLEAN_OPERATORS = ['eq', 'isNull'] as const;
15
15
 
16
- export function DataTableBooleanFilter({ value: incomingValue, onChange }: DataTableBooleanFilterProps) {
16
+ export function DataTableBooleanFilter({
17
+ value: incomingValue,
18
+ onChange,
19
+ }: Readonly<DataTableBooleanFilterProps>) {
17
20
  const initialOperator = incomingValue ? (Object.keys(incomingValue)[0] ?? 'eq') : 'eq';
18
21
  const initialValue = incomingValue ? Object.values(incomingValue)[0] : true;
19
22
  const [operator, setOperator] = useState<string>(initialOperator ?? 'eq');
@@ -10,7 +10,10 @@ export interface DataTableDateTimeFilterProps {
10
10
 
11
11
  export const DATETIME_OPERATORS = ['eq', 'before', 'after', 'between', 'isNull'] as const;
12
12
 
13
- export function DataTableDateTimeFilter({ value: incomingValue, onChange }: DataTableDateTimeFilterProps) {
13
+ export function DataTableDateTimeFilter({
14
+ value: incomingValue,
15
+ onChange,
16
+ }: Readonly<DataTableDateTimeFilterProps>) {
14
17
  const initialOperator = incomingValue ? Object.keys(incomingValue)[0] : 'eq';
15
18
  const initialValue = incomingValue ? Object.values(incomingValue)[0] : '';
16
19
  const [operator, setOperator] = useState<string>(initialOperator ?? 'eq');
@@ -12,7 +12,7 @@ export interface DataTableIdFilterProps {
12
12
 
13
13
  export const ID_OPERATORS = ['eq', 'notEq', 'in', 'notIn', 'isNull'] as const;
14
14
 
15
- export function DataTableIdFilter({ value: incomingValue, onChange }: DataTableIdFilterProps) {
15
+ export function DataTableIdFilter({ value: incomingValue, onChange }: Readonly<DataTableIdFilterProps>) {
16
16
  const initialOperator = incomingValue ? Object.keys(incomingValue)[0] : 'eq';
17
17
  const initialValue = incomingValue ? Object.values(incomingValue)[0] : '';
18
18
  const [operator, setOperator] = useState<string>(initialOperator ?? 'eq');
@@ -13,7 +13,11 @@ export interface DataTableNumberFilterProps {
13
13
 
14
14
  export const NUMBER_OPERATORS = ['eq', 'gt', 'gte', 'lt', 'lte', 'isNull', 'between'] as const;
15
15
 
16
- export function DataTableNumberFilter({ mode, value: incomingValue, onChange }: DataTableNumberFilterProps) {
16
+ export function DataTableNumberFilter({
17
+ mode,
18
+ value: incomingValue,
19
+ onChange,
20
+ }: Readonly<DataTableNumberFilterProps>) {
17
21
  const { activeChannel } = useChannel();
18
22
  const initialOperator = incomingValue ? Object.keys(incomingValue)[0] : 'eq';
19
23
  const initialValue = incomingValue ? Object.values(incomingValue)[0] : 0;
@@ -21,7 +21,10 @@ export const STRING_OPERATORS = [
21
21
  'isNull',
22
22
  ] as const;
23
23
 
24
- export function DataTableStringFilter({ value: incomingValue, onChange }: DataTableStringFilterProps) {
24
+ export function DataTableStringFilter({
25
+ value: incomingValue,
26
+ onChange,
27
+ }: Readonly<DataTableStringFilterProps>) {
25
28
  const initialOperator = incomingValue ? Object.keys(incomingValue)[0] : 'contains';
26
29
  const initialValue = incomingValue ? Object.values(incomingValue)[0] : '';
27
30
  const [operator, setOperator] = useState<string>(initialOperator ?? 'contains');
@@ -22,7 +22,10 @@ function useDelayedLoading(isLoading: boolean, delayMs: number = 100) {
22
22
  return delayedLoading;
23
23
  }
24
24
 
25
- export function RefreshButton({ onRefresh, isLoading }: { onRefresh: () => void; isLoading: boolean }) {
25
+ export function RefreshButton({
26
+ onRefresh,
27
+ isLoading,
28
+ }: Readonly<{ onRefresh: () => void; isLoading: boolean }>) {
26
29
  const delayedLoading = useDelayedLoading(isLoading, 100);
27
30
 
28
31
  const handleClick = () => {
@@ -28,7 +28,7 @@ function sortByOrder<T extends { order?: number; title: string }>(a: T, b: T) {
28
28
  return orderA - orderB;
29
29
  }
30
30
 
31
- export function NavMain({ items }: { items: Array<NavMenuSection | NavMenuItem> }) {
31
+ export function NavMain({ items }: Readonly<{ items: Array<NavMenuSection | NavMenuItem> }>) {
32
32
  const location = useLocation();
33
33
  // State to track which bottom section is currently open
34
34
  const [openBottomSectionId, setOpenBottomSectionId] = React.useState<string | null>(null);
@@ -32,7 +32,7 @@ interface AssetBulkActionsProps {
32
32
  refetch: () => void;
33
33
  }
34
34
 
35
- export function AssetBulkActions({ selection, bulkActions, refetch }: AssetBulkActionsProps) {
35
+ export function AssetBulkActions({ selection, bulkActions, refetch }: Readonly<AssetBulkActionsProps>) {
36
36
  const { pageId } = usePage();
37
37
  const { blockId } = usePageBlock();
38
38
 
@@ -8,7 +8,7 @@ export interface AssetPreviewSelectorProps {
8
8
  height: number;
9
9
  }
10
10
 
11
- export function AssetPreviewSelector({ size, setSize, width, height }: AssetPreviewSelectorProps) {
11
+ export function AssetPreviewSelector({ size, setSize, width, height }: Readonly<AssetPreviewSelectorProps>) {
12
12
  return (
13
13
  <div className="flex items-center gap-2">
14
14
  <Select value={size} onValueChange={value => setSize(value as PreviewPreset)}>
@@ -19,7 +19,7 @@ interface AssetPreviewProps {
19
19
  customFields?: any[];
20
20
  }
21
21
 
22
- export function AssetPreview({ asset, assets, customFields = [] }: AssetPreviewProps) {
22
+ export function AssetPreview({ asset, assets, customFields = [] }: Readonly<AssetPreviewProps>) {
23
23
  const [size, setSize] = useState<PreviewPreset>('medium');
24
24
  const [width, setWidth] = useState(0);
25
25
  const [height, setHeight] = useState(0);
@@ -8,7 +8,7 @@ export interface AssetPropertiesProps {
8
8
  asset: AssetFragment;
9
9
  }
10
10
 
11
- export function AssetProperties({ asset }: AssetPropertiesProps) {
11
+ export function AssetProperties({ asset }: Readonly<AssetPropertiesProps>) {
12
12
  return (
13
13
  <div className="space-y-4">
14
14
  <div>
@@ -13,7 +13,7 @@ interface FocalPointControlProps {
13
13
  onChange: (point: Point) => void;
14
14
  }
15
15
 
16
- export function FocalPointControl({ width, height, point, onChange }: FocalPointControlProps) {
16
+ export function FocalPointControl({ width, height, point, onChange }: Readonly<FocalPointControlProps>) {
17
17
  const [dragging, setDragging] = useState(false);
18
18
 
19
19
  useEffect(() => {
@@ -1,6 +1,6 @@
1
1
  import { DEFAULT_CHANNEL_CODE } from '@/vdb/constants.js';
2
2
  import { Trans } from '@/vdb/lib/trans.js';
3
3
 
4
- export function ChannelCodeLabel({ code }: { code: string } | { code: undefined }) {
4
+ export function ChannelCodeLabel({ code }: Readonly<{ code: string }> | Readonly<{ code: undefined }>) {
5
5
  return code === DEFAULT_CHANNEL_CODE ? <Trans>Default channel</Trans> : code;
6
6
  }
@@ -1,9 +1,8 @@
1
1
  import { useCopyToClipboard } from '@uidotdev/usehooks';
2
- import { CopyIcon } from 'lucide-react';
2
+ import { CheckIcon, CopyIcon } from 'lucide-react';
3
3
  import { useState } from 'react';
4
- import { CheckIcon } from 'lucide-react';
5
4
 
6
- export function CopyableText({ text }: { text: string }) {
5
+ export function CopyableText({ text }: Readonly<{ text: string }>) {
7
6
  const [copiedId, setCopiedId] = useState<string | null>(null);
8
7
  const [, copy] = useCopyToClipboard();
9
8
 
@@ -28,7 +28,7 @@ interface CustomFieldsFormProps {
28
28
  formPathPrefix?: string;
29
29
  }
30
30
 
31
- export function CustomFieldsForm({ entityType, control, formPathPrefix }: CustomFieldsFormProps) {
31
+ export function CustomFieldsForm({ entityType, control, formPathPrefix }: Readonly<CustomFieldsFormProps>) {
32
32
  const {
33
33
  settings: { displayLanguage },
34
34
  } = useUserSettings();
@@ -11,7 +11,7 @@ export interface ErrorPageProps {
11
11
  * @description
12
12
  * A generic error page that displays an error message.
13
13
  */
14
- export function ErrorPage({ message }: ErrorPageProps) {
14
+ export function ErrorPage({ message }: Readonly<ErrorPageProps>) {
15
15
  return (
16
16
  <Page pageId="error-page">
17
17
  <PageTitle>
@@ -33,7 +33,13 @@ interface HistoryEntryProps {
33
33
  children: React.ReactNode;
34
34
  }
35
35
 
36
- export function HistoryEntry({ entry, isNoteEntry, timelineIcon, title, children }: HistoryEntryProps) {
36
+ export function HistoryEntry({
37
+ entry,
38
+ isNoteEntry,
39
+ timelineIcon,
40
+ title,
41
+ children,
42
+ }: Readonly<HistoryEntryProps>) {
37
43
  const { formatDate } = useLocalFormat();
38
44
  const { editNote, deleteNote } = useHistoryTimeline();
39
45
 
@@ -6,7 +6,7 @@ interface HistoryNoteCheckboxProps {
6
6
  onChange: (value: boolean) => void;
7
7
  }
8
8
 
9
- export function HistoryNoteCheckbox({ value, onChange }: HistoryNoteCheckboxProps) {
9
+ export function HistoryNoteCheckbox({ value, onChange }: Readonly<HistoryNoteCheckboxProps>) {
10
10
  return (
11
11
  <div className="flex items-center space-x-2">
12
12
  <Checkbox
@@ -7,7 +7,7 @@ interface HistoryNoteInputProps {
7
7
  onAddNote: (note: string, isPrivate: boolean) => void;
8
8
  }
9
9
 
10
- export function HistoryNoteInput({ onAddNote }: HistoryNoteInputProps) {
10
+ export function HistoryNoteInput({ onAddNote }: Readonly<HistoryNoteInputProps>) {
11
11
  const [note, setNote] = useState('');
12
12
  const [noteIsPrivate, setNoteIsPrivate] = useState(true);
13
13
 
@@ -24,7 +24,7 @@ export function useHistoryTimeline() {
24
24
  return useContext(HistoryTimelineContext);
25
25
  }
26
26
 
27
- export function HistoryTimeline({ children, onEditNote, onDeleteNote }: HistoryTimelineProps) {
27
+ export function HistoryTimeline({ children, onEditNote, onDeleteNote }: Readonly<HistoryTimelineProps>) {
28
28
  const [noteEditorOpen, setNoteEditorOpen] = useState(false);
29
29
  const [noteEditorNote, setNoteEditorNote] = useState<NoteEditorNote>({
30
30
  noteId: '',
@@ -31,7 +31,7 @@ interface OptionValueInputProps {
31
31
  disabled?: boolean;
32
32
  }
33
33
 
34
- export function OptionValueInput({ groupIndex, disabled = false }: OptionValueInputProps) {
34
+ export function OptionValueInput({ groupIndex, disabled = false }: Readonly<OptionValueInputProps>) {
35
35
  const { control, watch } = useFormContext<FormValues>();
36
36
  const { fields, append, remove } = useFieldArray({
37
37
  control,
@@ -28,7 +28,7 @@ import {
28
28
  DropdownMenuTrigger,
29
29
  } from '@/vdb/components/ui/dropdown-menu.js';
30
30
  import { DisplayComponent } from '@/vdb/framework/component-registry/dynamic-component.js';
31
- import { BulkAction } from '@/vdb/framework/data-table/data-table-types.js';
31
+ import { BulkAction } from '@/vdb/framework/extension-api/types/index.js';
32
32
  import { ResultOf } from '@/vdb/graphql/graphql.js';
33
33
  import { useExtendedListQuery } from '@/vdb/hooks/use-extended-list-query.js';
34
34
  import { Trans, useLingui } from '@/vdb/lib/trans.js';
@@ -11,7 +11,7 @@ export interface PermissionGuardProps {
11
11
  * This component is used to protect a route from unauthorized access.
12
12
  * It will render the children if the user has the required permissions.
13
13
  */
14
- export function PermissionGuard({ requires, children }: PermissionGuardProps) {
14
+ export function PermissionGuard({ requires, children }: Readonly<PermissionGuardProps>) {
15
15
  const { hasPermissions } = usePermissions();
16
16
  const permissions = Array.isArray(requires) ? requires : [requires];
17
17
  if (!hasPermissions(permissions)) {
@@ -40,7 +40,7 @@ export interface ProductVariantSelectorProps {
40
40
  onProductVariantIdChange: (productVariantId: string) => void;
41
41
  }
42
42
 
43
- export function ProductVariantSelector({ onProductVariantIdChange }: ProductVariantSelectorProps) {
43
+ export function ProductVariantSelector({ onProductVariantIdChange }: Readonly<ProductVariantSelectorProps>) {
44
44
  const [search, setSearch] = useState('');
45
45
  const [open, setOpen] = useState(false);
46
46
  const debouncedSearch = useDebounce(search, 500);
@@ -1,7 +1,7 @@
1
1
  import { CUSTOMER_ROLE_CODE, SUPER_ADMIN_ROLE_CODE } from '@/vdb/constants.js';
2
2
  import { Trans } from '@/vdb/lib/trans.js';
3
3
 
4
- export function RoleCodeLabel({ code }: { code: string } | { code: undefined }) {
4
+ export function RoleCodeLabel({ code }: Readonly<{ code: string }> | Readonly<{ code: undefined }>) {
5
5
  return code === SUPER_ADMIN_ROLE_CODE ? (
6
6
  <Trans>Super Admin</Trans>
7
7
  ) : code === CUSTOMER_ROLE_CODE ? (
@@ -5,20 +5,20 @@ export type StockLevel = {
5
5
  stockAllocated: number;
6
6
  };
7
7
 
8
- export function StockLevelLabel({ stockLevels }: { stockLevels: StockLevel[] }) {
8
+ export function StockLevelLabel({ stockLevels }: Readonly<{ stockLevels: StockLevel[] }>) {
9
9
  const { i18n } = useLingui();
10
-
10
+
11
11
  if (!Array.isArray(stockLevels)) {
12
12
  return null;
13
13
  }
14
14
  const totalOnHand = stockLevels.reduce((acc, curr) => acc + curr.stockOnHand, 0);
15
15
  const totalAllocated = stockLevels.reduce((acc, curr) => acc + curr.stockAllocated, 0);
16
-
16
+
17
17
  return (
18
- <span
18
+ <span
19
19
  title={`${i18n.t('Stock on hand')}: ${totalOnHand}, ${i18n.t('Stock allocated')}: ${totalAllocated}`}
20
20
  >
21
21
  {totalOnHand} <span className="text-muted-foreground">/ {totalAllocated}</span>
22
22
  </span>
23
23
  );
24
- }
24
+ }
@@ -29,7 +29,7 @@ export interface TaxCategorySelectorProps {
29
29
  onChange: (value: string) => void;
30
30
  }
31
31
 
32
- export function TaxCategorySelector({ value, onChange }: TaxCategorySelectorProps) {
32
+ export function TaxCategorySelector({ value, onChange }: Readonly<TaxCategorySelectorProps>) {
33
33
  const { data, isLoading, isPending, status } = useQuery({
34
34
  queryKey: ['taxCategories'],
35
35
  staleTime: 1000 * 60 * 5,
@@ -28,7 +28,7 @@ export interface ZoneSelectorProps {
28
28
  onChange: (value: string) => void;
29
29
  }
30
30
 
31
- export function ZoneSelector({ value, onChange }: ZoneSelectorProps) {
31
+ export function ZoneSelector({ value, onChange }: Readonly<ZoneSelectorProps>) {
32
32
  const { data, isLoading, isPending } = useQuery({
33
33
  queryKey: ['zones'],
34
34
  staleTime: 1000 * 60 * 5,
@@ -1,7 +1,6 @@
1
- import { useEffect } from 'react';
2
- import { useState } from 'react';
1
+ import { useEffect, useState } from 'react';
2
+ import { DashboardAlertDefinition } from '../extension-api/types/alerts.js';
3
3
  import { globalRegistry } from '../registry/global-registry.js';
4
- import { DashboardAlertDefinition } from './types.js';
5
4
 
6
5
  globalRegistry.register('dashboardAlertRegistry', new Map<string, DashboardAlertDefinition>());
7
6
 
@@ -2,7 +2,8 @@ import { Button } from '@/vdb/components/ui/button.js';
2
2
  import { cn } from '@/vdb/lib/utils.js';
3
3
  import { useQuery } from '@tanstack/react-query';
4
4
  import { ComponentProps } from 'react';
5
- import { DashboardAlertDefinition } from './types.js';
5
+
6
+ import { DashboardAlertDefinition } from '../extension-api/types/alerts.js';
6
7
 
7
8
  interface AlertItemProps extends ComponentProps<'div'> {
8
9
  alert: DashboardAlertDefinition;
@@ -1,8 +1,8 @@
1
1
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/vdb/components/ui/card.js';
2
+ import { DashboardBaseWidgetProps } from '@/vdb/framework/extension-api/types/index.js';
2
3
  import { Trans } from '@/vdb/lib/trans.js';
3
4
  import { cn } from '@/vdb/lib/utils.js';
4
- import type React from 'react';
5
- import { createContext, PropsWithChildren, useContext, useEffect, useRef, useState } from 'react';
5
+ import { createContext, useContext, useEffect, useRef, useState } from 'react';
6
6
 
7
7
  type WidgetDimensions = {
8
8
  width: number;
@@ -19,14 +19,6 @@ export const useWidgetDimensions = () => {
19
19
  return context;
20
20
  };
21
21
 
22
- export type DashboardBaseWidgetProps = PropsWithChildren<{
23
- id: string;
24
- title?: string;
25
- description?: string;
26
- config?: Record<string, unknown>;
27
- actions?: React.ReactNode;
28
- }>;
29
-
30
22
  export function DashboardBaseWidget({
31
23
  id,
32
24
  config,
@@ -1,4 +1,4 @@
1
- import { DashboardWidgetDefinition } from './types.js';
1
+ import { DashboardWidgetDefinition } from '@/vdb/framework/extension-api/types/index.js';
2
2
  import { globalRegistry } from '../registry/global-registry.js';
3
3
 
4
4
  globalRegistry.register('dashboardWidgetRegistry', new Map<string, DashboardWidgetDefinition>());
@@ -1,4 +1,4 @@
1
- import { BulkAction } from '@/vdb/framework/data-table/data-table-types.js';
1
+ import { BulkAction } from '@/vdb/framework/extension-api/types/index.js';
2
2
  import { DocumentNode } from 'graphql';
3
3
 
4
4
  import { globalRegistry } from '../registry/global-registry.js';
@@ -1,6 +1,3 @@
1
- // Import all domain-specific types
2
- export * from './types/index.js';
3
-
4
1
  // Import types for the main interface
5
2
  import {
6
3
  DashboardActionBarItem,
@@ -1,7 +1,6 @@
1
+ import { Table } from '@tanstack/react-table';
1
2
  import { DocumentNode } from 'graphql';
2
3
 
3
- import { BulkAction } from '../../data-table/data-table-types.js';
4
-
5
4
  /**
6
5
  * @description
7
6
  * Allows you to define custom display components for specific columns in data tables.
@@ -24,6 +23,30 @@ export interface DashboardDataTableDisplayComponent {
24
23
  component: React.ComponentType<{ value: any; [key: string]: any }>;
25
24
  }
26
25
 
26
+ export type BulkActionContext<Item extends { id: string } & Record<string, any>> = {
27
+ selection: Item[];
28
+ table: Table<Item>;
29
+ };
30
+
31
+ export type BulkActionComponent<Item extends { id: string } & Record<string, any>> = React.FunctionComponent<
32
+ BulkActionContext<Item>
33
+ >;
34
+
35
+ /**
36
+ * @description
37
+ * **Status: Developer Preview**
38
+ *
39
+ * A bulk action is a component that will be rendered in the bulk actions dropdown.
40
+ *
41
+ * @docsCategory components
42
+ * @docsPage DataTableBulkActions
43
+ * @since 3.4.0
44
+ */
45
+ export type BulkAction = {
46
+ order?: number;
47
+ component: BulkActionComponent<any>;
48
+ };
49
+
27
50
  /**
28
51
  * @description
29
52
  * **Status: Developer Preview**
@@ -1,4 +1,4 @@
1
- import type React from 'react';
1
+ import React, { PropsWithChildren } from 'react';
2
2
 
3
3
  /**
4
4
  * @description
@@ -9,10 +9,13 @@ import type React from 'react';
9
9
  * @docsCategory extensions
10
10
  * @since 3.3.0
11
11
  */
12
- export interface DashboardBaseWidgetProps {
13
- widgetId: string;
12
+ export type DashboardBaseWidgetProps = PropsWithChildren<{
13
+ id: string;
14
+ title?: string;
15
+ description?: string;
14
16
  config?: Record<string, unknown>;
15
- }
17
+ actions?: React.ReactNode;
18
+ }>;
16
19
 
17
20
  /**
18
21
  * @description
@@ -18,7 +18,10 @@ const LocationWrapperContext = createContext<{
18
18
  setHoveredId: null,
19
19
  });
20
20
 
21
- export function LocationWrapper({ children, blockId }: { children: React.ReactNode; blockId?: string }) {
21
+ export function LocationWrapper({
22
+ children,
23
+ blockId,
24
+ }: Readonly<{ children: React.ReactNode; blockId?: string }>) {
22
25
  const page = usePage();
23
26
  const { settings } = useUserSettings();
24
27
  const [isPopoverOpen, setIsPopoverOpen] = useState(false);
@@ -10,7 +10,7 @@ import { useMediaQuery } from '@uidotdev/usehooks';
10
10
  import React, { ComponentProps } from 'react';
11
11
  import { Control, UseFormReturn } from 'react-hook-form';
12
12
 
13
- import { DashboardActionBarItem } from '../extension-api/extension-api-types.js';
13
+ import { DashboardActionBarItem } from '../extension-api/types/layout.js';
14
14
 
15
15
  import { PageBlockContext } from '@/vdb/framework/layout-engine/page-block-provider.js';
16
16
  import { PageContext, PageContextValue } from '@/vdb/framework/layout-engine/page-provider.js';
@@ -42,7 +42,7 @@ export interface PageProps extends ComponentProps<'div'> {
42
42
  * @docsWeight 0
43
43
  * @since 3.3.0
44
44
  */
45
- export function Page({ children, pageId, entity, form, submitHandler, ...props }: PageProps) {
45
+ export function Page({ children, pageId, entity, form, submitHandler, ...props }: Readonly<PageProps>) {
46
46
  const childArray = React.Children.toArray(children);
47
47
 
48
48
  const pageTitle = childArray.find(child => React.isValidElement(child) && child.type === PageTitle);
@@ -164,7 +164,7 @@ function isPageBlock(child: unknown): child is React.ReactElement<PageBlockProps
164
164
  * @docsWeight 0
165
165
  * @since 3.3.0
166
166
  */
167
- export function PageLayout({ children, className }: PageLayoutProps) {
167
+ export function PageLayout({ children, className }: Readonly<PageLayoutProps>) {
168
168
  const page = usePage();
169
169
  const isDesktop = useMediaQuery('only screen and (min-width : 769px)');
170
170
  // Separate blocks into categories
@@ -238,7 +238,7 @@ export function PageLayout({ children, className }: PageLayoutProps) {
238
238
  );
239
239
  }
240
240
 
241
- export function DetailFormGrid({ children }: { children: React.ReactNode }) {
241
+ export function DetailFormGrid({ children }: Readonly<{ children: React.ReactNode }>) {
242
242
  return <div className="md:grid md:grid-cols-2 gap-4 items-start mb-4">{children}</div>;
243
243
  }
244
244
 
@@ -252,7 +252,7 @@ export function DetailFormGrid({ children }: { children: React.ReactNode }) {
252
252
  * @docsPage PageTitle
253
253
  * @since 3.3.0
254
254
  */
255
- export function PageTitle({ children }: { children: React.ReactNode }) {
255
+ export function PageTitle({ children }: Readonly<{ children: React.ReactNode }>) {
256
256
  return <h1 className="text-2xl font-semibold">{children}</h1>;
257
257
  }
258
258
 
@@ -269,7 +269,7 @@ export function PageTitle({ children }: { children: React.ReactNode }) {
269
269
  * @docsWeight 0
270
270
  * @since 3.3.0
271
271
  */
272
- export function PageActionBar({ children }: { children: React.ReactNode }) {
272
+ export function PageActionBar({ children }: Readonly<{ children: React.ReactNode }>) {
273
273
  let childArray = React.Children.toArray(children);
274
274
 
275
275
  const leftContent = childArray.filter(child => isOfType(child, PageActionBarLeft));
@@ -291,7 +291,7 @@ export function PageActionBar({ children }: { children: React.ReactNode }) {
291
291
  * @docsPage PageActionBar
292
292
  * @since 3.3.0
293
293
  */
294
- export function PageActionBarLeft({ children }: { children: React.ReactNode }) {
294
+ export function PageActionBarLeft({ children }: Readonly<{ children: React.ReactNode }>) {
295
295
  return <div className="flex justify-start gap-2">{children}</div>;
296
296
  }
297
297
 
@@ -303,7 +303,7 @@ export function PageActionBarLeft({ children }: { children: React.ReactNode }) {
303
303
  * @docsPage PageActionBar
304
304
  * @since 3.3.0
305
305
  */
306
- export function PageActionBarRight({ children }: { children: React.ReactNode }) {
306
+ export function PageActionBarRight({ children }: Readonly<{ children: React.ReactNode }>) {
307
307
  const page = usePage();
308
308
  const actionBarItems = page.pageId ? getDashboardActionBarItems(page.pageId) : [];
309
309
  return (
@@ -355,7 +355,14 @@ export type PageBlockProps = {
355
355
  * @docsWeight 0
356
356
  * @since 3.3.0
357
357
  */
358
- export function PageBlock({ children, title, description, className, blockId, column }: PageBlockProps) {
358
+ export function PageBlock({
359
+ children,
360
+ title,
361
+ description,
362
+ className,
363
+ blockId,
364
+ column,
365
+ }: Readonly<PageBlockProps>) {
359
366
  return (
360
367
  <LocationWrapper blockId={blockId}>
361
368
  <PageBlockContext.Provider value={{ blockId, title, description, column }}>
@@ -9,21 +9,15 @@ import {
9
9
  PaginatedListDataTable,
10
10
  RowAction,
11
11
  } from '@/vdb/components/shared/paginated-list-data-table.js';
12
- import { BulkAction } from '@/vdb/framework/data-table/data-table-types.js';
13
12
  import { useUserSettings } from '@/vdb/hooks/use-user-settings.js';
14
13
  import { TypedDocumentNode } from '@graphql-typed-document-node/core';
15
14
  import { AnyRoute, AnyRouter, useNavigate } from '@tanstack/react-router';
16
15
  import { ColumnFiltersState, SortingState, Table } from '@tanstack/react-table';
17
16
  import { TableOptions } from '@tanstack/table-core';
18
17
 
18
+ import { BulkAction } from '@/vdb/framework/extension-api/types/index.js';
19
19
  import { addCustomFields } from '../document-introspection/add-custom-fields.js';
20
- import {
21
- FullWidthPageBlock,
22
- Page,
23
- PageActionBar,
24
- PageLayout,
25
- PageTitle,
26
- } from '../layout-engine/page-layout.js';
20
+ import { FullWidthPageBlock, Page, PageActionBar, PageLayout, PageTitle } from '../layout-engine/page-layout.js';
27
21
 
28
22
  /**
29
23
  * @description
@@ -1,14 +1,14 @@
1
+ import {
2
+ BulkAction,
3
+ DashboardActionBarItem,
4
+ DashboardPageBlockDefinition,
5
+ DashboardWidgetDefinition,
6
+ } from '@/vdb/framework/extension-api/types/index.js';
1
7
  import { DocumentNode } from 'graphql';
2
8
  import React from 'react';
3
9
 
4
- import { DashboardAlertDefinition } from '../alert/types.js';
5
10
  import { DataDisplayComponent, DataInputComponent } from '../component-registry/component-registry.js';
6
- import { DashboardWidgetDefinition } from '../dashboard-widget/types.js';
7
- import { BulkAction } from '../data-table/data-table-types.js';
8
- import {
9
- DashboardActionBarItem,
10
- DashboardPageBlockDefinition,
11
- } from '../extension-api/extension-api-types.js';
11
+ import { DashboardAlertDefinition } from '../extension-api/types/alerts.js';
12
12
  import { CustomFormComponentInputProps } from '../form-engine/custom-form-component.js';
13
13
  import { NavMenuConfig } from '../nav-menu/nav-menu-extensions.js';
14
14