@vendure/dashboard 3.3.8-master-202507290247 → 3.3.8-master-202507310242
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/package.json +4 -4
- package/src/app/routes/_authenticated/_collections/components/collection-contents-preview-table.tsx +1 -1
- package/src/app/routes/_authenticated/_collections/components/collection-filters-selector.tsx +11 -78
- package/src/app/routes/_authenticated/_global-settings/global-settings.tsx +16 -8
- package/src/app/routes/_authenticated/_payment-methods/components/payment-eligibility-checker-selector.tsx +11 -81
- package/src/app/routes/_authenticated/_payment-methods/components/payment-handler-selector.tsx +10 -77
- package/src/app/routes/_authenticated/_promotions/components/promotion-actions-selector.tsx +12 -87
- package/src/app/routes/_authenticated/_promotions/components/promotion-conditions-selector.tsx +12 -87
- package/src/app/routes/_authenticated/_shipping-methods/components/shipping-calculator-selector.tsx +10 -80
- package/src/app/routes/_authenticated/_shipping-methods/components/shipping-eligibility-checker-selector.tsx +10 -79
- package/src/app/routes/_authenticated/_shipping-methods/shipping-methods_.$id.tsx +8 -6
- package/src/app/routes/_authenticated/_system/components/payload-dialog.tsx +1 -1
- package/src/app/routes/_authenticated/_system/job-queue.graphql.ts +11 -0
- package/src/app/routes/_authenticated/_system/job-queue.tsx +99 -5
- package/src/lib/components/data-input/combination-mode-input.tsx +52 -0
- package/src/lib/components/data-input/configurable-operation-list-input.tsx +433 -0
- package/src/lib/components/data-input/custom-field-list-input.tsx +297 -0
- package/src/lib/components/data-input/datetime-input.tsx +5 -2
- package/src/lib/components/data-input/default-relation-input.tsx +599 -0
- package/src/lib/components/data-input/index.ts +6 -0
- package/src/lib/components/data-input/product-multi-selector.tsx +426 -0
- package/src/lib/components/data-input/relation-selector.tsx +7 -6
- package/src/lib/components/data-input/select-with-options.tsx +84 -0
- package/src/lib/components/data-input/struct-form-input.tsx +324 -0
- package/src/lib/components/shared/configurable-operation-arg-input.tsx +365 -21
- package/src/lib/components/shared/configurable-operation-input.tsx +81 -41
- package/src/lib/components/shared/configurable-operation-multi-selector.tsx +260 -0
- package/src/lib/components/shared/configurable-operation-selector.tsx +156 -0
- package/src/lib/components/shared/custom-fields-form.tsx +208 -37
- package/src/lib/components/shared/multi-select.tsx +1 -1
- package/src/lib/components/ui/form.tsx +4 -4
- package/src/lib/framework/extension-api/input-component-extensions.tsx +5 -1
- package/src/lib/framework/form-engine/form-schema-tools.spec.ts +472 -0
- package/src/lib/framework/form-engine/form-schema-tools.ts +340 -5
- package/src/lib/framework/form-engine/use-generated-form.tsx +24 -8
- package/src/lib/framework/form-engine/utils.ts +3 -9
- package/src/lib/framework/layout-engine/page-layout.tsx +11 -3
- package/src/lib/framework/page/list-page.tsx +9 -0
- package/src/lib/framework/page/use-detail-page.ts +3 -3
- package/src/lib/lib/utils.ts +26 -24
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vendure/dashboard",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "3.3.8-master-
|
|
4
|
+
"version": "3.3.8-master-202507310242",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -95,8 +95,8 @@
|
|
|
95
95
|
"@types/react-dom": "^19.0.4",
|
|
96
96
|
"@types/react-grid-layout": "^1.3.5",
|
|
97
97
|
"@uidotdev/usehooks": "^2.4.1",
|
|
98
|
-
"@vendure/common": "^3.3.8-master-
|
|
99
|
-
"@vendure/core": "^3.3.8-master-
|
|
98
|
+
"@vendure/common": "^3.3.8-master-202507310242",
|
|
99
|
+
"@vendure/core": "^3.3.8-master-202507310242",
|
|
100
100
|
"@vitejs/plugin-react": "^4.3.4",
|
|
101
101
|
"acorn": "^8.11.3",
|
|
102
102
|
"acorn-walk": "^8.3.2",
|
|
@@ -146,5 +146,5 @@
|
|
|
146
146
|
"lightningcss-linux-arm64-musl": "^1.29.3",
|
|
147
147
|
"lightningcss-linux-x64-musl": "^1.29.1"
|
|
148
148
|
},
|
|
149
|
-
"gitHead": "
|
|
149
|
+
"gitHead": "146703259a0efc748d92322ed5713a15503a015d"
|
|
150
150
|
}
|
package/src/app/routes/_authenticated/_collections/components/collection-filters-selector.tsx
CHANGED
|
@@ -1,17 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Button } from '@/vdb/components/ui/button.js';
|
|
3
|
-
import {
|
|
4
|
-
DropdownMenu,
|
|
5
|
-
DropdownMenuContent,
|
|
6
|
-
DropdownMenuItem,
|
|
7
|
-
DropdownMenuTrigger,
|
|
8
|
-
} from '@/vdb/components/ui/dropdown-menu.js';
|
|
9
|
-
import { Separator } from '@/vdb/components/ui/separator.js';
|
|
10
|
-
import { ConfigurableOperationDefFragment } from '@/vdb/graphql/fragments.js';
|
|
11
|
-
import { Trans } from '@/vdb/lib/trans.js';
|
|
12
|
-
import { useQuery } from '@tanstack/react-query';
|
|
1
|
+
import { ConfigurableOperationMultiSelector } from '@/vdb/components/shared/configurable-operation-multi-selector.js';
|
|
13
2
|
import { ConfigurableOperationInput as ConfigurableOperationInputType } from '@vendure/common/lib/generated-types';
|
|
14
|
-
import { Plus } from 'lucide-react';
|
|
15
3
|
import { getCollectionFiltersQueryOptions } from '../collections.graphql.js';
|
|
16
4
|
|
|
17
5
|
export interface CollectionFiltersSelectorProps {
|
|
@@ -20,72 +8,17 @@ export interface CollectionFiltersSelectorProps {
|
|
|
20
8
|
}
|
|
21
9
|
|
|
22
10
|
export function CollectionFiltersSelector({ value, onChange }: Readonly<CollectionFiltersSelectorProps>) {
|
|
23
|
-
const { data: filtersData } = useQuery(getCollectionFiltersQueryOptions);
|
|
24
|
-
|
|
25
|
-
const filters = filtersData?.collectionFilters;
|
|
26
|
-
|
|
27
|
-
const onFilterSelected = (filter: ConfigurableOperationDefFragment) => {
|
|
28
|
-
const filterDef = filters?.find(f => f.code === filter.code);
|
|
29
|
-
if (!filterDef) {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
onChange([
|
|
33
|
-
...value,
|
|
34
|
-
{
|
|
35
|
-
code: filter.code,
|
|
36
|
-
arguments: filterDef.args.map(arg => ({
|
|
37
|
-
name: arg.name,
|
|
38
|
-
value: arg.defaultValue != null ? arg.defaultValue.toString() : '',
|
|
39
|
-
})),
|
|
40
|
-
},
|
|
41
|
-
]);
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const onOperationValueChange = (
|
|
45
|
-
filter: ConfigurableOperationInputType,
|
|
46
|
-
newVal: ConfigurableOperationInputType,
|
|
47
|
-
) => {
|
|
48
|
-
onChange(value.map(f => (f.code === filter.code ? newVal : f)));
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const onOperationRemove = (index: number) => {
|
|
52
|
-
onChange(value.filter((_, i) => i !== index));
|
|
53
|
-
};
|
|
54
|
-
|
|
55
11
|
return (
|
|
56
|
-
<div className="
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
value={filter}
|
|
67
|
-
onChange={value => onOperationValueChange(filter, value)}
|
|
68
|
-
onRemove={() => onOperationRemove(index)}
|
|
69
|
-
/>
|
|
70
|
-
<Separator className="my-2" />
|
|
71
|
-
</div>
|
|
72
|
-
);
|
|
73
|
-
})}
|
|
74
|
-
<DropdownMenu>
|
|
75
|
-
<DropdownMenuTrigger asChild>
|
|
76
|
-
<Button variant="outline">
|
|
77
|
-
<Plus />
|
|
78
|
-
<Trans context="Add new collection filter">Add condition</Trans>
|
|
79
|
-
</Button>
|
|
80
|
-
</DropdownMenuTrigger>
|
|
81
|
-
<DropdownMenuContent className="w-96">
|
|
82
|
-
{filters?.map(filter => (
|
|
83
|
-
<DropdownMenuItem key={filter.code} onClick={() => onFilterSelected(filter)}>
|
|
84
|
-
{filter.description}
|
|
85
|
-
</DropdownMenuItem>
|
|
86
|
-
))}
|
|
87
|
-
</DropdownMenuContent>
|
|
88
|
-
</DropdownMenu>
|
|
12
|
+
<div className="mt-4">
|
|
13
|
+
<ConfigurableOperationMultiSelector
|
|
14
|
+
value={value}
|
|
15
|
+
onChange={onChange}
|
|
16
|
+
queryOptions={getCollectionFiltersQueryOptions}
|
|
17
|
+
queryKey="getCollectionFilters"
|
|
18
|
+
dataPath="collectionFilters"
|
|
19
|
+
buttonText="Add collection filter"
|
|
20
|
+
showEnhancedDropdown={false}
|
|
21
|
+
/>
|
|
89
22
|
</div>
|
|
90
23
|
);
|
|
91
24
|
}
|
|
@@ -6,6 +6,8 @@ import { Button } from '@/vdb/components/ui/button.js';
|
|
|
6
6
|
import { Input } from '@/vdb/components/ui/input.js';
|
|
7
7
|
import { Switch } from '@/vdb/components/ui/switch.js';
|
|
8
8
|
import { NEW_ENTITY_PATH } from '@/vdb/constants.js';
|
|
9
|
+
import { extendDetailFormQuery } from '@/vdb/framework/document-extension/extend-detail-form-query.js';
|
|
10
|
+
import { addCustomFields } from '@/vdb/framework/document-introspection/add-custom-fields.js';
|
|
9
11
|
import {
|
|
10
12
|
CustomFieldsPageBlock,
|
|
11
13
|
DetailFormGrid,
|
|
@@ -16,20 +18,25 @@ import {
|
|
|
16
18
|
PageLayout,
|
|
17
19
|
PageTitle,
|
|
18
20
|
} from '@/vdb/framework/layout-engine/page-layout.js';
|
|
19
|
-
import { useDetailPage } from '@/vdb/framework/page/use-detail-page.js';
|
|
20
|
-
import { api } from '@/vdb/graphql/api.js';
|
|
21
|
+
import { getDetailQueryOptions, useDetailPage } from '@/vdb/framework/page/use-detail-page.js';
|
|
21
22
|
import { Trans, useLingui } from '@/vdb/lib/trans.js';
|
|
22
23
|
import { createFileRoute, useNavigate } from '@tanstack/react-router';
|
|
23
24
|
import { toast } from 'sonner';
|
|
24
25
|
import { globalSettingsDocument, updateGlobalSettingsDocument } from './global-settings.graphql.js';
|
|
25
26
|
|
|
27
|
+
const pageId = 'global-settings';
|
|
28
|
+
|
|
26
29
|
export const Route = createFileRoute('/_authenticated/_global-settings/global-settings')({
|
|
27
30
|
component: GlobalSettingsPage,
|
|
28
31
|
loader: async ({ context }) => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
const { extendedQuery: extendedQueryDocument } = extendDetailFormQuery(
|
|
33
|
+
addCustomFields(globalSettingsDocument),
|
|
34
|
+
pageId,
|
|
35
|
+
);
|
|
36
|
+
await context.queryClient.ensureQueryData(
|
|
37
|
+
getDetailQueryOptions(extendedQueryDocument, { id: '' }),
|
|
38
|
+
{},
|
|
39
|
+
);
|
|
33
40
|
return {
|
|
34
41
|
breadcrumb: [{ path: '/global-settings', label: <Trans>Global settings</Trans> }],
|
|
35
42
|
};
|
|
@@ -45,8 +52,9 @@ function GlobalSettingsPage() {
|
|
|
45
52
|
|
|
46
53
|
const { form, submitHandler, entity, isPending } = useDetailPage({
|
|
47
54
|
queryDocument: globalSettingsDocument,
|
|
48
|
-
|
|
55
|
+
entityName: 'GlobalSettings',
|
|
49
56
|
updateDocument: updateGlobalSettingsDocument,
|
|
57
|
+
pageId,
|
|
50
58
|
setValuesForUpdate: entity => {
|
|
51
59
|
return {
|
|
52
60
|
id: entity.id,
|
|
@@ -78,7 +86,7 @@ function GlobalSettingsPage() {
|
|
|
78
86
|
});
|
|
79
87
|
|
|
80
88
|
return (
|
|
81
|
-
<Page pageId=
|
|
89
|
+
<Page pageId={pageId} form={form} submitHandler={submitHandler} entity={entity}>
|
|
82
90
|
<PageTitle>
|
|
83
91
|
<Trans>Global settings</Trans>
|
|
84
92
|
</PageTitle>
|
|
@@ -1,21 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
DropdownMenu,
|
|
5
|
-
DropdownMenuContent,
|
|
6
|
-
DropdownMenuItem,
|
|
7
|
-
DropdownMenuTrigger,
|
|
8
|
-
} from '@/vdb/components/ui/dropdown-menu.js';
|
|
9
|
-
import { api } from '@/vdb/graphql/api.js';
|
|
10
|
-
import {
|
|
11
|
-
configurableOperationDefFragment,
|
|
12
|
-
ConfigurableOperationDefFragment,
|
|
13
|
-
} from '@/vdb/graphql/fragments.js';
|
|
1
|
+
import { ConfigurableOperationSelector } from '@/vdb/components/shared/configurable-operation-selector.js';
|
|
2
|
+
import { configurableOperationDefFragment } from '@/vdb/graphql/fragments.js';
|
|
14
3
|
import { graphql } from '@/vdb/graphql/graphql.js';
|
|
15
|
-
import { Trans } from '@/vdb/lib/trans.js';
|
|
16
|
-
import { useQuery } from '@tanstack/react-query';
|
|
17
4
|
import { ConfigurableOperationInput as ConfigurableOperationInputType } from '@vendure/common/lib/generated-types';
|
|
18
|
-
import { Plus } from 'lucide-react';
|
|
19
5
|
|
|
20
6
|
export const paymentEligibilityCheckersDocument = graphql(
|
|
21
7
|
`
|
|
@@ -37,71 +23,15 @@ export function PaymentEligibilityCheckerSelector({
|
|
|
37
23
|
value,
|
|
38
24
|
onChange,
|
|
39
25
|
}: PaymentEligibilityCheckerSelectorProps) {
|
|
40
|
-
const { data: checkersData } = useQuery({
|
|
41
|
-
queryKey: ['paymentMethodEligibilityCheckers'],
|
|
42
|
-
queryFn: () => api.query(paymentEligibilityCheckersDocument),
|
|
43
|
-
staleTime: 1000 * 60 * 60 * 5,
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
const checkers = checkersData?.paymentMethodEligibilityCheckers;
|
|
47
|
-
|
|
48
|
-
const onCheckerSelected = (checker: ConfigurableOperationDefFragment) => {
|
|
49
|
-
const checkerDef = checkers?.find(c => c.code === checker.code);
|
|
50
|
-
if (!checkerDef) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
onChange({
|
|
54
|
-
code: checker.code,
|
|
55
|
-
arguments: checkerDef.args.map(arg => ({
|
|
56
|
-
name: arg.name,
|
|
57
|
-
value: arg.defaultValue != null ? arg.defaultValue.toString() : '',
|
|
58
|
-
})),
|
|
59
|
-
});
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
const onOperationValueChange = (newVal: ConfigurableOperationInputType) => {
|
|
63
|
-
onChange(newVal);
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const onOperationRemove = () => {
|
|
67
|
-
onChange(undefined);
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const checkerDef = checkers?.find(c => c.code === value?.code);
|
|
71
|
-
|
|
72
26
|
return (
|
|
73
|
-
<
|
|
74
|
-
{value
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
</div>
|
|
83
|
-
)}
|
|
84
|
-
<DropdownMenu>
|
|
85
|
-
{!value?.code && (
|
|
86
|
-
<DropdownMenuTrigger asChild>
|
|
87
|
-
<Button variant="outline">
|
|
88
|
-
<Plus />
|
|
89
|
-
<Trans>Select Payment Eligibility Checker</Trans>
|
|
90
|
-
</Button>
|
|
91
|
-
</DropdownMenuTrigger>
|
|
92
|
-
)}
|
|
93
|
-
<DropdownMenuContent className="w-96">
|
|
94
|
-
{checkers?.length ? (
|
|
95
|
-
checkers?.map(checker => (
|
|
96
|
-
<DropdownMenuItem key={checker.code} onClick={() => onCheckerSelected(checker)}>
|
|
97
|
-
{checker.description}
|
|
98
|
-
</DropdownMenuItem>
|
|
99
|
-
))
|
|
100
|
-
) : (
|
|
101
|
-
<DropdownMenuItem>No checkers found</DropdownMenuItem>
|
|
102
|
-
)}
|
|
103
|
-
</DropdownMenuContent>
|
|
104
|
-
</DropdownMenu>
|
|
105
|
-
</div>
|
|
27
|
+
<ConfigurableOperationSelector
|
|
28
|
+
value={value}
|
|
29
|
+
onChange={onChange}
|
|
30
|
+
queryDocument={paymentEligibilityCheckersDocument}
|
|
31
|
+
queryKey="paymentMethodEligibilityCheckers"
|
|
32
|
+
dataPath="paymentMethodEligibilityCheckers"
|
|
33
|
+
buttonText="Select Payment Eligibility Checker"
|
|
34
|
+
emptyText="No checkers found"
|
|
35
|
+
/>
|
|
106
36
|
);
|
|
107
37
|
}
|
package/src/app/routes/_authenticated/_payment-methods/components/payment-handler-selector.tsx
CHANGED
|
@@ -1,21 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
DropdownMenu,
|
|
5
|
-
DropdownMenuContent,
|
|
6
|
-
DropdownMenuItem,
|
|
7
|
-
DropdownMenuTrigger,
|
|
8
|
-
} from '@/vdb/components/ui/dropdown-menu.js';
|
|
9
|
-
import { api } from '@/vdb/graphql/api.js';
|
|
10
|
-
import {
|
|
11
|
-
configurableOperationDefFragment,
|
|
12
|
-
ConfigurableOperationDefFragment,
|
|
13
|
-
} from '@/vdb/graphql/fragments.js';
|
|
1
|
+
import { ConfigurableOperationSelector } from '@/vdb/components/shared/configurable-operation-selector.js';
|
|
2
|
+
import { configurableOperationDefFragment } from '@/vdb/graphql/fragments.js';
|
|
14
3
|
import { graphql } from '@/vdb/graphql/graphql.js';
|
|
15
|
-
import { Trans } from '@/vdb/lib/trans.js';
|
|
16
|
-
import { useQuery } from '@tanstack/react-query';
|
|
17
4
|
import { ConfigurableOperationInput as ConfigurableOperationInputType } from '@vendure/common/lib/generated-types';
|
|
18
|
-
import { Plus } from 'lucide-react';
|
|
19
5
|
|
|
20
6
|
export const paymentHandlersDocument = graphql(
|
|
21
7
|
`
|
|
@@ -34,67 +20,14 @@ interface PaymentHandlerSelectorProps {
|
|
|
34
20
|
}
|
|
35
21
|
|
|
36
22
|
export function PaymentHandlerSelector({ value, onChange }: Readonly<PaymentHandlerSelectorProps>) {
|
|
37
|
-
const { data: handlersData } = useQuery({
|
|
38
|
-
queryKey: ['paymentMethodHandlers'],
|
|
39
|
-
queryFn: () => api.query(paymentHandlersDocument),
|
|
40
|
-
staleTime: 1000 * 60 * 60 * 5,
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
const handlers = handlersData?.paymentMethodHandlers;
|
|
44
|
-
|
|
45
|
-
const onHandlerSelected = (handler: ConfigurableOperationDefFragment) => {
|
|
46
|
-
const handlerDef = handlers?.find(h => h.code === handler.code);
|
|
47
|
-
if (!handlerDef) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
onChange({
|
|
51
|
-
code: handler.code,
|
|
52
|
-
arguments: handlerDef.args.map(arg => ({
|
|
53
|
-
name: arg.name,
|
|
54
|
-
value: arg.defaultValue != null ? arg.defaultValue.toString() : '',
|
|
55
|
-
})),
|
|
56
|
-
});
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const onOperationValueChange = (newVal: ConfigurableOperationInputType) => {
|
|
60
|
-
onChange(newVal);
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const onOperationRemove = () => {
|
|
64
|
-
onChange(undefined);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
const handlerDef = handlers?.find(h => h.code === value?.code);
|
|
68
|
-
|
|
69
23
|
return (
|
|
70
|
-
<
|
|
71
|
-
{value
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
/>
|
|
79
|
-
</div>
|
|
80
|
-
)}
|
|
81
|
-
<DropdownMenu>
|
|
82
|
-
{!value?.code && (
|
|
83
|
-
<DropdownMenuTrigger asChild>
|
|
84
|
-
<Button variant="outline">
|
|
85
|
-
<Plus />
|
|
86
|
-
<Trans>Select Payment Handler</Trans>
|
|
87
|
-
</Button>
|
|
88
|
-
</DropdownMenuTrigger>
|
|
89
|
-
)}
|
|
90
|
-
<DropdownMenuContent className="w-96">
|
|
91
|
-
{handlers?.map(handler => (
|
|
92
|
-
<DropdownMenuItem key={handler.code} onClick={() => onHandlerSelected(handler)}>
|
|
93
|
-
{handler.description}
|
|
94
|
-
</DropdownMenuItem>
|
|
95
|
-
))}
|
|
96
|
-
</DropdownMenuContent>
|
|
97
|
-
</DropdownMenu>
|
|
98
|
-
</div>
|
|
24
|
+
<ConfigurableOperationSelector
|
|
25
|
+
value={value}
|
|
26
|
+
onChange={onChange}
|
|
27
|
+
queryDocument={paymentHandlersDocument}
|
|
28
|
+
queryKey="paymentMethodHandlers"
|
|
29
|
+
dataPath="paymentMethodHandlers"
|
|
30
|
+
buttonText="Select Payment Handler"
|
|
31
|
+
/>
|
|
99
32
|
);
|
|
100
33
|
}
|
|
@@ -1,22 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
DropdownMenu,
|
|
5
|
-
DropdownMenuContent,
|
|
6
|
-
DropdownMenuItem,
|
|
7
|
-
DropdownMenuTrigger,
|
|
8
|
-
} from '@/vdb/components/ui/dropdown-menu.js';
|
|
9
|
-
import { Separator } from '@/vdb/components/ui/separator.js';
|
|
10
|
-
import { api } from '@/vdb/graphql/api.js';
|
|
11
|
-
import {
|
|
12
|
-
configurableOperationDefFragment,
|
|
13
|
-
ConfigurableOperationDefFragment,
|
|
14
|
-
} from '@/vdb/graphql/fragments.js';
|
|
1
|
+
import { ConfigurableOperationMultiSelector } from '@/vdb/components/shared/configurable-operation-multi-selector.js';
|
|
2
|
+
import { configurableOperationDefFragment } from '@/vdb/graphql/fragments.js';
|
|
15
3
|
import { graphql } from '@/vdb/graphql/graphql.js';
|
|
16
|
-
import { Trans } from '@/vdb/lib/trans.js';
|
|
17
|
-
import { useQuery } from '@tanstack/react-query';
|
|
18
4
|
import { ConfigurableOperationInput as ConfigurableOperationInputType } from '@vendure/common/lib/generated-types';
|
|
19
|
-
import { Plus } from 'lucide-react';
|
|
20
5
|
|
|
21
6
|
export const promotionActionsDocument = graphql(
|
|
22
7
|
`
|
|
@@ -35,76 +20,16 @@ interface PromotionActionsSelectorProps {
|
|
|
35
20
|
}
|
|
36
21
|
|
|
37
22
|
export function PromotionActionsSelector({ value, onChange }: Readonly<PromotionActionsSelectorProps>) {
|
|
38
|
-
const { data: actionsData } = useQuery({
|
|
39
|
-
queryKey: ['promotionActions'],
|
|
40
|
-
queryFn: () => api.query(promotionActionsDocument),
|
|
41
|
-
staleTime: 1000 * 60 * 60 * 5,
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
const actions = actionsData?.promotionActions;
|
|
45
|
-
|
|
46
|
-
const onActionSelected = (action: ConfigurableOperationDefFragment) => {
|
|
47
|
-
const actionDef = actions?.find(a => a.code === action.code);
|
|
48
|
-
if (!actionDef) {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
onChange([
|
|
52
|
-
...value,
|
|
53
|
-
{
|
|
54
|
-
code: action.code,
|
|
55
|
-
arguments: actionDef.args.map(arg => ({
|
|
56
|
-
name: arg.name,
|
|
57
|
-
value: arg.defaultValue != null ? arg.defaultValue.toString() : '',
|
|
58
|
-
})),
|
|
59
|
-
},
|
|
60
|
-
]);
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const onOperationValueChange = (
|
|
64
|
-
action: ConfigurableOperationInputType,
|
|
65
|
-
newVal: ConfigurableOperationInputType,
|
|
66
|
-
) => {
|
|
67
|
-
onChange(value.map(a => (a.code === action.code ? newVal : a)));
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const onOperationRemove = (index: number) => {
|
|
71
|
-
onChange(value.filter((_, i) => i !== index));
|
|
72
|
-
};
|
|
73
|
-
|
|
74
23
|
return (
|
|
75
|
-
<
|
|
76
|
-
{
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
value={action}
|
|
86
|
-
onChange={value => onOperationValueChange(action, value)}
|
|
87
|
-
onRemove={() => onOperationRemove(index)}
|
|
88
|
-
/>
|
|
89
|
-
<Separator className="my-2" />
|
|
90
|
-
</div>
|
|
91
|
-
);
|
|
92
|
-
})}
|
|
93
|
-
<DropdownMenu>
|
|
94
|
-
<DropdownMenuTrigger asChild>
|
|
95
|
-
<Button variant="outline">
|
|
96
|
-
<Plus />
|
|
97
|
-
<Trans context="Add new promotion action">Add action</Trans>
|
|
98
|
-
</Button>
|
|
99
|
-
</DropdownMenuTrigger>
|
|
100
|
-
<DropdownMenuContent className="w-96">
|
|
101
|
-
{actions?.map(action => (
|
|
102
|
-
<DropdownMenuItem key={action.code} onClick={() => onActionSelected(action)}>
|
|
103
|
-
{action.description}
|
|
104
|
-
</DropdownMenuItem>
|
|
105
|
-
))}
|
|
106
|
-
</DropdownMenuContent>
|
|
107
|
-
</DropdownMenu>
|
|
108
|
-
</div>
|
|
24
|
+
<ConfigurableOperationMultiSelector
|
|
25
|
+
value={value}
|
|
26
|
+
onChange={onChange}
|
|
27
|
+
queryDocument={promotionActionsDocument}
|
|
28
|
+
queryKey="promotionActions"
|
|
29
|
+
dataPath="promotionActions"
|
|
30
|
+
buttonText="Add action"
|
|
31
|
+
dropdownTitle="Available Actions"
|
|
32
|
+
showEnhancedDropdown={true}
|
|
33
|
+
/>
|
|
109
34
|
);
|
|
110
35
|
}
|
package/src/app/routes/_authenticated/_promotions/components/promotion-conditions-selector.tsx
CHANGED
|
@@ -1,22 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
DropdownMenu,
|
|
5
|
-
DropdownMenuContent,
|
|
6
|
-
DropdownMenuItem,
|
|
7
|
-
DropdownMenuTrigger,
|
|
8
|
-
} from '@/vdb/components/ui/dropdown-menu.js';
|
|
9
|
-
import { Separator } from '@/vdb/components/ui/separator.js';
|
|
10
|
-
import { api } from '@/vdb/graphql/api.js';
|
|
11
|
-
import {
|
|
12
|
-
configurableOperationDefFragment,
|
|
13
|
-
ConfigurableOperationDefFragment,
|
|
14
|
-
} from '@/vdb/graphql/fragments.js';
|
|
1
|
+
import { ConfigurableOperationMultiSelector } from '@/vdb/components/shared/configurable-operation-multi-selector.js';
|
|
2
|
+
import { configurableOperationDefFragment } from '@/vdb/graphql/fragments.js';
|
|
15
3
|
import { graphql } from '@/vdb/graphql/graphql.js';
|
|
16
|
-
import { Trans } from '@/vdb/lib/trans.js';
|
|
17
|
-
import { useQuery } from '@tanstack/react-query';
|
|
18
4
|
import { ConfigurableOperationInput as ConfigurableOperationInputType } from '@vendure/common/lib/generated-types';
|
|
19
|
-
import { Plus } from 'lucide-react';
|
|
20
5
|
|
|
21
6
|
export const promotionConditionsDocument = graphql(
|
|
22
7
|
`
|
|
@@ -35,76 +20,16 @@ interface PromotionConditionsSelectorProps {
|
|
|
35
20
|
}
|
|
36
21
|
|
|
37
22
|
export function PromotionConditionsSelector({ value, onChange }: Readonly<PromotionConditionsSelectorProps>) {
|
|
38
|
-
const { data: conditionsData } = useQuery({
|
|
39
|
-
queryKey: ['promotionConditions'],
|
|
40
|
-
queryFn: () => api.query(promotionConditionsDocument),
|
|
41
|
-
staleTime: 1000 * 60 * 60 * 5,
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
const conditions = conditionsData?.promotionConditions;
|
|
45
|
-
|
|
46
|
-
const onConditionSelected = (condition: ConfigurableOperationDefFragment) => {
|
|
47
|
-
const conditionDef = conditions?.find(c => c.code === condition.code);
|
|
48
|
-
if (!conditionDef) {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
onChange([
|
|
52
|
-
...value,
|
|
53
|
-
{
|
|
54
|
-
code: condition.code,
|
|
55
|
-
arguments: conditionDef.args.map(arg => ({
|
|
56
|
-
name: arg.name,
|
|
57
|
-
value: arg.defaultValue != null ? arg.defaultValue.toString() : '',
|
|
58
|
-
})),
|
|
59
|
-
},
|
|
60
|
-
]);
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const onOperationValueChange = (
|
|
64
|
-
condition: ConfigurableOperationInputType,
|
|
65
|
-
newVal: ConfigurableOperationInputType,
|
|
66
|
-
) => {
|
|
67
|
-
onChange(value.map(c => (c.code === condition.code ? newVal : c)));
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const onOperationRemove = (index: number) => {
|
|
71
|
-
onChange(value.filter((_, i) => i !== index));
|
|
72
|
-
};
|
|
73
|
-
|
|
74
23
|
return (
|
|
75
|
-
<
|
|
76
|
-
{
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
value={condition}
|
|
86
|
-
onChange={value => onOperationValueChange(condition, value)}
|
|
87
|
-
onRemove={() => onOperationRemove(index)}
|
|
88
|
-
/>
|
|
89
|
-
<Separator className="my-2" />
|
|
90
|
-
</div>
|
|
91
|
-
);
|
|
92
|
-
})}
|
|
93
|
-
<DropdownMenu>
|
|
94
|
-
<DropdownMenuTrigger asChild>
|
|
95
|
-
<Button variant="outline">
|
|
96
|
-
<Plus />
|
|
97
|
-
<Trans context="Add new promotion condition">Add condition</Trans>
|
|
98
|
-
</Button>
|
|
99
|
-
</DropdownMenuTrigger>
|
|
100
|
-
<DropdownMenuContent className="w-96">
|
|
101
|
-
{conditions?.map(condition => (
|
|
102
|
-
<DropdownMenuItem key={condition.code} onClick={() => onConditionSelected(condition)}>
|
|
103
|
-
{condition.description}
|
|
104
|
-
</DropdownMenuItem>
|
|
105
|
-
))}
|
|
106
|
-
</DropdownMenuContent>
|
|
107
|
-
</DropdownMenu>
|
|
108
|
-
</div>
|
|
24
|
+
<ConfigurableOperationMultiSelector
|
|
25
|
+
value={value}
|
|
26
|
+
onChange={onChange}
|
|
27
|
+
queryDocument={promotionConditionsDocument}
|
|
28
|
+
queryKey="promotionConditions"
|
|
29
|
+
dataPath="promotionConditions"
|
|
30
|
+
buttonText="Add condition"
|
|
31
|
+
dropdownTitle="Available Conditions"
|
|
32
|
+
showEnhancedDropdown={true}
|
|
33
|
+
/>
|
|
109
34
|
);
|
|
110
35
|
}
|