@vendure/dashboard 3.3.6-master-202507050232 → 3.3.6-master-202507090236

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vendure/dashboard",
3
3
  "private": false,
4
- "version": "3.3.6-master-202507050232",
4
+ "version": "3.3.6-master-202507090236",
5
5
  "type": "module",
6
6
  "repository": {
7
7
  "type": "git",
@@ -86,8 +86,8 @@
86
86
  "@types/react-dom": "^19.0.4",
87
87
  "@types/react-grid-layout": "^1.3.5",
88
88
  "@uidotdev/usehooks": "^2.4.1",
89
- "@vendure/common": "^3.3.6-master-202507050232",
90
- "@vendure/core": "^3.3.6-master-202507050232",
89
+ "@vendure/common": "^3.3.6-master-202507090236",
90
+ "@vendure/core": "^3.3.6-master-202507090236",
91
91
  "@vitejs/plugin-react": "^4.3.4",
92
92
  "awesome-graphql-client": "^2.1.0",
93
93
  "class-variance-authority": "^0.7.1",
@@ -130,5 +130,5 @@
130
130
  "lightningcss-linux-arm64-musl": "^1.29.3",
131
131
  "lightningcss-linux-x64-musl": "^1.29.1"
132
132
  },
133
- "gitHead": "aa108b47a462b2ff023250e4f9e75a02529feb8a"
133
+ "gitHead": "df60d656c924e7574df61467ef1bbdb9a0221dcc"
134
134
  }
@@ -40,7 +40,7 @@ export function CustomerOrderTable({ customerId }: Readonly<CustomerOrderTablePr
40
40
  cell: ({ cell, row }) => {
41
41
  const value = cell.getValue();
42
42
  const currencyCode = row.original.currencyCode;
43
- return <Money value={value} currencyCode={currencyCode} />;
43
+ return <Money value={value} currency={currencyCode} />;
44
44
  },
45
45
  },
46
46
  totalWithTax: {
@@ -48,7 +48,7 @@ export function CustomerOrderTable({ customerId }: Readonly<CustomerOrderTablePr
48
48
  cell: ({ cell, row }) => {
49
49
  const value = cell.getValue();
50
50
  const currencyCode = row.original.currencyCode;
51
- return <Money value={value} currencyCode={currencyCode} />;
51
+ return <Money value={value} currency={currencyCode} />;
52
52
  },
53
53
  },
54
54
  state: {
@@ -10,10 +10,10 @@ export function MoneyGrossNet({ priceWithTax, price, currencyCode }: Readonly<Mo
10
10
  return (
11
11
  <div className="flex flex-col gap-1">
12
12
  <div>
13
- <Money value={priceWithTax} currencyCode={currencyCode} />
13
+ <Money value={priceWithTax} currency={currencyCode} />
14
14
  </div>
15
15
  <div className="text-xs text-muted-foreground">
16
- <Money value={price} currencyCode={currencyCode} />
16
+ <Money value={price} currency={currencyCode} />
17
17
  </div>
18
18
  </div>
19
19
  );
@@ -48,7 +48,7 @@ export function ShippingMethodSelector({
48
48
  <span className="text-sm font-medium">
49
49
  <Trans>Price</Trans>
50
50
  </span>
51
- <Money value={method.priceWithTax} currencyCode={currencyCode} />
51
+ <Money value={method.priceWithTax} currency={currencyCode} />
52
52
  </div>
53
53
  </div>
54
54
  </CardContent>
@@ -61,7 +61,7 @@ function OrderListPage() {
61
61
  cell: ({ cell, row }) => {
62
62
  const value = cell.getValue();
63
63
  const currencyCode = row.original.currencyCode;
64
- return <Money value={value} currencyCode={currencyCode} />;
64
+ return <Money value={value} currency={currencyCode} />;
65
65
  },
66
66
  },
67
67
  totalWithTax: {
@@ -69,7 +69,7 @@ function OrderListPage() {
69
69
  cell: ({ cell, row }) => {
70
70
  const value = cell.getValue();
71
71
  const currencyCode = row.original.currencyCode;
72
- return <Money value={value} currencyCode={currencyCode} />;
72
+ return <Money value={value} currency={currencyCode} />;
73
73
  },
74
74
  },
75
75
  state: {
@@ -84,7 +84,7 @@ function ProductDetailPage() {
84
84
  toast.success(i18n.t('Successfully updated product'));
85
85
  resetForm();
86
86
  if (creatingNewEntity) {
87
- await navigate({ to: `../${data.id}`, from: Route.id });
87
+ await navigate({ to: `../$id`, params: { id: data.id } });
88
88
  }
89
89
  },
90
90
  onError: err => {
@@ -7,7 +7,7 @@ import { useChannel } from '../../hooks/use-channel.js';
7
7
  import { useServerConfig } from '../../hooks/use-server-config.js';
8
8
  import { getOperationVariablesFields } from '../document-introspection/get-document-structure.js';
9
9
  import { createFormSchemaFromFields, getDefaultValuesFromFields } from './form-schema-tools.js';
10
- import { transformRelationFields } from './utils.js';
10
+ import { removeEmptyIdFields, transformRelationFields } from './utils.js';
11
11
 
12
12
  export interface GeneratedFormOptions<
13
13
  T extends TypedDocumentNode<any, any>,
@@ -64,7 +64,10 @@ export function useGeneratedForm<
64
64
  };
65
65
  if (onSubmit) {
66
66
  submitHandler = (event: FormEvent) => {
67
- form.handleSubmit(onSubmit as any)(event);
67
+ const onSubmitWrapper = (values: any) => {
68
+ onSubmit(removeEmptyIdFields(values, updateFields));
69
+ };
70
+ form.handleSubmit(onSubmitWrapper)(event);
68
71
  };
69
72
  }
70
73
 
@@ -0,0 +1,37 @@
1
+ import { graphql, VariablesOf } from 'gql.tada';
2
+ import { describe, expect, it } from 'vitest';
3
+
4
+ import { getOperationVariablesFields } from '../document-introspection/get-document-structure.js';
5
+
6
+ import { removeEmptyIdFields } from './utils.js';
7
+
8
+ const createProductDocument = graphql(`
9
+ mutation CreateProduct($input: CreateProductInput!) {
10
+ createProduct(input: $input) {
11
+ id
12
+ }
13
+ }
14
+ `);
15
+
16
+ type CreateProductInput = VariablesOf<typeof createProductDocument>;
17
+
18
+ describe('removeEmptyIdFields', () => {
19
+ it('should remove empty translation id field', () => {
20
+ const values: CreateProductInput = {
21
+ input: { translations: [{ id: '', languageCode: 'en' }] },
22
+ };
23
+ const fields = getOperationVariablesFields(createProductDocument);
24
+ const result = removeEmptyIdFields(values, fields);
25
+
26
+ expect(result).toEqual({ input: { translations: [{ languageCode: 'en' }] } });
27
+ });
28
+
29
+ it('should remove empty featuredAsset id field', () => {
30
+ const values: CreateProductInput = {
31
+ input: { featuredAssetId: '', translations: [] },
32
+ };
33
+ const fields = getOperationVariablesFields(createProductDocument);
34
+ const result = removeEmptyIdFields(values, fields);
35
+ expect(result).toEqual({ input: { translations: [] } });
36
+ });
37
+ });
@@ -56,3 +56,50 @@ export function transformRelationFields<E extends Record<string, any>>(fields: F
56
56
 
57
57
  return processedEntity;
58
58
  }
59
+
60
+ /**
61
+ * @description
62
+ * Due to the schema types, sometimes "create" mutations will have a default empty "id"
63
+ * field which can cause issues if we actually send them with a "create" mutation to the server.
64
+ * This function deletes any empty ID fields on the entity or its nested objects.
65
+ */
66
+ export function removeEmptyIdFields<T extends Record<string, any>>(values: T, fields: FieldInfo[]): T {
67
+ if (!values) {
68
+ return values;
69
+ }
70
+
71
+ // Create a deep copy to avoid mutating the original values
72
+ const result = structuredClone(values);
73
+
74
+ function recursiveRemove(obj: any, fieldDefs: FieldInfo[]) {
75
+ if (Array.isArray(obj)) {
76
+ for (const item of obj) {
77
+ recursiveRemove(item, fieldDefs);
78
+ }
79
+ } else if (typeof obj === 'object' && obj !== null) {
80
+ for (const field of fieldDefs) {
81
+ // Remove empty string ID fields at this level
82
+ if (field.type === 'ID' && typeof obj[field.name] === 'string' && obj[field.name] === '') {
83
+ delete obj[field.name];
84
+ }
85
+ // If the field is an object or array, recurse into it
86
+ if (Array.isArray(obj[field.name])) {
87
+ if (field.typeInfo) {
88
+ for (const item of obj[field.name]) {
89
+ recursiveRemove(item, field.typeInfo);
90
+ }
91
+ }
92
+ } else if (
93
+ typeof obj[field.name] === 'object' &&
94
+ obj[field.name] !== null &&
95
+ field.typeInfo
96
+ ) {
97
+ recursiveRemove(obj[field.name], field.typeInfo);
98
+ }
99
+ }
100
+ }
101
+ }
102
+
103
+ recursiveRemove(result, fields);
104
+ return result;
105
+ }