@vendure/dashboard 3.3.6-master-202507010731 → 3.3.6-master-202507011151

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 (28) hide show
  1. package/package.json +131 -131
  2. package/src/app/common/duplicate-bulk-action.tsx +134 -0
  3. package/src/app/routes/_authenticated/_collections/collections.graphql.ts +9 -0
  4. package/src/app/routes/_authenticated/_collections/collections.tsx +10 -0
  5. package/src/app/routes/_authenticated/_collections/components/collection-bulk-actions.tsx +66 -6
  6. package/src/app/routes/_authenticated/_product-variants/components/product-variant-bulk-actions.tsx +4 -5
  7. package/src/app/routes/_authenticated/_products/components/product-bulk-actions.tsx +19 -106
  8. package/src/app/routes/_authenticated/_products/products.graphql.ts +0 -17
  9. package/src/lib/components/shared/custom-fields-form.tsx +18 -1
  10. package/src/lib/components/shared/detail-page-button.tsx +1 -1
  11. package/src/lib/framework/extension-api/use-dashboard-extensions.ts +2 -1
  12. package/src/lib/framework/form-engine/use-generated-form.tsx +5 -8
  13. package/src/lib/framework/form-engine/utils.ts +43 -15
  14. package/src/lib/framework/page/use-detail-page.ts +4 -4
  15. package/src/lib/framework/page/use-extended-router.tsx +4 -5
  16. package/src/lib/graphql/common-operations.ts +18 -0
  17. package/src/lib/graphql/{fragments.tsx → fragments.ts} +1 -2
  18. package/src/lib/graphql/graphql-env.d.ts +3 -3
  19. package/src/lib/hooks/use-channel.ts +2 -1
  20. package/src/lib/hooks/use-extended-detail-query.ts +2 -1
  21. package/src/lib/hooks/use-extended-list-query.ts +3 -2
  22. package/src/lib/hooks/use-grouped-permissions.ts +4 -2
  23. package/src/lib/hooks/use-page-block.tsx +1 -1
  24. package/src/lib/hooks/use-page.tsx +2 -2
  25. package/src/lib/hooks/use-permissions.ts +3 -2
  26. package/src/lib/hooks/use-server-config.ts +2 -1
  27. package/src/lib/hooks/use-theme.ts +2 -1
  28. package/src/lib/providers/auth.tsx +34 -11
@@ -1,5 +1,5 @@
1
1
  import { useMutation } from '@tanstack/react-query';
2
- import { CopyIcon, LayersIcon, TagIcon, TrashIcon } from 'lucide-react';
2
+ import { LayersIcon, TagIcon, TrashIcon } from 'lucide-react';
3
3
  import { useState } from 'react';
4
4
  import { toast } from 'sonner';
5
5
 
@@ -9,12 +9,10 @@ import { api } from '@/graphql/api.js';
9
9
  import { ResultOf } from '@/graphql/graphql.js';
10
10
  import { useChannel, usePaginatedList } from '@/index.js';
11
11
  import { Trans, useLingui } from '@/lib/trans.js';
12
-
13
- import { Permission } from '@vendure/common/lib/generated-types';
12
+ import { DuplicateBulkAction } from '../../../../common/duplicate-bulk-action.js';
14
13
  import {
15
14
  assignProductsToChannelDocument,
16
15
  deleteProductsDocument,
17
- duplicateEntityDocument,
18
16
  getProductsWithFacetValuesByIdsDocument,
19
17
  productDetailDocument,
20
18
  removeProductsFromChannelDocument,
@@ -53,7 +51,7 @@ export const DeleteProductsBulkAction: BulkActionComponent<any> = ({ selection,
53
51
  });
54
52
  return (
55
53
  <DataTableBulkActionItem
56
- requiresPermission={[Permission.DeleteCatalog, Permission.DeleteProduct]}
54
+ requiresPermission={['DeleteCatalog', 'DeleteProduct']}
57
55
  onClick={() => mutate({ ids: selection.map(s => s.id) })}
58
56
  label={<Trans>Delete</Trans>}
59
57
  confirmationText={<Trans>Are you sure you want to delete {selection.length} products?</Trans>}
@@ -80,7 +78,7 @@ export const AssignProductsToChannelBulkAction: BulkActionComponent<any> = ({ se
80
78
  return (
81
79
  <>
82
80
  <DataTableBulkActionItem
83
- requiresPermission={[Permission.UpdateCatalog, Permission.UpdateProduct]}
81
+ requiresPermission={['UpdateCatalog', 'UpdateProduct']}
84
82
  onClick={() => setDialogOpen(true)}
85
83
  label={<Trans>Assign to channel</Trans>}
86
84
  icon={LayersIcon}
@@ -128,7 +126,7 @@ export const RemoveProductsFromChannelBulkAction: BulkActionComponent<any> = ({
128
126
 
129
127
  return (
130
128
  <DataTableBulkActionItem
131
- requiresPermission={[Permission.UpdateCatalog, Permission.UpdateProduct]}
129
+ requiresPermission={['UpdateCatalog', 'UpdateProduct']}
132
130
  onClick={handleRemove}
133
131
  label={<Trans>Remove from current channel</Trans>}
134
132
  confirmationText={
@@ -154,7 +152,7 @@ export const AssignFacetValuesToProductsBulkAction: BulkActionComponent<any> = (
154
152
  return (
155
153
  <>
156
154
  <DataTableBulkActionItem
157
- requiresPermission={[Permission.UpdateCatalog, Permission.UpdateProduct]}
155
+ requiresPermission={['UpdateCatalog', 'UpdateProduct']}
158
156
  onClick={() => setDialogOpen(true)}
159
157
  label={<Trans>Edit facet values</Trans>}
160
158
  icon={TagIcon}
@@ -174,105 +172,20 @@ export const AssignFacetValuesToProductsBulkAction: BulkActionComponent<any> = (
174
172
  };
175
173
 
176
174
  export const DuplicateProductsBulkAction: BulkActionComponent<any> = ({ selection, table }) => {
177
- const { refetchPaginatedList } = usePaginatedList();
178
- const { i18n } = useLingui();
179
- const [isDuplicating, setIsDuplicating] = useState(false);
180
- const [progress, setProgress] = useState({ completed: 0, total: 0 });
181
-
182
- const { mutateAsync } = useMutation({
183
- mutationFn: api.mutate(duplicateEntityDocument),
184
- });
185
-
186
- const handleDuplicate = async () => {
187
- if (isDuplicating) return;
188
-
189
- setIsDuplicating(true);
190
- setProgress({ completed: 0, total: selection.length });
191
-
192
- const results = {
193
- success: 0,
194
- failed: 0,
195
- errors: [] as string[],
196
- };
197
-
198
- try {
199
- // Process products sequentially to avoid overwhelming the server
200
- for (let i = 0; i < selection.length; i++) {
201
- const product = selection[i];
202
-
203
- try {
204
- const result = await mutateAsync({
205
- input: {
206
- entityName: 'Product',
207
- entityId: product.id,
208
- duplicatorInput: {
209
- code: 'product-duplicator',
210
- arguments: [
211
- {
212
- name: 'includeVariants',
213
- value: 'true',
214
- },
215
- ],
216
- },
217
- },
218
- });
219
-
220
- if ('newEntityId' in result.duplicateEntity) {
221
- results.success++;
222
- } else {
223
- results.failed++;
224
- const errorMsg =
225
- result.duplicateEntity.message ||
226
- result.duplicateEntity.duplicationError ||
227
- 'Unknown error';
228
- results.errors.push(`Product ${product.name || product.id}: ${errorMsg}`);
229
- }
230
- } catch (error) {
231
- results.failed++;
232
- results.errors.push(
233
- `Product ${product.name || product.id}: ${error instanceof Error ? error.message : 'Unknown error'}`,
234
- );
235
- }
236
-
237
- setProgress({ completed: i + 1, total: selection.length });
238
- }
239
-
240
- // Show results
241
- if (results.success > 0) {
242
- toast.success(i18n.t(`Successfully duplicated ${results.success} products`));
243
- }
244
- if (results.failed > 0) {
245
- const errorMessage =
246
- results.errors.length > 3
247
- ? `${results.errors.slice(0, 3).join(', ')}... and ${results.errors.length - 3} more`
248
- : results.errors.join(', ');
249
- toast.error(`Failed to duplicate ${results.failed} products: ${errorMessage}`);
250
- }
251
-
252
- if (results.success > 0) {
253
- refetchPaginatedList();
254
- table.resetRowSelection();
255
- }
256
- } finally {
257
- setIsDuplicating(false);
258
- setProgress({ completed: 0, total: 0 });
259
- }
260
- };
261
-
262
175
  return (
263
- <DataTableBulkActionItem
264
- requiresPermission={[Permission.UpdateCatalog, Permission.UpdateProduct]}
265
- onClick={handleDuplicate}
266
- label={
267
- isDuplicating ? (
268
- <Trans>
269
- Duplicating... ({progress.completed}/{progress.total})
270
- </Trans>
271
- ) : (
272
- <Trans>Duplicate</Trans>
273
- )
274
- }
275
- icon={CopyIcon}
176
+ <DuplicateBulkAction
177
+ entityType="Product"
178
+ duplicatorCode="product-duplicator"
179
+ duplicatorArguments={[
180
+ {
181
+ name: 'includeVariants',
182
+ value: 'true',
183
+ },
184
+ ]}
185
+ requiredPermissions={['UpdateCatalog', 'UpdateProduct']}
186
+ entityName="Product"
187
+ selection={selection}
188
+ table={table}
276
189
  />
277
190
  );
278
191
  };
@@ -187,20 +187,3 @@ export const getProductsWithFacetValuesByIdsDocument = graphql(`
187
187
  }
188
188
  }
189
189
  `);
190
-
191
- export const duplicateEntityDocument = graphql(`
192
- mutation DuplicateEntity($input: DuplicateEntityInput!) {
193
- duplicateEntity(input: $input) {
194
- ... on DuplicateEntitySuccess {
195
- newEntityId
196
- }
197
- ... on ErrorResult {
198
- errorCode
199
- message
200
- }
201
- ... on DuplicateEntityError {
202
- duplicationError
203
- }
204
- }
205
- }
206
- `);
@@ -41,7 +41,12 @@ export function CustomFieldsForm({ entityType, control, formPathPrefix }: Custom
41
41
  const customFields = useCustomFieldConfig(entityType);
42
42
 
43
43
  const getFieldName = (fieldDef: CustomFieldConfig) => {
44
- const name = fieldDef.type === 'relation' ? fieldDef.name + 'Id' : fieldDef.name;
44
+ const name =
45
+ fieldDef.type === 'relation'
46
+ ? fieldDef.list
47
+ ? fieldDef.name + 'Ids'
48
+ : fieldDef.name + 'Id'
49
+ : fieldDef.name;
45
50
  return formPathPrefix ? `${formPathPrefix}.customFields.${name}` : `customFields.${name}`;
46
51
  };
47
52
 
@@ -266,6 +271,18 @@ function FormInputForType({
266
271
  );
267
272
  case 'boolean':
268
273
  return <Switch checked={field.value} onCheckedChange={field.onChange} disabled={isReadonly} />;
274
+ case 'relation':
275
+ if (fieldDef.list) {
276
+ return (
277
+ <Input
278
+ {...field}
279
+ onChange={e => field.onChange(e.target.value.split(','))}
280
+ disabled={isReadonly}
281
+ />
282
+ );
283
+ } else {
284
+ return <Input {...field} disabled={isReadonly} />;
285
+ }
269
286
  default:
270
287
  return <Input {...field} disabled={isReadonly} />;
271
288
  }
@@ -20,7 +20,7 @@ export function DetailPageButton({
20
20
  }
21
21
  return (
22
22
  <Button asChild variant="ghost" disabled={disabled}>
23
- <Link to={href ?? `./${id}`} search={search ?? {}}>
23
+ <Link to={href ?? `./${id}`} search={search ?? {}} preload={false}>
24
24
  {label}
25
25
  {!disabled && <ChevronRight className="h-3 w-3 text-muted-foreground" />}
26
26
  </Link>
@@ -1,7 +1,8 @@
1
- import { onExtensionSourceChange } from '@/framework/extension-api/define-dashboard-extension.js';
2
1
  import { useEffect, useState } from 'react';
3
2
  import { runDashboardExtensions } from 'virtual:dashboard-extensions';
4
3
 
4
+ import { onExtensionSourceChange } from './define-dashboard-extension.js';
5
+
5
6
  /**
6
7
  * @description
7
8
  * This hook is used to load dashboard extensions via the `virtual:dashboard-extensions` module,
@@ -1,16 +1,13 @@
1
- import { getOperationVariablesFields } from '@/framework/document-introspection/get-document-structure.js';
2
- import {
3
- createFormSchemaFromFields,
4
- getDefaultValuesFromFields,
5
- } from '@/framework/form-engine/form-schema-tools.js';
6
- import { transformRelationFields } from '@/framework/form-engine/utils.js';
7
- import { useChannel } from '@/hooks/use-channel.js';
8
- import { useServerConfig } from '@/hooks/use-server-config.js';
9
1
  import type { TypedDocumentNode } from '@graphql-typed-document-node/core';
10
2
  import { zodResolver } from '@hookform/resolvers/zod';
11
3
  import { VariablesOf } from 'gql.tada';
12
4
  import { FormEvent } from 'react';
13
5
  import { useForm } from 'react-hook-form';
6
+ import { useChannel } from '../../hooks/use-channel.js';
7
+ import { useServerConfig } from '../../hooks/use-server-config.js';
8
+ import { getOperationVariablesFields } from '../document-introspection/get-document-structure.js';
9
+ import { createFormSchemaFromFields, getDefaultValuesFromFields } from './form-schema-tools.js';
10
+ import { transformRelationFields } from './utils.js';
14
11
 
15
12
  export interface GeneratedFormOptions<
16
13
  T extends TypedDocumentNode<any, any>,
@@ -1,24 +1,52 @@
1
1
  import { FieldInfo } from '../document-introspection/get-document-structure.js';
2
2
 
3
- export function transformRelationFields<E extends Record<string, any>>(fields: FieldInfo[], entity: E) {
4
- const processedEntity = { ...entity } as any;
3
+ /**
4
+ * Transforms relation fields in an entity, extracting IDs from relation objects.
5
+ * This is primarily used for custom fields of type "ID".
6
+ *
7
+ * @param fields - Array of field information
8
+ * @param entity - The entity to transform
9
+ * @returns A new entity with transformed relation fields
10
+ */
11
+ export function transformRelationFields<E extends Record<string, any>>(fields: FieldInfo[], entity: E): E {
12
+ // Create a shallow copy to avoid mutating the original entity
13
+ const processedEntity = { ...entity };
5
14
 
6
- for (const field of fields) {
7
- if (field.name !== 'customFields' || !field.typeInfo) {
8
- continue;
9
- }
15
+ // Skip processing if there are no custom fields
16
+ if (!entity.customFields || !processedEntity.customFields) {
17
+ return processedEntity;
18
+ }
10
19
 
11
- if (!entity.customFields || !processedEntity.customFields) {
12
- continue;
13
- }
20
+ // Find the customFields field info
21
+ const customFieldsInfo = fields.find(field => field.name === 'customFields' && field.typeInfo);
22
+ if (!customFieldsInfo?.typeInfo) {
23
+ return processedEntity;
24
+ }
25
+
26
+ // Process only ID type custom fields
27
+ const idTypeCustomFields = customFieldsInfo.typeInfo.filter(field => field.type === 'ID');
14
28
 
15
- for (const customField of field.typeInfo) {
16
- if (customField.type === 'ID') {
17
- const relationField = customField.name;
18
- const propertyAccessorKey = customField.name.replace(/Id$/, '');
19
- const relationValue = entity.customFields[propertyAccessorKey];
20
- const relationIdValue = relationValue?.id;
29
+ for (const customField of idTypeCustomFields) {
30
+ const relationField = customField.name;
31
+
32
+ if (customField.list) {
33
+ // For list fields, the accessor is the field name without the "Ids" suffix
34
+ const propertyAccessorKey = customField.name.replace(/Ids$/, '');
35
+ const relationValue = entity.customFields[propertyAccessorKey];
36
+
37
+ if (relationValue) {
38
+ const relationIdValue = relationValue.map((v: { id: string }) => v.id);
39
+ if (relationIdValue && relationIdValue.length > 0) {
40
+ processedEntity.customFields[relationField] = relationIdValue;
41
+ }
42
+ }
43
+ } else {
44
+ // For single fields, the accessor is the field name without the "Id" suffix
45
+ const propertyAccessorKey = customField.name.replace(/Id$/, '');
46
+ const relationValue = entity.customFields[propertyAccessorKey];
21
47
 
48
+ if (relationValue) {
49
+ const relationIdValue = relationValue.id;
22
50
  if (relationIdValue) {
23
51
  processedEntity.customFields[relationField] = relationIdValue;
24
52
  }
@@ -1,7 +1,3 @@
1
- import { NEW_ENTITY_PATH } from '@/constants.js';
2
- import { api, Variables } from '@/graphql/api.js';
3
- import { useCustomFieldConfig } from '@/hooks/use-custom-field-config.js';
4
- import { useExtendedDetailQuery } from '@/hooks/use-extended-detail-query.js';
5
1
  import { removeReadonlyCustomFields } from '@/lib/utils.js';
6
2
  import type { TypedDocumentNode } from '@graphql-typed-document-node/core';
7
3
  import {
@@ -16,6 +12,10 @@ import { DocumentNode } from 'graphql';
16
12
  import { FormEvent } from 'react';
17
13
  import { UseFormReturn } from 'react-hook-form';
18
14
 
15
+ import { NEW_ENTITY_PATH } from '../../constants.js';
16
+ import { api, Variables } from '../../graphql/api.js';
17
+ import { useCustomFieldConfig } from '../../hooks/use-custom-field-config.js';
18
+ import { useExtendedDetailQuery } from '../../hooks/use-extended-detail-query.js';
19
19
  import { addCustomFields } from '../document-introspection/add-custom-fields.js';
20
20
  import {
21
21
  getEntityName,
@@ -1,10 +1,9 @@
1
- import { ErrorPage } from '@/components/shared/error-page.js';
2
- import { useDashboardExtensions } from '@/framework/extension-api/use-dashboard-extensions.js';
3
- import { ListPage } from '@/framework/page/list-page.js';
4
- import { extensionRoutes } from '@/framework/page/page-api.js';
5
- import { AUTHENTICATED_ROUTE_PREFIX } from '@/constants.js';
6
1
  import { AnyRoute, createRoute, Router } from '@tanstack/react-router';
7
2
  import { useMemo } from 'react';
3
+ import { ErrorPage } from '../../components/shared/error-page.js';
4
+ import { AUTHENTICATED_ROUTE_PREFIX } from '../../constants.js';
5
+ import { useDashboardExtensions } from '../extension-api/use-dashboard-extensions.js';
6
+ import { extensionRoutes } from './page-api.js';
8
7
 
9
8
  /**
10
9
  * Extends the TanStack Router with additional routes for each dashboard
@@ -0,0 +1,18 @@
1
+ import { graphql } from './graphql.js';
2
+
3
+ export const duplicateEntityDocument = graphql(`
4
+ mutation DuplicateEntity($input: DuplicateEntityInput!) {
5
+ duplicateEntity(input: $input) {
6
+ ... on DuplicateEntitySuccess {
7
+ newEntityId
8
+ }
9
+ ... on ErrorResult {
10
+ errorCode
11
+ message
12
+ }
13
+ ... on DuplicateEntityError {
14
+ duplicationError
15
+ }
16
+ }
17
+ }
18
+ `);
@@ -1,4 +1,4 @@
1
- import { graphql, ResultOf } from "./graphql.js";
1
+ import { graphql, ResultOf } from './graphql.js';
2
2
 
3
3
  export const assetFragment = graphql(`
4
4
  fragment Asset on Asset {
@@ -58,5 +58,4 @@ export const errorResultFragment = graphql(`
58
58
  }
59
59
  `);
60
60
 
61
-
62
61
  export type ConfigurableOperationDefFragment = ResultOf<typeof configurableOperationDefFragment>;
@@ -100,7 +100,7 @@ export type introspection_types = {
100
100
  'CreateFulfillmentError': { kind: 'OBJECT'; name: 'CreateFulfillmentError'; fields: { 'errorCode': { name: 'errorCode'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'ENUM'; name: 'ErrorCode'; ofType: null; }; } }; 'fulfillmentHandlerError': { name: 'fulfillmentHandlerError'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'message': { name: 'message'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; };
101
101
  'CreateGroupOptionInput': { kind: 'INPUT_OBJECT'; name: 'CreateGroupOptionInput'; isOneOf: false; inputFields: [{ name: 'code'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; }; defaultValue: null }, { name: 'translations'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductOptionGroupTranslationInput'; ofType: null; }; }; }; }; defaultValue: null }]; };
102
102
  'CreatePaymentMethodInput': { kind: 'INPUT_OBJECT'; name: 'CreatePaymentMethodInput'; isOneOf: false; inputFields: [{ name: 'code'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; }; defaultValue: null }, { name: 'enabled'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; }; defaultValue: null }, { name: 'checker'; type: { kind: 'INPUT_OBJECT'; name: 'ConfigurableOperationInput'; ofType: null; }; defaultValue: null }, { name: 'handler'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ConfigurableOperationInput'; ofType: null; }; }; defaultValue: null }, { name: 'translations'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'PaymentMethodTranslationInput'; ofType: null; }; }; }; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'SCALAR'; name: 'JSON'; ofType: null; }; defaultValue: null }]; };
103
- 'CreateProductCustomFieldsInput': { kind: 'INPUT_OBJECT'; name: 'CreateProductCustomFieldsInput'; isOneOf: false; inputFields: [{ name: 'infoUrl'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'downloadable'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; defaultValue: null }, { name: 'lastUpdated'; type: { kind: 'SCALAR'; name: 'DateTime'; ofType: null; }; defaultValue: null }, { name: 'reviewRating'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; defaultValue: null }, { name: 'reviewCount'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; defaultValue: null }, { name: 'featuredReviewId'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }]; };
103
+ 'CreateProductCustomFieldsInput': { kind: 'INPUT_OBJECT'; name: 'CreateProductCustomFieldsInput'; isOneOf: false; inputFields: [{ name: 'infoUrl'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'downloadable'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; defaultValue: null }, { name: 'lastUpdated'; type: { kind: 'SCALAR'; name: 'DateTime'; ofType: null; }; defaultValue: null }, { name: 'reviewRating'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; defaultValue: null }, { name: 'reviewCount'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; defaultValue: null }, { name: 'featuredReviewId'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }, { name: 'promotedReviewsIds'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; }; defaultValue: null }]; };
104
104
  'CreateProductInput': { kind: 'INPUT_OBJECT'; name: 'CreateProductInput'; isOneOf: false; inputFields: [{ name: 'featuredAssetId'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }, { name: 'enabled'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; defaultValue: null }, { name: 'assetIds'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; }; defaultValue: null }, { name: 'facetValueIds'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; }; defaultValue: null }, { name: 'translations'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductTranslationInput'; ofType: null; }; }; }; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'INPUT_OBJECT'; name: 'CreateProductCustomFieldsInput'; ofType: null; }; defaultValue: null }]; };
105
105
  'CreateProductOptionGroupInput': { kind: 'INPUT_OBJECT'; name: 'CreateProductOptionGroupInput'; isOneOf: false; inputFields: [{ name: 'code'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; }; defaultValue: null }, { name: 'translations'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductOptionGroupTranslationInput'; ofType: null; }; }; }; }; defaultValue: null }, { name: 'options'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'CreateGroupOptionInput'; ofType: null; }; }; }; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'SCALAR'; name: 'JSON'; ofType: null; }; defaultValue: null }]; };
106
106
  'CreateProductOptionInput': { kind: 'INPUT_OBJECT'; name: 'CreateProductOptionInput'; isOneOf: false; inputFields: [{ name: 'productOptionGroupId'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; defaultValue: null }, { name: 'code'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; }; defaultValue: null }, { name: 'translations'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductOptionGroupTranslationInput'; ofType: null; }; }; }; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'SCALAR'; name: 'JSON'; ofType: null; }; defaultValue: null }]; };
@@ -280,7 +280,7 @@ export type introspection_types = {
280
280
  'PreviewCollectionVariantsInput': { kind: 'INPUT_OBJECT'; name: 'PreviewCollectionVariantsInput'; isOneOf: false; inputFields: [{ name: 'parentId'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }, { name: 'inheritFilters'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; }; defaultValue: null }, { name: 'filters'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ConfigurableOperationInput'; ofType: null; }; }; }; }; defaultValue: null }]; };
281
281
  'PriceRange': { kind: 'OBJECT'; name: 'PriceRange'; fields: { 'max': { name: 'max'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Money'; ofType: null; }; } }; 'min': { name: 'min'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Money'; ofType: null; }; } }; }; };
282
282
  'Product': { kind: 'OBJECT'; name: 'Product'; fields: { 'assets': { name: 'assets'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'Asset'; ofType: null; }; }; }; } }; 'channels': { name: 'channels'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'Channel'; ofType: null; }; }; }; } }; 'collections': { name: 'collections'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'Collection'; ofType: null; }; }; }; } }; 'createdAt': { name: 'createdAt'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'DateTime'; ofType: null; }; } }; 'customFields': { name: 'customFields'; type: { kind: 'OBJECT'; name: 'ProductCustomFields'; ofType: null; } }; 'description': { name: 'description'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'enabled': { name: 'enabled'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; } }; 'facetValues': { name: 'facetValues'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'FacetValue'; ofType: null; }; }; }; } }; 'featuredAsset': { name: 'featuredAsset'; type: { kind: 'OBJECT'; name: 'Asset'; ofType: null; } }; 'id': { name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; } }; 'languageCode': { name: 'languageCode'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'ENUM'; name: 'LanguageCode'; ofType: null; }; } }; 'name': { name: 'name'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'optionGroups': { name: 'optionGroups'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'ProductOptionGroup'; ofType: null; }; }; }; } }; 'reviews': { name: 'reviews'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'ProductReviewList'; ofType: null; }; } }; 'reviewsHistogram': { name: 'reviewsHistogram'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'ProductReviewHistogramItem'; ofType: null; }; }; }; } }; 'slug': { name: 'slug'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'translations': { name: 'translations'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'ProductTranslation'; ofType: null; }; }; }; } }; 'updatedAt': { name: 'updatedAt'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'DateTime'; ofType: null; }; } }; 'variantList': { name: 'variantList'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'ProductVariantList'; ofType: null; }; } }; 'variants': { name: 'variants'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'ProductVariant'; ofType: null; }; }; }; } }; }; };
283
- 'ProductCustomFields': { kind: 'OBJECT'; name: 'ProductCustomFields'; fields: { 'downloadable': { name: 'downloadable'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; 'featuredReview': { name: 'featuredReview'; type: { kind: 'OBJECT'; name: 'ProductReview'; ofType: null; } }; 'infoUrl': { name: 'infoUrl'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'lastUpdated': { name: 'lastUpdated'; type: { kind: 'SCALAR'; name: 'DateTime'; ofType: null; } }; 'reviewCount': { name: 'reviewCount'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; } }; 'reviewRating': { name: 'reviewRating'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; } }; 'shortName': { name: 'shortName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'translatableText': { name: 'translatableText'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; };
283
+ 'ProductCustomFields': { kind: 'OBJECT'; name: 'ProductCustomFields'; fields: { 'downloadable': { name: 'downloadable'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; 'featuredReview': { name: 'featuredReview'; type: { kind: 'OBJECT'; name: 'ProductReview'; ofType: null; } }; 'infoUrl': { name: 'infoUrl'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'lastUpdated': { name: 'lastUpdated'; type: { kind: 'SCALAR'; name: 'DateTime'; ofType: null; } }; 'promotedReviews': { name: 'promotedReviews'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'ProductReview'; ofType: null; }; }; } }; 'reviewCount': { name: 'reviewCount'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; } }; 'reviewRating': { name: 'reviewRating'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; } }; 'shortName': { name: 'shortName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'translatableText': { name: 'translatableText'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; };
284
284
  'ProductFilterParameter': { kind: 'INPUT_OBJECT'; name: 'ProductFilterParameter'; isOneOf: false; inputFields: [{ name: 'facetValueId'; type: { kind: 'INPUT_OBJECT'; name: 'IDOperators'; ofType: null; }; defaultValue: null }, { name: 'sku'; type: { kind: 'INPUT_OBJECT'; name: 'StringOperators'; ofType: null; }; defaultValue: null }, { name: 'id'; type: { kind: 'INPUT_OBJECT'; name: 'IDOperators'; ofType: null; }; defaultValue: null }, { name: 'createdAt'; type: { kind: 'INPUT_OBJECT'; name: 'DateOperators'; ofType: null; }; defaultValue: null }, { name: 'updatedAt'; type: { kind: 'INPUT_OBJECT'; name: 'DateOperators'; ofType: null; }; defaultValue: null }, { name: 'languageCode'; type: { kind: 'INPUT_OBJECT'; name: 'StringOperators'; ofType: null; }; defaultValue: null }, { name: 'name'; type: { kind: 'INPUT_OBJECT'; name: 'StringOperators'; ofType: null; }; defaultValue: null }, { name: 'slug'; type: { kind: 'INPUT_OBJECT'; name: 'StringOperators'; ofType: null; }; defaultValue: null }, { name: 'description'; type: { kind: 'INPUT_OBJECT'; name: 'StringOperators'; ofType: null; }; defaultValue: null }, { name: 'enabled'; type: { kind: 'INPUT_OBJECT'; name: 'BooleanOperators'; ofType: null; }; defaultValue: null }, { name: '_and'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductFilterParameter'; ofType: null; }; }; }; defaultValue: null }, { name: '_or'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductFilterParameter'; ofType: null; }; }; }; defaultValue: null }, { name: 'infoUrl'; type: { kind: 'INPUT_OBJECT'; name: 'StringOperators'; ofType: null; }; defaultValue: null }, { name: 'downloadable'; type: { kind: 'INPUT_OBJECT'; name: 'BooleanOperators'; ofType: null; }; defaultValue: null }, { name: 'shortName'; type: { kind: 'INPUT_OBJECT'; name: 'StringOperators'; ofType: null; }; defaultValue: null }, { name: 'lastUpdated'; type: { kind: 'INPUT_OBJECT'; name: 'DateOperators'; ofType: null; }; defaultValue: null }, { name: 'reviewRating'; type: { kind: 'INPUT_OBJECT'; name: 'NumberOperators'; ofType: null; }; defaultValue: null }, { name: 'reviewCount'; type: { kind: 'INPUT_OBJECT'; name: 'NumberOperators'; ofType: null; }; defaultValue: null }, { name: 'translatableText'; type: { kind: 'INPUT_OBJECT'; name: 'StringOperators'; ofType: null; }; defaultValue: null }]; };
285
285
  'ProductList': { kind: 'OBJECT'; name: 'ProductList'; fields: { 'items': { name: 'items'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'Product'; ofType: null; }; }; }; } }; 'totalItems': { name: 'totalItems'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Int'; ofType: null; }; } }; }; };
286
286
  'ProductListOptions': { kind: 'INPUT_OBJECT'; name: 'ProductListOptions'; isOneOf: false; inputFields: [{ name: 'skip'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; }; defaultValue: null }, { name: 'take'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; }; defaultValue: null }, { name: 'sort'; type: { kind: 'INPUT_OBJECT'; name: 'ProductSortParameter'; ofType: null; }; defaultValue: null }, { name: 'filter'; type: { kind: 'INPUT_OBJECT'; name: 'ProductFilterParameter'; ofType: null; }; defaultValue: null }, { name: 'filterOperator'; type: { kind: 'ENUM'; name: 'LogicalOperator'; ofType: null; }; defaultValue: null }]; };
@@ -465,7 +465,7 @@ export type introspection_types = {
465
465
  'UpdateOrderItemsResult': { kind: 'UNION'; name: 'UpdateOrderItemsResult'; fields: {}; possibleTypes: 'InsufficientStockError' | 'NegativeQuantityError' | 'Order' | 'OrderInterceptorError' | 'OrderLimitError' | 'OrderModificationError'; };
466
466
  'UpdateOrderNoteInput': { kind: 'INPUT_OBJECT'; name: 'UpdateOrderNoteInput'; isOneOf: false; inputFields: [{ name: 'noteId'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; defaultValue: null }, { name: 'note'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'isPublic'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; defaultValue: null }]; };
467
467
  'UpdatePaymentMethodInput': { kind: 'INPUT_OBJECT'; name: 'UpdatePaymentMethodInput'; isOneOf: false; inputFields: [{ name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; defaultValue: null }, { name: 'code'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'enabled'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; defaultValue: null }, { name: 'checker'; type: { kind: 'INPUT_OBJECT'; name: 'ConfigurableOperationInput'; ofType: null; }; defaultValue: null }, { name: 'handler'; type: { kind: 'INPUT_OBJECT'; name: 'ConfigurableOperationInput'; ofType: null; }; defaultValue: null }, { name: 'translations'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'PaymentMethodTranslationInput'; ofType: null; }; }; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'SCALAR'; name: 'JSON'; ofType: null; }; defaultValue: null }]; };
468
- 'UpdateProductCustomFieldsInput': { kind: 'INPUT_OBJECT'; name: 'UpdateProductCustomFieldsInput'; isOneOf: false; inputFields: [{ name: 'infoUrl'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'downloadable'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; defaultValue: null }, { name: 'lastUpdated'; type: { kind: 'SCALAR'; name: 'DateTime'; ofType: null; }; defaultValue: null }, { name: 'reviewRating'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; defaultValue: null }, { name: 'reviewCount'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; defaultValue: null }, { name: 'featuredReviewId'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }]; };
468
+ 'UpdateProductCustomFieldsInput': { kind: 'INPUT_OBJECT'; name: 'UpdateProductCustomFieldsInput'; isOneOf: false; inputFields: [{ name: 'infoUrl'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'downloadable'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; defaultValue: null }, { name: 'lastUpdated'; type: { kind: 'SCALAR'; name: 'DateTime'; ofType: null; }; defaultValue: null }, { name: 'reviewRating'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; defaultValue: null }, { name: 'reviewCount'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; defaultValue: null }, { name: 'featuredReviewId'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }, { name: 'promotedReviewsIds'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; }; defaultValue: null }]; };
469
469
  'UpdateProductInput': { kind: 'INPUT_OBJECT'; name: 'UpdateProductInput'; isOneOf: false; inputFields: [{ name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; defaultValue: null }, { name: 'enabled'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; defaultValue: null }, { name: 'featuredAssetId'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }, { name: 'assetIds'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; }; defaultValue: null }, { name: 'facetValueIds'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; }; defaultValue: null }, { name: 'translations'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductTranslationInput'; ofType: null; }; }; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'INPUT_OBJECT'; name: 'UpdateProductCustomFieldsInput'; ofType: null; }; defaultValue: null }]; };
470
470
  'UpdateProductOptionGroupInput': { kind: 'INPUT_OBJECT'; name: 'UpdateProductOptionGroupInput'; isOneOf: false; inputFields: [{ name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; defaultValue: null }, { name: 'code'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'translations'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductOptionGroupTranslationInput'; ofType: null; }; }; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'SCALAR'; name: 'JSON'; ofType: null; }; defaultValue: null }]; };
471
471
  'UpdateProductOptionInput': { kind: 'INPUT_OBJECT'; name: 'UpdateProductOptionInput'; isOneOf: false; inputFields: [{ name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; defaultValue: null }, { name: 'code'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'translations'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductOptionGroupTranslationInput'; ofType: null; }; }; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'SCALAR'; name: 'JSON'; ofType: null; }; defaultValue: null }]; };
@@ -1,6 +1,7 @@
1
- import { ChannelContext } from '@/providers/channel-provider.js';
2
1
  import * as React from 'react';
3
2
 
3
+ import { ChannelContext } from '../providers/channel-provider.js';
4
+
4
5
  // Hook to use the channel context
5
6
 
6
7
  /**
@@ -1,9 +1,10 @@
1
- import { extendDetailFormQuery } from '@/framework/document-extension/extend-detail-form-query.js';
2
1
  import { useLingui } from '@/lib/trans.js';
3
2
  import { DocumentNode } from 'graphql';
4
3
  import { useEffect, useMemo, useRef } from 'react';
5
4
  import { toast } from 'sonner';
6
5
 
6
+ import { extendDetailFormQuery } from '../framework/document-extension/extend-detail-form-query.js';
7
+
7
8
  /**
8
9
  * @description
9
10
  * Extends a detail page query document with any registered extensions provided by
@@ -1,10 +1,11 @@
1
- import { getListQueryDocuments } from '@/framework/data-table/data-table-extensions.js';
2
- import { extendDocument } from '@/framework/document-extension/extend-document.js';
3
1
  import { useLingui } from '@/lib/trans.js';
4
2
  import { DocumentNode } from 'graphql';
5
3
  import { useEffect, useMemo, useRef } from 'react';
6
4
  import { toast } from 'sonner';
7
5
 
6
+ import { getListQueryDocuments } from '../framework/data-table/data-table-extensions.js';
7
+ import { extendDocument } from '../framework/document-extension/extend-document.js';
8
+
8
9
  import { usePageBlock } from './use-page-block.js';
9
10
  import { usePage } from './use-page.js';
10
11
 
@@ -1,7 +1,9 @@
1
- import { useServerConfig } from '@/hooks/use-server-config.js';
2
- import { ServerConfig } from '@/providers/server-config.js';
3
1
  import { useMemo } from 'react';
4
2
 
3
+ import { ServerConfig } from '../providers/server-config.js';
4
+
5
+ import { useServerConfig } from './use-server-config.js';
6
+
5
7
  export function useGroupedPermissions() {
6
8
  const serverConfig = useServerConfig();
7
9
  const permissionDefinitions = serverConfig?.permissions ?? [];
@@ -1,5 +1,5 @@
1
- import { PageBlockContext } from '@/framework/layout-engine/page-block-provider.js';
2
1
  import { useContext } from 'react';
2
+ import { PageBlockContext } from '../framework/layout-engine/page-block-provider.js';
3
3
 
4
4
  export function usePageBlock() {
5
5
  const pageBlock = useContext(PageBlockContext);
@@ -1,5 +1,5 @@
1
- import { useContext } from "react";
2
- import { PageContext } from '@/framework/layout-engine/page-provider.js';
1
+ import { useContext } from 'react';
2
+ import { PageContext } from '../framework/layout-engine/page-provider.js';
3
3
 
4
4
  export function usePage() {
5
5
  const page = useContext(PageContext);
@@ -1,7 +1,8 @@
1
- import { useAuth } from '@/hooks/use-auth.js';
2
- import { useChannel } from '@/hooks/use-channel.js';
3
1
  import { Permission } from '@vendure/common/lib/generated-types';
4
2
 
3
+ import { useAuth } from './use-auth.js';
4
+ import { useChannel } from './use-channel.js';
5
+
5
6
  /**
6
7
  * @description
7
8
  * **Status: Developer Preview**
@@ -1,4 +1,5 @@
1
- import { ServerConfigContext } from '@/providers/server-config.js';
2
1
  import React from 'react';
3
2
 
3
+ import { ServerConfigContext } from '../providers/server-config.js';
4
+
4
5
  export const useServerConfig = () => React.useContext(ServerConfigContext);
@@ -1,6 +1,7 @@
1
- import { ThemeProviderContext } from '@/providers/theme-provider.js';
2
1
  import { useContext } from 'react';
3
2
 
3
+ import { ThemeProviderContext } from '../providers/theme-provider.js';
4
+
4
5
  export const useTheme = () => {
5
6
  const context = useContext(ThemeProviderContext);
6
7