@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.
- package/dist/{CodeEditorComponent-lf915EGg.js → CodeEditorComponent-txM4ls17.js} +2 -2
- package/dist/{InputDateComponent-DD_fCyi_.js → InputDateComponent-C4QUlrmn.js} +2 -2
- package/dist/{RuleEngineComponent-CVD0pObW.js → RuleEngineComponent-dEe0FTBs.js} +266 -261
- package/dist/{en-CcBUYKzR.js → en-B-7ylwWx.js} +30 -1
- package/dist/{fetchCoreResourcesSuggestions-BS4pPkGo.js → fetchCoreResourcesSuggestions-DZuapPGj.js} +1 -1
- package/dist/helpers/numbers.d.ts +25 -0
- package/dist/helpers/numbers.test.d.ts +1 -0
- package/dist/hooks/useConfirmDialog.test.d.ts +1 -0
- package/dist/hooks/useOverlay.d.ts +9 -1
- package/dist/{it-y1Q1-MMT.js → it-BXPKgQsm.js} +30 -1
- package/dist/locales/en.d.ts +29 -0
- package/dist/{main-DIL89neT.js → main-Op1RV9MX.js} +23801 -19311
- package/dist/main.d.ts +9 -3
- package/dist/main.js +176 -165
- package/dist/mocks/data/core_schemas.d.ts +2 -0
- package/dist/mocks/data/event_stores.d.ts +2 -0
- package/dist/mocks/data/event_stores.test.d.ts +1 -0
- package/dist/{parseISO-CeYGLBle.js → parseISO-C1OS0R6q.js} +1 -1
- package/dist/providers/TokenProvider/MockTokenProvider.d.ts +1 -1
- package/dist/providers/TokenProvider/TokenProvider.d.ts +1 -1
- package/dist/style.css +1 -1
- package/dist/tailwind.global.css +8 -4
- package/dist/ui/atoms/AvatarLetter/AvatarLetter.d.ts +6 -1
- package/dist/ui/atoms/ButtonFilter.d.ts +17 -1
- package/dist/ui/atoms/Container.d.ts +10 -0
- package/dist/ui/atoms/PageHeading/PageHeading.d.ts +22 -4
- package/dist/ui/atoms/RadialProgress.d.ts +2 -2
- package/dist/ui/atoms/Section.d.ts +35 -0
- package/dist/ui/atoms/Spacer.d.ts +29 -4
- package/dist/ui/atoms/Stack.d.ts +48 -2
- package/dist/ui/atoms/Table/Table.d.ts +8 -0
- package/dist/ui/atoms/Tabs.d.ts +8 -0
- package/dist/ui/atoms/VisibilityTrigger.d.ts +19 -0
- package/dist/ui/atoms/VisibilityTrigger.test.d.ts +1 -0
- package/dist/ui/composite/Address.d.ts +9 -0
- package/dist/ui/composite/HomePageLayout.d.ts +3 -2
- package/dist/ui/composite/ListDetailsItem.d.ts +14 -1
- package/dist/ui/composite/PageLayout.d.ts +71 -1
- package/dist/ui/composite/PageLoading.d.ts +35 -0
- package/dist/ui/composite/PageLoading.test.d.ts +1 -0
- package/dist/ui/composite/PageSkeleton.d.ts +6 -0
- package/dist/ui/composite/Routes/LoadingPage.test.d.ts +1 -0
- package/dist/ui/forms/InputSelect/InputSelect.d.ts +8 -0
- package/dist/ui/internals/Overlay.test.d.ts +1 -0
- package/dist/ui/internals/bodyScrollLock.d.ts +2 -0
- package/dist/ui/internals/overlayContext.d.ts +36 -0
- package/dist/ui/resources/ResourceAddress/ResourceAddress.d.ts +12 -2
- package/dist/ui/resources/ResourceDetails/ResourceDetails.d.ts +9 -0
- package/dist/ui/resources/ResourceDetails/ResourceDetails.test.d.ts +1 -0
- package/dist/ui/resources/ResourceDetailsModal/ResourceAttributes.d.ts +11 -0
- package/dist/ui/resources/ResourceDetailsModal/ResourceDetailsContent.d.ts +43 -0
- package/dist/ui/resources/ResourceDetailsModal/ResourceDetailsContent.test.d.ts +1 -0
- package/dist/ui/resources/ResourceDetailsModal/ResourceEvents.d.ts +15 -0
- package/dist/ui/resources/ResourceDetailsModal/index.d.ts +2 -0
- package/dist/ui/resources/ResourceDetailsModal/resourceFields.d.ts +19 -0
- package/dist/ui/resources/ResourceDetailsModal/resourceFields.test.d.ts +1 -0
- package/dist/ui/resources/ResourceDetailsModal/useInfiniteScrollCursor.d.ts +39 -0
- package/dist/ui/resources/ResourceDetailsModal/useResourceDetailsModal.d.ts +23 -0
- package/dist/ui/resources/ResourceMetadata/ResourceMetadata.d.ts +9 -0
- package/dist/ui/resources/ResourceTags.d.ts +21 -1
- package/dist/ui/resources/ResourceTags.test.d.ts +1 -0
- package/dist/ui/resources/useResourceFilters/FieldOptionsSelect.d.ts +20 -0
- package/dist/ui/resources/useResourceFilters/FiltersBar.d.ts +64 -0
- package/dist/ui/resources/useResourceFilters/FiltersDrawer.d.ts +35 -0
- package/dist/ui/resources/useResourceFilters/FiltersSearchBar.d.ts +2 -2
- package/dist/ui/resources/useResourceFilters/activeFilters.d.ts +111 -0
- package/dist/ui/resources/useResourceFilters/activeFilters.test.d.ts +1 -0
- package/dist/ui/resources/useResourceFilters/types.d.ts +50 -0
- package/dist/ui/resources/useResourceFilters/useResourceFilters.d.ts +48 -0
- package/dist/ui/resources/useResourceFilters/utils.d.ts +10 -0
- package/dist/ui/resources/useResourceList/adaptMetricsOrderToCore.d.ts +5 -0
- package/dist/ui/resources/useResourceList/index.d.ts +1 -0
- package/dist/ui/resources/useResourceList/listFetcher.d.ts +7 -1
- package/dist/ui/resources/useResourceList/resourceListSignals.d.ts +46 -0
- package/dist/ui/resources/useResourceList/resourceListSignals.integration.test.d.ts +1 -0
- package/dist/ui/resources/useResourceList/resourceListSignals.test.d.ts +1 -0
- package/dist/ui/resources/useResourceList/useResourceList.d.ts +3 -1
- package/dist/ui/resources/useResourceTable/index.d.ts +2 -0
- package/dist/ui/resources/useResourceTable/types.d.ts +252 -0
- package/dist/ui/resources/useResourceTable/useResourceTable.d.ts +11 -0
- package/dist/ui/resources/useResourceTable/useResourceTable.test.d.ts +1 -0
- package/package.json +5 -3
- package/dist/ui/resources/useResourceList/VisibilityTrigger.d.ts +0 -8
- /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
|
-
|
|
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;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -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;
|
|
@@ -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 {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
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
|
-
*
|
|
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
|
/**
|