@vendure/dashboard 3.4.2-master-202509090229 → 3.4.2
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/_administrators/administrators_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_channels/channels_.$id.tsx +4 -4
- package/src/app/routes/_authenticated/_collections/collections_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_countries/countries_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_customer-groups/customer-groups_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_customers/customers_.$id.tsx +4 -4
- package/src/app/routes/_authenticated/_facets/facets.tsx +5 -8
- package/src/app/routes/_authenticated/_facets/facets_.$facetId.values_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_facets/facets_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_payment-methods/payment-methods_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_product-variants/product-variants_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_products/products_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_promotions/promotions_.$id.tsx +4 -4
- package/src/app/routes/_authenticated/_roles/roles_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_sellers/sellers_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_shipping-methods/shipping-methods_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_stock-locations/stock-locations_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_tax-categories/tax-categories_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_tax-rates/tax-rates_.$id.tsx +4 -3
- package/src/app/routes/_authenticated/_zones/zones_.$id.tsx +3 -3
- package/src/lib/components/data-input/affixed-input.tsx +18 -0
- package/src/lib/components/data-input/boolean-input.tsx +7 -0
- package/src/lib/components/data-input/checkbox-input.tsx +7 -0
- package/src/lib/components/data-input/datetime-input.tsx +7 -0
- package/src/lib/components/data-input/money-input.tsx +8 -0
- package/src/lib/components/data-input/number-input.tsx +7 -0
- package/src/lib/components/data-input/password-input.tsx +7 -0
- package/src/lib/components/data-input/rich-text-input.tsx +7 -0
- package/src/lib/components/data-input/text-input.tsx +7 -0
- package/src/lib/components/data-input/textarea-input.tsx +7 -0
- package/src/lib/components/data-table/data-table-view-options.tsx +29 -26
- package/src/lib/components/data-table/data-table.tsx +20 -0
- package/src/lib/components/data-table/types.ts +39 -0
- package/src/lib/components/layout/channel-switcher.tsx +1 -3
- package/src/lib/components/shared/asset/asset-gallery.tsx +58 -0
- package/src/lib/components/shared/asset/asset-picker-dialog.tsx +39 -0
- package/src/lib/components/shared/detail-page-button.tsx +8 -22
- package/src/lib/components/shared/facet-value-chip.tsx +7 -0
- package/src/lib/components/shared/facet-value-selector.tsx +55 -0
- package/src/lib/components/shared/form-field-wrapper.tsx +51 -0
- package/src/lib/components/shared/paginated-list-data-table.tsx +128 -16
- package/src/lib/components/shared/permission-guard.tsx +30 -0
- package/src/lib/components/shared/table-cell/order-table-cell-components.tsx +1 -1
- package/src/lib/components/shared/translatable-form-field.tsx +52 -0
- package/src/lib/components/shared/vendure-image.tsx +114 -2
- package/src/lib/framework/extension-api/define-dashboard-extension.ts +25 -3
- package/src/lib/framework/extension-api/extension-api-types.ts +12 -3
- package/src/lib/framework/extension-api/types/alerts.ts +2 -3
- package/src/lib/framework/extension-api/types/data-table.ts +2 -2
- package/src/lib/framework/extension-api/types/detail-forms.ts +2 -2
- package/src/lib/framework/extension-api/types/form-components.ts +2 -2
- package/src/lib/framework/extension-api/types/layout.ts +24 -13
- package/src/lib/framework/extension-api/types/login.ts +6 -5
- package/src/lib/framework/extension-api/types/navigation.ts +3 -3
- package/src/lib/framework/extension-api/types/widgets.ts +7 -3
- package/src/lib/framework/form-engine/form-engine-types.ts +13 -7
- package/src/lib/framework/form-engine/use-generated-form.tsx +44 -0
- package/src/lib/framework/layout-engine/page-layout.tsx +94 -31
- package/src/lib/framework/page/detail-page.tsx +3 -5
- package/src/lib/framework/page/list-page.tsx +87 -5
- package/src/lib/framework/page/use-detail-page.ts +4 -5
- package/src/lib/graphql/api.ts +2 -2
- package/src/lib/graphql/graphql-env.d.ts +7 -16
- package/src/lib/hooks/use-auth.tsx +1 -3
- package/src/lib/hooks/use-channel.ts +4 -2
- package/src/lib/hooks/use-page-block.tsx +9 -0
- package/src/lib/hooks/use-permissions.ts +6 -2
- package/src/lib/index.ts +2 -0
- package/src/lib/providers/auth.tsx +34 -2
- package/src/lib/providers/channel-provider.tsx +22 -1
- package/src/lib/components/shared/table-cell/table-cell-types.ts +0 -33
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vendure/dashboard",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "3.4.2
|
|
4
|
+
"version": "3.4.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -100,8 +100,8 @@
|
|
|
100
100
|
"@types/react": "^19.0.10",
|
|
101
101
|
"@types/react-dom": "^19.0.4",
|
|
102
102
|
"@uidotdev/usehooks": "^2.4.1",
|
|
103
|
-
"@vendure/common": "
|
|
104
|
-
"@vendure/core": "
|
|
103
|
+
"@vendure/common": "3.4.2",
|
|
104
|
+
"@vendure/core": "3.4.2",
|
|
105
105
|
"@vitejs/plugin-react": "^4.3.4",
|
|
106
106
|
"acorn": "^8.11.3",
|
|
107
107
|
"acorn-walk": "^8.3.2",
|
|
@@ -152,5 +152,5 @@
|
|
|
152
152
|
"lightningcss-linux-arm64-musl": "^1.29.3",
|
|
153
153
|
"lightningcss-linux-x64-musl": "^1.29.1"
|
|
154
154
|
},
|
|
155
|
-
"gitHead": "
|
|
155
|
+
"gitHead": "77218033e22397ad50f39d952d440e7879927814"
|
|
156
156
|
}
|
|
@@ -74,14 +74,14 @@ function AdministratorDetailPage() {
|
|
|
74
74
|
},
|
|
75
75
|
params: { id: params.id },
|
|
76
76
|
onSuccess: async data => {
|
|
77
|
-
toast(i18n.t('Successfully updated administrator'));
|
|
77
|
+
toast(i18n.t(creatingNewEntity ? 'Successfully created administrator' : 'Successfully updated administrator'));
|
|
78
78
|
resetForm();
|
|
79
79
|
if (creatingNewEntity) {
|
|
80
80
|
await navigate({ to: `../$id`, params: { id: data.id } });
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
83
|
onError: err => {
|
|
84
|
-
toast(i18n.t('Failed to update administrator'), {
|
|
84
|
+
toast(i18n.t(creatingNewEntity ? 'Failed to create administrator' : 'Failed to update administrator'), {
|
|
85
85
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
86
86
|
});
|
|
87
87
|
},
|
|
@@ -101,7 +101,7 @@ function AdministratorDetailPage() {
|
|
|
101
101
|
type="submit"
|
|
102
102
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
103
103
|
>
|
|
104
|
-
<Trans>Update</Trans>
|
|
104
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
105
105
|
</Button>
|
|
106
106
|
</PermissionGuard>
|
|
107
107
|
</PageActionBarRight>
|
|
@@ -82,20 +82,20 @@ function ChannelDetailPage() {
|
|
|
82
82
|
params: { id: params.id },
|
|
83
83
|
onSuccess: async data => {
|
|
84
84
|
if (data.__typename === 'Channel') {
|
|
85
|
-
toast(i18n.t('Successfully updated channel'));
|
|
85
|
+
toast(i18n.t(creatingNewEntity ? 'Successfully created channel' : 'Successfully updated channel'));
|
|
86
86
|
refreshChannels();
|
|
87
87
|
resetForm();
|
|
88
88
|
if (creatingNewEntity) {
|
|
89
89
|
await navigate({ to: `../$id`, params: { id: data.id } });
|
|
90
90
|
}
|
|
91
91
|
} else {
|
|
92
|
-
toast(i18n.t('Failed to update channel'), {
|
|
92
|
+
toast(i18n.t(creatingNewEntity ? 'Failed to create channel' : 'Failed to update channel'), {
|
|
93
93
|
description: data.message,
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
96
|
},
|
|
97
97
|
onError: err => {
|
|
98
|
-
toast(i18n.t('Failed to update channel'), {
|
|
98
|
+
toast(i18n.t(creatingNewEntity ? 'Failed to create channel' : 'Failed to update channel'), {
|
|
99
99
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
100
100
|
});
|
|
101
101
|
},
|
|
@@ -122,7 +122,7 @@ function ChannelDetailPage() {
|
|
|
122
122
|
type="submit"
|
|
123
123
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
124
124
|
>
|
|
125
|
-
<Trans>Update</Trans>
|
|
125
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
126
126
|
</Button>
|
|
127
127
|
</PermissionGuard>
|
|
128
128
|
</PageActionBarRight>
|
|
@@ -89,14 +89,14 @@ function CollectionDetailPage() {
|
|
|
89
89
|
},
|
|
90
90
|
params: { id: params.id },
|
|
91
91
|
onSuccess: async data => {
|
|
92
|
-
toast(i18n.t('Successfully updated collection'));
|
|
92
|
+
toast(i18n.t(creatingNewEntity ? 'Successfully created collection' : 'Successfully updated collection'));
|
|
93
93
|
resetForm();
|
|
94
94
|
if (creatingNewEntity) {
|
|
95
95
|
await navigate({ to: `../$id`, params: { id: data.id } });
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
onError: err => {
|
|
99
|
-
toast(i18n.t('Failed to update collection'), {
|
|
99
|
+
toast(i18n.t(creatingNewEntity ? 'Failed to create collection' : 'Failed to update collection'), {
|
|
100
100
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
101
101
|
});
|
|
102
102
|
},
|
|
@@ -118,7 +118,7 @@ function CollectionDetailPage() {
|
|
|
118
118
|
type="submit"
|
|
119
119
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
120
120
|
>
|
|
121
|
-
<Trans>Update</Trans>
|
|
121
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
122
122
|
</Button>
|
|
123
123
|
</PermissionGuard>
|
|
124
124
|
</PageActionBarRight>
|
|
@@ -61,14 +61,14 @@ function CountryDetailPage() {
|
|
|
61
61
|
},
|
|
62
62
|
params: { id: params.id },
|
|
63
63
|
onSuccess: async data => {
|
|
64
|
-
toast(i18n.t('Successfully updated country'));
|
|
64
|
+
toast(i18n.t(creatingNewEntity ? 'Successfully created country' : 'Successfully updated country'));
|
|
65
65
|
form.reset(form.getValues());
|
|
66
66
|
if (creatingNewEntity) {
|
|
67
67
|
await navigate({ to: `../$id`, params: { id: data.id } });
|
|
68
68
|
}
|
|
69
69
|
},
|
|
70
70
|
onError: err => {
|
|
71
|
-
toast(i18n.t('Failed to update country'), {
|
|
71
|
+
toast(i18n.t(creatingNewEntity ? 'Failed to create country' : 'Failed to update country'), {
|
|
72
72
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
73
73
|
});
|
|
74
74
|
},
|
|
@@ -84,7 +84,7 @@ function CountryDetailPage() {
|
|
|
84
84
|
type="submit"
|
|
85
85
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
86
86
|
>
|
|
87
|
-
<Trans>Update</Trans>
|
|
87
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
88
88
|
</Button>
|
|
89
89
|
</PermissionGuard>
|
|
90
90
|
</PageActionBarRight>
|
|
@@ -61,14 +61,14 @@ function CustomerGroupDetailPage() {
|
|
|
61
61
|
},
|
|
62
62
|
params: { id: params.id },
|
|
63
63
|
onSuccess: async data => {
|
|
64
|
-
toast.success(i18n.t('Successfully updated customer group'));
|
|
64
|
+
toast.success(i18n.t(creatingNewEntity ? 'Successfully created customer group' : 'Successfully updated customer group'));
|
|
65
65
|
resetForm();
|
|
66
66
|
if (creatingNewEntity && data?.id) {
|
|
67
67
|
await navigate({ to: `../$id`, params: { id: data.id } });
|
|
68
68
|
}
|
|
69
69
|
},
|
|
70
70
|
onError: err => {
|
|
71
|
-
toast.error(i18n.t('Failed to update customer group'), {
|
|
71
|
+
toast.error(i18n.t(creatingNewEntity ? 'Failed to create customer group' : 'Failed to update customer group'), {
|
|
72
72
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
73
73
|
});
|
|
74
74
|
},
|
|
@@ -86,7 +86,7 @@ function CustomerGroupDetailPage() {
|
|
|
86
86
|
type="submit"
|
|
87
87
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
88
88
|
>
|
|
89
|
-
<Trans>Update</Trans>
|
|
89
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
90
90
|
</Button>
|
|
91
91
|
</PermissionGuard>
|
|
92
92
|
</PageActionBarRight>
|
|
@@ -89,19 +89,19 @@ function CustomerDetailPage() {
|
|
|
89
89
|
params: { id: params.id },
|
|
90
90
|
onSuccess: async data => {
|
|
91
91
|
if (data.__typename === 'Customer') {
|
|
92
|
-
toast.success(i18n.t('Successfully updated customer'));
|
|
92
|
+
toast.success(i18n.t(creatingNewEntity ? 'Successfully created customer' : 'Successfully updated customer'));
|
|
93
93
|
resetForm();
|
|
94
94
|
if (creatingNewEntity) {
|
|
95
95
|
await navigate({ to: `../$id`, params: { id: data.id } });
|
|
96
96
|
}
|
|
97
97
|
} else {
|
|
98
|
-
toast.error(i18n.t('Failed to update customer'), {
|
|
98
|
+
toast.error(i18n.t(creatingNewEntity ? 'Failed to create customer' : 'Failed to update customer'), {
|
|
99
99
|
description: data.message,
|
|
100
100
|
});
|
|
101
101
|
}
|
|
102
102
|
},
|
|
103
103
|
onError: err => {
|
|
104
|
-
toast.error(i18n.t('Failed to update customer'), {
|
|
104
|
+
toast.error(i18n.t(creatingNewEntity ? 'Failed to create customer' : 'Failed to update customer'), {
|
|
105
105
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
106
106
|
});
|
|
107
107
|
},
|
|
@@ -150,7 +150,7 @@ function CustomerDetailPage() {
|
|
|
150
150
|
type="submit"
|
|
151
151
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
152
152
|
>
|
|
153
|
-
<Trans>Update</Trans>
|
|
153
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
154
154
|
</Button>
|
|
155
155
|
</PermissionGuard>
|
|
156
156
|
</PageActionBarRight>
|
|
@@ -17,16 +17,16 @@ import {
|
|
|
17
17
|
} from './components/facet-bulk-actions.js';
|
|
18
18
|
import { FacetValuesSheet } from './components/facet-values-sheet.js';
|
|
19
19
|
import { deleteFacetDocument, facetListDocument } from './facets.graphql.js';
|
|
20
|
-
import { DataTableCellComponent } from '@/vdb/components/
|
|
20
|
+
import { DataTableCellComponent } from '@/vdb/components/data-table/types.js';
|
|
21
21
|
|
|
22
22
|
export const Route = createFileRoute('/_authenticated/_facets/facets')({
|
|
23
23
|
component: FacetListPage,
|
|
24
24
|
loader: () => ({ breadcrumb: () => <Trans>Facets</Trans> }),
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
-
const FacetValuesCell: DataTableCellComponent<ResultOf<
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
const FacetValuesCell: DataTableCellComponent<ResultOf<typeof facetListDocument>['facets']['items'][0]> = ({
|
|
28
|
+
row,
|
|
29
|
+
}) => {
|
|
30
30
|
const value = row.original.valueList;
|
|
31
31
|
if (!value) {
|
|
32
32
|
return null;
|
|
@@ -44,10 +44,7 @@ const FacetValuesCell: DataTableCellComponent<ResultOf<
|
|
|
44
44
|
/>
|
|
45
45
|
);
|
|
46
46
|
})}
|
|
47
|
-
<FacetValuesSheet
|
|
48
|
-
facetId={row.original.id}
|
|
49
|
-
facetName={row.original.name}
|
|
50
|
-
>
|
|
47
|
+
<FacetValuesSheet facetId={row.original.id} facetName={row.original.name}>
|
|
51
48
|
{list.totalItems > 3 ? (
|
|
52
49
|
<div>
|
|
53
50
|
<Trans>+ {list.totalItems - 3} more</Trans>
|
|
@@ -81,7 +81,7 @@ function FacetValueDetailPage() {
|
|
|
81
81
|
},
|
|
82
82
|
params: { id: params.id },
|
|
83
83
|
onSuccess: async data => {
|
|
84
|
-
toast(i18n.t('Successfully updated facet value'));
|
|
84
|
+
toast(i18n.t(creatingNewEntity ? 'Successfully created facet value' : 'Successfully updated facet value'));
|
|
85
85
|
resetForm();
|
|
86
86
|
const created = Array.isArray(data) ? data[0] : data;
|
|
87
87
|
if (creatingNewEntity && created) {
|
|
@@ -89,7 +89,7 @@ function FacetValueDetailPage() {
|
|
|
89
89
|
}
|
|
90
90
|
},
|
|
91
91
|
onError: err => {
|
|
92
|
-
toast(i18n.t('Failed to update facet value'), {
|
|
92
|
+
toast(i18n.t(creatingNewEntity ? 'Failed to create facet value' : 'Failed to update facet value'), {
|
|
93
93
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
94
94
|
});
|
|
95
95
|
},
|
|
@@ -107,7 +107,7 @@ function FacetValueDetailPage() {
|
|
|
107
107
|
type="submit"
|
|
108
108
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
109
109
|
>
|
|
110
|
-
<Trans>Update</Trans>
|
|
110
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
111
111
|
</Button>
|
|
112
112
|
</PermissionGuard>
|
|
113
113
|
</PageActionBarRight>
|
|
@@ -72,14 +72,14 @@ function FacetDetailPage() {
|
|
|
72
72
|
},
|
|
73
73
|
params: { id: params.id },
|
|
74
74
|
onSuccess: async data => {
|
|
75
|
-
toast(i18n.t('Successfully updated facet'));
|
|
75
|
+
toast(i18n.t(creatingNewEntity ? 'Successfully created facet' : 'Successfully updated facet'));
|
|
76
76
|
resetForm();
|
|
77
77
|
if (creatingNewEntity) {
|
|
78
78
|
await navigate({ to: `../$id`, params: { id: data.id } });
|
|
79
79
|
}
|
|
80
80
|
},
|
|
81
81
|
onError: err => {
|
|
82
|
-
toast(i18n.t('Failed to update facet'), {
|
|
82
|
+
toast(i18n.t(creatingNewEntity ? 'Failed to create facet' : 'Failed to update facet'), {
|
|
83
83
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
84
84
|
});
|
|
85
85
|
},
|
|
@@ -95,7 +95,7 @@ function FacetDetailPage() {
|
|
|
95
95
|
type="submit"
|
|
96
96
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
97
97
|
>
|
|
98
|
-
<Trans>Update</Trans>
|
|
98
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
99
99
|
</Button>
|
|
100
100
|
</PermissionGuard>
|
|
101
101
|
</PageActionBarRight>
|
|
@@ -95,14 +95,14 @@ function PaymentMethodDetailPage() {
|
|
|
95
95
|
},
|
|
96
96
|
params: { id: params.id },
|
|
97
97
|
onSuccess: async data => {
|
|
98
|
-
toast.success(i18n.t('Successfully updated payment method'));
|
|
98
|
+
toast.success(i18n.t(creatingNewEntity ? 'Successfully created payment method' : 'Successfully updated payment method'));
|
|
99
99
|
resetForm();
|
|
100
100
|
if (creatingNewEntity) {
|
|
101
101
|
await navigate({ to: `../$id`, params: { id: data.id } });
|
|
102
102
|
}
|
|
103
103
|
},
|
|
104
104
|
onError: err => {
|
|
105
|
-
toast.error(i18n.t('Failed to update payment method'), {
|
|
105
|
+
toast.error(i18n.t(creatingNewEntity ? 'Failed to create payment method' : 'Failed to update payment method'), {
|
|
106
106
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
107
107
|
});
|
|
108
108
|
},
|
|
@@ -120,7 +120,7 @@ function PaymentMethodDetailPage() {
|
|
|
120
120
|
type="submit"
|
|
121
121
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
122
122
|
>
|
|
123
|
-
<Trans>Update</Trans>
|
|
123
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
124
124
|
</Button>
|
|
125
125
|
</PermissionGuard>
|
|
126
126
|
</PageActionBarRight>
|
|
@@ -97,14 +97,14 @@ function ProductVariantDetailPage() {
|
|
|
97
97
|
},
|
|
98
98
|
params: { id: params.id },
|
|
99
99
|
onSuccess: data => {
|
|
100
|
-
toast.success(i18n.t('Successfully updated product'));
|
|
100
|
+
toast.success(i18n.t(creatingNewEntity ? 'Successfully created product variant' : 'Successfully updated product variant'));
|
|
101
101
|
resetForm();
|
|
102
102
|
if (creatingNewEntity) {
|
|
103
103
|
navigate({ to: `../${(data as any)?.[0]?.id}`, from: Route.id });
|
|
104
104
|
}
|
|
105
105
|
},
|
|
106
106
|
onError: err => {
|
|
107
|
-
toast.error(i18n.t('Failed to update product'), {
|
|
107
|
+
toast.error(i18n.t(creatingNewEntity ? 'Failed to create product variant' : 'Failed to update product variant'), {
|
|
108
108
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
109
109
|
});
|
|
110
110
|
},
|
|
@@ -124,7 +124,7 @@ function ProductVariantDetailPage() {
|
|
|
124
124
|
type="submit"
|
|
125
125
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
126
126
|
>
|
|
127
|
-
<Trans>Update</Trans>
|
|
127
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
128
128
|
</Button>
|
|
129
129
|
</PermissionGuard>
|
|
130
130
|
</PageActionBarRight>
|
|
@@ -81,14 +81,14 @@ function ProductDetailPage() {
|
|
|
81
81
|
},
|
|
82
82
|
params: { id: params.id },
|
|
83
83
|
onSuccess: async data => {
|
|
84
|
-
toast.success(i18n.t('Successfully updated product'));
|
|
84
|
+
toast.success(i18n.t(creatingNewEntity ? 'Successfully created product' : 'Successfully updated product'));
|
|
85
85
|
resetForm();
|
|
86
86
|
if (creatingNewEntity) {
|
|
87
87
|
await navigate({ to: `../$id`, params: { id: data.id } });
|
|
88
88
|
}
|
|
89
89
|
},
|
|
90
90
|
onError: err => {
|
|
91
|
-
toast.error(i18n.t('Failed to update product'), {
|
|
91
|
+
toast.error(i18n.t(creatingNewEntity ? 'Failed to create product' : 'Failed to update product'), {
|
|
92
92
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
93
93
|
});
|
|
94
94
|
},
|
|
@@ -104,7 +104,7 @@ function ProductDetailPage() {
|
|
|
104
104
|
type="submit"
|
|
105
105
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
106
106
|
>
|
|
107
|
-
<Trans>Update</Trans>
|
|
107
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
108
108
|
</Button>
|
|
109
109
|
</PermissionGuard>
|
|
110
110
|
</PageActionBarRight>
|
|
@@ -99,19 +99,19 @@ function PromotionDetailPage() {
|
|
|
99
99
|
params: { id: params.id },
|
|
100
100
|
onSuccess: async data => {
|
|
101
101
|
if (data.__typename === 'Promotion') {
|
|
102
|
-
toast.success(i18n.t('Successfully updated promotion'));
|
|
102
|
+
toast.success(i18n.t(creatingNewEntity ? 'Successfully created promotion' : 'Successfully updated promotion'));
|
|
103
103
|
resetForm();
|
|
104
104
|
if (creatingNewEntity) {
|
|
105
105
|
await navigate({ to: `../$id`, params: { id: data.id } });
|
|
106
106
|
}
|
|
107
107
|
} else {
|
|
108
|
-
toast.error(i18n.t('Failed to update promotion'), {
|
|
108
|
+
toast.error(i18n.t(creatingNewEntity ? 'Failed to create promotion' : 'Failed to update promotion'), {
|
|
109
109
|
description: data.message,
|
|
110
110
|
});
|
|
111
111
|
}
|
|
112
112
|
},
|
|
113
113
|
onError: err => {
|
|
114
|
-
toast.error(i18n.t('Failed to update promotion'), {
|
|
114
|
+
toast.error(i18n.t(creatingNewEntity ? 'Failed to create promotion' : 'Failed to update promotion'), {
|
|
115
115
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
116
116
|
});
|
|
117
117
|
},
|
|
@@ -127,7 +127,7 @@ function PromotionDetailPage() {
|
|
|
127
127
|
type="submit"
|
|
128
128
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
129
129
|
>
|
|
130
|
-
<Trans>Update</Trans>
|
|
130
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
131
131
|
</Button>
|
|
132
132
|
</PermissionGuard>
|
|
133
133
|
</PageActionBarRight>
|
|
@@ -61,14 +61,14 @@ function RoleDetailPage() {
|
|
|
61
61
|
},
|
|
62
62
|
params: { id: params.id },
|
|
63
63
|
onSuccess: async data => {
|
|
64
|
-
toast.success(i18n.t('Successfully updated role'));
|
|
64
|
+
toast.success(i18n.t(creatingNewEntity ? 'Successfully created role' : 'Successfully updated role'));
|
|
65
65
|
resetForm();
|
|
66
66
|
if (creatingNewEntity) {
|
|
67
67
|
await navigate({ to: `../$id`, params: { id: data.id } });
|
|
68
68
|
}
|
|
69
69
|
},
|
|
70
70
|
onError: err => {
|
|
71
|
-
toast.error(i18n.t('Failed to update role'), {
|
|
71
|
+
toast.error(i18n.t(creatingNewEntity ? 'Failed to create role' : 'Failed to update role'), {
|
|
72
72
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
73
73
|
});
|
|
74
74
|
},
|
|
@@ -84,7 +84,7 @@ function RoleDetailPage() {
|
|
|
84
84
|
type="submit"
|
|
85
85
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
86
86
|
>
|
|
87
|
-
<Trans>Update</Trans>
|
|
87
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
88
88
|
</Button>
|
|
89
89
|
</PermissionGuard>
|
|
90
90
|
</PageActionBarRight>
|
|
@@ -55,14 +55,14 @@ function SellerDetailPage() {
|
|
|
55
55
|
},
|
|
56
56
|
params: { id: params.id },
|
|
57
57
|
onSuccess: async data => {
|
|
58
|
-
toast(i18n.t('Successfully updated seller'));
|
|
58
|
+
toast(i18n.t(creatingNewEntity ? 'Successfully created seller' : 'Successfully updated seller'));
|
|
59
59
|
form.reset(form.getValues());
|
|
60
60
|
if (creatingNewEntity) {
|
|
61
61
|
await navigate({ to: `../$id`, params: { id: data.id } });
|
|
62
62
|
}
|
|
63
63
|
},
|
|
64
64
|
onError: err => {
|
|
65
|
-
toast(i18n.t('Failed to update seller'), {
|
|
65
|
+
toast(i18n.t(creatingNewEntity ? 'Failed to create seller' : 'Failed to update seller'), {
|
|
66
66
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
67
67
|
});
|
|
68
68
|
},
|
|
@@ -78,7 +78,7 @@ function SellerDetailPage() {
|
|
|
78
78
|
type="submit"
|
|
79
79
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
80
80
|
>
|
|
81
|
-
<Trans>Update</Trans>
|
|
81
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
82
82
|
</Button>
|
|
83
83
|
</PermissionGuard>
|
|
84
84
|
</PageActionBarRight>
|
|
@@ -84,14 +84,14 @@ function ShippingMethodDetailPage() {
|
|
|
84
84
|
},
|
|
85
85
|
params: { id: params.id },
|
|
86
86
|
onSuccess: async data => {
|
|
87
|
-
toast.success(i18n.t('Successfully updated shipping method'));
|
|
87
|
+
toast.success(i18n.t(creatingNewEntity ? 'Successfully created shipping method' : 'Successfully updated shipping method'));
|
|
88
88
|
resetForm();
|
|
89
89
|
if (creatingNewEntity) {
|
|
90
90
|
await navigate({ to: `../$id`, params: { id: data.id } });
|
|
91
91
|
}
|
|
92
92
|
},
|
|
93
93
|
onError: err => {
|
|
94
|
-
toast.error(i18n.t('Failed to update shipping method'), {
|
|
94
|
+
toast.error(i18n.t(creatingNewEntity ? 'Failed to create shipping method' : 'Failed to update shipping method'), {
|
|
95
95
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
96
96
|
});
|
|
97
97
|
},
|
|
@@ -109,7 +109,7 @@ function ShippingMethodDetailPage() {
|
|
|
109
109
|
type="submit"
|
|
110
110
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
111
111
|
>
|
|
112
|
-
<Trans>Update</Trans>
|
|
112
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
113
113
|
</Button>
|
|
114
114
|
</PermissionGuard>
|
|
115
115
|
</PageActionBarRight>
|
|
@@ -64,14 +64,14 @@ function StockLocationDetailPage() {
|
|
|
64
64
|
},
|
|
65
65
|
params: { id: params.id },
|
|
66
66
|
onSuccess: async data => {
|
|
67
|
-
toast.success(i18n.t('Successfully updated stock location'));
|
|
67
|
+
toast.success(i18n.t(creatingNewEntity ? 'Successfully created stock location' : 'Successfully updated stock location'));
|
|
68
68
|
resetForm();
|
|
69
69
|
if (creatingNewEntity) {
|
|
70
70
|
await navigate({ to: `../$id`, params: { id: data.id } });
|
|
71
71
|
}
|
|
72
72
|
},
|
|
73
73
|
onError: err => {
|
|
74
|
-
toast.error(i18n.t('Failed to update stock location'), {
|
|
74
|
+
toast.error(i18n.t(creatingNewEntity ? 'Failed to create stock location' : 'Failed to update stock location'), {
|
|
75
75
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
76
76
|
});
|
|
77
77
|
},
|
|
@@ -89,7 +89,7 @@ function StockLocationDetailPage() {
|
|
|
89
89
|
type="submit"
|
|
90
90
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
91
91
|
>
|
|
92
|
-
<Trans>Update</Trans>
|
|
92
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
93
93
|
</Button>
|
|
94
94
|
</PermissionGuard>
|
|
95
95
|
</PageActionBarRight>
|
|
@@ -63,14 +63,14 @@ function TaxCategoryDetailPage() {
|
|
|
63
63
|
},
|
|
64
64
|
params: { id: params.id },
|
|
65
65
|
onSuccess: async data => {
|
|
66
|
-
toast.success(i18n.t('Successfully updated tax category'));
|
|
66
|
+
toast.success(i18n.t(creatingNewEntity ? 'Successfully created tax category' : 'Successfully updated tax category'));
|
|
67
67
|
form.reset(form.getValues());
|
|
68
68
|
if (creatingNewEntity) {
|
|
69
69
|
await navigate({ to: `../$id`, params: { id: data.id } });
|
|
70
70
|
}
|
|
71
71
|
},
|
|
72
72
|
onError: err => {
|
|
73
|
-
toast.error(i18n.t('Failed to update tax category'), {
|
|
73
|
+
toast.error(i18n.t(creatingNewEntity ? 'Failed to create tax category' : 'Failed to update tax category'), {
|
|
74
74
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
75
75
|
});
|
|
76
76
|
},
|
|
@@ -88,7 +88,7 @@ function TaxCategoryDetailPage() {
|
|
|
88
88
|
type="submit"
|
|
89
89
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
90
90
|
>
|
|
91
|
-
<Trans>Update</Trans>
|
|
91
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
92
92
|
</Button>
|
|
93
93
|
</PermissionGuard>
|
|
94
94
|
</PageActionBarRight>
|
|
@@ -67,14 +67,14 @@ function TaxRateDetailPage() {
|
|
|
67
67
|
},
|
|
68
68
|
params: { id: params.id },
|
|
69
69
|
onSuccess: async data => {
|
|
70
|
-
toast.success(i18n.t('Successfully updated tax rate'));
|
|
70
|
+
toast.success(i18n.t(creatingNewEntity ? 'Successfully created tax rate' : 'Successfully updated tax rate'));
|
|
71
71
|
resetForm();
|
|
72
72
|
if (creatingNewEntity) {
|
|
73
73
|
await navigate({ to: `../$id`, params: { id: data.id } });
|
|
74
74
|
}
|
|
75
75
|
},
|
|
76
76
|
onError: err => {
|
|
77
|
-
toast.error(i18n.t('Failed to update tax rate'), {
|
|
77
|
+
toast.error(i18n.t(creatingNewEntity ? 'Failed to create tax rate' : 'Failed to update tax rate'), {
|
|
78
78
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
79
79
|
});
|
|
80
80
|
},
|
|
@@ -90,7 +90,7 @@ function TaxRateDetailPage() {
|
|
|
90
90
|
type="submit"
|
|
91
91
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
92
92
|
>
|
|
93
|
-
<Trans>Update</Trans>
|
|
93
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
94
94
|
</Button>
|
|
95
95
|
</PermissionGuard>
|
|
96
96
|
</PageActionBarRight>
|
|
@@ -120,6 +120,7 @@ function TaxRateDetailPage() {
|
|
|
120
120
|
label={<Trans>Rate</Trans>}
|
|
121
121
|
render={({ field }) => (
|
|
122
122
|
<AffixedInput
|
|
123
|
+
{...field}
|
|
123
124
|
type="number"
|
|
124
125
|
suffix="%"
|
|
125
126
|
value={field.value}
|
|
@@ -56,14 +56,14 @@ function ZoneDetailPage() {
|
|
|
56
56
|
},
|
|
57
57
|
params: { id: params.id },
|
|
58
58
|
onSuccess: async data => {
|
|
59
|
-
toast.success(i18n.t('Successfully updated zone'));
|
|
59
|
+
toast.success(i18n.t(creatingNewEntity ? 'Successfully created zone' : 'Successfully updated zone'));
|
|
60
60
|
resetForm();
|
|
61
61
|
if (creatingNewEntity) {
|
|
62
62
|
await navigate({ to: `../$id`, params: { id: data.id } });
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
onError: err => {
|
|
66
|
-
toast.error(i18n.t('Failed to update zone'), {
|
|
66
|
+
toast.error(i18n.t(creatingNewEntity ? 'Failed to create zone' : 'Failed to update zone'), {
|
|
67
67
|
description: err instanceof Error ? err.message : 'Unknown error',
|
|
68
68
|
});
|
|
69
69
|
},
|
|
@@ -79,7 +79,7 @@ function ZoneDetailPage() {
|
|
|
79
79
|
type="submit"
|
|
80
80
|
disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
|
|
81
81
|
>
|
|
82
|
-
<Trans>Update</Trans>
|
|
82
|
+
{creatingNewEntity ? <Trans>Create</Trans> : <Trans>Update</Trans>}
|
|
83
83
|
</Button>
|
|
84
84
|
</PermissionGuard>
|
|
85
85
|
</PageActionBarRight>
|
|
@@ -10,6 +10,24 @@ export type AffixedInputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>
|
|
|
10
10
|
suffix?: ReactNode;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* @description
|
|
15
|
+
* A component for displaying an input with a prefix and/or a suffix.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```tsx
|
|
19
|
+
* <AffixedInput
|
|
20
|
+
* {...field}
|
|
21
|
+
* type="number"
|
|
22
|
+
* suffix="%"
|
|
23
|
+
* value={field.value}
|
|
24
|
+
* onChange={e => field.onChange(e.target.valueAsNumber)}
|
|
25
|
+
* />
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @docsCategory form-components
|
|
29
|
+
* @docsPage AffixedInput
|
|
30
|
+
*/
|
|
13
31
|
export function AffixedInput({ prefix, suffix, className = '', ...props }: Readonly<AffixedInputProps>) {
|
|
14
32
|
const readOnly = props.disabled || isReadonlyField(props.fieldDef);
|
|
15
33
|
const prefixRef = useRef<HTMLSpanElement>(null);
|
|
@@ -2,6 +2,13 @@ import { Switch } from '@/vdb/components/ui/switch.js';
|
|
|
2
2
|
import { DashboardFormComponentProps } from '@/vdb/framework/form-engine/form-engine-types.js';
|
|
3
3
|
import { isReadonlyField } from '@/vdb/framework/form-engine/utils.js';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* @description
|
|
7
|
+
* Displays a boolean value as a switch toggle.
|
|
8
|
+
*
|
|
9
|
+
* @docsCategory form-components
|
|
10
|
+
* @docsPage BooleanInput
|
|
11
|
+
*/
|
|
5
12
|
export function BooleanInput({ value, onChange, fieldDef }: Readonly<DashboardFormComponentProps>) {
|
|
6
13
|
const checked = typeof value === 'string' ? value === 'true' : value;
|
|
7
14
|
const readOnly = isReadonlyField(fieldDef);
|