@vendure/dashboard 3.4.0-minor-202506250934 → 3.4.0
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 +102 -3
- package/dist/plugin/api/api-extensions.d.ts +1 -0
- package/dist/plugin/api/api-extensions.js +38 -0
- package/dist/plugin/api/metrics.resolver.d.ts +8 -0
- package/dist/plugin/api/metrics.resolver.js +40 -0
- package/dist/plugin/config/metrics-strategies.d.ts +39 -0
- package/dist/plugin/config/metrics-strategies.js +74 -0
- package/dist/plugin/constants.d.ts +4 -3
- package/dist/plugin/constants.js +10 -277
- package/dist/plugin/dashboard.plugin.d.ts +95 -0
- package/dist/plugin/dashboard.plugin.js +168 -0
- package/dist/plugin/index.d.ts +2 -1
- package/dist/plugin/index.js +18 -1
- package/dist/plugin/package.json +3 -0
- package/dist/plugin/service/metrics.service.d.ts +15 -0
- package/dist/plugin/service/metrics.service.js +145 -0
- package/dist/plugin/types.d.ts +23 -0
- package/dist/plugin/types.js +13 -0
- package/dist/vite/constants.d.ts +5 -0
- package/dist/vite/constants.js +277 -0
- package/dist/vite/index.d.ts +1 -0
- package/dist/vite/index.js +1 -0
- package/dist/vite/types.d.ts +40 -0
- package/dist/{plugin → vite}/utils/ast-utils.d.ts +0 -5
- package/dist/vite/utils/ast-utils.js +29 -0
- package/dist/vite/utils/ast-utils.spec.d.ts +1 -0
- package/dist/vite/utils/ast-utils.spec.js +45 -0
- package/dist/vite/utils/compiler.d.ts +22 -0
- package/dist/vite/utils/compiler.js +162 -0
- package/dist/vite/utils/config-loader.d.ts +1 -0
- package/dist/vite/utils/config-loader.js +1 -0
- package/dist/vite/utils/logger.d.ts +3 -0
- package/dist/vite/utils/logger.js +39 -0
- package/dist/vite/utils/plugin-discovery.d.ts +27 -0
- package/dist/vite/utils/plugin-discovery.js +387 -0
- package/dist/vite/utils/tsconfig-utils.d.ts +9 -0
- package/dist/vite/utils/tsconfig-utils.js +50 -0
- package/dist/vite/utils/ui-config.d.ts +3 -0
- package/dist/vite/utils/ui-config.js +30 -0
- package/dist/{plugin → vite}/vite-plugin-config-loader.d.ts +3 -3
- package/dist/{plugin → vite}/vite-plugin-config-loader.js +18 -13
- package/dist/{plugin → vite}/vite-plugin-config.js +6 -7
- package/dist/{plugin → vite}/vite-plugin-dashboard-metadata.d.ts +1 -3
- package/dist/{plugin → vite}/vite-plugin-dashboard-metadata.js +20 -10
- package/dist/vite/vite-plugin-tailwind-source.d.ts +7 -0
- package/dist/vite/vite-plugin-tailwind-source.js +61 -0
- package/dist/vite/vite-plugin-theme.js +130 -0
- package/dist/vite/vite-plugin-ui-config.d.ts +123 -0
- package/dist/{plugin → vite}/vite-plugin-ui-config.js +3 -11
- package/dist/vite/vite-plugin-vendure-dashboard.d.ts +85 -0
- package/dist/{plugin → vite}/vite-plugin-vendure-dashboard.js +10 -7
- package/index.html +1 -1
- package/package.json +56 -31
- package/src/app/app-providers.tsx +7 -7
- package/src/app/common/delete-bulk-action.tsx +148 -0
- package/src/app/common/duplicate-bulk-action.tsx +134 -0
- package/src/app/main.tsx +9 -9
- package/src/app/routes/__root.tsx +1 -2
- package/src/app/routes/_authenticated/_administrators/administrators.graphql.ts +10 -1
- package/src/app/routes/_authenticated/_administrators/administrators.tsx +15 -8
- package/src/app/routes/_authenticated/_administrators/administrators_.$id.tsx +16 -12
- package/src/app/routes/_authenticated/_administrators/components/administrator-bulk-actions.tsx +15 -0
- package/src/app/routes/_authenticated/_administrators/components/role-permissions-display.tsx +16 -16
- package/src/app/routes/_authenticated/_assets/assets.graphql.ts +13 -2
- package/src/app/routes/_authenticated/_assets/assets.tsx +16 -4
- package/src/app/routes/_authenticated/_assets/assets_.$id.tsx +52 -38
- package/src/app/routes/_authenticated/_assets/components/asset-bulk-actions.tsx +45 -0
- package/src/app/routes/_authenticated/_channels/channels.graphql.ts +10 -1
- package/src/app/routes/_authenticated/_channels/channels.tsx +17 -10
- package/src/app/routes/_authenticated/_channels/channels_.$id.tsx +21 -17
- package/src/app/routes/_authenticated/_channels/components/channel-bulk-actions.tsx +15 -0
- package/src/app/routes/_authenticated/_collections/collections.graphql.ts +60 -3
- package/src/app/routes/_authenticated/_collections/collections.tsx +168 -124
- package/src/app/routes/_authenticated/_collections/collections_.$id.tsx +21 -17
- package/src/app/routes/_authenticated/_collections/components/collection-bulk-actions.tsx +123 -0
- package/src/app/routes/_authenticated/_collections/components/collection-contents-preview-table.tsx +8 -9
- package/src/app/routes/_authenticated/_collections/components/collection-contents-sheet.tsx +9 -5
- package/src/app/routes/_authenticated/_collections/components/collection-contents-table.tsx +10 -9
- package/src/app/routes/_authenticated/_collections/components/collection-filters-selector.tsx +12 -79
- package/src/app/routes/_authenticated/_collections/components/move-collections-dialog.tsx +430 -0
- package/src/app/routes/_authenticated/_collections/components/move-single-collection.tsx +33 -0
- package/src/app/routes/_authenticated/_countries/components/country-bulk-actions.tsx +15 -0
- package/src/app/routes/_authenticated/_countries/countries.graphql.ts +11 -2
- package/src/app/routes/_authenticated/_countries/countries.tsx +13 -6
- package/src/app/routes/_authenticated/_countries/countries_.$id.tsx +21 -17
- package/src/app/routes/_authenticated/_customer-groups/components/customer-group-bulk-actions.tsx +15 -0
- package/src/app/routes/_authenticated/_customer-groups/components/customer-group-members-sheet.tsx +12 -5
- package/src/app/routes/_authenticated/_customer-groups/components/customer-group-members-table.tsx +22 -17
- package/src/app/routes/_authenticated/_customer-groups/customer-groups.graphql.ts +11 -2
- package/src/app/routes/_authenticated/_customer-groups/customer-groups.tsx +13 -6
- package/src/app/routes/_authenticated/_customer-groups/customer-groups_.$id.tsx +18 -15
- package/src/app/routes/_authenticated/_customers/components/customer-address-card.tsx +19 -19
- package/src/app/routes/_authenticated/_customers/components/customer-address-form.tsx +10 -10
- package/src/app/routes/_authenticated/_customers/components/customer-bulk-actions.tsx +15 -0
- package/src/app/routes/_authenticated/_customers/components/customer-history/customer-history-container.tsx +5 -5
- package/src/app/routes/_authenticated/_customers/components/customer-history/customer-history.tsx +11 -7
- package/src/app/routes/_authenticated/_customers/components/customer-history/use-customer-history.ts +4 -4
- package/src/app/routes/_authenticated/_customers/components/customer-order-table.tsx +75 -73
- package/src/app/routes/_authenticated/_customers/components/customer-status-badge.tsx +4 -4
- package/src/app/routes/_authenticated/_customers/customers.graphql.ts +10 -2
- package/src/app/routes/_authenticated/_customers/customers.tsx +13 -6
- package/src/app/routes/_authenticated/_customers/customers_.$id.tsx +19 -15
- package/src/app/routes/_authenticated/_facets/components/edit-facet-value.tsx +9 -9
- package/src/app/routes/_authenticated/_facets/components/facet-bulk-actions.tsx +104 -0
- package/src/app/routes/_authenticated/_facets/components/facet-values-sheet.tsx +4 -4
- package/src/app/routes/_authenticated/_facets/components/facet-values-table.tsx +76 -65
- package/src/app/routes/_authenticated/_facets/facets.graphql.ts +80 -1
- package/src/app/routes/_authenticated/_facets/facets.tsx +31 -7
- package/src/app/routes/_authenticated/_facets/facets_.$facetId.values_.$id.tsx +147 -0
- package/src/app/routes/_authenticated/_facets/facets_.$id.tsx +17 -13
- package/src/app/routes/_authenticated/_global-settings/global-settings.graphql.ts +1 -1
- package/src/app/routes/_authenticated/_global-settings/global-settings.tsx +26 -18
- package/src/app/routes/_authenticated/_orders/components/add-manual-payment-dialog.tsx +191 -0
- package/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsx +11 -15
- package/src/app/routes/_authenticated/_orders/components/edit-order-table.tsx +111 -80
- package/src/app/routes/_authenticated/_orders/components/fulfill-order-dialog.tsx +320 -0
- package/src/app/routes/_authenticated/_orders/components/fulfillment-details.tsx +153 -0
- package/src/app/routes/_authenticated/_orders/components/money-gross-net.tsx +11 -9
- package/src/app/routes/_authenticated/_orders/components/order-address.tsx +19 -13
- package/src/app/routes/_authenticated/_orders/components/order-history/order-history-container.tsx +67 -62
- package/src/app/routes/_authenticated/_orders/components/order-history/order-history.tsx +391 -39
- package/src/app/routes/_authenticated/_orders/components/order-history/use-order-history.ts +9 -5
- package/src/app/routes/_authenticated/_orders/components/order-line-custom-fields-form.tsx +28 -13
- package/src/app/routes/_authenticated/_orders/components/order-modification-preview-dialog.tsx +364 -0
- package/src/app/routes/_authenticated/_orders/components/order-modification-summary.tsx +222 -0
- package/src/app/routes/_authenticated/_orders/components/order-table-totals.tsx +39 -22
- package/src/app/routes/_authenticated/_orders/components/order-table.tsx +148 -87
- package/src/app/routes/_authenticated/_orders/components/order-tax-summary.tsx +37 -36
- package/src/app/routes/_authenticated/_orders/components/payment-details.tsx +274 -48
- package/src/app/routes/_authenticated/_orders/components/settle-refund-dialog.tsx +80 -0
- package/src/app/routes/_authenticated/_orders/components/shipping-method-selector.tsx +43 -44
- package/src/app/routes/_authenticated/_orders/components/state-transition-control.tsx +102 -0
- package/src/app/routes/_authenticated/_orders/components/use-transition-order-to-state.tsx +144 -0
- package/src/app/routes/_authenticated/_orders/orders.graphql.ts +219 -5
- package/src/app/routes/_authenticated/_orders/orders.tsx +23 -22
- package/src/app/routes/_authenticated/_orders/orders_.$id.tsx +190 -42
- package/src/app/routes/_authenticated/_orders/orders_.$id_.modify.tsx +550 -0
- package/src/app/routes/_authenticated/_orders/orders_.draft.$id.tsx +187 -107
- package/src/app/routes/_authenticated/_orders/utils/order-types.ts +10 -0
- package/src/app/routes/_authenticated/_orders/utils/order-utils.ts +78 -0
- package/src/app/routes/_authenticated/_payment-methods/components/payment-eligibility-checker-selector.tsx +12 -79
- package/src/app/routes/_authenticated/_payment-methods/components/payment-handler-selector.tsx +12 -79
- package/src/app/routes/_authenticated/_payment-methods/components/payment-method-bulk-actions.tsx +58 -0
- package/src/app/routes/_authenticated/_payment-methods/payment-methods.graphql.ts +29 -2
- package/src/app/routes/_authenticated/_payment-methods/payment-methods.tsx +36 -14
- package/src/app/routes/_authenticated/_payment-methods/payment-methods_.$id.tsx +22 -15
- package/src/app/routes/_authenticated/_product-variants/components/product-variant-bulk-actions.tsx +110 -0
- package/src/app/routes/_authenticated/_product-variants/components/variant-price-detail.tsx +7 -6
- package/src/app/routes/_authenticated/_product-variants/product-variants.graphql.ts +64 -3
- package/src/app/routes/_authenticated/_product-variants/product-variants.tsx +39 -9
- package/src/app/routes/_authenticated/_product-variants/product-variants_.$id.tsx +33 -22
- package/src/app/routes/_authenticated/_products/components/add-product-variant-dialog.tsx +10 -10
- package/src/app/routes/_authenticated/_products/components/assign-facet-values-dialog.tsx +281 -0
- package/src/app/routes/_authenticated/_products/components/create-product-options-dialog.tsx +57 -41
- package/src/app/routes/_authenticated/_products/components/create-product-variants-dialog.tsx +11 -11
- package/src/app/routes/_authenticated/_products/components/create-product-variants.tsx +18 -14
- package/src/app/routes/_authenticated/_products/components/option-value-input.tsx +23 -17
- package/src/app/routes/_authenticated/_products/components/product-bulk-actions.tsx +123 -0
- package/src/app/routes/_authenticated/_products/components/product-option-select.tsx +28 -34
- package/src/app/routes/_authenticated/_products/components/product-variants-table.tsx +84 -53
- package/src/app/routes/_authenticated/_products/products.graphql.ts +70 -2
- package/src/app/routes/_authenticated/_products/products.tsx +36 -7
- package/src/app/routes/_authenticated/_products/products_.$id.tsx +34 -26
- package/src/app/routes/_authenticated/_profile/profile.graphql.ts +1 -1
- package/src/app/routes/_authenticated/_profile/profile.tsx +8 -8
- package/src/app/routes/_authenticated/_promotions/components/promotion-actions-selector.tsx +14 -86
- package/src/app/routes/_authenticated/_promotions/components/promotion-bulk-actions.tsx +82 -0
- package/src/app/routes/_authenticated/_promotions/components/promotion-conditions-selector.tsx +14 -86
- package/src/app/routes/_authenticated/_promotions/promotions.graphql.ts +27 -2
- package/src/app/routes/_authenticated/_promotions/promotions.tsx +31 -7
- package/src/app/routes/_authenticated/_promotions/promotions_.$id.tsx +20 -16
- package/src/app/routes/_authenticated/_roles/components/expandable-permissions.tsx +5 -5
- package/src/app/routes/_authenticated/_roles/components/permissions-grid.tsx +21 -17
- package/src/app/routes/_authenticated/_roles/components/role-bulk-actions.tsx +15 -0
- package/src/app/routes/_authenticated/_roles/roles.graphql.ts +10 -1
- package/src/app/routes/_authenticated/_roles/roles.tsx +17 -10
- package/src/app/routes/_authenticated/_roles/roles_.$id.tsx +16 -12
- package/src/app/routes/_authenticated/_sellers/components/seller-bulk-actions.tsx +15 -0
- package/src/app/routes/_authenticated/_sellers/sellers.graphql.ts +10 -1
- package/src/app/routes/_authenticated/_sellers/sellers.tsx +13 -6
- package/src/app/routes/_authenticated/_sellers/sellers_.$id.tsx +17 -13
- package/src/app/routes/_authenticated/_shipping-methods/components/fulfillment-handler-selector.tsx +6 -6
- package/src/app/routes/_authenticated/_shipping-methods/components/shipping-calculator-selector.tsx +12 -80
- package/src/app/routes/_authenticated/_shipping-methods/components/shipping-eligibility-checker-selector.tsx +15 -80
- package/src/app/routes/_authenticated/_shipping-methods/components/shipping-method-bulk-actions.tsx +61 -0
- package/src/app/routes/_authenticated/_shipping-methods/components/test-shipping-method-dialog.tsx +3 -3
- package/src/app/routes/_authenticated/_shipping-methods/shipping-methods.graphql.ts +29 -2
- package/src/app/routes/_authenticated/_shipping-methods/shipping-methods.tsx +25 -6
- package/src/app/routes/_authenticated/_shipping-methods/shipping-methods_.$id.tsx +25 -19
- package/src/app/routes/_authenticated/_stock-locations/components/stock-location-bulk-actions.tsx +58 -0
- package/src/app/routes/_authenticated/_stock-locations/stock-locations.graphql.ts +26 -1
- package/src/app/routes/_authenticated/_stock-locations/stock-locations.tsx +25 -6
- package/src/app/routes/_authenticated/_stock-locations/stock-locations_.$id.tsx +16 -12
- package/src/app/routes/_authenticated/_system/components/payload-dialog.tsx +5 -5
- package/src/app/routes/_authenticated/_system/healthchecks.tsx +5 -5
- package/src/app/routes/_authenticated/_system/job-queue.graphql.ts +12 -1
- package/src/app/routes/_authenticated/_system/job-queue.tsx +110 -11
- package/src/app/routes/_authenticated/_system/scheduled-tasks.tsx +34 -28
- package/src/app/routes/_authenticated/_tax-categories/components/tax-category-bulk-actions.tsx +15 -0
- package/src/app/routes/_authenticated/_tax-categories/tax-categories.graphql.ts +11 -2
- package/src/app/routes/_authenticated/_tax-categories/tax-categories.tsx +14 -7
- package/src/app/routes/_authenticated/_tax-categories/tax-categories_.$id.tsx +20 -16
- package/src/app/routes/_authenticated/_tax-rates/components/tax-rate-bulk-actions.tsx +15 -0
- package/src/app/routes/_authenticated/_tax-rates/tax-rates.graphql.ts +11 -2
- package/src/app/routes/_authenticated/_tax-rates/tax-rates.tsx +15 -8
- package/src/app/routes/_authenticated/_tax-rates/tax-rates_.$id.tsx +22 -18
- package/src/app/routes/_authenticated/_zones/components/zone-bulk-actions.tsx +15 -0
- package/src/app/routes/_authenticated/_zones/components/zone-countries-sheet.tsx +4 -4
- package/src/app/routes/_authenticated/_zones/components/zone-countries-table.tsx +12 -15
- package/src/app/routes/_authenticated/_zones/zones.graphql.ts +11 -2
- package/src/app/routes/_authenticated/_zones/zones.tsx +13 -6
- package/src/app/routes/_authenticated/_zones/zones_.$id.tsx +18 -14
- package/src/app/routes/_authenticated/index.tsx +6 -6
- package/src/app/routes/_authenticated.tsx +4 -4
- package/src/app/routes/login.tsx +2 -2
- package/src/app/styles.css +5 -2
- package/src/lib/components/data-display/boolean.tsx +1 -1
- package/src/lib/components/data-display/date-time.tsx +9 -3
- package/src/lib/components/data-display/json.tsx +1 -1
- package/src/lib/components/data-display/money.tsx +2 -3
- package/src/lib/components/data-input/affixed-input.tsx +3 -8
- package/src/lib/components/data-input/combination-mode-input.tsx +52 -0
- package/src/lib/components/data-input/configurable-operation-list-input.tsx +433 -0
- package/src/lib/components/data-input/custom-field-list-input.tsx +297 -0
- package/src/lib/components/data-input/customer-group-input.tsx +2 -2
- package/src/lib/components/data-input/datetime-input.tsx +132 -146
- package/src/lib/components/data-input/default-relation-input.tsx +599 -0
- package/src/lib/components/data-input/facet-value-input.tsx +30 -22
- package/src/lib/components/data-input/index.ts +17 -0
- package/src/lib/components/data-input/money-input.tsx +5 -12
- package/src/lib/components/data-input/product-multi-selector.tsx +426 -0
- package/src/lib/components/data-input/relation-input.tsx +164 -0
- package/src/lib/components/data-input/relation-selector.tsx +476 -0
- package/src/lib/components/data-input/{richt-text-input.tsx → rich-text-input.tsx} +15 -9
- package/src/lib/components/data-input/select-with-options.tsx +84 -0
- package/src/lib/components/data-input/struct-form-input.tsx +324 -0
- package/src/lib/components/data-table/add-filter-menu.tsx +9 -18
- package/src/lib/components/data-table/data-table-bulk-action-item.tsx +101 -0
- package/src/lib/components/data-table/data-table-bulk-actions.tsx +108 -0
- package/src/lib/components/data-table/data-table-column-header.tsx +4 -22
- package/src/lib/components/data-table/data-table-faceted-filter.tsx +8 -8
- package/src/lib/components/data-table/data-table-filter-badge.tsx +16 -8
- package/src/lib/components/data-table/data-table-filter-dialog.tsx +8 -8
- package/src/lib/components/data-table/data-table-pagination.tsx +4 -4
- package/src/lib/components/data-table/data-table-utils.ts +34 -0
- package/src/lib/components/data-table/data-table-view-options.tsx +27 -23
- package/src/lib/components/data-table/data-table.tsx +90 -43
- package/src/lib/components/data-table/filters/data-table-boolean-filter.tsx +11 -8
- package/src/lib/components/data-table/filters/data-table-datetime-filter.tsx +14 -23
- package/src/lib/components/data-table/filters/data-table-id-filter.tsx +15 -10
- package/src/lib/components/data-table/filters/data-table-number-filter.tsx +18 -17
- package/src/lib/components/data-table/filters/data-table-string-filter.tsx +29 -12
- package/src/lib/components/data-table/human-readable-operator.tsx +3 -3
- package/src/lib/components/data-table/refresh-button.tsx +30 -15
- package/src/lib/components/data-table/use-generated-columns.tsx +322 -0
- package/src/lib/components/labeled-data.tsx +21 -0
- package/src/lib/components/layout/app-layout.tsx +8 -13
- package/src/lib/components/layout/app-sidebar.tsx +5 -5
- package/src/lib/components/layout/channel-switcher.tsx +171 -62
- package/src/lib/components/layout/content-language-selector.tsx +16 -10
- package/src/lib/components/layout/dev-mode-indicator.tsx +18 -0
- package/src/lib/components/layout/generated-breadcrumbs.tsx +1 -1
- package/src/lib/components/layout/language-dialog.tsx +7 -12
- package/src/lib/components/layout/manage-languages-dialog.tsx +405 -0
- package/src/lib/components/layout/nav-item-wrapper.tsx +107 -0
- package/src/lib/components/layout/nav-main.tsx +200 -111
- package/src/lib/components/layout/nav-projects.tsx +2 -2
- package/src/lib/components/layout/nav-user.tsx +7 -7
- package/src/lib/components/layout/prerelease-popup.tsx +1 -1
- package/src/lib/components/login/login-form.tsx +85 -50
- package/src/lib/components/shared/alerts.tsx +3 -3
- package/src/lib/components/shared/animated-number.tsx +2 -2
- package/src/lib/components/shared/asset/asset-bulk-actions.tsx +109 -0
- package/src/lib/components/shared/asset/asset-focal-point-editor.tsx +29 -19
- package/src/lib/components/shared/asset/asset-gallery.tsx +25 -20
- package/src/lib/components/shared/asset/asset-picker-dialog.tsx +63 -66
- package/src/lib/components/shared/asset/asset-preview-dialog.tsx +3 -7
- package/src/lib/components/shared/asset/asset-preview-selector.tsx +4 -6
- package/src/lib/components/shared/asset/asset-preview.tsx +7 -21
- package/src/lib/components/shared/asset/asset-properties.tsx +7 -9
- package/src/lib/components/shared/asset/focal-point-control.tsx +5 -13
- package/src/lib/components/shared/assign-to-channel-bulk-action.tsx +71 -0
- package/src/lib/components/shared/assign-to-channel-dialog.tsx +155 -0
- package/src/lib/components/shared/assigned-facet-values.tsx +1 -5
- package/src/lib/components/shared/channel-code-label.tsx +3 -4
- package/src/lib/components/shared/channel-selector.tsx +6 -6
- package/src/lib/components/shared/configurable-operation-arg-input.tsx +367 -23
- package/src/lib/components/shared/configurable-operation-input.tsx +87 -48
- package/src/lib/components/shared/configurable-operation-multi-selector.tsx +260 -0
- package/src/lib/components/shared/configurable-operation-selector.tsx +156 -0
- package/src/lib/components/shared/confirmation-dialog.tsx +2 -2
- package/src/lib/components/shared/copyable-text.tsx +3 -4
- package/src/lib/components/shared/country-selector.tsx +21 -18
- package/src/lib/components/shared/currency-selector.tsx +5 -5
- package/src/lib/components/shared/custom-fields-form.tsx +423 -50
- package/src/lib/components/shared/customer-address-form.tsx +18 -13
- package/src/lib/components/shared/customer-group-selector.tsx +6 -6
- package/src/lib/components/shared/customer-selector.tsx +24 -18
- package/src/lib/components/shared/detail-page-button.tsx +45 -1
- package/src/lib/components/shared/entity-assets.tsx +33 -34
- package/src/lib/components/shared/error-page.tsx +6 -6
- package/src/lib/components/shared/facet-value-chip.tsx +12 -5
- package/src/lib/components/shared/facet-value-selector.tsx +64 -63
- package/src/lib/components/shared/form-field-wrapper.tsx +47 -24
- package/src/lib/components/shared/history-timeline/history-entry-date.tsx +37 -0
- package/src/lib/components/shared/history-timeline/history-entry.tsx +146 -70
- package/src/lib/components/shared/history-timeline/history-note-checkbox.tsx +3 -3
- package/src/lib/components/shared/history-timeline/history-note-editor.tsx +4 -4
- package/src/lib/components/shared/history-timeline/history-note-input.tsx +7 -7
- package/src/lib/components/shared/history-timeline/history-timeline.tsx +8 -48
- package/src/lib/components/shared/language-selector.tsx +5 -5
- package/src/lib/components/shared/logo-mark.tsx +2 -2
- package/src/lib/components/shared/multi-select.tsx +6 -6
- package/src/lib/components/shared/navigation-confirmation.tsx +24 -9
- package/src/lib/components/shared/option-value-input.tsx +18 -16
- package/src/lib/components/shared/paginated-list-data-table.tsx +35 -230
- package/src/lib/components/shared/permission-guard.tsx +4 -4
- package/src/lib/components/shared/product-variant-selector.tsx +59 -34
- package/src/lib/components/shared/remove-from-channel-bulk-action.tsx +90 -0
- package/src/lib/components/shared/role-code-label.tsx +10 -6
- package/src/lib/components/shared/role-selector.tsx +4 -4
- package/src/lib/components/shared/seller-selector.tsx +21 -17
- package/src/lib/components/shared/stock-level-label.tsx +5 -5
- package/src/lib/components/shared/tax-category-selector.tsx +5 -5
- package/src/lib/components/shared/translatable-form-field.tsx +46 -23
- package/src/lib/components/shared/vendure-image.tsx +31 -2
- package/src/lib/components/shared/zone-selector.tsx +5 -6
- package/src/lib/components/ui/accordion.tsx +3 -3
- package/src/lib/components/ui/alert-dialog.tsx +10 -10
- package/src/lib/components/ui/alert.tsx +3 -3
- package/src/lib/components/ui/aspect-ratio.tsx +9 -0
- package/src/lib/components/ui/badge.tsx +2 -2
- package/src/lib/components/ui/breadcrumb.tsx +4 -4
- package/src/lib/components/ui/button.tsx +10 -3
- package/src/lib/components/ui/calendar.tsx +392 -459
- package/src/lib/components/ui/card.tsx +2 -2
- package/src/lib/components/ui/carousel.tsx +241 -0
- package/src/lib/components/ui/chart.tsx +351 -0
- package/src/lib/components/ui/checkbox.tsx +2 -2
- package/src/lib/components/ui/command.tsx +12 -6
- package/src/lib/components/ui/context-menu.tsx +252 -0
- package/src/lib/components/ui/dialog.tsx +2 -2
- package/src/lib/components/ui/drawer.tsx +133 -0
- package/src/lib/components/ui/dropdown-menu.tsx +7 -7
- package/src/lib/components/ui/form.tsx +8 -8
- package/src/lib/components/ui/hover-card.tsx +3 -3
- package/src/lib/components/ui/input-otp.tsx +77 -0
- package/src/lib/components/ui/input.tsx +1 -1
- package/src/lib/components/ui/label.tsx +2 -2
- package/src/lib/components/ui/menubar.tsx +274 -0
- package/src/lib/components/ui/navigation-menu.tsx +168 -0
- package/src/lib/components/ui/pagination.tsx +87 -108
- package/src/lib/components/ui/popover.tsx +3 -3
- package/src/lib/components/ui/progress.tsx +29 -0
- package/src/lib/components/ui/radio-group.tsx +45 -0
- package/src/lib/components/ui/resizable.tsx +54 -0
- package/src/lib/components/ui/scroll-area.tsx +2 -2
- package/src/lib/components/ui/select.tsx +151 -129
- package/src/lib/components/ui/separator.tsx +2 -2
- package/src/lib/components/ui/sheet.tsx +5 -5
- package/src/lib/components/ui/sidebar.tsx +10 -10
- package/src/lib/components/ui/skeleton.tsx +1 -1
- package/src/lib/components/ui/slider.tsx +63 -0
- package/src/lib/components/ui/switch.tsx +2 -2
- package/src/lib/components/ui/table.tsx +2 -2
- package/src/lib/components/ui/tabs.tsx +3 -3
- package/src/lib/components/ui/textarea.tsx +1 -1
- package/src/lib/components/ui/toggle-group.tsx +73 -0
- package/src/lib/components/ui/toggle.tsx +45 -0
- package/src/lib/components/ui/tooltip.tsx +3 -3
- package/src/lib/framework/alert/alert-extensions.tsx +2 -3
- package/src/lib/framework/alert/alert-item.tsx +5 -3
- package/src/lib/framework/component-registry/component-registry.tsx +33 -47
- package/src/lib/framework/component-registry/dynamic-component.tsx +3 -3
- package/src/lib/framework/dashboard-widget/base-widget.tsx +5 -13
- package/src/lib/framework/dashboard-widget/latest-orders-widget/index.tsx +8 -8
- package/src/lib/framework/dashboard-widget/latest-orders-widget/latest-orders-widget.graphql.ts +1 -1
- package/src/lib/framework/dashboard-widget/metrics-widget/index.tsx +7 -8
- package/src/lib/framework/dashboard-widget/metrics-widget/metrics-widget.graphql.ts +1 -1
- package/src/lib/framework/dashboard-widget/orders-summary/index.tsx +7 -8
- package/src/lib/framework/dashboard-widget/orders-summary/order-summary-widget.graphql.ts +1 -1
- package/src/lib/framework/dashboard-widget/widget-extensions.tsx +1 -1
- package/src/lib/framework/data-table/data-table-extensions.ts +35 -0
- package/src/lib/framework/defaults.ts +5 -11
- package/src/lib/framework/document-extension/extend-detail-form-query.ts +50 -0
- package/src/lib/framework/document-extension/extend-document.spec.ts +884 -0
- package/src/lib/framework/document-extension/extend-document.ts +159 -0
- package/src/lib/framework/document-introspection/add-custom-fields.ts +50 -2
- package/src/lib/framework/document-introspection/get-document-structure.spec.ts +321 -2
- package/src/lib/framework/document-introspection/get-document-structure.ts +187 -36
- package/src/lib/framework/document-introspection/hooks.ts +4 -1
- package/src/lib/framework/extension-api/define-dashboard-extension.ts +35 -49
- package/src/lib/framework/extension-api/display-component-extensions.tsx +69 -0
- package/src/lib/framework/extension-api/extension-api-types.ts +34 -98
- package/src/lib/framework/extension-api/input-component-extensions.tsx +73 -0
- package/src/lib/framework/extension-api/logic/alerts.ts +10 -0
- package/src/lib/framework/extension-api/logic/data-table.ts +60 -0
- package/src/lib/framework/extension-api/logic/detail-forms.ts +48 -0
- package/src/lib/framework/extension-api/logic/form-components.ts +13 -0
- package/src/lib/framework/extension-api/logic/index.ts +9 -0
- package/src/lib/framework/extension-api/logic/layout.ts +22 -0
- package/src/lib/framework/extension-api/logic/login.ts +17 -0
- package/src/lib/framework/extension-api/logic/navigation.ts +38 -0
- package/src/lib/framework/extension-api/logic/widgets.ts +10 -0
- package/src/lib/framework/extension-api/types/alerts.ts +54 -0
- package/src/lib/framework/extension-api/types/data-table.ts +96 -0
- package/src/lib/framework/extension-api/types/detail-forms.ts +94 -0
- package/src/lib/framework/extension-api/types/form-components.ts +43 -0
- package/src/lib/framework/extension-api/types/index.ts +9 -0
- package/src/lib/framework/extension-api/types/layout.ts +90 -0
- package/src/lib/framework/extension-api/types/login.ts +96 -0
- package/src/lib/framework/extension-api/types/navigation.ts +76 -0
- package/src/lib/framework/extension-api/types/widgets.ts +93 -0
- package/src/lib/framework/extension-api/use-dashboard-extensions.ts +2 -1
- package/src/lib/framework/extension-api/use-login-extensions.ts +26 -0
- package/src/lib/framework/form-engine/custom-form-component-extensions.ts +38 -0
- package/src/lib/framework/form-engine/custom-form-component.tsx +33 -0
- package/src/lib/framework/form-engine/form-schema-tools.spec.ts +472 -0
- package/src/lib/framework/form-engine/form-schema-tools.ts +341 -6
- package/src/lib/framework/form-engine/overridden-form-component.tsx +51 -0
- package/src/lib/framework/form-engine/use-generated-form.tsx +82 -24
- package/src/lib/framework/form-engine/utils.spec.ts +37 -0
- package/src/lib/framework/form-engine/utils.ts +99 -0
- package/src/lib/framework/layout-engine/dev-mode-button.tsx +24 -0
- package/src/lib/framework/layout-engine/layout-extensions.ts +1 -4
- package/src/lib/framework/layout-engine/location-wrapper.tsx +98 -72
- package/src/lib/framework/layout-engine/page-block-provider.tsx +6 -0
- package/src/lib/framework/layout-engine/page-layout.tsx +135 -58
- package/src/lib/framework/page/detail-page-route-loader.tsx +26 -7
- package/src/lib/framework/page/detail-page.tsx +94 -37
- package/src/lib/framework/page/list-page.tsx +18 -11
- package/src/lib/framework/page/use-detail-page.ts +47 -13
- package/src/lib/framework/page/use-extended-router.tsx +4 -5
- package/src/lib/framework/registry/global-registry.ts +4 -0
- package/src/lib/framework/registry/registry-types.ts +17 -5
- package/src/lib/graphql/api.ts +25 -3
- package/src/lib/graphql/common-operations.ts +18 -0
- package/src/lib/graphql/{fragments.tsx → fragments.ts} +1 -2
- package/src/lib/graphql/graphql-env.d.ts +27 -24
- package/src/lib/graphql/settings-store-operations.ts +17 -0
- package/src/lib/hooks/use-auth.tsx +1 -1
- package/src/lib/hooks/use-channel.ts +1 -1
- package/src/lib/hooks/use-extended-detail-query.ts +37 -0
- package/src/lib/hooks/use-extended-list-query.ts +75 -0
- package/src/lib/hooks/use-floating-bulk-actions.ts +82 -0
- package/src/lib/hooks/use-grouped-permissions.ts +3 -2
- package/src/lib/hooks/use-local-format.ts +20 -5
- package/src/lib/hooks/use-page-block.tsx +18 -0
- package/src/lib/hooks/use-page.tsx +2 -2
- package/src/lib/hooks/use-permissions.ts +3 -2
- package/src/lib/hooks/use-server-config.ts +1 -1
- package/src/lib/hooks/use-theme.ts +1 -1
- package/src/lib/hooks/use-user-settings.tsx +1 -1
- package/src/lib/index.ts +85 -7
- package/src/lib/lib/trans.tsx +3 -3
- package/src/lib/lib/utils.ts +52 -1
- package/src/lib/providers/auth.tsx +37 -14
- package/src/lib/providers/channel-provider.tsx +17 -15
- package/src/lib/providers/server-config.tsx +13 -11
- package/src/lib/providers/theme-provider.tsx +2 -3
- package/src/lib/providers/user-settings.tsx +78 -3
- package/src/lib/virtual.d.ts +26 -2
- package/src/vite-env.d.ts +2 -0
- package/vite/tests/barrel-exports.spec.ts +30 -0
- package/vite/tests/fixtures-barrel-exports/my-plugin/index.ts +1 -0
- package/vite/tests/fixtures-barrel-exports/my-plugin/src/my.plugin.ts +8 -0
- package/vite/tests/fixtures-barrel-exports/package.json +6 -0
- package/vite/tests/fixtures-barrel-exports/vendure-config.ts +19 -0
- package/vite/tests/fixtures-npm-plugin/fake_node_modules/test-plugin/index.js +20 -0
- package/vite/tests/fixtures-npm-plugin/fake_node_modules/test-plugin/package.json +8 -0
- package/vite/tests/fixtures-npm-plugin/package.json +6 -0
- package/vite/tests/fixtures-npm-plugin/vendure-config.ts +18 -0
- package/vite/tests/fixtures-path-alias/js-aliased/index.ts +1 -0
- package/vite/tests/fixtures-path-alias/js-aliased/src/js-aliased.plugin.ts +8 -0
- package/vite/tests/fixtures-path-alias/package.json +6 -0
- package/vite/tests/fixtures-path-alias/star-aliased/index.ts +1 -0
- package/vite/tests/fixtures-path-alias/star-aliased/src/star-aliased.plugin.ts +8 -0
- package/vite/tests/fixtures-path-alias/ts-aliased/index.ts +1 -0
- package/vite/tests/fixtures-path-alias/ts-aliased/src/ts-aliased.plugin.ts +8 -0
- package/vite/tests/fixtures-path-alias/vendure-config.ts +20 -0
- package/vite/tests/npm-plugin.spec.ts +46 -0
- package/vite/tests/path-alias.spec.ts +61 -0
- package/vite/tests/tsconfig.json +21 -0
- package/vite/types.ts +44 -0
- package/vite/utils/ast-utils.spec.ts +1 -80
- package/vite/utils/ast-utils.ts +0 -86
- package/vite/utils/compiler.ts +244 -0
- package/vite/utils/config-loader.ts +0 -445
- package/vite/utils/logger.ts +43 -0
- package/vite/utils/plugin-discovery.ts +494 -0
- package/vite/utils/tsconfig-utils.ts +79 -0
- package/vite/utils/ui-config.ts +30 -42
- package/vite/vite-plugin-config-loader.ts +25 -17
- package/vite/vite-plugin-config.ts +6 -7
- package/vite/vite-plugin-dashboard-metadata.ts +27 -16
- package/vite/vite-plugin-tailwind-source.ts +81 -0
- package/vite/vite-plugin-theme.ts +69 -69
- package/vite/vite-plugin-ui-config.ts +119 -17
- package/vite/vite-plugin-vendure-dashboard.ts +60 -16
- package/dist/plugin/utils/ast-utils.js +0 -96
- package/dist/plugin/utils/ast-utils.spec.js +0 -120
- package/dist/plugin/utils/config-loader.d.ts +0 -52
- package/dist/plugin/utils/config-loader.js +0 -343
- package/dist/plugin/utils/ui-config.d.ts +0 -3
- package/dist/plugin/utils/ui-config.js +0 -34
- package/dist/plugin/vite-plugin-theme.js +0 -130
- package/dist/plugin/vite-plugin-ui-config.d.ts +0 -15
- package/dist/plugin/vite-plugin-vendure-dashboard.d.ts +0 -44
- package/src/lib/components/shared/rich-text-editor.tsx +0 -0
- package/src/lib/framework/alert/types.ts +0 -13
- package/src/lib/framework/dashboard-widget/types.ts +0 -22
- /package/dist/{plugin/utils/ast-utils.spec.d.ts → vite/types.js} +0 -0
- /package/dist/{plugin → vite}/utils/schema-generator.d.ts +0 -0
- /package/dist/{plugin → vite}/utils/schema-generator.js +0 -0
- /package/dist/{plugin → vite}/vite-plugin-admin-api-schema.d.ts +0 -0
- /package/dist/{plugin → vite}/vite-plugin-admin-api-schema.js +0 -0
- /package/dist/{plugin → vite}/vite-plugin-config.d.ts +0 -0
- /package/dist/{plugin → vite}/vite-plugin-gql-tada.d.ts +0 -0
- /package/dist/{plugin → vite}/vite-plugin-gql-tada.js +0 -0
- /package/dist/{plugin → vite}/vite-plugin-theme.d.ts +0 -0
- /package/dist/{plugin → vite}/vite-plugin-transform-index.d.ts +0 -0
- /package/dist/{plugin → vite}/vite-plugin-transform-index.js +0 -0
- /package/src/lib/components/data-table/{data-table-types.ts → types.ts} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TypedDocumentNode } from '@graphql-typed-document-node/core';
|
|
2
|
-
import { VariablesOf } from 'gql.tada';
|
|
2
|
+
import { ResultOf, VariablesOf } from 'gql.tada';
|
|
3
3
|
import {
|
|
4
4
|
DocumentNode,
|
|
5
5
|
FieldNode,
|
|
@@ -32,33 +32,165 @@ export interface FieldInfo {
|
|
|
32
32
|
*/
|
|
33
33
|
export function getListQueryFields(documentNode: DocumentNode): FieldInfo[] {
|
|
34
34
|
const fields: FieldInfo[] = [];
|
|
35
|
-
const fragments
|
|
35
|
+
const fragments = collectFragments(documentNode);
|
|
36
|
+
const operationDefinition = findQueryOperation(documentNode);
|
|
37
|
+
|
|
38
|
+
for (const query of operationDefinition.selectionSet.selections) {
|
|
39
|
+
if (query.kind === 'Field') {
|
|
40
|
+
const queryField = query;
|
|
41
|
+
const fieldInfo = getQueryInfo(queryField.name.value);
|
|
42
|
+
if (fieldInfo.isPaginatedList) {
|
|
43
|
+
processPaginatedList(queryField, fieldInfo, fields, fragments);
|
|
44
|
+
} else if (queryField.selectionSet) {
|
|
45
|
+
// Check for nested paginated lists
|
|
46
|
+
findNestedPaginatedLists(queryField, fieldInfo.type, fields, fragments);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return fields;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Utility type to get all valid paths into a type
|
|
55
|
+
export type PathTo<T> = T extends object
|
|
56
|
+
? {
|
|
57
|
+
[K in keyof T & (string | number)]: [K] | [K, ...PathTo<T[K]>];
|
|
58
|
+
}[keyof T & (string | number)]
|
|
59
|
+
: [];
|
|
36
60
|
|
|
37
|
-
|
|
61
|
+
/**
|
|
62
|
+
* @description
|
|
63
|
+
* This function is used to get the FieldInfo for the fields in the path of a DocumentNode.
|
|
64
|
+
*
|
|
65
|
+
* For example, in the following query:
|
|
66
|
+
*
|
|
67
|
+
* ```graphql
|
|
68
|
+
* query {
|
|
69
|
+
* product {
|
|
70
|
+
* id
|
|
71
|
+
* name
|
|
72
|
+
* variants {
|
|
73
|
+
* id
|
|
74
|
+
* name
|
|
75
|
+
* }
|
|
76
|
+
* }
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* The path `['product', 'variants']` will return the FieldInfo for the `variants` field,
|
|
81
|
+
* namely the `id` and `name` fields.
|
|
82
|
+
*/
|
|
83
|
+
export function getFieldsFromDocumentNode<
|
|
84
|
+
T extends TypedDocumentNode<any, any>,
|
|
85
|
+
P extends PathTo<ResultOf<T>>,
|
|
86
|
+
>(documentNode: T, path: P): FieldInfo[] {
|
|
87
|
+
const fragments = collectFragments(documentNode);
|
|
88
|
+
const operationDefinition = findQueryOperation(documentNode);
|
|
89
|
+
|
|
90
|
+
// Navigate to the target path
|
|
91
|
+
let currentSelections = operationDefinition.selectionSet.selections;
|
|
92
|
+
let currentType = 'Query';
|
|
93
|
+
|
|
94
|
+
for (let i = 0; i < path.length; i++) {
|
|
95
|
+
const pathSegment = path[i] as string;
|
|
96
|
+
const { fieldNode } = findFieldInSelections(
|
|
97
|
+
currentSelections,
|
|
98
|
+
pathSegment,
|
|
99
|
+
fragments,
|
|
100
|
+
path.slice(0, i + 1),
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
const fieldInfo = getObjectFieldInfo(currentType, pathSegment);
|
|
104
|
+
if (!fieldInfo) {
|
|
105
|
+
throw new Error(`Could not determine type for field "${pathSegment}"`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// If this is the last path segment, collect the fields
|
|
109
|
+
if (i === path.length - 1) {
|
|
110
|
+
return collectFieldsFromNode(fieldNode, fieldInfo.type, fragments);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Continue navigating deeper
|
|
114
|
+
if (!fieldNode.selectionSet) {
|
|
115
|
+
throw new Error(`Field "${pathSegment}" has no selection set but path continues`);
|
|
116
|
+
}
|
|
117
|
+
currentSelections = fieldNode.selectionSet.selections;
|
|
118
|
+
currentType = fieldInfo.type;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function collectFragments(documentNode: DocumentNode): Record<string, FragmentDefinitionNode> {
|
|
125
|
+
const fragments: Record<string, FragmentDefinitionNode> = {};
|
|
38
126
|
documentNode.definitions.forEach(def => {
|
|
39
127
|
if (def.kind === 'FragmentDefinition') {
|
|
40
128
|
fragments[def.name.value] = def;
|
|
41
129
|
}
|
|
42
130
|
});
|
|
131
|
+
return fragments;
|
|
132
|
+
}
|
|
43
133
|
|
|
134
|
+
function findQueryOperation(documentNode: DocumentNode): OperationDefinitionNode {
|
|
44
135
|
const operationDefinition = documentNode.definitions.find(
|
|
45
136
|
(def): def is OperationDefinitionNode =>
|
|
46
137
|
def.kind === 'OperationDefinition' && def.operation === 'query',
|
|
47
138
|
);
|
|
139
|
+
if (!operationDefinition) {
|
|
140
|
+
throw new Error('Could not find query operation definition');
|
|
141
|
+
}
|
|
142
|
+
return operationDefinition;
|
|
143
|
+
}
|
|
48
144
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
145
|
+
function findMutationOperation(documentNode: DocumentNode): OperationDefinitionNode {
|
|
146
|
+
const operationDefinition = documentNode.definitions.find(
|
|
147
|
+
(def): def is OperationDefinitionNode =>
|
|
148
|
+
def.kind === 'OperationDefinition' && def.operation === 'mutation',
|
|
149
|
+
);
|
|
150
|
+
if (!operationDefinition) {
|
|
151
|
+
throw new Error('Could not find mutation operation definition');
|
|
152
|
+
}
|
|
153
|
+
return operationDefinition;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function findFieldInSelections(
|
|
157
|
+
selections: readonly any[],
|
|
158
|
+
pathSegment: string,
|
|
159
|
+
fragments: Record<string, FragmentDefinitionNode>,
|
|
160
|
+
currentPath: string[] = [],
|
|
161
|
+
): { fieldNode: FieldNode; fragmentSelections: readonly any[] } {
|
|
162
|
+
for (const selection of selections) {
|
|
163
|
+
if (selection.kind === 'Field' && selection.name.value === pathSegment) {
|
|
164
|
+
return { fieldNode: selection, fragmentSelections: [] };
|
|
165
|
+
} else if (selection.kind === 'FragmentSpread') {
|
|
166
|
+
const fragment = fragments[selection.name.value];
|
|
167
|
+
if (fragment) {
|
|
168
|
+
const fragmentField = fragment.selectionSet.selections.find(
|
|
169
|
+
s => s.kind === 'Field' && s.name.value === pathSegment,
|
|
170
|
+
) as FieldNode;
|
|
171
|
+
if (fragmentField) {
|
|
172
|
+
return { fieldNode: fragmentField, fragmentSelections: fragment.selectionSet.selections };
|
|
173
|
+
}
|
|
58
174
|
}
|
|
59
175
|
}
|
|
60
176
|
}
|
|
177
|
+
const pathString = currentPath.join('.');
|
|
178
|
+
throw new Error(`Field "${pathSegment}" not found at path ${pathString}`);
|
|
179
|
+
}
|
|
61
180
|
|
|
181
|
+
function collectFieldsFromNode(
|
|
182
|
+
fieldNode: FieldNode,
|
|
183
|
+
typeName: string,
|
|
184
|
+
fragments: Record<string, FragmentDefinitionNode>,
|
|
185
|
+
): FieldInfo[] {
|
|
186
|
+
const fields: FieldInfo[] = [];
|
|
187
|
+
if (fieldNode.selectionSet) {
|
|
188
|
+
for (const selection of fieldNode.selectionSet.selections) {
|
|
189
|
+
if (selection.kind === 'Field' || selection.kind === 'FragmentSpread') {
|
|
190
|
+
collectFields(typeName, selection, fields, fragments);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
62
194
|
return fields;
|
|
63
195
|
}
|
|
64
196
|
|
|
@@ -199,6 +331,20 @@ function unwrapVariableDefinitionType(type: TypeNode): NamedTypeNode {
|
|
|
199
331
|
return type;
|
|
200
332
|
}
|
|
201
333
|
|
|
334
|
+
/**
|
|
335
|
+
* @description
|
|
336
|
+
* Helper function to get the first field selection from a query operation definition.
|
|
337
|
+
*/
|
|
338
|
+
function getFirstQueryField(documentNode: DocumentNode): FieldNode {
|
|
339
|
+
const operationDefinition = findQueryOperation(documentNode);
|
|
340
|
+
const firstSelection = operationDefinition.selectionSet.selections[0];
|
|
341
|
+
if (firstSelection?.kind === 'Field') {
|
|
342
|
+
return firstSelection;
|
|
343
|
+
} else {
|
|
344
|
+
throw new Error('Could not determine query field');
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
202
348
|
/**
|
|
203
349
|
* @description
|
|
204
350
|
* This function is used to get the name of the query from a DocumentNode.
|
|
@@ -216,16 +362,32 @@ function unwrapVariableDefinitionType(type: TypeNode): NamedTypeNode {
|
|
|
216
362
|
* The query name is `product`.
|
|
217
363
|
*/
|
|
218
364
|
export function getQueryName(documentNode: DocumentNode): string {
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
365
|
+
const firstField = getFirstQueryField(documentNode);
|
|
366
|
+
return firstField.name.value;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* @description
|
|
371
|
+
* This function is used to get the entity name from a DocumentNode.
|
|
372
|
+
*
|
|
373
|
+
* For example, in the following query:
|
|
374
|
+
*
|
|
375
|
+
* ```graphql
|
|
376
|
+
* query ProductDetail($id: ID!) {
|
|
377
|
+
* product(id: $id) {
|
|
378
|
+
* ...ProductDetail
|
|
379
|
+
* }
|
|
380
|
+
* }
|
|
381
|
+
* ```
|
|
382
|
+
*
|
|
383
|
+
* The entity name is `Product`.
|
|
384
|
+
*/
|
|
385
|
+
export function getEntityName(documentNode: DocumentNode): string {
|
|
386
|
+
const firstField = getFirstQueryField(documentNode);
|
|
387
|
+
// Get the return type from the field definition
|
|
388
|
+
const fieldName = firstField.name.value;
|
|
389
|
+
const queryInfo = getQueryInfo(fieldName);
|
|
390
|
+
return queryInfo.type;
|
|
229
391
|
}
|
|
230
392
|
|
|
231
393
|
/**
|
|
@@ -272,15 +434,7 @@ export function getObjectPathToPaginatedList(
|
|
|
272
434
|
documentNode: DocumentNode,
|
|
273
435
|
currentPath: string[] = [],
|
|
274
436
|
): string[] {
|
|
275
|
-
|
|
276
|
-
const operationDefinition = documentNode.definitions.find(
|
|
277
|
-
(def): def is OperationDefinitionNode =>
|
|
278
|
-
def.kind === 'OperationDefinition' && def.operation === 'query',
|
|
279
|
-
);
|
|
280
|
-
if (!operationDefinition) {
|
|
281
|
-
throw new Error('Could not find query operation definition');
|
|
282
|
-
}
|
|
283
|
-
|
|
437
|
+
const operationDefinition = findQueryOperation(documentNode);
|
|
284
438
|
return findPaginatedListPath(operationDefinition.selectionSet, 'Query', currentPath);
|
|
285
439
|
}
|
|
286
440
|
|
|
@@ -332,11 +486,8 @@ function findPaginatedListPath(
|
|
|
332
486
|
* The mutation name is `createProduct`.
|
|
333
487
|
*/
|
|
334
488
|
export function getMutationName(documentNode: DocumentNode): string {
|
|
335
|
-
const operationDefinition = documentNode
|
|
336
|
-
|
|
337
|
-
def.kind === 'OperationDefinition' && def.operation === 'mutation',
|
|
338
|
-
);
|
|
339
|
-
const firstSelection = operationDefinition?.selectionSet.selections[0];
|
|
489
|
+
const operationDefinition = findMutationOperation(documentNode);
|
|
490
|
+
const firstSelection = operationDefinition.selectionSet.selections[0];
|
|
340
491
|
if (firstSelection?.kind === 'Field') {
|
|
341
492
|
return firstSelection.name.value;
|
|
342
493
|
} else {
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
FieldInfo,
|
|
3
|
+
getListQueryFields,
|
|
4
|
+
} from '@/vdb/framework/document-introspection/get-document-structure.js';
|
|
2
5
|
import { DocumentNode } from 'graphql';
|
|
3
6
|
import { useMemo } from 'react';
|
|
4
7
|
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import { registerDashboardWidget } from '../dashboard-widget/widget-extensions.js';
|
|
2
|
-
import {
|
|
3
|
-
registerDashboardActionBarItem,
|
|
4
|
-
registerDashboardPageBlock,
|
|
5
|
-
} from '../layout-engine/layout-extensions.js';
|
|
6
|
-
import { addNavMenuItem, addNavMenuSection, NavMenuItem } from '../nav-menu/nav-menu-extensions.js';
|
|
7
|
-
import { registerRoute } from '../page/page-api.js';
|
|
8
1
|
import { globalRegistry } from '../registry/global-registry.js';
|
|
9
2
|
|
|
10
3
|
import { DashboardExtension } from './extension-api-types.js';
|
|
4
|
+
import {
|
|
5
|
+
registerAlertExtensions,
|
|
6
|
+
registerDataTableExtensions,
|
|
7
|
+
registerDetailFormExtensions,
|
|
8
|
+
registerFormComponentExtensions,
|
|
9
|
+
registerLayoutExtensions,
|
|
10
|
+
registerLoginExtensions,
|
|
11
|
+
registerNavigationExtensions,
|
|
12
|
+
registerWidgetExtensions,
|
|
13
|
+
} from './logic/index.js';
|
|
11
14
|
|
|
12
15
|
globalRegistry.register('extensionSourceChangeCallbacks', new Set<() => void>());
|
|
13
16
|
globalRegistry.register('registerDashboardExtensionCallbacks', new Set<() => void>());
|
|
@@ -34,48 +37,31 @@ export function executeDashboardExtensionCallbacks() {
|
|
|
34
37
|
*/
|
|
35
38
|
export function defineDashboardExtension(extension: DashboardExtension) {
|
|
36
39
|
globalRegistry.get('registerDashboardExtensionCallbacks').add(() => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
if (extension.actionBarItems) {
|
|
65
|
-
for (const item of extension.actionBarItems) {
|
|
66
|
-
registerDashboardActionBarItem(item);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
if (extension.pageBlocks) {
|
|
70
|
-
for (const block of extension.pageBlocks) {
|
|
71
|
-
registerDashboardPageBlock(block);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
if (extension.widgets) {
|
|
75
|
-
for (const widget of extension.widgets) {
|
|
76
|
-
registerDashboardWidget(widget);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
40
|
+
// Register navigation extensions (nav sections and routes)
|
|
41
|
+
registerNavigationExtensions(extension.navSections, extension.routes);
|
|
42
|
+
|
|
43
|
+
// Register layout extensions (action bar items and page blocks)
|
|
44
|
+
registerLayoutExtensions(extension.actionBarItems, extension.pageBlocks);
|
|
45
|
+
|
|
46
|
+
// Register widget extensions
|
|
47
|
+
registerWidgetExtensions(extension.widgets);
|
|
48
|
+
|
|
49
|
+
// Register form component extensions (custom form components, input components, and display components)
|
|
50
|
+
registerFormComponentExtensions(extension.customFormComponents);
|
|
51
|
+
|
|
52
|
+
// Register data table extensions
|
|
53
|
+
registerDataTableExtensions(extension.dataTables);
|
|
54
|
+
|
|
55
|
+
// Register detail form extensions
|
|
56
|
+
registerDetailFormExtensions(extension.detailForms);
|
|
57
|
+
|
|
58
|
+
// Register alert extensions
|
|
59
|
+
registerAlertExtensions(extension.alerts);
|
|
60
|
+
|
|
61
|
+
// Register login extensions
|
|
62
|
+
registerLoginExtensions(extension.login);
|
|
63
|
+
|
|
64
|
+
// Execute extension source change callbacks
|
|
79
65
|
const callbacks = globalRegistry.get('extensionSourceChangeCallbacks');
|
|
80
66
|
if (callbacks.size) {
|
|
81
67
|
for (const callback of callbacks) {
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { BooleanDisplayBadge, BooleanDisplayCheckbox } from '@/vdb/components/data-display/boolean.js';
|
|
2
|
+
import { DateTime } from '@/vdb/components/data-display/date-time.js';
|
|
3
|
+
import { Money } from '@/vdb/components/data-display/money.js';
|
|
4
|
+
import { VendureImage } from '@/vdb/components/shared/vendure-image.js';
|
|
5
|
+
import { DataDisplayComponent } from '../component-registry/component-registry.js';
|
|
6
|
+
import { globalRegistry } from '../registry/global-registry.js';
|
|
7
|
+
|
|
8
|
+
globalRegistry.register('displayComponents', new Map<string, DataDisplayComponent>());
|
|
9
|
+
|
|
10
|
+
// Create component function for asset display
|
|
11
|
+
const AssetDisplay: DataDisplayComponent = ({ value }) => <VendureImage asset={value} preset="tiny" />;
|
|
12
|
+
|
|
13
|
+
// Register built-in display components
|
|
14
|
+
const displayComponents = globalRegistry.get('displayComponents');
|
|
15
|
+
displayComponents.set('vendure:booleanCheckbox', BooleanDisplayCheckbox);
|
|
16
|
+
displayComponents.set('vendure:booleanBadge', BooleanDisplayBadge);
|
|
17
|
+
displayComponents.set('vendure:dateTime', DateTime);
|
|
18
|
+
displayComponents.set('vendure:asset', AssetDisplay);
|
|
19
|
+
displayComponents.set('vendure:money', Money);
|
|
20
|
+
|
|
21
|
+
export function getDisplayComponent(id: string): DataDisplayComponent | undefined {
|
|
22
|
+
return globalRegistry.get('displayComponents').get(id);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @description
|
|
27
|
+
* Gets a display component using the targeting properties.
|
|
28
|
+
* Uses the same key pattern as registration: pageId_blockId_fieldName
|
|
29
|
+
*/
|
|
30
|
+
export function getTargetedDisplayComponent(
|
|
31
|
+
pageId: string,
|
|
32
|
+
blockId: string,
|
|
33
|
+
field: string,
|
|
34
|
+
): DataDisplayComponent | undefined {
|
|
35
|
+
const key = generateDisplayComponentKey(pageId, blockId, field);
|
|
36
|
+
return globalRegistry.get('displayComponents').get(key);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @description
|
|
41
|
+
* Generates a display component key based on the targeting properties.
|
|
42
|
+
* Follows the existing pattern: pageId_blockId_fieldName
|
|
43
|
+
*/
|
|
44
|
+
export function generateDisplayComponentKey(pageId: string, blockId: string, field: string): string {
|
|
45
|
+
return `${pageId}_${blockId}_${field}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function addDisplayComponent({
|
|
49
|
+
pageId,
|
|
50
|
+
blockId,
|
|
51
|
+
field,
|
|
52
|
+
component,
|
|
53
|
+
}: {
|
|
54
|
+
pageId: string;
|
|
55
|
+
blockId: string;
|
|
56
|
+
field: string;
|
|
57
|
+
component: React.ComponentType<{ value: any; [key: string]: any }>;
|
|
58
|
+
}) {
|
|
59
|
+
const displayComponents = globalRegistry.get('displayComponents');
|
|
60
|
+
|
|
61
|
+
// Generate the key using the helper function
|
|
62
|
+
const key = generateDisplayComponentKey(pageId, blockId, field);
|
|
63
|
+
|
|
64
|
+
if (displayComponents.has(key)) {
|
|
65
|
+
// eslint-disable-next-line no-console
|
|
66
|
+
console.warn(`Display component with key "${key}" is already registered and will be overwritten.`);
|
|
67
|
+
}
|
|
68
|
+
displayComponents.set(key, component);
|
|
69
|
+
}
|
|
@@ -1,100 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
loader?: RouteOptions['loader'];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface ActionBarButtonState {
|
|
18
|
-
disabled: boolean;
|
|
19
|
-
visible: boolean;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface DashboardNavSectionDefinition {
|
|
23
|
-
id: string;
|
|
24
|
-
title: string;
|
|
25
|
-
icon?: LucideIcon;
|
|
26
|
-
order?: number;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* @description
|
|
31
|
-
* **Status: Developer Preview**
|
|
32
|
-
*
|
|
33
|
-
* Allows you to define custom action bar items for any page in the dashboard.
|
|
34
|
-
*
|
|
35
|
-
* @docsCategory extensions
|
|
36
|
-
* @since 3.3.0
|
|
37
|
-
*/
|
|
38
|
-
export interface DashboardActionBarItem {
|
|
39
|
-
/**
|
|
40
|
-
* @description
|
|
41
|
-
* The ID of the page where the action bar item should be displayed.
|
|
42
|
-
*/
|
|
43
|
-
pageId: string;
|
|
44
|
-
/**
|
|
45
|
-
* @description
|
|
46
|
-
* A React component that will be rendered in the action bar.
|
|
47
|
-
*/
|
|
48
|
-
component: React.FunctionComponent<{ context: PageContextValue }>;
|
|
49
|
-
/**
|
|
50
|
-
* @description
|
|
51
|
-
* Any permissions that are required to display this action bar item.
|
|
52
|
-
*/
|
|
53
|
-
requiresPermission?: string | string[];
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export interface DashboardActionBarDropdownMenuItem {
|
|
57
|
-
locationId: string;
|
|
58
|
-
component: React.FunctionComponent<{ context: PageContextValue }>;
|
|
59
|
-
requiresPermission?: string | string[];
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export type PageBlockPosition = { blockId: string; order: 'before' | 'after' | 'replace' };
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* @description
|
|
66
|
-
* **Status: Developer Preview**
|
|
67
|
-
*
|
|
68
|
-
* The location of a page block in the dashboard. The location can be found by turning on
|
|
69
|
-
* "developer mode" in the dashboard user menu (bottom left corner) and then
|
|
70
|
-
* clicking the `< />` icon when hovering over a page block.
|
|
71
|
-
*
|
|
72
|
-
* @docsCategory extensions
|
|
73
|
-
* @since 3.3.0
|
|
74
|
-
*/
|
|
75
|
-
export type PageBlockLocation = {
|
|
76
|
-
pageId: string;
|
|
77
|
-
position: PageBlockPosition;
|
|
78
|
-
column: 'main' | 'side';
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* @description
|
|
83
|
-
* **Status: Developer Preview**
|
|
84
|
-
*
|
|
85
|
-
* This allows you to insert a custom component into a specific location
|
|
86
|
-
* on any page in the dashboard.
|
|
87
|
-
*
|
|
88
|
-
* @docsCategory extensions
|
|
89
|
-
* @since 3.3.0
|
|
90
|
-
*/
|
|
91
|
-
export interface DashboardPageBlockDefinition {
|
|
92
|
-
id: string;
|
|
93
|
-
title?: React.ReactNode;
|
|
94
|
-
location: PageBlockLocation;
|
|
95
|
-
component: React.FunctionComponent<{ context: PageContextValue }>;
|
|
96
|
-
requiresPermission?: string | string[];
|
|
97
|
-
}
|
|
1
|
+
// Import types for the main interface
|
|
2
|
+
import {
|
|
3
|
+
DashboardActionBarItem,
|
|
4
|
+
DashboardAlertDefinition,
|
|
5
|
+
DashboardCustomFormComponents,
|
|
6
|
+
DashboardDataTableExtensionDefinition,
|
|
7
|
+
DashboardDetailFormExtensionDefinition,
|
|
8
|
+
DashboardLoginExtensions,
|
|
9
|
+
DashboardNavSectionDefinition,
|
|
10
|
+
DashboardPageBlockDefinition,
|
|
11
|
+
DashboardRouteDefinition,
|
|
12
|
+
DashboardWidgetDefinition,
|
|
13
|
+
} from './types/index.js';
|
|
98
14
|
|
|
99
15
|
/**
|
|
100
16
|
* @description
|
|
@@ -128,7 +44,7 @@ export interface DashboardExtension {
|
|
|
128
44
|
actionBarItems?: DashboardActionBarItem[];
|
|
129
45
|
/**
|
|
130
46
|
* @description
|
|
131
|
-
*
|
|
47
|
+
* Allows you to define custom alerts that can be displayed in the dashboard.
|
|
132
48
|
*/
|
|
133
49
|
alerts?: DashboardAlertDefinition[];
|
|
134
50
|
/**
|
|
@@ -137,4 +53,24 @@ export interface DashboardExtension {
|
|
|
137
53
|
* given components and optionally also add a nav menu item.
|
|
138
54
|
*/
|
|
139
55
|
widgets?: DashboardWidgetDefinition[];
|
|
56
|
+
/**
|
|
57
|
+
* @description
|
|
58
|
+
* Unified registration for custom form custom field components.
|
|
59
|
+
*/
|
|
60
|
+
customFormComponents?: DashboardCustomFormComponents;
|
|
61
|
+
/**
|
|
62
|
+
* @description
|
|
63
|
+
* Allows you to customize aspects of existing data tables in the dashboard.
|
|
64
|
+
*/
|
|
65
|
+
dataTables?: DashboardDataTableExtensionDefinition[];
|
|
66
|
+
/**
|
|
67
|
+
* @description
|
|
68
|
+
* Allows you to customize the detail form for any page in the dashboard.
|
|
69
|
+
*/
|
|
70
|
+
detailForms?: DashboardDetailFormExtensionDefinition[];
|
|
71
|
+
/**
|
|
72
|
+
* @description
|
|
73
|
+
* Allows you to customize the login page with custom components.
|
|
74
|
+
*/
|
|
75
|
+
login?: DashboardLoginExtensions;
|
|
140
76
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { CombinationModeInput } from '@/vdb/components/data-input/combination-mode-input.js';
|
|
2
|
+
import { DateTimeInput } from '@/vdb/components/data-input/datetime-input.js';
|
|
3
|
+
import { FacetValueInput } from '@/vdb/components/data-input/facet-value-input.js';
|
|
4
|
+
import { MoneyInput } from '@/vdb/components/data-input/money-input.js';
|
|
5
|
+
import { ProductMultiInput } from '@/vdb/components/data-input/product-multi-selector.js';
|
|
6
|
+
import { Checkbox } from '@/vdb/components/ui/checkbox.js';
|
|
7
|
+
import { Input } from '@/vdb/components/ui/input.js';
|
|
8
|
+
import { DataInputComponent } from '../component-registry/component-registry.js';
|
|
9
|
+
import { globalRegistry } from '../registry/global-registry.js';
|
|
10
|
+
|
|
11
|
+
globalRegistry.register('inputComponents', new Map<string, DataInputComponent>());
|
|
12
|
+
|
|
13
|
+
// Create component functions for built-in components
|
|
14
|
+
const TextInput: DataInputComponent = props => (
|
|
15
|
+
<Input {...props} onChange={e => props.onChange(e.target.value)} />
|
|
16
|
+
);
|
|
17
|
+
const NumberInput: DataInputComponent = props => (
|
|
18
|
+
<Input {...props} onChange={e => props.onChange(e.target.valueAsNumber)} type="number" />
|
|
19
|
+
);
|
|
20
|
+
const CheckboxInput: DataInputComponent = props => (
|
|
21
|
+
<Checkbox
|
|
22
|
+
{...props}
|
|
23
|
+
checked={props.value === 'true' || props.value === true}
|
|
24
|
+
onCheckedChange={value => props.onChange(value)}
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
// Register built-in input components
|
|
29
|
+
const inputComponents = globalRegistry.get('inputComponents');
|
|
30
|
+
inputComponents.set('vendure:moneyInput', MoneyInput);
|
|
31
|
+
inputComponents.set('vendure:textInput', TextInput);
|
|
32
|
+
inputComponents.set('vendure:numberInput', NumberInput);
|
|
33
|
+
inputComponents.set('vendure:dateTimeInput', DateTimeInput);
|
|
34
|
+
inputComponents.set('vendure:checkboxInput', CheckboxInput);
|
|
35
|
+
inputComponents.set('vendure:facetValueInput', FacetValueInput);
|
|
36
|
+
inputComponents.set('vendure:combinationModeInput', CombinationModeInput);
|
|
37
|
+
inputComponents.set('vendure:productMultiInput', ProductMultiInput);
|
|
38
|
+
|
|
39
|
+
export function getInputComponent(id: string): DataInputComponent | undefined {
|
|
40
|
+
return globalRegistry.get('inputComponents').get(id);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @description
|
|
45
|
+
* Generates a component key based on the targeting properties.
|
|
46
|
+
* Follows the existing pattern: pageId_blockId_fieldName
|
|
47
|
+
*/
|
|
48
|
+
export function generateInputComponentKey(pageId: string, blockId: string, field: string): string {
|
|
49
|
+
return `${pageId}_${blockId}_${field}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function addInputComponent({
|
|
53
|
+
pageId,
|
|
54
|
+
blockId,
|
|
55
|
+
field,
|
|
56
|
+
component,
|
|
57
|
+
}: {
|
|
58
|
+
pageId: string;
|
|
59
|
+
blockId: string;
|
|
60
|
+
field: string;
|
|
61
|
+
component: DataInputComponent;
|
|
62
|
+
}) {
|
|
63
|
+
const inputComponents = globalRegistry.get('inputComponents');
|
|
64
|
+
|
|
65
|
+
// Generate the key using the helper function
|
|
66
|
+
const key = generateInputComponentKey(pageId, blockId, field);
|
|
67
|
+
|
|
68
|
+
if (inputComponents.has(key)) {
|
|
69
|
+
// eslint-disable-next-line no-console
|
|
70
|
+
console.warn(`Input component with key "${key}" is already registered and will be overwritten.`);
|
|
71
|
+
}
|
|
72
|
+
inputComponents.set(key, component);
|
|
73
|
+
}
|