@vendure/dashboard 3.4.2-master-202509020230 → 3.4.2-master-202509030226

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/package.json +4 -4
  2. package/src/app/routes/_authenticated/_channels/channels_.$id.tsx +3 -0
  3. package/src/app/routes/_authenticated/_collections/components/collection-bulk-actions.tsx +7 -7
  4. package/src/app/routes/_authenticated/_facets/components/facet-bulk-actions.tsx +3 -3
  5. package/src/app/routes/_authenticated/_payment-methods/components/payment-method-bulk-actions.tsx +2 -2
  6. package/src/app/routes/_authenticated/_product-variants/components/product-variant-bulk-actions.tsx +4 -4
  7. package/src/app/routes/_authenticated/_products/components/add-option-group-dialog.tsx +127 -0
  8. package/src/app/routes/_authenticated/_products/components/add-product-variant-dialog.tsx +41 -39
  9. package/src/app/routes/_authenticated/_products/components/create-product-options-dialog.tsx +1 -33
  10. package/src/app/routes/_authenticated/_products/components/create-product-variants-dialog.tsx +7 -42
  11. package/src/app/routes/_authenticated/_products/components/create-product-variants.tsx +38 -134
  12. package/src/app/routes/_authenticated/_products/components/option-groups-editor.tsx +180 -0
  13. package/src/app/routes/_authenticated/_products/components/option-value-input.tsx +9 -39
  14. package/src/app/routes/_authenticated/_products/components/product-bulk-actions.tsx +2 -2
  15. package/src/app/routes/_authenticated/_products/products.graphql.ts +136 -0
  16. package/src/app/routes/_authenticated/_products/products_.$id.tsx +9 -9
  17. package/src/app/routes/_authenticated/_products/products_.$id_.variants.tsx +405 -0
  18. package/src/app/routes/_authenticated/_promotions/components/promotion-bulk-actions.tsx +2 -2
  19. package/src/app/routes/_authenticated/_shipping-methods/components/shipping-method-bulk-actions.tsx +2 -2
  20. package/src/app/routes/_authenticated/_stock-locations/components/stock-location-bulk-actions.tsx +3 -3
  21. package/src/lib/components/data-input/rich-text-input.tsx +8 -4
  22. package/src/lib/components/layout/channel-switcher.tsx +27 -6
  23. package/src/lib/components/layout/manage-languages-dialog.tsx +2 -2
  24. package/src/lib/components/shared/asset/asset-gallery.tsx +20 -2
  25. package/src/lib/components/shared/asset/asset-picker-dialog.tsx +5 -5
  26. package/src/lib/components/shared/assign-to-channel-dialog.tsx +2 -2
  27. package/src/lib/components/shared/remove-from-channel-bulk-action.tsx +2 -2
  28. package/src/lib/graphql/api.ts +3 -1
  29. package/src/lib/hooks/use-permissions.ts +4 -4
  30. package/src/lib/providers/auth.tsx +8 -0
  31. package/src/lib/providers/channel-provider.tsx +48 -57
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vendure/dashboard",
3
3
  "private": false,
4
- "version": "3.4.2-master-202509020230",
4
+ "version": "3.4.2-master-202509030226",
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": "^3.4.2-master-202509020230",
104
- "@vendure/core": "^3.4.2-master-202509020230",
103
+ "@vendure/common": "^3.4.2-master-202509030226",
104
+ "@vendure/core": "^3.4.2-master-202509030226",
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": "061ef50c94ef21121b3fa30e6c5cd63899b62a8e"
155
+ "gitHead": "ea17999f2c068b9d5c96d81f4646393acb5baedf"
156
156
  }
@@ -22,6 +22,7 @@ import {
22
22
  } from '@/vdb/framework/layout-engine/page-layout.js';
23
23
  import { detailPageRouteLoader } from '@/vdb/framework/page/detail-page-route-loader.js';
24
24
  import { useDetailPage } from '@/vdb/framework/page/use-detail-page.js';
25
+ import { useChannel } from '@/vdb/hooks/use-channel.js';
25
26
  import { Trans, useLingui } from '@/vdb/lib/trans.js';
26
27
  import { createFileRoute, useNavigate } from '@tanstack/react-router';
27
28
  import { toast } from 'sonner';
@@ -49,6 +50,7 @@ function ChannelDetailPage() {
49
50
  const navigate = useNavigate();
50
51
  const creatingNewEntity = params.id === NEW_ENTITY_PATH;
51
52
  const { i18n } = useLingui();
53
+ const { refreshChannels } = useChannel();
52
54
 
53
55
  const { form, submitHandler, entity, isPending, resetForm } = useDetailPage({
54
56
  pageId,
@@ -81,6 +83,7 @@ function ChannelDetailPage() {
81
83
  onSuccess: async data => {
82
84
  if (data.__typename === 'Channel') {
83
85
  toast(i18n.t('Successfully updated channel'));
86
+ refreshChannels();
84
87
  resetForm();
85
88
  if (creatingNewEntity) {
86
89
  await navigate({ to: `../$id`, params: { id: data.id } });
@@ -1,15 +1,15 @@
1
1
  import { useQueryClient } from '@tanstack/react-query';
2
- import { useState } from 'react';
3
2
  import { FolderTree } from 'lucide-react';
3
+ import { useState } from 'react';
4
4
 
5
- import { Trans } from '@/vdb/lib/trans.js';
5
+ import { DataTableBulkActionItem } from '@/vdb/components/data-table/data-table-bulk-action-item.js';
6
6
  import { AssignToChannelBulkAction } from '@/vdb/components/shared/assign-to-channel-bulk-action.js';
7
+ import { usePaginatedList } from '@/vdb/components/shared/paginated-list-data-table.js';
7
8
  import { RemoveFromChannelBulkAction } from '@/vdb/components/shared/remove-from-channel-bulk-action.js';
8
- import { api } from '@/vdb/graphql/api.js';
9
9
  import { BulkActionComponent } from '@/vdb/framework/extension-api/types/data-table.js';
10
+ import { api } from '@/vdb/graphql/api.js';
10
11
  import { useChannel } from '@/vdb/hooks/use-channel.js';
11
- import { DataTableBulkActionItem } from '@/vdb/components/data-table/data-table-bulk-action-item.js';
12
- import { usePaginatedList } from '@/vdb/components/shared/paginated-list-data-table.js';
12
+ import { Trans } from '@/vdb/lib/trans.js';
13
13
  import { DeleteBulkAction } from '../../../../common/delete-bulk-action.js';
14
14
  import { DuplicateBulkAction } from '../../../../common/duplicate-bulk-action.js';
15
15
  import {
@@ -41,7 +41,7 @@ export const AssignCollectionsToChannelBulkAction: BulkActionComponent<any> = ({
41
41
  };
42
42
 
43
43
  export const RemoveCollectionsFromChannelBulkAction: BulkActionComponent<any> = ({ selection, table }) => {
44
- const { selectedChannel } = useChannel();
44
+ const { activeChannel } = useChannel();
45
45
  const queryClient = useQueryClient();
46
46
 
47
47
  return (
@@ -53,7 +53,7 @@ export const RemoveCollectionsFromChannelBulkAction: BulkActionComponent<any> =
53
53
  requiredPermissions={['UpdateCatalog', 'UpdateCollection']}
54
54
  buildInput={() => ({
55
55
  collectionIds: selection.map(s => s.id),
56
- channelId: selectedChannel?.id,
56
+ channelId: activeChannel?.id,
57
57
  })}
58
58
  onSuccess={() => {
59
59
  queryClient.invalidateQueries({ queryKey: ['childCollections'] });
@@ -2,9 +2,9 @@ import { toast } from 'sonner';
2
2
 
3
3
  import { AssignToChannelBulkAction } from '@/vdb/components/shared/assign-to-channel-bulk-action.js';
4
4
  import { RemoveFromChannelBulkAction } from '@/vdb/components/shared/remove-from-channel-bulk-action.js';
5
+ import { BulkActionComponent } from '@/vdb/framework/extension-api/types/data-table.js';
5
6
  import { api } from '@/vdb/graphql/api.js';
6
7
  import { ResultOf } from '@/vdb/graphql/graphql.js';
7
- import { BulkActionComponent } from '@/vdb/framework/extension-api/types/data-table.js';
8
8
  import { useChannel } from '@/vdb/hooks/use-channel.js';
9
9
  import { useLingui } from '@/vdb/lib/trans.js';
10
10
  import { DeleteBulkAction } from '../../../../common/delete-bulk-action.js';
@@ -45,7 +45,7 @@ export const AssignFacetsToChannelBulkAction: BulkActionComponent<any> = ({ sele
45
45
  };
46
46
 
47
47
  export const RemoveFacetsFromChannelBulkAction: BulkActionComponent<any> = ({ selection, table }) => {
48
- const { selectedChannel } = useChannel();
48
+ const { activeChannel } = useChannel();
49
49
  const { i18n } = useLingui();
50
50
 
51
51
  return (
@@ -57,7 +57,7 @@ export const RemoveFacetsFromChannelBulkAction: BulkActionComponent<any> = ({ se
57
57
  requiredPermissions={['UpdateCatalog', 'UpdateFacet']}
58
58
  buildInput={() => ({
59
59
  facetIds: selection.map(s => s.id),
60
- channelId: selectedChannel?.id,
60
+ channelId: activeChannel?.id,
61
61
  })}
62
62
  onSuccess={result => {
63
63
  const typedResult = result as ResultOf<typeof removeFacetsFromChannelDocument>;
@@ -40,7 +40,7 @@ export const AssignPaymentMethodsToChannelBulkAction: BulkActionComponent<any> =
40
40
  };
41
41
 
42
42
  export const RemovePaymentMethodsFromChannelBulkAction: BulkActionComponent<any> = ({ selection, table }) => {
43
- const { selectedChannel } = useChannel();
43
+ const { activeChannel } = useChannel();
44
44
 
45
45
  return (
46
46
  <RemoveFromChannelBulkAction
@@ -51,7 +51,7 @@ export const RemovePaymentMethodsFromChannelBulkAction: BulkActionComponent<any>
51
51
  requiredPermissions={['UpdatePaymentMethod']}
52
52
  buildInput={() => ({
53
53
  paymentMethodIds: selection.map(s => s.id),
54
- channelId: selectedChannel?.id,
54
+ channelId: activeChannel?.id,
55
55
  })}
56
56
  />
57
57
  );
@@ -4,11 +4,11 @@ import { useState } from 'react';
4
4
  import { DataTableBulkActionItem } from '@/vdb/components/data-table/data-table-bulk-action-item.js';
5
5
  import { AssignToChannelBulkAction } from '@/vdb/components/shared/assign-to-channel-bulk-action.js';
6
6
  import { usePriceFactor } from '@/vdb/components/shared/assign-to-channel-dialog.js';
7
+ import { usePaginatedList } from '@/vdb/components/shared/paginated-list-data-table.js';
7
8
  import { RemoveFromChannelBulkAction } from '@/vdb/components/shared/remove-from-channel-bulk-action.js';
8
- import { api } from '@/vdb/graphql/api.js';
9
9
  import { BulkActionComponent } from '@/vdb/framework/extension-api/types/data-table.js';
10
+ import { api } from '@/vdb/graphql/api.js';
10
11
  import { useChannel } from '@/vdb/hooks/use-channel.js';
11
- import { usePaginatedList } from '@/vdb/components/shared/paginated-list-data-table.js';
12
12
  import { Trans } from '@/vdb/lib/trans.js';
13
13
  import { DeleteBulkAction } from '../../../../common/delete-bulk-action.js';
14
14
 
@@ -58,7 +58,7 @@ export const RemoveProductVariantsFromChannelBulkAction: BulkActionComponent<any
58
58
  selection,
59
59
  table,
60
60
  }) => {
61
- const { selectedChannel } = useChannel();
61
+ const { activeChannel } = useChannel();
62
62
 
63
63
  return (
64
64
  <RemoveFromChannelBulkAction
@@ -69,7 +69,7 @@ export const RemoveProductVariantsFromChannelBulkAction: BulkActionComponent<any
69
69
  requiredPermissions={['UpdateCatalog', 'UpdateProduct']}
70
70
  buildInput={() => ({
71
71
  productVariantIds: selection.map(s => s.id),
72
- channelId: selectedChannel?.id,
72
+ channelId: activeChannel?.id,
73
73
  })}
74
74
  />
75
75
  );
@@ -0,0 +1,127 @@
1
+ import { Button } from '@/vdb/components/ui/button.js';
2
+ import {
3
+ Dialog,
4
+ DialogContent,
5
+ DialogFooter,
6
+ DialogHeader,
7
+ DialogTitle,
8
+ DialogTrigger,
9
+ } from '@/vdb/components/ui/dialog.js';
10
+ import { Form } from '@/vdb/components/ui/form.js';
11
+ import { api } from '@/vdb/graphql/api.js';
12
+ import { Trans, useLingui } from '@/vdb/lib/trans.js';
13
+ import { zodResolver } from '@hookform/resolvers/zod';
14
+ import { useMutation } from '@tanstack/react-query';
15
+ import { Plus, Save } from 'lucide-react';
16
+ import { useState } from 'react';
17
+ import { useForm } from 'react-hook-form';
18
+ import { toast } from 'sonner';
19
+ import { addOptionGroupToProductDocument, createProductOptionGroupDocument } from '../products.graphql.js';
20
+ import { OptionGroup, optionGroupSchema, SingleOptionGroupEditor } from './option-groups-editor.js';
21
+
22
+ export function AddOptionGroupDialog({
23
+ productId,
24
+ onSuccess,
25
+ }: Readonly<{
26
+ productId: string;
27
+ onSuccess?: () => void;
28
+ }>) {
29
+ const [open, setOpen] = useState(false);
30
+ const { i18n } = useLingui();
31
+
32
+ const form = useForm<OptionGroup>({
33
+ resolver: zodResolver(optionGroupSchema),
34
+ defaultValues: {
35
+ name: '',
36
+ values: [],
37
+ },
38
+ mode: 'onChange',
39
+ });
40
+
41
+ const createOptionGroupMutation = useMutation({
42
+ mutationFn: api.mutate(createProductOptionGroupDocument),
43
+ });
44
+
45
+ const addOptionGroupToProductMutation = useMutation({
46
+ mutationFn: api.mutate(addOptionGroupToProductDocument),
47
+ });
48
+
49
+ const handleSave = async () => {
50
+ const formValue = form.getValues();
51
+ if (!formValue.name || formValue.values.length === 0) return;
52
+
53
+ try {
54
+ const createResult = await createOptionGroupMutation.mutateAsync({
55
+ input: {
56
+ code: formValue.name.toLowerCase().replace(/\s+/g, '-'),
57
+ translations: [
58
+ {
59
+ languageCode: 'en',
60
+ name: formValue.name,
61
+ },
62
+ ],
63
+ options: formValue.values.map(value => ({
64
+ code: value.value.toLowerCase().replace(/\s+/g, '-'),
65
+ translations: [
66
+ {
67
+ languageCode: 'en',
68
+ name: value.value,
69
+ },
70
+ ],
71
+ })),
72
+ },
73
+ });
74
+
75
+ if (createResult?.createProductOptionGroup) {
76
+ await addOptionGroupToProductMutation.mutateAsync({
77
+ productId,
78
+ optionGroupId: createResult.createProductOptionGroup.id,
79
+ });
80
+ }
81
+
82
+ toast.success(i18n.t('Successfully created option group'));
83
+ setOpen(false);
84
+ onSuccess?.();
85
+ } catch (error) {
86
+ toast.error(i18n.t('Failed to create option group'), {
87
+ description: error instanceof Error ? error.message : i18n.t('Unknown error'),
88
+ });
89
+ }
90
+ };
91
+
92
+ return (
93
+ <Dialog open={open} onOpenChange={setOpen}>
94
+ <DialogTrigger asChild>
95
+ <Button variant="outline">
96
+ <Plus className="mr-2 h-4 w-4" />
97
+ <Trans>Add option group</Trans>
98
+ </Button>
99
+ </DialogTrigger>
100
+ <DialogContent className="max-w-2xl" aria-description={'Add option group'}>
101
+ <DialogHeader>
102
+ <DialogTitle>
103
+ <Trans>Add option group to product</Trans>
104
+ </DialogTitle>
105
+ </DialogHeader>
106
+ <div className="space-y-4">
107
+ <Form {...form}>
108
+ <SingleOptionGroupEditor control={form.control} fieldArrayPath={''} />
109
+ </Form>
110
+ </div>
111
+ <DialogFooter>
112
+ <Button
113
+ onClick={handleSave}
114
+ disabled={
115
+ !form.formState.isValid ||
116
+ createOptionGroupMutation.isPending ||
117
+ addOptionGroupToProductMutation.isPending
118
+ }
119
+ >
120
+ <Save className="mr-2 h-4 w-4" />
121
+ <Trans>Save option group</Trans>
122
+ </Button>
123
+ </DialogFooter>
124
+ </DialogContent>
125
+ </Dialog>
126
+ );
127
+ }
@@ -22,6 +22,7 @@ import { useCallback, useEffect, useState } from 'react';
22
22
  import { useForm } from 'react-hook-form';
23
23
  import { toast } from 'sonner';
24
24
  import * as z from 'zod';
25
+ import { createProductOptionDocument } from '../products.graphql.js';
25
26
  import { CreateProductOptionsDialog } from './create-product-options-dialog.js';
26
27
  import { ProductOptionSelect } from './product-option-select.js';
27
28
 
@@ -63,43 +64,6 @@ const createProductVariantDocument = graphql(`
63
64
  }
64
65
  `);
65
66
 
66
- const createProductOptionDocument = graphql(`
67
- mutation CreateProductOption($input: CreateProductOptionInput!) {
68
- createProductOption(input: $input) {
69
- id
70
- code
71
- name
72
- groupId
73
- }
74
- }
75
- `);
76
-
77
- const createProductOptionGroupDocument = graphql(`
78
- mutation CreateProductOptionGroup($input: CreateProductOptionGroupInput!) {
79
- createProductOptionGroup(input: $input) {
80
- id
81
- }
82
- }
83
- `);
84
-
85
- const addOptionGroupToProductDocument = graphql(`
86
- mutation AddOptionGroupToProduct($productId: ID!, $optionGroupId: ID!) {
87
- addOptionGroupToProduct(productId: $productId, optionGroupId: $optionGroupId) {
88
- id
89
- optionGroups {
90
- id
91
- code
92
- name
93
- options {
94
- id
95
- code
96
- name
97
- }
98
- }
99
- }
100
- }
101
- `);
102
-
103
67
  const formSchema = z.object({
104
68
  name: z.string().min(1, 'Name is required'),
105
69
  sku: z.string().min(1, 'SKU is required'),
@@ -256,8 +220,8 @@ export function AddProductVariantDialog({
256
220
  [createProductVariantMutation, productData?.product, duplicateVariantError, productId],
257
221
  );
258
222
 
259
- // If there are no option groups, show the create options dialog instead
260
- if (productData?.product?.optionGroups.length === 0) {
223
+ // If there are no option groups and no variants, show the create options dialog instead
224
+ if (productData?.product?.optionGroups.length === 0 && productData?.product?.variants.length === 0) {
261
225
  return (
262
226
  <CreateProductOptionsDialog
263
227
  productId={productId}
@@ -269,6 +233,35 @@ export function AddProductVariantDialog({
269
233
  );
270
234
  }
271
235
 
236
+ // If there are no option groups but there are existing variants, show a different UI
237
+ if (productData?.product?.optionGroups.length === 0 && productData?.product?.variants.length > 0) {
238
+ return (
239
+ <Dialog open={open} onOpenChange={setOpen}>
240
+ <DialogTrigger asChild>
241
+ <Button variant="outline">
242
+ <Plus className="mr-2 h-4 w-4" />
243
+ <Trans>Add variant</Trans>
244
+ </Button>
245
+ </DialogTrigger>
246
+ <DialogContent>
247
+ <DialogHeader>
248
+ <DialogTitle>
249
+ <Trans>Add product options first</Trans>
250
+ </DialogTitle>
251
+ </DialogHeader>
252
+ <div className="space-y-4">
253
+ <p className="text-sm text-muted-foreground">
254
+ <Trans>
255
+ This product has existing variants but no option groups defined. You need to
256
+ add option groups before creating new variants.
257
+ </Trans>
258
+ </p>
259
+ </div>
260
+ </DialogContent>
261
+ </Dialog>
262
+ );
263
+ }
264
+
272
265
  return (
273
266
  <Dialog open={open} onOpenChange={setOpen}>
274
267
  <DialogTrigger asChild>
@@ -291,6 +284,15 @@ export function AddProductVariantDialog({
291
284
  }}
292
285
  className="space-y-4"
293
286
  >
287
+ {productData?.product?.optionGroups.length && (
288
+ <div className="flex flex-col gap-2">
289
+ <div className="flex justify-between items-center">
290
+ <label className="text-sm font-medium">
291
+ <Trans>Product options</Trans>
292
+ </label>
293
+ </div>
294
+ </div>
295
+ )}
294
296
  <div className="grid grid-cols-2 gap-4">
295
297
  {productData?.product?.optionGroups.map(group => (
296
298
  <ProductOptionSelect
@@ -20,6 +20,7 @@ import { useState } from 'react';
20
20
  import { useForm } from 'react-hook-form';
21
21
  import { toast } from 'sonner';
22
22
  import * as z from 'zod';
23
+ import { addOptionGroupToProductDocument, createProductOptionGroupDocument } from '../products.graphql.js';
23
24
 
24
25
  const getProductDocument = graphql(`
25
26
  query GetProduct($productId: ID!) {
@@ -51,39 +52,6 @@ const getProductDocument = graphql(`
51
52
  }
52
53
  `);
53
54
 
54
- const createProductOptionGroupDocument = graphql(`
55
- mutation CreateProductOptionGroup($input: CreateProductOptionGroupInput!) {
56
- createProductOptionGroup(input: $input) {
57
- id
58
- code
59
- name
60
- options {
61
- id
62
- code
63
- name
64
- }
65
- }
66
- }
67
- `);
68
-
69
- const addOptionGroupToProductDocument = graphql(`
70
- mutation AddOptionGroupToProduct($productId: ID!, $optionGroupId: ID!) {
71
- addOptionGroupToProduct(productId: $productId, optionGroupId: $optionGroupId) {
72
- id
73
- optionGroups {
74
- id
75
- code
76
- name
77
- options {
78
- id
79
- code
80
- name
81
- }
82
- }
83
- }
84
- }
85
- `);
86
-
87
55
  const updateProductVariantDocument = graphql(`
88
56
  mutation UpdateProductVariant($input: UpdateProductVariantInput!) {
89
57
  updateProductVariant(input: $input) {
@@ -9,54 +9,19 @@ import {
9
9
  DialogTrigger,
10
10
  } from '@/vdb/components/ui/dialog.js';
11
11
  import { api } from '@/vdb/graphql/api.js';
12
- import { graphql } from '@/vdb/graphql/graphql.js';
13
12
  import { useChannel } from '@/vdb/hooks/use-channel.js';
14
13
  import { Trans } from '@/vdb/lib/trans.js';
15
14
  import { normalizeString } from '@/vdb/lib/utils.js';
16
15
  import { useMutation } from '@tanstack/react-query';
17
16
  import { Plus } from 'lucide-react';
18
17
  import { useCallback, useState } from 'react';
18
+ import {
19
+ addOptionGroupToProductDocument,
20
+ createProductOptionGroupDocument,
21
+ createProductVariantsDocument,
22
+ } from '../products.graphql.js';
19
23
  import { CreateProductVariants, VariantConfiguration } from './create-product-variants.js';
20
24
 
21
- const createProductOptionsMutation = graphql(`
22
- mutation CreateOptionGroups($input: CreateProductOptionGroupInput!) {
23
- createProductOptionGroup(input: $input) {
24
- id
25
- name
26
- options {
27
- id
28
- code
29
- name
30
- }
31
- }
32
- }
33
- `);
34
-
35
- export const addOptionGroupToProductDocument = graphql(`
36
- mutation AddOptionGroupToProduct($productId: ID!, $optionGroupId: ID!) {
37
- addOptionGroupToProduct(productId: $productId, optionGroupId: $optionGroupId) {
38
- id
39
- optionGroups {
40
- id
41
- code
42
- options {
43
- id
44
- code
45
- }
46
- }
47
- }
48
- }
49
- `);
50
-
51
- export const createProductVariantsDocument = graphql(`
52
- mutation CreateProductVariants($input: [CreateProductVariantInput!]!) {
53
- createProductVariants(input: $input) {
54
- id
55
- name
56
- }
57
- }
58
- `);
59
-
60
25
  export function CreateProductVariantsDialog({
61
26
  productId,
62
27
  productName,
@@ -71,7 +36,7 @@ export function CreateProductVariantsDialog({
71
36
  const [open, setOpen] = useState(false);
72
37
 
73
38
  const createOptionGroupMutation = useMutation({
74
- mutationFn: api.mutate(createProductOptionsMutation),
39
+ mutationFn: api.mutate(createProductOptionGroupDocument),
75
40
  });
76
41
 
77
42
  const addOptionGroupToProductMutation = useMutation({
@@ -180,7 +145,7 @@ export function CreateProductVariantsDialog({
180
145
  </Button>
181
146
  </DialogTrigger>
182
147
 
183
- <DialogContent>
148
+ <DialogContent className="max-w-90vw">
184
149
  <DialogHeader>
185
150
  <DialogTitle>
186
151
  <Trans>Create Variants</Trans>