@vendure/dashboard 3.4.3-master-202509260228 → 3.5.0-minor-202510012036
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/README.md +4 -0
- package/dist/plugin/api/api-extensions.js +11 -14
- package/dist/plugin/api/metrics.resolver.d.ts +2 -2
- package/dist/plugin/api/metrics.resolver.js +2 -2
- package/dist/plugin/config/metrics-strategies.d.ts +9 -9
- package/dist/plugin/config/metrics-strategies.js +6 -6
- package/dist/plugin/constants.d.ts +2 -0
- package/dist/plugin/constants.js +3 -1
- package/dist/plugin/dashboard.plugin.js +13 -0
- package/dist/plugin/service/metrics.service.d.ts +3 -3
- package/dist/plugin/service/metrics.service.js +37 -53
- package/dist/plugin/types.d.ts +9 -12
- package/dist/plugin/types.js +7 -11
- package/dist/vite/vite-plugin-config.js +13 -9
- package/dist/vite/vite-plugin-translations.d.ts +22 -0
- package/dist/vite/vite-plugin-translations.js +66 -0
- package/dist/vite/vite-plugin-vendure-dashboard.js +10 -8
- package/lingui.config.js +25 -2
- package/package.json +159 -156
- package/src/app/app-providers.tsx +0 -4
- package/src/app/common/delete-bulk-action.tsx +6 -5
- package/src/app/common/duplicate-bulk-action.tsx +4 -5
- package/src/app/common/duplicate-entity-dialog.tsx +1 -1
- package/src/app/common/set-document-direction.ts +7 -0
- package/src/app/main.tsx +50 -17
- package/src/app/routes/_authenticated/_administrators/administrators.tsx +8 -6
- package/src/app/routes/_authenticated/_administrators/administrators_.$id.tsx +17 -6
- package/src/app/routes/_authenticated/_administrators/components/role-permissions-display.tsx +2 -2
- package/src/app/routes/_authenticated/_assets/assets.tsx +1 -1
- package/src/app/routes/_authenticated/_assets/assets_.$id.tsx +4 -4
- package/src/app/routes/_authenticated/_assets/components/asset-bulk-actions.tsx +8 -6
- package/src/app/routes/_authenticated/_assets/components/asset-tag-filter.tsx +1 -1
- package/src/app/routes/_authenticated/_assets/components/asset-tags-editor.tsx +1 -1
- package/src/app/routes/_authenticated/_assets/components/manage-tags-dialog.tsx +3 -8
- package/src/app/routes/_authenticated/_channels/channels.tsx +3 -6
- package/src/app/routes/_authenticated/_channels/channels_.$id.tsx +5 -5
- package/src/app/routes/_authenticated/_collections/collections.tsx +10 -6
- package/src/app/routes/_authenticated/_collections/collections_.$id.tsx +16 -5
- package/src/app/routes/_authenticated/_collections/components/collection-bulk-actions.tsx +1 -1
- package/src/app/routes/_authenticated/_collections/components/collection-contents-sheet.tsx +1 -1
- package/src/app/routes/_authenticated/_collections/components/move-collections-dialog.tsx +6 -6
- package/src/app/routes/_authenticated/_countries/countries.graphql.ts +2 -0
- package/src/app/routes/_authenticated/_countries/countries.tsx +2 -3
- package/src/app/routes/_authenticated/_countries/countries_.$id.tsx +4 -4
- package/src/app/routes/_authenticated/_customer-groups/components/customer-group-members-sheet.tsx +1 -1
- package/src/app/routes/_authenticated/_customer-groups/components/customer-group-members-table.tsx +4 -4
- package/src/app/routes/_authenticated/_customer-groups/customer-groups.tsx +2 -4
- package/src/app/routes/_authenticated/_customer-groups/customer-groups_.$id.tsx +13 -6
- package/src/app/routes/_authenticated/_customers/components/customer-address-card.tsx +8 -8
- package/src/app/routes/_authenticated/_customers/components/customer-address-form.tsx +3 -3
- package/src/app/routes/_authenticated/_customers/components/customer-history/customer-history-container.tsx +1 -1
- package/src/app/routes/_authenticated/_customers/components/customer-history/customer-history-utils.tsx +1 -1
- package/src/app/routes/_authenticated/_customers/components/customer-history/default-customer-history-components.tsx +1 -1
- package/src/app/routes/_authenticated/_customers/components/customer-history/use-customer-history.ts +1 -1
- package/src/app/routes/_authenticated/_customers/components/customer-status-badge.tsx +1 -1
- package/src/app/routes/_authenticated/_customers/customers.graphql.ts +4 -0
- package/src/app/routes/_authenticated/_customers/customers.tsx +23 -11
- package/src/app/routes/_authenticated/_customers/customers_.$id.tsx +10 -8
- package/src/app/routes/_authenticated/_facets/components/edit-facet-value.tsx +1 -1
- package/src/app/routes/_authenticated/_facets/components/facet-bulk-actions.tsx +6 -5
- package/src/app/routes/_authenticated/_facets/components/facet-values-sheet.tsx +1 -1
- package/src/app/routes/_authenticated/_facets/components/facet-values-table.tsx +1 -1
- package/src/app/routes/_authenticated/_facets/facets.tsx +5 -5
- package/src/app/routes/_authenticated/_facets/facets_.$facetId.values_.$id.tsx +7 -5
- package/src/app/routes/_authenticated/_facets/facets_.$id.tsx +18 -6
- package/src/app/routes/_authenticated/_global-settings/global-settings.tsx +5 -5
- package/src/app/routes/_authenticated/_orders/components/add-manual-payment-dialog.tsx +19 -21
- package/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/edit-order-table.tsx +22 -22
- package/src/app/routes/_authenticated/_orders/components/fulfill-order-dialog.tsx +6 -6
- package/src/app/routes/_authenticated/_orders/components/fulfillment-details.tsx +15 -9
- package/src/app/routes/_authenticated/_orders/components/order-address.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/order-detail-shared.tsx +11 -9
- package/src/app/routes/_authenticated/_orders/components/order-history/default-order-history-components.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/order-history/order-history-container.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/order-history/order-history-utils.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/order-history/use-order-history.ts +1 -1
- package/src/app/routes/_authenticated/_orders/components/order-line-custom-fields-form.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/order-modification-preview-dialog.tsx +4 -4
- package/src/app/routes/_authenticated/_orders/components/order-modification-summary.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/order-table-totals.tsx +27 -27
- package/src/app/routes/_authenticated/_orders/components/order-table.tsx +2 -2
- package/src/app/routes/_authenticated/_orders/components/order-tax-summary.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/payment-details.tsx +26 -20
- package/src/app/routes/_authenticated/_orders/components/seller-orders-card.tsx +3 -1
- package/src/app/routes/_authenticated/_orders/components/settle-refund-dialog.tsx +6 -6
- package/src/app/routes/_authenticated/_orders/components/shipping-method-selector.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/state-transition-control.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/use-transition-order-to-state.tsx +3 -2
- package/src/app/routes/_authenticated/_orders/orders.tsx +5 -9
- package/src/app/routes/_authenticated/_orders/orders_.$aggregateOrderId_.seller-orders.$sellerOrderId.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/orders_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/orders_.$id_.modify.tsx +4 -4
- package/src/app/routes/_authenticated/_orders/orders_.draft.$id.tsx +17 -17
- package/src/app/routes/_authenticated/_orders/utils/order-detail-loaders.tsx +1 -1
- package/src/app/routes/_authenticated/_payment-methods/payment-methods.tsx +5 -6
- package/src/app/routes/_authenticated/_payment-methods/payment-methods_.$id.tsx +13 -6
- package/src/app/routes/_authenticated/_product-variants/components/product-variant-bulk-actions.tsx +1 -1
- package/src/app/routes/_authenticated/_product-variants/components/variant-price-detail.tsx +1 -1
- package/src/app/routes/_authenticated/_product-variants/product-variants.graphql.ts +10 -0
- package/src/app/routes/_authenticated/_product-variants/product-variants.tsx +9 -2
- package/src/app/routes/_authenticated/_product-variants/product-variants_.$id.tsx +13 -6
- package/src/app/routes/_authenticated/_products/components/add-option-group-dialog.tsx +5 -5
- package/src/app/routes/_authenticated/_products/components/add-product-variant-dialog.tsx +5 -5
- package/src/app/routes/_authenticated/_products/components/assign-facet-values-dialog.tsx +5 -4
- package/src/app/routes/_authenticated/_products/components/create-product-options-dialog.tsx +9 -12
- package/src/app/routes/_authenticated/_products/components/create-product-variants-dialog.tsx +1 -1
- package/src/app/routes/_authenticated/_products/components/create-product-variants.tsx +4 -4
- package/src/app/routes/_authenticated/_products/components/option-groups-editor.tsx +1 -1
- package/src/app/routes/_authenticated/_products/components/product-bulk-actions.tsx +1 -1
- package/src/app/routes/_authenticated/_products/components/product-option-group-badge.tsx +19 -0
- package/src/app/routes/_authenticated/_products/components/product-option-select.tsx +3 -3
- package/src/app/routes/_authenticated/_products/components/product-options-table.tsx +114 -0
- package/src/app/routes/_authenticated/_products/product-option-groups.graphql.ts +103 -0
- package/src/app/routes/_authenticated/_products/products.graphql.ts +44 -32
- package/src/app/routes/_authenticated/_products/products.tsx +34 -5
- package/src/app/routes/_authenticated/_products/products_.$id.tsx +29 -12
- package/src/app/routes/_authenticated/_products/products_.$id_.variants.tsx +11 -11
- package/src/app/routes/_authenticated/_products/products_.$productId.option-groups.$id.tsx +177 -0
- package/src/app/routes/_authenticated/_products/products_.$productId.option-groups.$productOptionGroupId.options_.$id.tsx +208 -0
- package/src/app/routes/_authenticated/_profile/profile.tsx +4 -4
- package/src/app/routes/_authenticated/_promotions/promotions.tsx +2 -4
- package/src/app/routes/_authenticated/_promotions/promotions_.$id.tsx +16 -9
- package/src/app/routes/_authenticated/_roles/components/permissions-table-grid.tsx +1 -1
- package/src/app/routes/_authenticated/_roles/roles.tsx +3 -6
- package/src/app/routes/_authenticated/_roles/roles_.$id.tsx +4 -6
- package/src/app/routes/_authenticated/_sellers/sellers.tsx +3 -4
- package/src/app/routes/_authenticated/_sellers/sellers_.$id.tsx +4 -4
- package/src/app/routes/_authenticated/_shipping-methods/components/price-display.tsx +5 -5
- package/src/app/routes/_authenticated/_shipping-methods/components/shipping-method-test-result-wrapper.tsx +1 -1
- package/src/app/routes/_authenticated/_shipping-methods/components/test-address-form.tsx +11 -11
- package/src/app/routes/_authenticated/_shipping-methods/components/test-order-builder.tsx +1 -1
- package/src/app/routes/_authenticated/_shipping-methods/components/test-shipping-methods-result.tsx +8 -8
- package/src/app/routes/_authenticated/_shipping-methods/components/test-shipping-methods-sheet.tsx +1 -1
- package/src/app/routes/_authenticated/_shipping-methods/components/test-single-method-result.tsx +8 -8
- package/src/app/routes/_authenticated/_shipping-methods/components/test-single-shipping-method-sheet.tsx +4 -4
- package/src/app/routes/_authenticated/_shipping-methods/shipping-methods.tsx +2 -3
- package/src/app/routes/_authenticated/_shipping-methods/shipping-methods_.$id.tsx +2 -2
- package/src/app/routes/_authenticated/_stock-locations/stock-locations.tsx +3 -4
- package/src/app/routes/_authenticated/_stock-locations/stock-locations_.$id.tsx +13 -6
- package/src/app/routes/_authenticated/_system/healthchecks.tsx +10 -4
- package/src/app/routes/_authenticated/_system/job-queue.tsx +10 -13
- package/src/app/routes/_authenticated/_system/scheduled-tasks.tsx +18 -16
- package/src/app/routes/_authenticated/_tax-categories/tax-categories.tsx +2 -4
- package/src/app/routes/_authenticated/_tax-categories/tax-categories_.$id.tsx +13 -6
- package/src/app/routes/_authenticated/_tax-rates/tax-rates.tsx +8 -12
- package/src/app/routes/_authenticated/_tax-rates/tax-rates_.$id.tsx +6 -4
- package/src/app/routes/_authenticated/_zones/components/zone-countries-sheet.tsx +4 -1
- package/src/app/routes/_authenticated/_zones/zones.tsx +4 -4
- package/src/app/routes/_authenticated/_zones/zones_.$id.tsx +8 -5
- package/src/app/routes/_authenticated/index.tsx +46 -25
- package/src/app/styles.css +4 -0
- package/src/i18n/common-strings.ts +111 -0
- package/src/i18n/locales/ar.po +4777 -0
- package/src/i18n/locales/cs.po +4777 -0
- package/src/i18n/locales/de.po +4299 -1101
- package/src/i18n/locales/en.po +3857 -659
- package/src/i18n/locales/es.po +4777 -0
- package/src/i18n/locales/fa.po +4777 -0
- package/src/i18n/locales/fr.po +4777 -0
- package/src/i18n/locales/he.po +4777 -0
- package/src/i18n/locales/hr.po +4777 -0
- package/src/i18n/locales/it.po +4777 -0
- package/src/i18n/locales/ja.po +4777 -0
- package/src/i18n/locales/ko.po +4628 -0
- package/src/i18n/locales/nb.po +4777 -0
- package/src/i18n/locales/ne.po +4777 -0
- package/src/i18n/locales/nl.po +4628 -0
- package/src/i18n/locales/pl.po +4777 -0
- package/src/i18n/locales/pt_BR.po +4777 -0
- package/src/i18n/locales/pt_PT.po +4777 -0
- package/src/i18n/locales/ru.po +4777 -0
- package/src/i18n/locales/sv.po +4777 -0
- package/src/i18n/locales/tr.po +4777 -0
- package/src/i18n/locales/uk.po +4777 -0
- package/src/i18n/locales/zh_Hans.po +4777 -0
- package/src/i18n/locales/zh_Hant.po +4777 -0
- package/src/lib/components/data-display/json.tsx +16 -1
- package/src/lib/components/data-input/combination-mode-input.tsx +1 -1
- package/src/lib/components/data-input/custom-field-list-input.tsx +11 -7
- package/src/lib/components/data-input/customer-group-input.tsx +27 -33
- package/src/lib/components/data-input/datetime-input.tsx +40 -1
- package/src/lib/components/data-input/default-relation-input.tsx +5 -4
- package/src/lib/components/data-input/index.ts +3 -0
- package/src/lib/components/data-input/product-multi-selector-input.tsx +14 -14
- package/src/lib/components/data-input/relation-selector.tsx +1 -1
- package/src/lib/components/data-input/select-with-options.tsx +1 -1
- package/src/lib/components/data-input/slug-input.tsx +290 -0
- package/src/lib/components/data-table/add-filter-menu.tsx +17 -10
- package/src/lib/components/data-table/data-table-bulk-action-item.tsx +45 -8
- package/src/lib/components/data-table/data-table-bulk-actions.tsx +4 -4
- package/src/lib/components/data-table/data-table-column-header.tsx +13 -8
- package/src/lib/components/data-table/data-table-context.tsx +91 -0
- package/src/lib/components/data-table/data-table-faceted-filter.tsx +2 -1
- package/src/lib/components/data-table/data-table-filter-badge.tsx +9 -5
- package/src/lib/components/data-table/data-table-filter-dialog.tsx +1 -1
- package/src/lib/components/data-table/data-table-utils.ts +21 -4
- package/src/lib/components/data-table/data-table-view-options.tsx +21 -10
- package/src/lib/components/data-table/data-table.tsx +146 -94
- package/src/lib/components/data-table/filters/data-table-boolean-filter.tsx +4 -4
- package/src/lib/components/data-table/global-views-bar.tsx +97 -0
- package/src/lib/components/data-table/global-views-sheet.tsx +11 -0
- package/src/lib/components/data-table/human-readable-operator.tsx +1 -1
- package/src/lib/components/data-table/manage-global-views-button.tsx +26 -0
- package/src/lib/components/data-table/my-views-button.tsx +47 -0
- package/src/lib/components/data-table/refresh-button.tsx +12 -3
- package/src/lib/components/data-table/save-view-button.tsx +41 -0
- package/src/lib/components/data-table/save-view-dialog.tsx +113 -0
- package/src/lib/components/data-table/use-generated-columns.tsx +13 -8
- package/src/lib/components/data-table/user-views-sheet.tsx +11 -0
- package/src/lib/components/data-table/views-sheet.tsx +305 -0
- package/src/lib/components/date-range-picker.tsx +186 -0
- package/src/lib/components/layout/app-sidebar.tsx +3 -1
- package/src/lib/components/layout/channel-switcher.tsx +8 -10
- package/src/lib/components/layout/dev-mode-indicator.tsx +1 -1
- package/src/lib/components/layout/generated-breadcrumbs.tsx +10 -8
- package/src/lib/components/layout/language-dialog.tsx +34 -13
- package/src/lib/components/layout/manage-languages-dialog.tsx +1 -1
- package/src/lib/components/layout/nav-main.tsx +23 -13
- package/src/lib/components/layout/nav-user.tsx +19 -23
- package/src/lib/components/login/login-form.tsx +1 -1
- package/src/lib/components/shared/asset/asset-bulk-actions.tsx +4 -4
- package/src/lib/components/shared/asset/asset-focal-point-editor.tsx +1 -1
- package/src/lib/components/shared/asset/asset-gallery.tsx +15 -14
- package/src/lib/components/shared/assign-to-channel-bulk-action.tsx +11 -11
- package/src/lib/components/shared/assign-to-channel-dialog.tsx +6 -5
- package/src/lib/components/shared/channel-code-label.tsx +1 -1
- package/src/lib/components/shared/channel-selector.tsx +4 -4
- package/src/lib/components/shared/configurable-operation-multi-selector.tsx +16 -14
- package/src/lib/components/shared/configurable-operation-selector.tsx +1 -1
- package/src/lib/components/shared/confirmation-dialog.tsx +8 -8
- package/src/lib/components/shared/country-selector.tsx +1 -1
- package/src/lib/components/shared/currency-selector.tsx +4 -4
- package/src/lib/components/shared/custom-fields-form.tsx +8 -24
- package/src/lib/components/shared/customer-address-form.tsx +3 -3
- package/src/lib/components/shared/customer-group-selector.tsx +1 -1
- package/src/lib/components/shared/customer-selector.tsx +1 -1
- package/src/lib/components/shared/error-page.tsx +1 -1
- package/src/lib/components/shared/facet-value-selector.tsx +10 -10
- package/src/lib/components/shared/history-timeline/history-note-checkbox.tsx +1 -1
- package/src/lib/components/shared/history-timeline/history-note-editor.tsx +1 -1
- package/src/lib/components/shared/history-timeline/history-note-entry.tsx +1 -1
- package/src/lib/components/shared/language-selector.tsx +4 -4
- package/src/lib/components/shared/navigation-confirmation.tsx +1 -1
- package/src/lib/components/shared/paginated-list-data-table.tsx +64 -34
- package/src/lib/components/shared/remove-from-channel-bulk-action.tsx +6 -5
- package/src/lib/components/shared/rich-text-editor/image-dialog.tsx +1 -1
- package/src/lib/components/shared/rich-text-editor/link-dialog.tsx +1 -1
- package/src/lib/components/shared/rich-text-editor/responsive-toolbar.tsx +1 -1
- package/src/lib/components/shared/rich-text-editor/table-edit-icons.tsx +1 -1
- package/src/lib/components/shared/role-code-label.tsx +1 -1
- package/src/lib/components/shared/role-selector.tsx +4 -4
- package/src/lib/components/shared/seller-selector.tsx +1 -1
- package/src/lib/components/shared/stock-level-label.tsx +3 -5
- package/src/lib/components/shared/table-cell/order-table-cell-components.tsx +3 -1
- package/src/lib/components/shared/tax-category-selector.tsx +1 -1
- package/src/lib/components/shared/translatable-form-field.tsx +15 -15
- package/src/lib/components/shared/zone-selector.tsx +1 -1
- package/src/lib/components/ui/button.tsx +1 -1
- package/src/lib/framework/dashboard-widget/base-widget.tsx +11 -9
- package/src/lib/framework/dashboard-widget/latest-orders-widget/index.tsx +35 -6
- package/src/lib/framework/dashboard-widget/metrics-widget/index.tsx +18 -12
- package/src/lib/framework/dashboard-widget/metrics-widget/metrics-widget.graphql.ts +9 -3
- package/src/lib/framework/dashboard-widget/orders-summary/index.tsx +26 -79
- package/src/lib/framework/dashboard-widget/widget-filters-context.tsx +35 -0
- package/src/lib/framework/defaults.ts +34 -63
- package/src/lib/framework/document-introspection/add-custom-fields.spec.ts +319 -9
- package/src/lib/framework/document-introspection/add-custom-fields.ts +60 -31
- package/src/lib/framework/document-introspection/get-document-structure.spec.ts +1 -159
- package/src/lib/framework/document-introspection/include-only-selected-list-fields.spec.ts +1840 -0
- package/src/lib/framework/document-introspection/include-only-selected-list-fields.ts +940 -0
- package/src/lib/framework/document-introspection/testing-utils.ts +161 -0
- package/src/lib/framework/extension-api/display-component-extensions.tsx +2 -0
- package/src/lib/framework/extension-api/types/data-table.ts +62 -4
- package/src/lib/framework/extension-api/types/navigation.ts +16 -0
- package/src/lib/framework/form-engine/utils.ts +34 -0
- package/src/lib/framework/layout-engine/page-layout.tsx +36 -36
- package/src/lib/framework/page/detail-page.tsx +10 -10
- package/src/lib/framework/page/list-page.tsx +289 -4
- package/src/lib/framework/page/use-extended-router.tsx +101 -34
- package/src/lib/graphql/api.ts +6 -2
- package/src/lib/graphql/graphql-env.d.ts +38 -26
- package/src/lib/hooks/use-display-locale.ts +40 -0
- package/src/lib/hooks/use-dynamic-translations.ts +46 -0
- package/src/lib/hooks/use-extended-detail-query.ts +1 -1
- package/src/lib/hooks/use-extended-list-query.ts +6 -1
- package/src/lib/hooks/use-local-format.ts +15 -1
- package/src/lib/hooks/use-saved-views.ts +230 -0
- package/src/lib/hooks/use-ui-language-loader.ts +30 -0
- package/src/lib/index.ts +15 -0
- package/src/lib/lib/load-i18n-messages.ts +17 -0
- package/src/lib/lib/trans.tsx +15 -11
- package/src/lib/providers/i18n-provider.tsx +7 -14
- package/src/lib/types/saved-views.ts +39 -0
- package/src/lib/utils/saved-views-utils.ts +40 -0
|
@@ -19,7 +19,7 @@ export function registerDefaults() {
|
|
|
19
19
|
sections: [
|
|
20
20
|
{
|
|
21
21
|
id: 'insights',
|
|
22
|
-
title: 'Insights',
|
|
22
|
+
title: /* i18n*/ 'Insights',
|
|
23
23
|
placement: 'top',
|
|
24
24
|
icon: LayoutDashboardIcon,
|
|
25
25
|
url: '/',
|
|
@@ -27,42 +27,42 @@ export function registerDefaults() {
|
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
29
|
id: 'catalog',
|
|
30
|
-
title: 'Catalog',
|
|
30
|
+
title: /* i18n*/ 'Catalog',
|
|
31
31
|
icon: SquareTerminal,
|
|
32
32
|
placement: 'top',
|
|
33
33
|
order: 200,
|
|
34
34
|
items: [
|
|
35
35
|
{
|
|
36
36
|
id: 'products',
|
|
37
|
-
title: 'Products',
|
|
37
|
+
title: /* i18n*/ 'Products',
|
|
38
38
|
url: '/products',
|
|
39
39
|
order: 100,
|
|
40
40
|
requiresPermission: ['ReadProduct', 'ReadCatalog'],
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
id: 'product-variants',
|
|
44
|
-
title: 'Product Variants',
|
|
44
|
+
title: /* i18n*/ 'Product Variants',
|
|
45
45
|
url: '/product-variants',
|
|
46
46
|
order: 200,
|
|
47
47
|
requiresPermission: ['ReadProduct', 'ReadCatalog'],
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
50
|
id: 'facets',
|
|
51
|
-
title: 'Facets',
|
|
51
|
+
title: /* i18n*/ 'Facets',
|
|
52
52
|
url: '/facets',
|
|
53
53
|
order: 300,
|
|
54
54
|
requiresPermission: ['ReadProduct', 'ReadCatalog'],
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
id: 'collections',
|
|
58
|
-
title: 'Collections',
|
|
58
|
+
title: /* i18n*/ 'Collections',
|
|
59
59
|
url: '/collections',
|
|
60
60
|
order: 400,
|
|
61
61
|
requiresPermission: ['ReadCollection', 'ReadCatalog'],
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
id: 'assets',
|
|
65
|
-
title: 'Assets',
|
|
65
|
+
title: /* i18n*/ 'Assets',
|
|
66
66
|
url: '/assets',
|
|
67
67
|
order: 500,
|
|
68
68
|
requiresPermission: ['ReadAsset', 'ReadCatalog'],
|
|
@@ -71,14 +71,14 @@ export function registerDefaults() {
|
|
|
71
71
|
},
|
|
72
72
|
{
|
|
73
73
|
id: 'sales',
|
|
74
|
-
title: 'Sales',
|
|
74
|
+
title: /* i18n*/ 'Sales',
|
|
75
75
|
icon: ShoppingCart,
|
|
76
76
|
placement: 'top',
|
|
77
77
|
order: 300,
|
|
78
78
|
items: [
|
|
79
79
|
{
|
|
80
80
|
id: 'orders',
|
|
81
|
-
title: 'Orders',
|
|
81
|
+
title: /* i18n*/ 'Orders',
|
|
82
82
|
url: '/orders',
|
|
83
83
|
order: 100,
|
|
84
84
|
requiresPermission: ['ReadOrder'],
|
|
@@ -87,21 +87,21 @@ export function registerDefaults() {
|
|
|
87
87
|
},
|
|
88
88
|
{
|
|
89
89
|
id: 'customers',
|
|
90
|
-
title: 'Customers',
|
|
90
|
+
title: /* i18n*/ 'Customers',
|
|
91
91
|
icon: Users,
|
|
92
92
|
placement: 'top',
|
|
93
93
|
order: 400,
|
|
94
94
|
items: [
|
|
95
95
|
{
|
|
96
96
|
id: 'customers',
|
|
97
|
-
title: 'Customers',
|
|
97
|
+
title: /* i18n*/ 'Customers',
|
|
98
98
|
url: '/customers',
|
|
99
99
|
order: 100,
|
|
100
100
|
requiresPermission: ['ReadCustomer'],
|
|
101
101
|
},
|
|
102
102
|
{
|
|
103
103
|
id: 'customer-groups',
|
|
104
|
-
title: 'Customer Groups',
|
|
104
|
+
title: /* i18n*/ 'Customer Groups',
|
|
105
105
|
url: '/customer-groups',
|
|
106
106
|
order: 200,
|
|
107
107
|
requiresPermission: ['ReadCustomerGroup'],
|
|
@@ -110,14 +110,14 @@ export function registerDefaults() {
|
|
|
110
110
|
},
|
|
111
111
|
{
|
|
112
112
|
id: 'marketing',
|
|
113
|
-
title: 'Marketing',
|
|
113
|
+
title: /* i18n*/ 'Marketing',
|
|
114
114
|
icon: Mail,
|
|
115
115
|
placement: 'top',
|
|
116
116
|
order: 500,
|
|
117
117
|
items: [
|
|
118
118
|
{
|
|
119
119
|
id: 'promotions',
|
|
120
|
-
title: 'Promotions',
|
|
120
|
+
title: /* i18n*/ 'Promotions',
|
|
121
121
|
url: '/promotions',
|
|
122
122
|
order: 100,
|
|
123
123
|
requiresPermission: ['ReadPromotion'],
|
|
@@ -126,28 +126,28 @@ export function registerDefaults() {
|
|
|
126
126
|
},
|
|
127
127
|
{
|
|
128
128
|
id: 'system',
|
|
129
|
-
title: 'System',
|
|
129
|
+
title: /* i18n*/ 'System',
|
|
130
130
|
icon: Terminal,
|
|
131
131
|
placement: 'bottom',
|
|
132
132
|
order: 200,
|
|
133
133
|
items: [
|
|
134
134
|
{
|
|
135
135
|
id: 'job-queue',
|
|
136
|
-
title: 'Job Queue',
|
|
136
|
+
title: /* i18n*/ 'Job Queue',
|
|
137
137
|
url: '/job-queue',
|
|
138
138
|
order: 100,
|
|
139
139
|
requiresPermission: ['ReadSystem'],
|
|
140
140
|
},
|
|
141
141
|
{
|
|
142
142
|
id: 'healthchecks',
|
|
143
|
-
title: 'Healthchecks',
|
|
143
|
+
title: /* i18n*/ 'Healthchecks',
|
|
144
144
|
url: '/healthchecks',
|
|
145
145
|
order: 200,
|
|
146
146
|
requiresPermission: ['ReadSystem'],
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
149
|
id: 'scheduled-tasks',
|
|
150
|
-
title: 'Scheduled Tasks',
|
|
150
|
+
title: /* i18n*/ 'Scheduled Tasks',
|
|
151
151
|
url: '/scheduled-tasks',
|
|
152
152
|
order: 300,
|
|
153
153
|
requiresPermission: ['ReadSystem'],
|
|
@@ -156,91 +156,91 @@ export function registerDefaults() {
|
|
|
156
156
|
},
|
|
157
157
|
{
|
|
158
158
|
id: 'settings',
|
|
159
|
-
title: 'Settings',
|
|
159
|
+
title: /* i18n*/ 'Settings',
|
|
160
160
|
icon: Settings2,
|
|
161
161
|
placement: 'bottom',
|
|
162
162
|
order: 100,
|
|
163
163
|
items: [
|
|
164
164
|
{
|
|
165
165
|
id: 'sellers',
|
|
166
|
-
title: 'Sellers',
|
|
166
|
+
title: /* i18n*/ 'Sellers',
|
|
167
167
|
url: '/sellers',
|
|
168
168
|
order: 100,
|
|
169
169
|
requiresPermission: ['ReadSeller'],
|
|
170
170
|
},
|
|
171
171
|
{
|
|
172
172
|
id: 'channels',
|
|
173
|
-
title: 'Channels',
|
|
173
|
+
title: /* i18n*/ 'Channels',
|
|
174
174
|
url: '/channels',
|
|
175
175
|
order: 200,
|
|
176
176
|
requiresPermission: ['ReadChannel'],
|
|
177
177
|
},
|
|
178
178
|
{
|
|
179
179
|
id: 'stock-locations',
|
|
180
|
-
title: 'Stock Locations',
|
|
180
|
+
title: /* i18n*/ 'Stock Locations',
|
|
181
181
|
url: '/stock-locations',
|
|
182
182
|
order: 300,
|
|
183
183
|
requiresPermission: ['ReadStockLocation'],
|
|
184
184
|
},
|
|
185
185
|
{
|
|
186
186
|
id: 'administrators',
|
|
187
|
-
title: 'Administrators',
|
|
187
|
+
title: /* i18n*/ 'Administrators',
|
|
188
188
|
url: '/administrators',
|
|
189
189
|
order: 400,
|
|
190
190
|
requiresPermission: ['ReadAdministrator'],
|
|
191
191
|
},
|
|
192
192
|
{
|
|
193
193
|
id: 'roles',
|
|
194
|
-
title: 'Roles',
|
|
194
|
+
title: /* i18n*/ 'Roles',
|
|
195
195
|
url: '/roles',
|
|
196
196
|
order: 500,
|
|
197
197
|
requiresPermission: ['ReadAdministrator'],
|
|
198
198
|
},
|
|
199
199
|
{
|
|
200
200
|
id: 'shipping-methods',
|
|
201
|
-
title: 'Shipping Methods',
|
|
201
|
+
title: /* i18n*/ 'Shipping Methods',
|
|
202
202
|
url: '/shipping-methods',
|
|
203
203
|
order: 600,
|
|
204
204
|
requiresPermission: ['ReadShippingMethod'],
|
|
205
205
|
},
|
|
206
206
|
{
|
|
207
207
|
id: 'payment-methods',
|
|
208
|
-
title: 'Payment Methods',
|
|
208
|
+
title: /* i18n*/ 'Payment Methods',
|
|
209
209
|
url: '/payment-methods',
|
|
210
210
|
order: 700,
|
|
211
211
|
requiresPermission: ['ReadPaymentMethod'],
|
|
212
212
|
},
|
|
213
213
|
{
|
|
214
214
|
id: 'tax-categories',
|
|
215
|
-
title: 'Tax Categories',
|
|
215
|
+
title: /* i18n*/ 'Tax Categories',
|
|
216
216
|
url: '/tax-categories',
|
|
217
217
|
order: 800,
|
|
218
218
|
requiresPermission: ['ReadTaxCategory'],
|
|
219
219
|
},
|
|
220
220
|
{
|
|
221
221
|
id: 'tax-rates',
|
|
222
|
-
title: 'Tax Rates',
|
|
222
|
+
title: /* i18n*/ 'Tax Rates',
|
|
223
223
|
url: '/tax-rates',
|
|
224
224
|
order: 900,
|
|
225
225
|
requiresPermission: ['ReadTaxRate'],
|
|
226
226
|
},
|
|
227
227
|
{
|
|
228
228
|
id: 'countries',
|
|
229
|
-
title: 'Countries',
|
|
229
|
+
title: /* i18n*/ 'Countries',
|
|
230
230
|
url: '/countries',
|
|
231
231
|
order: 1000,
|
|
232
232
|
requiresPermission: ['ReadCountry'],
|
|
233
233
|
},
|
|
234
234
|
{
|
|
235
235
|
id: 'zones',
|
|
236
|
-
title: 'Zones',
|
|
236
|
+
title: /* i18n*/ 'Zones',
|
|
237
237
|
url: '/zones',
|
|
238
238
|
order: 1100,
|
|
239
239
|
requiresPermission: ['ReadZone'],
|
|
240
240
|
},
|
|
241
241
|
{
|
|
242
242
|
id: 'global-settings',
|
|
243
|
-
title: 'Global Settings',
|
|
243
|
+
title: /* i18n*/ 'Global Settings',
|
|
244
244
|
url: '/global-settings',
|
|
245
245
|
order: 1200,
|
|
246
246
|
requiresPermission: ['UpdateGlobalSettings'],
|
|
@@ -252,7 +252,7 @@ export function registerDefaults() {
|
|
|
252
252
|
|
|
253
253
|
registerDashboardWidget({
|
|
254
254
|
id: 'metrics-widget',
|
|
255
|
-
name: 'Metrics Widget',
|
|
255
|
+
name: /* i18n*/ 'Metrics Widget',
|
|
256
256
|
component: MetricsWidget,
|
|
257
257
|
defaultSize: { w: 12, h: 6, x: 0, y: 0 },
|
|
258
258
|
minSize: { w: 6, h: 4 },
|
|
@@ -260,44 +260,15 @@ export function registerDefaults() {
|
|
|
260
260
|
|
|
261
261
|
registerDashboardWidget({
|
|
262
262
|
id: 'latest-orders-widget',
|
|
263
|
-
name: 'Latest Orders Widget',
|
|
263
|
+
name: /* i18n*/ 'Latest Orders Widget',
|
|
264
264
|
component: LatestOrdersWidget,
|
|
265
265
|
defaultSize: { w: 6, h: 7, x: 0, y: 0 },
|
|
266
266
|
});
|
|
267
267
|
|
|
268
268
|
registerDashboardWidget({
|
|
269
269
|
id: 'orders-summary-widget',
|
|
270
|
-
name: 'Orders Summary Widget',
|
|
270
|
+
name: /* i18n*/ 'Orders Summary Widget',
|
|
271
271
|
component: OrdersSummaryWidget,
|
|
272
272
|
defaultSize: { w: 6, h: 3, x: 6, y: 0 },
|
|
273
273
|
});
|
|
274
|
-
|
|
275
|
-
// registerAlert<boolean>({
|
|
276
|
-
// id: 'test-alert',
|
|
277
|
-
// title: data => `Test Alert ${String(data)}`,
|
|
278
|
-
// description: 'This is a test alert',
|
|
279
|
-
// severity: 'info',
|
|
280
|
-
// check: () => Promise.resolve(true),
|
|
281
|
-
// actions: [
|
|
282
|
-
// {
|
|
283
|
-
// label: 'Test Action',
|
|
284
|
-
// onClick: () => console.log('Test Action'),
|
|
285
|
-
// },
|
|
286
|
-
// ],
|
|
287
|
-
// });
|
|
288
|
-
|
|
289
|
-
// registerAlert<boolean>({
|
|
290
|
-
// id: 'test-alert-2',
|
|
291
|
-
// title: 'Test Alert 2',
|
|
292
|
-
// description: 'This is a test alert 2',
|
|
293
|
-
// severity: 'info',
|
|
294
|
-
// check: () => Promise.resolve(true),
|
|
295
|
-
// shouldShow: data => data === true,
|
|
296
|
-
// actions: [
|
|
297
|
-
// {
|
|
298
|
-
// label: 'Test Action',
|
|
299
|
-
// onClick: () => console.log('Test Action'),
|
|
300
|
-
// },
|
|
301
|
-
// ],
|
|
302
|
-
// });
|
|
303
274
|
}
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
import { CustomFieldConfig, CustomFields } from '@vendure/common/lib/generated-types';
|
|
2
2
|
import { graphql } from 'gql.tada';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
FieldNode,
|
|
6
|
-
FragmentDefinitionNode,
|
|
7
|
-
Kind,
|
|
8
|
-
OperationDefinitionNode,
|
|
9
|
-
print,
|
|
10
|
-
} from 'graphql';
|
|
11
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
3
|
+
import { DocumentNode, FieldNode, FragmentDefinitionNode, Kind, print } from 'graphql';
|
|
4
|
+
import { beforeEach, describe, expect, it } from 'vitest';
|
|
12
5
|
|
|
13
6
|
import { addCustomFields } from './add-custom-fields.js';
|
|
14
7
|
|
|
@@ -239,4 +232,321 @@ describe('addCustomFields()', () => {
|
|
|
239
232
|
addsCustomFieldsToType('Address', addressFragment);
|
|
240
233
|
});
|
|
241
234
|
});
|
|
235
|
+
|
|
236
|
+
describe('Nested entity handling', () => {
|
|
237
|
+
it('User example: Should not add custom fields to Asset fragment used in nested featuredAsset', () => {
|
|
238
|
+
const assetFragment = graphql(`
|
|
239
|
+
fragment Asset on Asset {
|
|
240
|
+
id
|
|
241
|
+
createdAt
|
|
242
|
+
updatedAt
|
|
243
|
+
name
|
|
244
|
+
fileSize
|
|
245
|
+
mimeType
|
|
246
|
+
type
|
|
247
|
+
preview
|
|
248
|
+
source
|
|
249
|
+
width
|
|
250
|
+
height
|
|
251
|
+
focalPoint {
|
|
252
|
+
x
|
|
253
|
+
y
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
`);
|
|
257
|
+
|
|
258
|
+
const documentNode = graphql(
|
|
259
|
+
`
|
|
260
|
+
query CollectionList($options: CollectionListOptions) {
|
|
261
|
+
collections(options: $options) {
|
|
262
|
+
items {
|
|
263
|
+
id
|
|
264
|
+
createdAt
|
|
265
|
+
updatedAt
|
|
266
|
+
featuredAsset {
|
|
267
|
+
...Asset
|
|
268
|
+
}
|
|
269
|
+
name
|
|
270
|
+
slug
|
|
271
|
+
breadcrumbs {
|
|
272
|
+
id
|
|
273
|
+
name
|
|
274
|
+
slug
|
|
275
|
+
}
|
|
276
|
+
children {
|
|
277
|
+
id
|
|
278
|
+
name
|
|
279
|
+
}
|
|
280
|
+
position
|
|
281
|
+
isPrivate
|
|
282
|
+
parentId
|
|
283
|
+
productVariants {
|
|
284
|
+
totalItems
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
totalItems
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
`,
|
|
291
|
+
[assetFragment],
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
const customFieldsConfig = new Map<string, CustomFieldConfig[]>();
|
|
295
|
+
customFieldsConfig.set('Collection', [
|
|
296
|
+
{ name: 'featuredProducts', type: 'relation', list: true, scalarFields: ['id', 'name'] },
|
|
297
|
+
{ name: 'alternativeAsset', type: 'relation', list: false, scalarFields: ['id', 'name'] },
|
|
298
|
+
]);
|
|
299
|
+
customFieldsConfig.set('Asset', [
|
|
300
|
+
{ name: 'assetCustomField1', type: 'string', list: false },
|
|
301
|
+
{ name: 'assetCustomField2', type: 'string', list: false },
|
|
302
|
+
{ name: 'assetCustomField3', type: 'string', list: false },
|
|
303
|
+
]);
|
|
304
|
+
|
|
305
|
+
const result = addCustomFields(documentNode, { customFieldsMap: customFieldsConfig });
|
|
306
|
+
const printed = print(result);
|
|
307
|
+
|
|
308
|
+
// Should add customFields ONLY to Collection items (top-level entity)
|
|
309
|
+
expect(printed).toContain('customFields {');
|
|
310
|
+
expect(printed).toContain('featuredProducts {');
|
|
311
|
+
expect(printed).toContain('alternativeAsset {');
|
|
312
|
+
|
|
313
|
+
// Should NOT add customFields to Asset fragment (only used in nested context)
|
|
314
|
+
const fragmentMatch = printed.match(/fragment Asset on Asset\s*\{[^}]*\}/s);
|
|
315
|
+
expect(fragmentMatch).toBeTruthy();
|
|
316
|
+
expect(fragmentMatch![0]).not.toContain('customFields');
|
|
317
|
+
expect(fragmentMatch![0]).not.toContain('assetCustomField1');
|
|
318
|
+
|
|
319
|
+
// Should NOT add customFields to children (nested Collection entities)
|
|
320
|
+
const childrenMatch = printed.match(/children\s*\{[^}]+\}/s);
|
|
321
|
+
expect(childrenMatch).toBeTruthy();
|
|
322
|
+
expect(childrenMatch![0]).not.toContain('customFields');
|
|
323
|
+
|
|
324
|
+
// Should NOT add customFields to breadcrumbs
|
|
325
|
+
const breadcrumbsMatch = printed.match(/breadcrumbs\s*\{[^}]+\}/s);
|
|
326
|
+
expect(breadcrumbsMatch).toBeTruthy();
|
|
327
|
+
expect(breadcrumbsMatch![0]).not.toContain('customFields');
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it('Should only add custom fields to top-level entity, not nested related entities', () => {
|
|
331
|
+
const documentNode = graphql(`
|
|
332
|
+
query CollectionList($options: CollectionListOptions) {
|
|
333
|
+
collections(options: $options) {
|
|
334
|
+
items {
|
|
335
|
+
id
|
|
336
|
+
name
|
|
337
|
+
slug
|
|
338
|
+
featuredAsset {
|
|
339
|
+
id
|
|
340
|
+
preview
|
|
341
|
+
}
|
|
342
|
+
children {
|
|
343
|
+
id
|
|
344
|
+
name
|
|
345
|
+
slug
|
|
346
|
+
}
|
|
347
|
+
breadcrumbs {
|
|
348
|
+
id
|
|
349
|
+
name
|
|
350
|
+
slug
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
totalItems
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
`);
|
|
357
|
+
|
|
358
|
+
const customFieldsConfig = new Map<string, CustomFieldConfig[]>();
|
|
359
|
+
customFieldsConfig.set('Collection', [
|
|
360
|
+
{ name: 'featuredProducts', type: 'relation', list: true, scalarFields: ['id', 'name'] },
|
|
361
|
+
{ name: 'alternativeAsset', type: 'relation', list: false, scalarFields: ['id', 'name'] },
|
|
362
|
+
]);
|
|
363
|
+
customFieldsConfig.set('Asset', [
|
|
364
|
+
{ name: 'assetCustomField1', type: 'string', list: false },
|
|
365
|
+
{ name: 'assetCustomField2', type: 'string', list: false },
|
|
366
|
+
]);
|
|
367
|
+
|
|
368
|
+
const result = addCustomFields(documentNode, { customFieldsMap: customFieldsConfig });
|
|
369
|
+
const printed = print(result);
|
|
370
|
+
|
|
371
|
+
// Should add customFields to top-level Collection (items)
|
|
372
|
+
expect(printed).toContain('customFields {');
|
|
373
|
+
expect(printed).toContain('featuredProducts {');
|
|
374
|
+
expect(printed).toContain('alternativeAsset {');
|
|
375
|
+
|
|
376
|
+
// Should NOT add customFields to nested Collection entities (children, breadcrumbs)
|
|
377
|
+
const childrenMatch = printed.match(/children\s*\{[^}]+\}/s);
|
|
378
|
+
const breadcrumbsMatch = printed.match(/breadcrumbs\s*\{[^}]+\}/s);
|
|
379
|
+
|
|
380
|
+
expect(childrenMatch).toBeTruthy();
|
|
381
|
+
expect(breadcrumbsMatch).toBeTruthy();
|
|
382
|
+
expect(childrenMatch![0]).not.toContain('customFields');
|
|
383
|
+
expect(breadcrumbsMatch![0]).not.toContain('customFields');
|
|
384
|
+
|
|
385
|
+
// Should NOT add customFields to nested Asset entity (featuredAsset)
|
|
386
|
+
const featuredAssetMatch = printed.match(/featuredAsset\s*\{[^}]+\}/s);
|
|
387
|
+
expect(featuredAssetMatch).toBeTruthy();
|
|
388
|
+
expect(featuredAssetMatch![0]).not.toContain('customFields');
|
|
389
|
+
expect(featuredAssetMatch![0]).not.toContain('assetCustomField1');
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
it('Should NOT add custom fields to fragments that are only used in nested contexts', () => {
|
|
393
|
+
const assetFragment = graphql(`
|
|
394
|
+
fragment Asset on Asset {
|
|
395
|
+
id
|
|
396
|
+
name
|
|
397
|
+
preview
|
|
398
|
+
}
|
|
399
|
+
`);
|
|
400
|
+
|
|
401
|
+
const documentNode = graphql(
|
|
402
|
+
`
|
|
403
|
+
query ProductList($options: ProductListOptions) {
|
|
404
|
+
products(options: $options) {
|
|
405
|
+
items {
|
|
406
|
+
id
|
|
407
|
+
name
|
|
408
|
+
featuredAsset {
|
|
409
|
+
...Asset
|
|
410
|
+
}
|
|
411
|
+
variants {
|
|
412
|
+
id
|
|
413
|
+
name
|
|
414
|
+
assets {
|
|
415
|
+
...Asset
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
totalItems
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
`,
|
|
423
|
+
[assetFragment],
|
|
424
|
+
);
|
|
425
|
+
|
|
426
|
+
const customFieldsConfig = new Map<string, CustomFieldConfig[]>();
|
|
427
|
+
customFieldsConfig.set('Product', [{ name: 'productCustomField', type: 'string', list: false }]);
|
|
428
|
+
customFieldsConfig.set('Asset', [{ name: 'assetCustomField', type: 'string', list: false }]);
|
|
429
|
+
customFieldsConfig.set('ProductVariant', [
|
|
430
|
+
{ name: 'variantCustomField', type: 'string', list: false },
|
|
431
|
+
]);
|
|
432
|
+
|
|
433
|
+
const result = addCustomFields(documentNode, { customFieldsMap: customFieldsConfig });
|
|
434
|
+
const printed = print(result);
|
|
435
|
+
|
|
436
|
+
// Should add customFields to Product (top-level query entity)
|
|
437
|
+
expect(printed).toContain('customFields {');
|
|
438
|
+
expect(printed).toContain('productCustomField');
|
|
439
|
+
|
|
440
|
+
// Should NOT add customFields to Asset fragment (only used in nested contexts)
|
|
441
|
+
expect(printed).not.toMatch(/fragment Asset on Asset\s*\{[^}]*customFields/s);
|
|
442
|
+
|
|
443
|
+
// Should NOT add customFields to nested ProductVariant entities
|
|
444
|
+
const variantsMatch = printed.match(/variants\s*\{[^}]+\}/s);
|
|
445
|
+
expect(variantsMatch).toBeTruthy();
|
|
446
|
+
expect(variantsMatch![0]).not.toContain('customFields');
|
|
447
|
+
expect(variantsMatch![0]).not.toContain('variantCustomField');
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
it('Should add custom fields to fragments used at top level', () => {
|
|
451
|
+
const productFragment = graphql(`
|
|
452
|
+
fragment ProductDetails on Product {
|
|
453
|
+
id
|
|
454
|
+
name
|
|
455
|
+
slug
|
|
456
|
+
}
|
|
457
|
+
`);
|
|
458
|
+
|
|
459
|
+
const documentNode = graphql(
|
|
460
|
+
`
|
|
461
|
+
query ProductList($options: ProductListOptions) {
|
|
462
|
+
products(options: $options) {
|
|
463
|
+
items {
|
|
464
|
+
...ProductDetails
|
|
465
|
+
featuredAsset {
|
|
466
|
+
id
|
|
467
|
+
preview
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
totalItems
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
`,
|
|
474
|
+
[productFragment],
|
|
475
|
+
);
|
|
476
|
+
|
|
477
|
+
const customFieldsConfig = new Map<string, CustomFieldConfig[]>();
|
|
478
|
+
customFieldsConfig.set('Product', [{ name: 'productCustomField', type: 'string', list: false }]);
|
|
479
|
+
customFieldsConfig.set('Asset', [{ name: 'assetCustomField', type: 'string', list: false }]);
|
|
480
|
+
|
|
481
|
+
const result = addCustomFields(documentNode, { customFieldsMap: customFieldsConfig });
|
|
482
|
+
const printed = print(result);
|
|
483
|
+
|
|
484
|
+
// Should add customFields to ProductDetails fragment (used at top level in items)
|
|
485
|
+
expect(printed).toContain('fragment ProductDetails on Product');
|
|
486
|
+
expect(printed).toContain('productCustomField');
|
|
487
|
+
|
|
488
|
+
// Should NOT add customFields to featuredAsset (nested entity)
|
|
489
|
+
const featuredAssetMatch = printed.match(/featuredAsset\s*\{[^}]+\}/s);
|
|
490
|
+
expect(featuredAssetMatch).toBeTruthy();
|
|
491
|
+
expect(featuredAssetMatch![0]).not.toContain('customFields');
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
it('Should handle complex nested structure with multiple entity types', () => {
|
|
495
|
+
const documentNode = graphql(`
|
|
496
|
+
query ComplexQuery {
|
|
497
|
+
orders {
|
|
498
|
+
items {
|
|
499
|
+
id
|
|
500
|
+
code
|
|
501
|
+
customer {
|
|
502
|
+
id
|
|
503
|
+
firstName
|
|
504
|
+
addresses {
|
|
505
|
+
id
|
|
506
|
+
streetLine1
|
|
507
|
+
country {
|
|
508
|
+
id
|
|
509
|
+
name
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
lines {
|
|
514
|
+
id
|
|
515
|
+
productVariant {
|
|
516
|
+
id
|
|
517
|
+
name
|
|
518
|
+
product {
|
|
519
|
+
id
|
|
520
|
+
name
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
`);
|
|
528
|
+
|
|
529
|
+
const customFieldsConfig = new Map<string, CustomFieldConfig[]>();
|
|
530
|
+
customFieldsConfig.set('Order', [{ name: 'orderCustomField', type: 'string', list: false }]);
|
|
531
|
+
customFieldsConfig.set('Customer', [
|
|
532
|
+
{ name: 'customerCustomField', type: 'string', list: false },
|
|
533
|
+
]);
|
|
534
|
+
customFieldsConfig.set('Address', [{ name: 'addressCustomField', type: 'string', list: false }]);
|
|
535
|
+
customFieldsConfig.set('Product', [{ name: 'productCustomField', type: 'string', list: false }]);
|
|
536
|
+
|
|
537
|
+
const result = addCustomFields(documentNode, { customFieldsMap: customFieldsConfig });
|
|
538
|
+
const printed = print(result);
|
|
539
|
+
|
|
540
|
+
// Should only add customFields to top-level Order entity
|
|
541
|
+
expect(printed).toContain('customFields {');
|
|
542
|
+
expect(printed).toContain('orderCustomField');
|
|
543
|
+
|
|
544
|
+
// Should NOT add customFields to any nested entities
|
|
545
|
+
expect(printed).not.toMatch(/customer\s*\{[^}]*customFields/s);
|
|
546
|
+
expect(printed).not.toMatch(/addresses\s*\{[^}]*customFields/s);
|
|
547
|
+
expect(printed).not.toMatch(/country\s*\{[^}]*customFields/s);
|
|
548
|
+
expect(printed).not.toMatch(/productVariant\s*\{[^}]*customFields/s);
|
|
549
|
+
expect(printed).not.toMatch(/product\s*\{[^}]*customFields/s);
|
|
550
|
+
});
|
|
551
|
+
});
|
|
242
552
|
});
|