@commercelayer/app-elements 7.12.0 → 7.14.0

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 (84) hide show
  1. package/dist/{CodeEditorComponent-lf915EGg.js → CodeEditorComponent-txM4ls17.js} +2 -2
  2. package/dist/{InputDateComponent-DD_fCyi_.js → InputDateComponent-C4QUlrmn.js} +2 -2
  3. package/dist/{RuleEngineComponent-CVD0pObW.js → RuleEngineComponent-dEe0FTBs.js} +266 -261
  4. package/dist/{en-CcBUYKzR.js → en-B-7ylwWx.js} +30 -1
  5. package/dist/{fetchCoreResourcesSuggestions-BS4pPkGo.js → fetchCoreResourcesSuggestions-DZuapPGj.js} +1 -1
  6. package/dist/helpers/numbers.d.ts +25 -0
  7. package/dist/helpers/numbers.test.d.ts +1 -0
  8. package/dist/hooks/useConfirmDialog.test.d.ts +1 -0
  9. package/dist/hooks/useOverlay.d.ts +9 -1
  10. package/dist/{it-y1Q1-MMT.js → it-BXPKgQsm.js} +30 -1
  11. package/dist/locales/en.d.ts +29 -0
  12. package/dist/{main-DIL89neT.js → main-Op1RV9MX.js} +23801 -19311
  13. package/dist/main.d.ts +9 -3
  14. package/dist/main.js +176 -165
  15. package/dist/mocks/data/core_schemas.d.ts +2 -0
  16. package/dist/mocks/data/event_stores.d.ts +2 -0
  17. package/dist/mocks/data/event_stores.test.d.ts +1 -0
  18. package/dist/{parseISO-CeYGLBle.js → parseISO-C1OS0R6q.js} +1 -1
  19. package/dist/providers/TokenProvider/MockTokenProvider.d.ts +1 -1
  20. package/dist/providers/TokenProvider/TokenProvider.d.ts +1 -1
  21. package/dist/style.css +1 -1
  22. package/dist/tailwind.global.css +8 -4
  23. package/dist/ui/atoms/AvatarLetter/AvatarLetter.d.ts +6 -1
  24. package/dist/ui/atoms/ButtonFilter.d.ts +17 -1
  25. package/dist/ui/atoms/Container.d.ts +10 -0
  26. package/dist/ui/atoms/PageHeading/PageHeading.d.ts +22 -4
  27. package/dist/ui/atoms/RadialProgress.d.ts +2 -2
  28. package/dist/ui/atoms/Section.d.ts +35 -0
  29. package/dist/ui/atoms/Spacer.d.ts +29 -4
  30. package/dist/ui/atoms/Stack.d.ts +48 -2
  31. package/dist/ui/atoms/Table/Table.d.ts +8 -0
  32. package/dist/ui/atoms/Tabs.d.ts +8 -0
  33. package/dist/ui/atoms/VisibilityTrigger.d.ts +19 -0
  34. package/dist/ui/atoms/VisibilityTrigger.test.d.ts +1 -0
  35. package/dist/ui/composite/Address.d.ts +9 -0
  36. package/dist/ui/composite/HomePageLayout.d.ts +3 -2
  37. package/dist/ui/composite/ListDetailsItem.d.ts +14 -1
  38. package/dist/ui/composite/PageLayout.d.ts +71 -1
  39. package/dist/ui/composite/PageLoading.d.ts +35 -0
  40. package/dist/ui/composite/PageLoading.test.d.ts +1 -0
  41. package/dist/ui/composite/PageSkeleton.d.ts +6 -0
  42. package/dist/ui/composite/Routes/LoadingPage.test.d.ts +1 -0
  43. package/dist/ui/forms/InputSelect/InputSelect.d.ts +8 -0
  44. package/dist/ui/internals/Overlay.test.d.ts +1 -0
  45. package/dist/ui/internals/bodyScrollLock.d.ts +2 -0
  46. package/dist/ui/internals/overlayContext.d.ts +36 -0
  47. package/dist/ui/resources/ResourceAddress/ResourceAddress.d.ts +12 -2
  48. package/dist/ui/resources/ResourceDetails/ResourceDetails.d.ts +9 -0
  49. package/dist/ui/resources/ResourceDetails/ResourceDetails.test.d.ts +1 -0
  50. package/dist/ui/resources/ResourceDetailsModal/ResourceAttributes.d.ts +11 -0
  51. package/dist/ui/resources/ResourceDetailsModal/ResourceDetailsContent.d.ts +43 -0
  52. package/dist/ui/resources/ResourceDetailsModal/ResourceDetailsContent.test.d.ts +1 -0
  53. package/dist/ui/resources/ResourceDetailsModal/ResourceEvents.d.ts +15 -0
  54. package/dist/ui/resources/ResourceDetailsModal/index.d.ts +2 -0
  55. package/dist/ui/resources/ResourceDetailsModal/resourceFields.d.ts +19 -0
  56. package/dist/ui/resources/ResourceDetailsModal/resourceFields.test.d.ts +1 -0
  57. package/dist/ui/resources/ResourceDetailsModal/useInfiniteScrollCursor.d.ts +39 -0
  58. package/dist/ui/resources/ResourceDetailsModal/useResourceDetailsModal.d.ts +23 -0
  59. package/dist/ui/resources/ResourceMetadata/ResourceMetadata.d.ts +9 -0
  60. package/dist/ui/resources/ResourceTags.d.ts +21 -1
  61. package/dist/ui/resources/ResourceTags.test.d.ts +1 -0
  62. package/dist/ui/resources/useResourceFilters/FieldOptionsSelect.d.ts +20 -0
  63. package/dist/ui/resources/useResourceFilters/FiltersBar.d.ts +64 -0
  64. package/dist/ui/resources/useResourceFilters/FiltersDrawer.d.ts +35 -0
  65. package/dist/ui/resources/useResourceFilters/FiltersSearchBar.d.ts +2 -2
  66. package/dist/ui/resources/useResourceFilters/activeFilters.d.ts +111 -0
  67. package/dist/ui/resources/useResourceFilters/activeFilters.test.d.ts +1 -0
  68. package/dist/ui/resources/useResourceFilters/types.d.ts +50 -0
  69. package/dist/ui/resources/useResourceFilters/useResourceFilters.d.ts +48 -0
  70. package/dist/ui/resources/useResourceFilters/utils.d.ts +10 -0
  71. package/dist/ui/resources/useResourceList/adaptMetricsOrderToCore.d.ts +5 -0
  72. package/dist/ui/resources/useResourceList/index.d.ts +1 -0
  73. package/dist/ui/resources/useResourceList/listFetcher.d.ts +7 -1
  74. package/dist/ui/resources/useResourceList/resourceListSignals.d.ts +46 -0
  75. package/dist/ui/resources/useResourceList/resourceListSignals.integration.test.d.ts +1 -0
  76. package/dist/ui/resources/useResourceList/resourceListSignals.test.d.ts +1 -0
  77. package/dist/ui/resources/useResourceList/useResourceList.d.ts +3 -1
  78. package/dist/ui/resources/useResourceTable/index.d.ts +2 -0
  79. package/dist/ui/resources/useResourceTable/types.d.ts +252 -0
  80. package/dist/ui/resources/useResourceTable/useResourceTable.d.ts +11 -0
  81. package/dist/ui/resources/useResourceTable/useResourceTable.test.d.ts +1 -0
  82. package/package.json +5 -3
  83. package/dist/ui/resources/useResourceList/VisibilityTrigger.d.ts +0 -8
  84. /package/dist/{ui/resources/useResourceList/VisibilityTrigger.test.d.ts → dictionaries/orders.test.d.ts} +0 -0
@@ -1,9 +1,28 @@
1
1
  import { ListableResourceType } from '@commercelayer/sdk';
2
2
  import { EditTagsOverlayProps } from '../../hooks/useEditTagsOverlay';
3
- type TaggableResource = Extract<ListableResourceType, "addresses" | "bundles" | "coupons" | "customers" | "gift_cards" | "line_items" | "line_item_options" | "order_subscriptions" | "orders" | "buy_x_pay_y_promotions" | "external_promotions" | "fixed_amount_promotions" | "fixed_price_promotions" | "flex_promotions" | "free_gift_promotions" | "free_shipping_promotions" | "percentage_discount_promotions" | "returns" | "shipments" | "shipping_methods" | "sku_options" | "skus">;
3
+ /**
4
+ * The resources the API can tag, as a value so that a caller can ask at runtime —
5
+ * `ResourceAdminBlocks` leaves the block out for a stock item or an import.
6
+ *
7
+ * The SDK declares an `isTaggable()` helper and a `taggableResources` array in its
8
+ * types but ships neither in its build, so calling them typechecks and then throws.
9
+ * Hence our own list, checked against `ListableResourceType` by `satisfies`.
10
+ */
11
+ export declare const taggableResources: readonly ["addresses", "bundles", "coupons", "customers", "gift_cards", "line_items", "line_item_options", "order_subscriptions", "orders", "buy_x_pay_y_promotions", "external_promotions", "fixed_amount_promotions", "fixed_price_promotions", "flex_promotions", "free_gift_promotions", "free_shipping_promotions", "percentage_discount_promotions", "returns", "shipments", "shipping_methods", "sku_options", "skus"];
12
+ export type TaggableResource = (typeof taggableResources)[number];
13
+ /** Whether the API can tag this resource. */
14
+ export declare function isTaggableResource(resourceType: ListableResourceType): resourceType is TaggableResource;
4
15
  interface TagsOverlay extends Omit<EditTagsOverlayProps, "resourceId" | "resourceType"> {
5
16
  }
6
17
  export interface ResourceTagsProps {
18
+ /**
19
+ * How the block renders, overriding what it infers from where it sits.
20
+ *
21
+ * Inferred by default — `PageLayout`'s sidebar slot reports `"sidebar"`, while a
22
+ * page and a drawer both report the wider `"default"`. Pass it only to force a
23
+ * rendering the surrounding surface would not choose.
24
+ */
25
+ variant?: "default" | "sidebar";
7
26
  resourceType: TaggableResource;
8
27
  resourceId: string;
9
28
  /**
@@ -19,6 +38,7 @@ export interface ResourceTagsProps {
19
38
  * This component generates an all-in-one visualization and editing interface for managing tags relationship of requested resource.
20
39
  */
21
40
  export declare const ResourceTags: import('../atoms/SkeletonTemplate').SkeletonTemplateComponent<{
41
+ variant?: "default" | "sidebar" | undefined;
22
42
  resourceType: TaggableResource;
23
43
  resourceId: string;
24
44
  overlay?: TagsOverlay
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ import { JSX } from 'react';
2
+ import { FilterItemOptions } from './types';
3
+ type SelectRender = Extract<FilterItemOptions["render"], {
4
+ component: "inputSelect";
5
+ }>;
6
+ /**
7
+ * Renders an `options` filter as a (multi) select dropdown, the style used by the
8
+ * dashboard metrics filters.
9
+ *
10
+ * Options come from the Core API. Anything already selected is fetched
11
+ * separately, so its label resolves even when it is not in the first page, and
12
+ * when `searchBy` is set typing searches server-side instead of filtering only
13
+ * what has been loaded.
14
+ */
15
+ export declare function FieldOptionsSelect({ item, }: {
16
+ item: FilterItemOptions & {
17
+ render: SelectRender;
18
+ };
19
+ }): JSX.Element | null;
20
+ export {};
@@ -0,0 +1,64 @@
1
+ import { JSX, ReactNode } from 'react';
2
+ import { FiltersInstructions, FormFullValues } from './types';
3
+ export interface FiltersBarProps {
4
+ /**
5
+ * Url query string to be parsed.
6
+ * It must be "reactive", so most of the time it should come from the router.
7
+ */
8
+ queryString: string;
9
+ /**
10
+ * Callback triggered when the user interacts with the search bar or removes a
11
+ * filter. The implementation should update the url query string.
12
+ */
13
+ onUpdate: (newQueryString: string) => void;
14
+ /**
15
+ * Filters that are already implied by the current view, typically the ones
16
+ * defining the active tab.
17
+ *
18
+ * They are not rendered as pills, removing a pill reverts that single filter
19
+ * back to the value defined here, and "clear all" reverts to this set rather
20
+ * than to no filters at all.
21
+ */
22
+ defaultValues?: FormFullValues;
23
+ /**
24
+ * Overrides the filters button behavior. When set, the built-in drawer is not
25
+ * opened and the app is responsible for rendering the filters form — for
26
+ * example by navigating to a dedicated filters page.
27
+ */
28
+ onFilterClick?: () => void;
29
+ /**
30
+ * Placeholder text for the search bar
31
+ * @default 'Search...'
32
+ */
33
+ searchBarPlaceholder?: string;
34
+ /**
35
+ * Milliseconds to wait before triggering the search bar callback
36
+ * @default 500
37
+ */
38
+ searchBarDebounceMs?: number;
39
+ /**
40
+ * Hide the search bar, keeping the filters button and the pills.
41
+ * @default false
42
+ */
43
+ hideSearchBar?: boolean;
44
+ /**
45
+ * Rendered to the right of the filters button, for page level actions such as
46
+ * an export button.
47
+ */
48
+ actions?: ReactNode;
49
+ }
50
+ interface InternalProps {
51
+ instructions: FiltersInstructions;
52
+ predicateWhitelist: string[];
53
+ /** Opens the drawer rendered by `FiltersDrawer`. */
54
+ openDrawer: () => void;
55
+ }
56
+ /**
57
+ * Search bar with the filters button on the right and the applied filters
58
+ * rendered as removable pills below.
59
+ */
60
+ export declare function FiltersBar({ queryString, onUpdate, defaultValues, onFilterClick, searchBarPlaceholder, searchBarDebounceMs, hideSearchBar, actions, instructions, predicateWhitelist, openDrawer, }: FiltersBarProps & InternalProps): JSX.Element;
61
+ export declare namespace FiltersBar {
62
+ var displayName: string;
63
+ }
64
+ export {};
@@ -0,0 +1,35 @@
1
+ import { JSX } from 'react';
2
+ import { OverlayProps } from '../../internals/Overlay';
3
+ import { FiltersInstructions } from './types';
4
+ export interface FiltersDrawerProps {
5
+ /**
6
+ * Callback triggered when the user applies the filters.
7
+ * The implementation should update the url query string.
8
+ */
9
+ onUpdate: (newQueryString: string) => void;
10
+ /**
11
+ * Title of the drawer
12
+ * @default 'Filters'
13
+ */
14
+ title?: string;
15
+ }
16
+ interface InternalProps {
17
+ instructions: FiltersInstructions;
18
+ predicateWhitelist: string[];
19
+ /** Overlay component from the hook, shared with the bar's filters button. */
20
+ Overlay: React.FC<OverlayProps>;
21
+ close: () => void;
22
+ /** Current url query string, from the hook scope. */
23
+ queryString: string;
24
+ }
25
+ /**
26
+ * Side drawer containing the filters form, opened by the `FiltersBar` filters
27
+ * button.
28
+ *
29
+ * Render it once per page, as a sibling of `FiltersBar`.
30
+ */
31
+ export declare function FiltersDrawer({ onUpdate, title, instructions, predicateWhitelist, Overlay, close, queryString, }: FiltersDrawerProps & InternalProps): JSX.Element;
32
+ export declare namespace FiltersDrawer {
33
+ var displayName: string;
34
+ }
35
+ export {};
@@ -1,7 +1,7 @@
1
1
  import { JSX } from 'react';
2
2
  import { SearchBarProps } from '../../composite/SearchBar';
3
3
  import { FiltersInstructions } from './types';
4
- export interface FilterSearchBarProps extends Pick<SearchBarProps, "placeholder" | "debounceMs"> {
4
+ export interface FilterSearchBarProps extends Pick<SearchBarProps, "placeholder" | "debounceMs" | "variant"> {
5
5
  /**
6
6
  * Array of instruction items to build the filters behaviors
7
7
  */
@@ -31,7 +31,7 @@ export interface FilterSearchBarProps extends Pick<SearchBarProps, "placeholder"
31
31
  */
32
32
  predicateWhitelist: string[];
33
33
  }
34
- declare function FiltersSearchBar({ instructions, placeholder, onUpdate, queryString, predicateWhitelist, debounceMs, }: FilterSearchBarProps): JSX.Element;
34
+ declare function FiltersSearchBar({ instructions, placeholder, onUpdate, queryString, predicateWhitelist, debounceMs, variant, }: FilterSearchBarProps): JSX.Element;
35
35
  declare namespace FiltersSearchBar {
36
36
  var displayName: string;
37
37
  }
@@ -0,0 +1,111 @@
1
+ import { ListableResourceType } from '@commercelayer/sdk';
2
+ import { formatDateRange } from '../../../helpers/date';
3
+ import { CurrencyRangeFieldValue, FiltersInstructionItem, FiltersInstructions, FormFullValues, UiFilterValue } from './types';
4
+ /**
5
+ * Shared helpers to read the active filters out of a url query string and turn
6
+ * them into human readable labels.
7
+ *
8
+ * Used by both `FiltersNav` (legacy `ButtonFilter` look) and `FiltersBar`
9
+ * (metrics-style pills), so label resolution only ever has one implementation.
10
+ */
11
+ export declare function getInstructionItemByFilterPredicate({ instructions, filterPredicate, }: {
12
+ instructions: FiltersInstructions;
13
+ filterPredicate: string;
14
+ }): FiltersInstructionItem | undefined;
15
+ /**
16
+ * Get label for user defined ButtonFilter component by reading the `instructionItem` object.
17
+ * If the filter has options and only one value is selected, the label will be the option label.
18
+ * Otherwise, the label will be the filter group label plus the number of selected values.
19
+ */
20
+ export declare function getButtonFilterLabel({ values, instructionItem, }: {
21
+ values: string | string[];
22
+ instructionItem: FiltersInstructionItem;
23
+ }): string;
24
+ export declare function extractCurrencyRangeFilterValues({ activeFilters, instructions, }: {
25
+ activeFilters: Array<[string, UiFilterValue]>;
26
+ instructions: FiltersInstructions;
27
+ }): Array<[string, CurrencyRangeFieldValue]>;
28
+ /**
29
+ * Checks if a filter predicate belongs to a currency range filter
30
+ * by checking the instructions
31
+ */
32
+ export declare function predicateBelongsToCurrencyRange({ filterPredicate, instructions, }: {
33
+ filterPredicate: string;
34
+ instructions: FiltersInstructions;
35
+ }): boolean;
36
+ export declare function makeCurrencyRangeFilterButtonLabel(value: CurrencyRangeFieldValue): string;
37
+ /**
38
+ * Resolves every selected value to its option label and joins them.
39
+ *
40
+ * Unlike {@link getButtonFilterLabel}, which collapses multiple values into a
41
+ * counter (`Markets · 2`), this spells them all out (`Europe, Italy`) because a
42
+ * pill already shows the filter name separately.
43
+ */
44
+ export declare function formatPillFilterValue({ values, instructionItem, }: {
45
+ values: string | string[];
46
+ instructionItem: FiltersInstructionItem;
47
+ }): string;
48
+ /**
49
+ * Compares two filter values ignoring array wrapping and ordering, so that
50
+ * `"placed"`, `["placed"]` and `["placed"]` in a different order all match.
51
+ * Range values (objects) are compared as-is.
52
+ */
53
+ export declare function isSameFilterValue(a: unknown, b: unknown): boolean;
54
+ export interface PillFilter {
55
+ /**
56
+ * Predicate of the filter, or `timePreset` for the time range.
57
+ * Used as react key and to know what to reset when removing the pill.
58
+ */
59
+ id: string;
60
+ /** Filter group label, e.g. `Payment status`. */
61
+ label: string;
62
+ /**
63
+ * Formatted value(s), e.g. `Paid, Authorized`.
64
+ * `undefined` when it has to be resolved by fetching the resource, see `fetch`.
65
+ */
66
+ value?: string;
67
+ /**
68
+ * Set for filters backed by a resource (`inputResourceGroup`, `inputSelect`),
69
+ * whose labels live on the resources themselves and have to be retrieved.
70
+ */
71
+ fetch?: {
72
+ resource: ListableResourceType;
73
+ ids: string[];
74
+ fieldForLabel: string;
75
+ fieldForValue: string;
76
+ };
77
+ /** Which reset strategy the remove button has to apply. */
78
+ kind: "group" | "timeRange";
79
+ }
80
+ /**
81
+ * Reads the url query string and returns one descriptor per active filter, ready
82
+ * to be rendered as a pill.
83
+ *
84
+ * Filters matching `defaultValues` are omitted: on a page where the current view
85
+ * (e.g. a tab) already implies a set of filters, only the user's additions are
86
+ * worth showing as removable pills.
87
+ *
88
+ * The free text filter is always omitted, since it is already visible in the
89
+ * search bar, and so are hidden filters and `viewTitle`.
90
+ */
91
+ export declare function getPillFilters({ instructions, queryString, predicateWhitelist, defaultValues, timezone, locale, }: {
92
+ instructions: FiltersInstructions;
93
+ queryString: string;
94
+ predicateWhitelist: string[];
95
+ defaultValues?: FormFullValues;
96
+ timezone?: string;
97
+ locale?: Parameters<typeof formatDateRange>[0]["locale"];
98
+ }): PillFilter[];
99
+ /**
100
+ * Form values to apply when clearing all the filters at once.
101
+ *
102
+ * Hidden filters, `viewTitle` and the free text search are preserved — they are
103
+ * not represented as pills, so wiping them would be an invisible side effect.
104
+ * Everything else goes back to `defaultValues` (empty when not provided).
105
+ */
106
+ export declare function getClearedFormValues({ instructions, queryString, predicateWhitelist, defaultValues, }: {
107
+ instructions: FiltersInstructions;
108
+ queryString: string;
109
+ predicateWhitelist: string[];
110
+ defaultValues?: FormFullValues;
111
+ }): FormFullValues;
@@ -138,6 +138,47 @@ export type FilterItemOptions = BaseFilterItem & {
138
138
  * props required for the UI component
139
139
  */
140
140
  props: Omit<InputResourceGroupProps, "onChange" | "defaultValues" | "title">;
141
+ } | {
142
+ /**
143
+ * UI component to render: a select dropdown, matching the style of the
144
+ * dashboard metrics filters. Prefer it over `inputResourceGroup` when the
145
+ * options are many, since it searches server-side instead of showing a
146
+ * checkbox list with a "see all" overlay.
147
+ */
148
+ component: "inputSelect";
149
+ /**
150
+ * props required for the UI component.
151
+ *
152
+ * Either a fixed list of `options` — statuses, kinds, anything the app
153
+ * already knows — or a `resource` the options are fetched from.
154
+ */
155
+ props: ({
156
+ /**
157
+ * The options to choose from. An option can be hidden from the UI
158
+ * and still be accepted in the query, e.g. a status that is only
159
+ * ever set through a predefined link.
160
+ */
161
+ options: Array<{
162
+ label: string;
163
+ value: string;
164
+ isHidden?: boolean;
165
+ }>;
166
+ } | (Pick<InputResourceGroupProps, "resource" | "fieldForLabel" | "fieldForValue" | "searchBy" | "sortBy" | "filters" | "hideWhenSingleItem"> & {
167
+ /**
168
+ * How many options to load upfront. Capped at 25 by the Core API, which
169
+ * is why `searchBy` should be set when more options exist.
170
+ * @default 25
171
+ */
172
+ limit?: number;
173
+ })) & {
174
+ placeholder?: string;
175
+ isClearable?: boolean;
176
+ /**
177
+ * Filter predicates are usually `_in`, so multiple values are expected.
178
+ * @default true
179
+ */
180
+ isMulti?: boolean;
181
+ };
141
182
  };
142
183
  };
143
184
  export interface FilterItemTextSearch extends Omit<BaseFilterItem, "sdk"> {
@@ -186,6 +227,15 @@ export type FiltersInstructionItem = FilterItemOptions | FilterItemTextSearch |
186
227
  export type FiltersInstructions = FiltersInstructionItem[];
187
228
  export declare function isItemOptions(item: FiltersInstructionItem): item is FilterItemOptions;
188
229
  export declare function isTextSearch(item: FiltersInstructionItem): item is FilterItemTextSearch;
230
+ /**
231
+ * The predicate of the free text filter shown in the search bar, if any.
232
+ *
233
+ * Not simply the first `textSearch` instruction: apps also declare `textSearch`
234
+ * items for predicates they only want whitelisted (hidden ones driving tabs, for
235
+ * instance), and those can come first. There is at most one `searchBar` in a set
236
+ * of instructions, so this is unambiguous.
237
+ */
238
+ export declare function getSearchBarPredicate(instructions: FiltersInstructions): string | undefined;
189
239
  export declare function isCurrencyRange(item: FiltersInstructionItem): item is FilterItemCurrencyRange;
190
240
  export declare function isGroupedPredicates(item: FiltersInstructionItem): item is FilterItemGroupedPredicates;
191
241
  /**
@@ -1,7 +1,11 @@
1
1
  import { ListableResourceType, QueryFilter } from '@commercelayer/sdk';
2
+ import { SearchBarProps } from '../../composite/SearchBar';
2
3
  import { UseResourceListConfig } from '../useResourceList';
3
4
  import { ResourceListProps } from '../useResourceList/useResourceList';
5
+ import { ResourceTableProps, UseResourceTableConfig } from '../useResourceTable/types';
4
6
  import { makeFilterAdapters } from './adapters';
7
+ import { FiltersBarProps } from './FiltersBar';
8
+ import { FiltersDrawerProps } from './FiltersDrawer';
5
9
  import { FiltersFormProps } from './FiltersForm';
6
10
  import { FiltersNavProps } from './FiltersNav';
7
11
  import { FiltersInstructions } from './types';
@@ -29,8 +33,34 @@ interface UseResourceFiltersHook {
29
33
  * Helper methods to transform filters from/to url query string, sdk and form values
30
34
  */
31
35
  adapters: ReturnType<typeof makeFilterAdapters>;
36
+ /**
37
+ * Search bar with the filters button on the right and the applied filters
38
+ * rendered as removable pills below.
39
+ *
40
+ * Clicking the filters button opens the drawer rendered by `FiltersDrawer`,
41
+ * unless an `onFilterClick` prop is provided.
42
+ *
43
+ * @example
44
+ * ```jsx
45
+ * const { FiltersBar, FiltersDrawer, FilteredTable } = useResourceFilters({ instructions })
46
+ *
47
+ * <FiltersBar queryString={queryString} onUpdate={onUpdate} />
48
+ * <FilteredTable type='orders' columns={columns} />
49
+ * <FiltersDrawer onUpdate={onUpdate} />
50
+ * ```
51
+ */
52
+ FiltersBar: (props: FiltersBarProps) => React.ReactNode;
53
+ /**
54
+ * Side drawer with the filters form, opened by the `FiltersBar` filters button.
55
+ * Render it once per page as a sibling of `FiltersBar`.
56
+ */
57
+ FiltersDrawer: (props: FiltersDrawerProps) => React.ReactNode;
32
58
  /**
33
59
  * Search bar component with filters navigation buttons
60
+ *
61
+ * @deprecated Use `FiltersBar` together with `FiltersDrawer` instead, they
62
+ * render the search bar and the filters as pills in the style used by the
63
+ * dashboard. This component will be removed in a future major release.
34
64
  */
35
65
  SearchWithNav: (props: Pick<FiltersNavProps, "onFilterClick" | "queryString"> & {
36
66
  /**
@@ -44,6 +74,11 @@ interface UseResourceFiltersHook {
44
74
  * @default 'Search...'
45
75
  */
46
76
  searchBarPlaceholder?: string;
77
+ /**
78
+ * Visual variant of the search bar. Use `outline` to match the style used
79
+ * in the dashboard (metrics) pages.
80
+ */
81
+ searchBarVariant?: SearchBarProps["variant"];
47
82
  /**
48
83
  * Milliseconds to wait before triggering the search bar callback
49
84
  * @default 500
@@ -65,6 +100,19 @@ interface UseResourceFiltersHook {
65
100
  };
66
101
  hideTitle?: boolean;
67
102
  }) => React.ReactNode;
103
+ /**
104
+ * Filtered ResourceTable component based on current active filters.
105
+ * Table sibling of `FilteredList`: renders a column-model data table wired
106
+ * to the active search/filters and pagination.
107
+ */
108
+ FilteredTable: <TResource extends ListableResourceType>(props: Omit<UseResourceTableConfig<TResource>, "query" | "metricsQuery"> & ResourceTableProps & {
109
+ query?: Omit<NonNullable<UseResourceTableConfig<TResource>["query"]>, "filters">;
110
+ metricsQuery?: Omit<NonNullable<UseResourceTableConfig<TResource>["metricsQuery"]>, "filter"> & {
111
+ /** Filters need to be configured within the `useResourceFilters` options. */
112
+ filter?: never;
113
+ };
114
+ hideTitle?: boolean;
115
+ }) => React.ReactNode;
68
116
  /**
69
117
  * SDK filters object to be used in the sdk query
70
118
  */
@@ -27,3 +27,13 @@ export declare function getActiveFilterCountFromUrl({ includeTextSearch, instruc
27
27
  queryString: string;
28
28
  }): number;
29
29
  export declare function getAllowedValuesFromItemOptions(instructionItem: FilterItemOptions): string[] | undefined;
30
+ /**
31
+ * Whether an `options` filter holds a single value rather than a list.
32
+ *
33
+ * Two components can be single-valued and they say so differently: a toggle
34
+ * button through `mode`, a select through `isMulti`. Anything reading a filter
35
+ * value has to know which, so the value can be unwrapped from the array the URL
36
+ * always parses into — a predicate like `archived_at_null` expects `"hide"`,
37
+ * not `["hide"]`.
38
+ */
39
+ export declare function isSingleValueOptionsItem(instructionItem: FilterItemOptions): boolean;
@@ -70,5 +70,10 @@ export interface MetricsResourceOrder {
70
70
  first_name?: string;
71
71
  last_name?: string;
72
72
  };
73
+ customer?: {
74
+ id?: string;
75
+ email?: string;
76
+ total_orders_count?: number;
77
+ };
73
78
  }
74
79
  export declare function adaptMetricsOrderToCore(metricsOrder: MetricsResourceOrder): Order;
@@ -1 +1,2 @@
1
+ export { refreshResourceLists, removeFromResourceLists, } from './resourceListSignals';
1
2
  export { type ResourceListItemTemplateProps, type ResourceListProps, type UseResourceListConfig, useResourceList, } from './useResourceList';
@@ -12,11 +12,17 @@ export interface FetcherResponse<TResource> {
12
12
  cursor?: string | null;
13
13
  };
14
14
  }
15
- export declare function listFetcher<TResource extends ListableResourceType>({ currentData, resourceType, client, clientType, query, mode, pageNumber, }: {
15
+ export declare function listFetcher<TResource extends ListableResourceType>({ currentData, resourceType, client, clientType, query, mode, pageNumber, cursor, }: {
16
16
  currentData?: FetcherResponse<Resource<TResource>>;
17
17
  resourceType: TResource;
18
18
  mode?: "infinite" | "pagination";
19
19
  pageNumber?: number;
20
+ /**
21
+ * Metrics API only: the cursor that opens the requested page. Used in
22
+ * `pagination` mode, where the caller keeps track of one cursor per page
23
+ * (the metrics API can only move forward on its own).
24
+ */
25
+ cursor?: string | null;
20
26
  } & ({
21
27
  client: CommerceLayerBundle;
22
28
  clientType: "coreSdkClient";
@@ -0,0 +1,46 @@
1
+ import { ListableResourceType } from '@commercelayer/sdk';
2
+ /**
3
+ * What a mounted list is being asked to do.
4
+ * - `removeItem` drops a single row without any request
5
+ * - `refresh` refetches from the first page
6
+ */
7
+ type ResourceListSignal = {
8
+ kind: "removeItem";
9
+ resourceId: string;
10
+ } | {
11
+ kind: "refresh";
12
+ };
13
+ type ResourceListSubscriber = (signal: ResourceListSignal) => void;
14
+ /**
15
+ * Subscribe a mounted list to the signals for a resource type.
16
+ * Called by `useResourceList`; returns the unsubscribe function.
17
+ */
18
+ export declare function subscribeToResourceLists(type: ListableResourceType, subscriber: ResourceListSubscriber): () => void;
19
+ /**
20
+ * Drop a row from every mounted list of the given resource type, with no
21
+ * request. Call it right after a successful delete.
22
+ *
23
+ * Needed when the component that deletes is not the one rendering the list —
24
+ * typically a details drawer rendered as a sibling of the list, which leaves the
25
+ * list mounted, so it would otherwise keep showing the deleted row until the
26
+ * page is reloaded. Lists that do not hold the row ignore the signal, and the
27
+ * total record count is adjusted for those that do.
28
+ *
29
+ * @example
30
+ * await sdkClient.stock_items.delete(stockItem.id)
31
+ * removeFromResourceLists("stock_items", stockItem.id)
32
+ */
33
+ export declare function removeFromResourceLists(type: ListableResourceType, resourceId: string): void;
34
+ /**
35
+ * Refetch every mounted list of the given resource type from the first page.
36
+ *
37
+ * Prefer `removeFromResourceLists` after a delete: it is instant, and it neither
38
+ * flashes the loading skeleton nor renumbers an infinite list mid-scroll. Reach
39
+ * for this one when rows were created or edited elsewhere and the list content
40
+ * can no longer be patched locally.
41
+ *
42
+ * A signal emitted while no list is mounted is a no-op — which is harmless,
43
+ * since a list fetches on mount anyway.
44
+ */
45
+ export declare function refreshResourceLists(type: ListableResourceType): void;
46
+ export {};
@@ -79,7 +79,9 @@ export type UseResourceListConfig<TResource extends ListableResourceType> = {
79
79
  preProcess?: (list: Array<Resource<TResource>>) => Array<Resource<TResource>>;
80
80
  /**
81
81
  * Pagination type: 'infinite' for infinite scrolling (default), 'pagination' for classic prev/next pagination.
82
- * Note: 'pagination' mode is only supported for Core API (not Metrics API).
82
+ * Works with both the Core API and the Metrics API. Since the Metrics API is
83
+ * cursor-based, prev/next works by remembering the cursor that opens each
84
+ * visited page; arbitrary page jumps are not possible there.
83
85
  */
84
86
  paginationType?: "infinite" | "pagination";
85
87
  /**
@@ -0,0 +1,2 @@
1
+ export type { ResourceTableColumn, ResourceTableProps, ResourceTableSort, UseResourceTableConfig, UseResourceTableReturn, } from './types';
2
+ export { useResourceTable } from './useResourceTable';