@hartl-services/medusa-base 2.4.0 → 2.6.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/.medusa/server/src/admin/admin-components/features/plugin-features/components/ImageSettingInput.js +48 -0
- package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginActionsSection.js +3 -2
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginFeaturesSettingsPage.js +17 -0
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginPageShell.js +20 -0
- package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginSettingsForm.js +16 -3
- package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/hooks/usePluginFeatureEnabled.d.ts +5 -1
- package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/hooks/usePluginFeatures.d.ts +20 -4
- package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/hooks/usePluginFeatures.js +1 -1
- package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/hooks/usePluginSettingsForm.d.ts +5 -1
- package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/lib/action-runs.d.ts +1 -1
- package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/lib/action-runs.js +3 -2
- package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/lib/plugin-features-admin-client.d.ts +20 -4
- package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/lib/plugin-features-admin-client.js +1 -1
- package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/lib/settings-draft.d.ts +17 -2
- package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/lib/settings-draft.js +33 -1
- package/{dist → .medusa/server/src/admin}/admin-components/i18n/texts.d.ts +3 -0
- package/{dist → .medusa/server/src/admin}/admin-components/i18n/texts.js +3 -0
- package/.medusa/server/src/admin/admin-components/index.d.ts +36 -0
- package/.medusa/server/src/admin/admin-components/index.js +37 -0
- package/.medusa/server/src/admin/admin-components/shared/lib/date-input.d.ts +8 -0
- package/.medusa/server/src/admin/admin-components/shared/lib/date-input.js +43 -0
- package/.medusa/server/src/admin/admin-components/shared/lib/errors.d.ts +9 -0
- package/{dist/admin-components → .medusa/server/src/admin/admin-components/shared}/lib/errors.js +4 -6
- package/.medusa/server/src/admin/admin-components/shared/lib/file-validation.d.ts +24 -0
- package/.medusa/server/src/admin/admin-components/shared/lib/file-validation.js +18 -0
- package/.medusa/server/src/admin/admin-components/shared/lib/format.d.ts +32 -0
- package/.medusa/server/src/admin/admin-components/shared/lib/format.js +77 -0
- package/.medusa/server/src/admin/admin-components/shared/lib/pdf-preview.d.ts +16 -0
- package/.medusa/server/src/admin/admin-components/shared/lib/pdf-preview.js +31 -0
- package/.medusa/server/src/admin/admin-components/shared/lib/pdf.d.ts +6 -0
- package/.medusa/server/src/admin/admin-components/shared/lib/pdf.js +13 -0
- package/.medusa/server/src/admin/admin-components/shared/lib/use-debounced-value.d.ts +2 -0
- package/.medusa/server/src/admin/admin-components/shared/lib/use-debounced-value.js +10 -0
- package/.medusa/server/src/admin/admin-components/shared/lib/use-pdf-preview.d.ts +24 -0
- package/.medusa/server/src/admin/admin-components/shared/lib/use-pdf-preview.js +47 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/AdminDatePicker.d.ts +8 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/AdminDatePicker.js +9 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/BackLink.d.ts +8 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/BackLink.js +5 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/DateRangeFilter.d.ts +20 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/DateRangeFilter.js +17 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/FilePickerButton.d.ts +14 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/FilePickerButton.js +14 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/MappedStatusBadge.d.ts +17 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/MappedStatusBadge.js +12 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/OffsetTablePagination.d.ts +15 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/OffsetTablePagination.js +19 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/PdfPreviewModal.d.ts +20 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/PdfPreviewModal.js +7 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/PluginFeatureRoute.d.ts +19 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/PluginFeatureRoute.js +16 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/QueryState.d.ts +24 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/QueryState.js +23 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/SearchableReferenceField.d.ts +63 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/SearchableReferenceField.js +84 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/SectionHeader.d.ts +15 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/SectionHeader.js +13 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/mapped-status.d.ts +6 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/mapped-status.js +10 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/offset-pagination.d.ts +17 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/offset-pagination.js +15 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/reference-results-state.d.ts +16 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/reference-results-state.js +13 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/InsertMenu.d.ts +8 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/InsertMenu.js +10 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/LinkPrompt.d.ts +14 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/LinkPrompt.js +26 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/RichTextEditor.d.ts +15 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/RichTextEditor.js +8 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/RichTextToolbar.d.ts +10 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/RichTextToolbar.js +49 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/SlashMenu.d.ts +11 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/SlashMenu.js +44 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/build-extensions.d.ts +8 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/build-extensions.js +43 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/drag-handle.d.ts +15 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/drag-handle.js +161 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/drag-target.d.ts +30 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/drag-target.js +47 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/editor-styles.d.ts +6 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/editor-styles.js +46 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/index.d.ts +9 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/index.js +6 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/link-href.d.ts +8 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/link-href.js +21 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/link-policy.d.ts +13 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/link-policy.js +20 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/slash-command.d.ts +13 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/slash-command.js +60 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/slash-items.d.ts +25 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/slash-items.js +10 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/tiptap.d.ts +7 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/tiptap.js +7 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/use-rich-text-editor.d.ts +44 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/use-rich-text-editor.js +37 -0
- package/.medusa/server/src/admin/index.js +4513 -1447
- package/.medusa/server/src/admin/index.mjs +4515 -1452
- package/.medusa/server/src/api/admin/email/attachments/[id]/mail-kinds/route.js +16 -0
- package/.medusa/server/src/api/admin/email/attachments/[id]/route.js +15 -0
- package/.medusa/server/src/api/admin/email/attachments/[id]/versions/[version_id]/download/route.js +16 -0
- package/.medusa/server/src/api/admin/email/attachments/[id]/versions/route.js +41 -0
- package/.medusa/server/src/api/admin/email/attachments/route.js +21 -0
- package/.medusa/server/src/api/admin/email/templates/[kind]/preview/route.js +31 -0
- package/.medusa/server/src/api/admin/email/templates/[kind]/route.js +28 -0
- package/.medusa/server/src/api/admin/email/templates/[kind]/send-test/route.js +179 -0
- package/.medusa/server/src/api/admin/email/templates/[kind]/test-sources/route.js +19 -0
- package/.medusa/server/src/api/admin/email/templates/route.js +15 -0
- package/.medusa/server/src/api/admin/plugin-features/[plugin_key]/actions/[action_key]/route.js +2 -2
- package/.medusa/server/src/api/admin/plugin-features/[plugin_key]/actions/[action_key]/runs/route.js +2 -2
- package/.medusa/server/src/api/admin/plugin-features/[plugin_key]/route.js +2 -2
- package/.medusa/server/src/api/admin/plugin-features/[plugin_key]/settings/route.js +2 -2
- package/.medusa/server/src/api/admin/plugin-features/route.js +2 -2
- package/.medusa/server/src/api/attachment-download-response.js +12 -0
- package/.medusa/server/src/api/email-template-response.js +43 -0
- package/.medusa/server/src/api/middlewares.js +75 -17
- package/.medusa/server/src/api/plugin-actions.js +6 -5
- package/.medusa/server/src/api/plugin-features-http.js +4 -9
- package/.medusa/server/src/api/store/carts/[id]/completion-check/route.js +15 -0
- package/.medusa/server/src/api/store/plugin-features/[plugin_key]/route.js +2 -2
- package/.medusa/server/src/api/store/plugin-features/route.js +2 -2
- package/.medusa/server/src/documents/plugin-features.js +1 -7
- package/.medusa/server/src/documents/templates/financial-document.js +12 -11
- package/.medusa/server/src/documents/templates/html-factory.js +1 -1
- package/.medusa/server/src/documents/templates/html-utils.js +4 -10
- package/.medusa/server/src/documents/templates/layout.js +30 -11
- package/.medusa/server/src/documents/templates/packing-list.js +8 -7
- package/.medusa/server/src/documents/utils/document-render-settings.js +9 -6
- package/.medusa/server/src/email/application/handle-customer-verification-event.js +8 -3
- package/.medusa/server/src/email/application/handle-invite-event.js +8 -3
- package/.medusa/server/src/email/application/handle-password-reset-event.js +8 -3
- package/.medusa/server/src/email/application/notification-attachments.js +86 -0
- package/.medusa/server/src/email/application/template-data-from-order.js +339 -0
- package/.medusa/server/src/email/config/index.js +5 -29
- package/.medusa/server/src/email/domain/business-keys.js +5 -5
- package/.medusa/server/src/email/domain/documents-fact-fingerprint.js +3 -3
- package/.medusa/server/src/email/domain/order-summary.js +21 -27
- package/.medusa/server/src/email/domain/refund-summary.js +7 -12
- package/.medusa/server/src/email/domain/return-summary.js +32 -38
- package/.medusa/server/src/email/domain/shipment-summary.js +22 -28
- package/.medusa/server/src/email/plugin-features.js +2 -10
- package/.medusa/server/src/email/rendering/calendar-dates.js +19 -0
- package/.medusa/server/src/email/rendering/default-templates.js +99 -682
- package/.medusa/server/src/email/rendering/email-html.js +189 -0
- package/.medusa/server/src/email/rendering/load-email-shop-details.js +14 -12
- package/.medusa/server/src/email/rendering/render-email.js +46 -13
- package/.medusa/server/src/email/rendering/resolve-shop-configuration.js +3 -14
- package/.medusa/server/src/email/templates/blocks/dynamic-blocks.js +427 -0
- package/.medusa/server/src/email/templates/blocks/placeholders.js +71 -0
- package/.medusa/server/src/email/templates/blocks/render-document.js +137 -0
- package/.medusa/server/src/email/templates/code-override.js +18 -0
- package/.medusa/server/src/email/templates/defaults/documents.js +129 -0
- package/.medusa/server/src/email/templates/defaults/subjects.js +62 -0
- package/.medusa/server/src/email/templates/defaults/texts.js +42 -0
- package/.medusa/server/src/email/templates/index.js +22 -0
- package/.medusa/server/src/email/templates/load-template.js +39 -0
- package/.medusa/server/src/email/templates/preview.js +33 -0
- package/.medusa/server/src/email/templates/render.js +70 -0
- package/.medusa/server/src/email/templates/sample-data.js +165 -0
- package/.medusa/server/src/email/templates/types.js +3 -0
- package/.medusa/server/src/email/templates/validate.js +113 -0
- package/.medusa/server/src/files/config/index.js +6 -9
- package/.medusa/server/src/migration-scripts/move-logo-to-shop-appearance.js +53 -0
- package/.medusa/server/src/modules/documents/domain/cancellation-snapshot.js +4 -3
- package/.medusa/server/src/modules/documents/domain/merchant.js +4 -3
- package/.medusa/server/src/modules/documents/domain/options.js +3 -5
- package/.medusa/server/src/modules/documents/domain/tax-breakdown.js +4 -7
- package/.medusa/server/src/modules/documents/service.js +12 -33
- package/.medusa/server/src/modules/email/domain/attachment.js +22 -8
- package/.medusa/server/src/modules/email/migrations/Migration20261009083539.js +80 -0
- package/.medusa/server/src/modules/email/migrations/Migration20261009100654.js +17 -0
- package/.medusa/server/src/modules/email/models/email-attachment-document-version.js +39 -0
- package/.medusa/server/src/modules/email/models/email-attachment-document.js +27 -0
- package/.medusa/server/src/modules/email/models/email-template.js +25 -0
- package/.medusa/server/src/modules/email/service.js +370 -93
- package/.medusa/server/src/modules/plugin-features/domain/plugin-settings.js +9 -11
- package/.medusa/server/src/modules/plugin-features/service.js +2 -1
- package/.medusa/server/src/providers/s3-cache/cache/cache-manager.js +3 -3
- package/.medusa/server/src/providers/s3-cache/s3-object-store.js +3 -9
- package/.medusa/server/src/providers/smtp/service.js +13 -13
- package/.medusa/server/src/public/descriptor.js +16 -18
- package/.medusa/server/src/public/enforcement.js +29 -1
- package/.medusa/server/src/public/index.js +8 -2
- package/.medusa/server/src/public/module-access.js +9 -2
- package/.medusa/server/src/public/shop-master-data.js +109 -18
- package/.medusa/server/src/shared/lib/coerce.js +26 -0
- package/.medusa/server/src/shared/lib/collections.js +19 -0
- package/.medusa/server/src/shared/lib/dates.js +43 -0
- package/.medusa/server/src/shared/lib/errors.js +11 -0
- package/.medusa/server/src/shared/lib/hash.js +8 -0
- package/.medusa/server/src/shared/lib/index.js +29 -0
- package/.medusa/server/src/shared/lib/logging.js +61 -0
- package/.medusa/server/src/shared/lib/money.js +47 -0
- package/.medusa/server/src/shared/lib/text.js +53 -0
- package/.medusa/server/src/shared/lib/transaction.js +58 -0
- package/.medusa/server/src/{api → shared/lib}/wire-response.js +1 -1
- package/.medusa/server/src/shop-config/options.js +3 -5
- package/.medusa/server/src/subscribers/packing-list-fulfillment-canceled.js +4 -6
- package/.medusa/server/src/workflows/documents/issue-invoice-after-shipment.js +10 -12
- package/.medusa/server/src/workflows/documents/issue-packing-list.js +5 -6
- package/.medusa/server/src/workflows/documents/reconcile-order-cancellation.js +6 -8
- package/.medusa/server/src/workflows/email/dispatch-email-message.js +11 -41
- package/.medusa/server/src/workflows/email/prepare-order-received-email.js +2 -2
- package/.medusa/server/src/workflows/hooks/check-cart-completion.js +32 -0
- package/.medusa/server/src/workflows/hooks/complete-cart-fields.js +30 -0
- package/.medusa/server/src/workflows/hooks/complete-cart-participants.js +4 -8
- package/.medusa/server/src/workflows/hooks/complete-cart.js +6 -2
- package/.medusa/server/src/workflows/hooks/refunded-cart-payment.js +23 -0
- package/README.md +446 -54
- package/dist/documents/templates/financial-document.js +11 -10
- package/dist/documents/templates/html-factory.d.ts +1 -1
- package/dist/documents/templates/html-factory.js +1 -1
- package/dist/documents/templates/html-utils.d.ts +0 -1
- package/dist/documents/templates/html-utils.js +3 -9
- package/dist/documents/templates/layout.js +29 -10
- package/dist/documents/templates/packing-list.js +7 -6
- package/dist/documents/types/documents.d.ts +7 -1
- package/dist/email/config/index.js +4 -28
- package/dist/email/types/shop-configuration.d.ts +6 -5
- package/dist/files/config/index.js +5 -8
- package/dist/modules/documents/domain/options.js +2 -4
- package/dist/public/descriptor.js +15 -17
- package/dist/public/enforcement.d.ts +21 -1
- package/dist/public/enforcement.js +28 -0
- package/dist/public/index.d.ts +3 -2
- package/dist/public/index.js +7 -1
- package/dist/public/module-access.d.ts +8 -0
- package/dist/public/module-access.js +8 -1
- package/dist/public/shop-master-data.d.ts +22 -5
- package/dist/public/shop-master-data.js +108 -17
- package/dist/public/types.d.ts +10 -2
- package/dist/shared/lib/coerce.d.ts +19 -0
- package/dist/shared/lib/coerce.js +25 -0
- package/dist/shared/lib/collections.d.ts +3 -0
- package/dist/shared/lib/collections.js +18 -0
- package/dist/shared/lib/dates.d.ts +12 -0
- package/dist/shared/lib/dates.js +42 -0
- package/dist/shared/lib/errors.d.ts +2 -0
- package/dist/shared/lib/errors.js +10 -0
- package/dist/shared/lib/hash.d.ts +2 -0
- package/dist/shared/lib/hash.js +7 -0
- package/dist/shared/lib/index.d.ts +10 -0
- package/dist/shared/lib/index.js +28 -0
- package/dist/shared/lib/logging.d.ts +26 -0
- package/dist/shared/lib/logging.js +60 -0
- package/dist/shared/lib/money.d.ts +13 -0
- package/dist/shared/lib/money.js +46 -0
- package/dist/shared/lib/text.d.ts +19 -0
- package/dist/shared/lib/text.js +52 -0
- package/dist/shared/lib/transaction.d.ts +26 -0
- package/dist/shared/lib/transaction.js +57 -0
- package/dist/shared/lib/wire-response.d.ts +6 -0
- package/dist/shared/lib/wire-response.js +9 -0
- package/dist/shop-config/options.js +2 -4
- package/package.json +19 -4
- package/.medusa/server/src/api/admin/email/terms-versions/[id]/download/route.js +0 -16
- package/.medusa/server/src/api/admin/email/terms-versions/route.js +0 -47
- package/.medusa/server/src/api/terms-download-response.js +0 -12
- package/.medusa/server/src/modules/email/models/email-terms-version.js +0 -37
- package/dist/admin-components/features/plugin-features/components/ImageSettingInput.js +0 -42
- package/dist/admin-components/features/plugin-features/components/PluginFeaturesSettingsPage.js +0 -16
- package/dist/admin-components/features/plugin-features/components/PluginPageShell.js +0 -20
- package/dist/admin-components/features/plugin-features/lib/image-upload.d.ts +0 -6
- package/dist/admin-components/features/plugin-features/lib/image-upload.js +0 -17
- package/dist/admin-components/index.d.ts +0 -14
- package/dist/admin-components/index.js +0 -14
- package/dist/admin-components/lib/errors.d.ts +0 -6
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/ImageSettingInput.d.ts +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginActionsSection.d.ts +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginDetailPage.d.ts +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginDetailPage.js +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginFeatureGate.d.ts +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginFeatureGate.js +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginFeatureSections.d.ts +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginFeatureSections.js +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginFeaturesCard.d.ts +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginFeaturesCard.js +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginFeaturesSettingsPage.d.ts +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginHubCard.d.ts +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginHubCard.js +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginPageShell.d.ts +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginSettingsForm.d.ts +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginStatusChips.d.ts +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/components/PluginStatusChips.js +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/hooks/usePluginFeatureEnabled.js +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/hooks/usePluginSettingsForm.js +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/lib/plugin-paths.d.ts +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/lib/plugin-paths.js +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/queries/pluginFeatureKeys.d.ts +0 -0
- /package/{dist → .medusa/server/src/admin}/admin-components/features/plugin-features/queries/pluginFeatureKeys.js +0 -0
- /package/{dist/admin-components → .medusa/server/src/admin/admin-components/shared}/lib/sdk.d.ts +0 -0
- /package/{dist/admin-components → .medusa/server/src/admin/admin-components/shared}/lib/sdk.js +0 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from "@medusajs/ui";
|
|
3
|
+
import { useRef } from "react";
|
|
4
|
+
/** Button that opens the file dialog; the native input stays hidden. */
|
|
5
|
+
export const FilePickerButton = ({ accept, label, disabled, isLoading, id, "aria-describedby": describedBy, onFileSelected, }) => {
|
|
6
|
+
const fileInput = useRef(null);
|
|
7
|
+
return (_jsxs(_Fragment, { children: [_jsx("input", { ref: fileInput, id: id, "aria-describedby": describedBy, type: "file", accept: accept, className: "hidden", disabled: disabled, onChange: (event) => {
|
|
8
|
+
const file = event.target.files?.[0];
|
|
9
|
+
event.target.value = "";
|
|
10
|
+
if (file) {
|
|
11
|
+
onFileSelected(file);
|
|
12
|
+
}
|
|
13
|
+
} }), _jsx(Button, { type: "button", size: "small", variant: "secondary", isLoading: isLoading, disabled: disabled || isLoading, onClick: () => fileInput.current?.click(), children: label })] }));
|
|
14
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { StatusBadge } from "@medusajs/ui";
|
|
2
|
+
import type { ComponentProps } from "react";
|
|
3
|
+
export type MappedStatus = {
|
|
4
|
+
label: string;
|
|
5
|
+
color: NonNullable<ComponentProps<typeof StatusBadge>["color"]>;
|
|
6
|
+
};
|
|
7
|
+
type MappedStatusBadgeProps = {
|
|
8
|
+
/** An empty value renders `ADMIN_DASH` instead of a badge. */
|
|
9
|
+
value: string | null | undefined;
|
|
10
|
+
/** Label and colour per status; `null` hides the badge for that status. */
|
|
11
|
+
map: Record<string, MappedStatus | null>;
|
|
12
|
+
/** For a value missing from `map`; default: the raw value in grey. */
|
|
13
|
+
fallback?: MappedStatus | null;
|
|
14
|
+
};
|
|
15
|
+
/** `StatusBadge` for a status string with a label and colour per status. */
|
|
16
|
+
export declare const MappedStatusBadge: ({ value, map, fallback, }: MappedStatusBadgeProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { StatusBadge } from "@medusajs/ui";
|
|
3
|
+
import { ADMIN_DASH } from "../lib/format";
|
|
4
|
+
import { resolveMappedStatus } from "./mapped-status";
|
|
5
|
+
/** `StatusBadge` for a status string with a label and colour per status. */
|
|
6
|
+
export const MappedStatusBadge = ({ value, map, fallback, }) => {
|
|
7
|
+
if (!value) {
|
|
8
|
+
return _jsx(_Fragment, { children: ADMIN_DASH });
|
|
9
|
+
}
|
|
10
|
+
const status = resolveMappedStatus(value, map, fallback === undefined ? { label: value, color: "grey" } : fallback);
|
|
11
|
+
return status ? (_jsx(StatusBadge, { color: status.color, children: status.label })) : null;
|
|
12
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type OffsetTablePaginationProps = {
|
|
2
|
+
/** Total number of rows over all pages. */
|
|
3
|
+
count: number;
|
|
4
|
+
offset: number;
|
|
5
|
+
limit: number;
|
|
6
|
+
onOffsetChange: (offset: number) => void;
|
|
7
|
+
/** Highest offset the API accepts; the next page is disabled beyond it. */
|
|
8
|
+
maxOffset?: number;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* German `Table.Pagination` for an offset/limit list: page navigation moves
|
|
12
|
+
* `offset` by `limit`; render it below the `Table` when `count > 0`.
|
|
13
|
+
*/
|
|
14
|
+
export declare const OffsetTablePagination: ({ count, offset, limit, onOffsetChange, maxOffset, }: OffsetTablePaginationProps) => import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Table } from "@medusajs/ui";
|
|
3
|
+
import { getOffsetPagination } from "./offset-pagination";
|
|
4
|
+
// Table.Pagination renders "1 - 20 von 45 Ergebnisse", "1 von 3 Seiten".
|
|
5
|
+
const translations = {
|
|
6
|
+
of: "von",
|
|
7
|
+
results: "Ergebnisse",
|
|
8
|
+
pages: "Seiten",
|
|
9
|
+
prev: "Zurück",
|
|
10
|
+
next: "Weiter",
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* German `Table.Pagination` for an offset/limit list: page navigation moves
|
|
14
|
+
* `offset` by `limit`; render it below the `Table` when `count > 0`.
|
|
15
|
+
*/
|
|
16
|
+
export const OffsetTablePagination = ({ count, offset, limit, onOffsetChange, maxOffset, }) => {
|
|
17
|
+
const page = getOffsetPagination({ count, offset, limit, maxOffset });
|
|
18
|
+
return (_jsx(Table.Pagination, { canNextPage: page.canNext, canPreviousPage: page.canPrevious, count: count, nextPage: () => onOffsetChange(page.nextOffset), pageCount: page.pageCount, pageIndex: page.pageIndex, pageSize: limit, previousPage: () => onOffsetChange(page.previousOffset), translations: translations }));
|
|
19
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
type PdfPreviewModalProps = {
|
|
2
|
+
open: boolean;
|
|
3
|
+
onOpenChange: (open: boolean) => void;
|
|
4
|
+
title: string;
|
|
5
|
+
/** Object URL (or any URL) of the PDF; `null` until loaded. */
|
|
6
|
+
url: string | null;
|
|
7
|
+
isLoading?: boolean;
|
|
8
|
+
/** Shown instead of the PDF. */
|
|
9
|
+
error?: string | null;
|
|
10
|
+
/** Accessible title of the frame; default "Vorschau". */
|
|
11
|
+
frameTitle?: string;
|
|
12
|
+
loadingText?: string;
|
|
13
|
+
closeLabel?: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Full-screen PDF preview. Owns no URL: the caller creates the object URL and
|
|
17
|
+
* revokes it when the modal closes (see `fetchPdfObjectUrl`).
|
|
18
|
+
*/
|
|
19
|
+
export declare const PdfPreviewModal: ({ open, onOpenChange, title, url, isLoading, error, frameTitle, loadingText, closeLabel, }: PdfPreviewModalProps) => import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, FocusModal, Text } from "@medusajs/ui";
|
|
3
|
+
/**
|
|
4
|
+
* Full-screen PDF preview. Owns no URL: the caller creates the object URL and
|
|
5
|
+
* revokes it when the modal closes (see `fetchPdfObjectUrl`).
|
|
6
|
+
*/
|
|
7
|
+
export const PdfPreviewModal = ({ open, onOpenChange, title, url, isLoading = false, error = null, frameTitle = "Vorschau", loadingText = "Wird geladen.", closeLabel = "Schließen", }) => (_jsx(FocusModal, { onOpenChange: onOpenChange, open: open, children: _jsxs(FocusModal.Content, { children: [_jsx(FocusModal.Header, { children: _jsx(FocusModal.Title, { children: title }) }), _jsx(FocusModal.Body, { className: "h-[75vh] p-0", children: url && !isLoading ? (_jsx("iframe", { className: "h-full w-full border-0", src: url, title: frameTitle })) : error ? (_jsx(Text, { "aria-atomic": "true", "aria-live": "assertive", className: "p-6 text-ui-fg-error", role: "alert", children: error })) : (_jsx(Text, { "aria-atomic": "true", "aria-live": "polite", className: "p-6 text-ui-fg-subtle", role: "status", children: loadingText })) }), _jsx(FocusModal.Footer, { children: _jsx(FocusModal.Close, { asChild: true, children: _jsx(Button, { variant: "secondary", children: closeLabel }) }) })] }) }));
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
type PluginFeatureRouteProps = {
|
|
3
|
+
pluginKey: string;
|
|
4
|
+
/** Also required to be on; none = plugin switch only. */
|
|
5
|
+
featureKey?: string;
|
|
6
|
+
/** Named in the disabled notice when given. */
|
|
7
|
+
featureLabel?: string;
|
|
8
|
+
/** Render nothing (instead of the notice) when the toggles cannot be read. */
|
|
9
|
+
hideOnError?: boolean;
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Body of an Admin route (page) that belongs to a plugin or one of its
|
|
14
|
+
* features: nothing while the toggles load, `children` when on, otherwise the
|
|
15
|
+
* "disabled" notice that links to the hub. Never flashes the notice for an
|
|
16
|
+
* enabled plugin.
|
|
17
|
+
*/
|
|
18
|
+
export declare const PluginFeatureRoute: ({ pluginKey, featureKey, featureLabel, hideOnError, children, }: PluginFeatureRouteProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { PluginFeatureDisabledNotice } from "../../features/plugin-features/components/PluginFeatureGate";
|
|
3
|
+
import { usePluginFeatureEnabled } from "../../features/plugin-features/hooks/usePluginFeatureEnabled";
|
|
4
|
+
/**
|
|
5
|
+
* Body of an Admin route (page) that belongs to a plugin or one of its
|
|
6
|
+
* features: nothing while the toggles load, `children` when on, otherwise the
|
|
7
|
+
* "disabled" notice that links to the hub. Never flashes the notice for an
|
|
8
|
+
* enabled plugin.
|
|
9
|
+
*/
|
|
10
|
+
export const PluginFeatureRoute = ({ pluginKey, featureKey, featureLabel, hideOnError = false, children, }) => {
|
|
11
|
+
const { enabled, isPending, isError } = usePluginFeatureEnabled(pluginKey, ...(featureKey ? [featureKey] : []));
|
|
12
|
+
if (isPending || (hideOnError && isError)) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
return enabled ? (_jsx(_Fragment, { children: children })) : (_jsx(PluginFeatureDisabledNotice, { pluginKey: pluginKey, featureLabel: featureLabel }));
|
|
16
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
type QueryStateProps = {
|
|
3
|
+
isLoading: boolean;
|
|
4
|
+
error?: unknown;
|
|
5
|
+
/** Forces the error branch; default `Boolean(error)`. */
|
|
6
|
+
isError?: boolean;
|
|
7
|
+
/** Shows `emptyText` instead of `children`. */
|
|
8
|
+
isEmpty?: boolean;
|
|
9
|
+
loadingText?: string;
|
|
10
|
+
/**
|
|
11
|
+
* A string is shown as is; a function gets the error's message
|
|
12
|
+
* (`undefined` when it has none) to compose the text.
|
|
13
|
+
*/
|
|
14
|
+
errorText?: string | ((message: string | undefined) => string);
|
|
15
|
+
emptyText?: string;
|
|
16
|
+
children?: ReactNode;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Body of a section whose data comes from a query: loading, error or empty
|
|
20
|
+
* text, otherwise `children`. Pass `isLoading` for the first load only
|
|
21
|
+
* (`isPending` / `isLoading`), `error` as the query's error or `null`.
|
|
22
|
+
*/
|
|
23
|
+
export declare const QueryState: ({ isLoading, error, isError, isEmpty, loadingText, errorText, emptyText, children, }: QueryStateProps) => import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Text } from "@medusajs/ui";
|
|
3
|
+
import { getErrorMessage } from "../lib/errors";
|
|
4
|
+
const Message = ({ children, tone = "subtle", }) => (_jsx("div", { className: "px-6 py-8", children: _jsx(Text, { className: tone === "error" ? "text-ui-fg-error" : "text-ui-fg-subtle", role: tone === "error" ? "alert" : "status", children: children }) }));
|
|
5
|
+
/**
|
|
6
|
+
* Body of a section whose data comes from a query: loading, error or empty
|
|
7
|
+
* text, otherwise `children`. Pass `isLoading` for the first load only
|
|
8
|
+
* (`isPending` / `isLoading`), `error` as the query's error or `null`.
|
|
9
|
+
*/
|
|
10
|
+
export const QueryState = ({ isLoading, error, isError, isEmpty = false, loadingText = "Wird geladen…", errorText = "Konnte nicht geladen werden.", emptyText = "Keine Einträge vorhanden.", children, }) => {
|
|
11
|
+
if (isLoading) {
|
|
12
|
+
return _jsx(Message, { children: loadingText });
|
|
13
|
+
}
|
|
14
|
+
if (isError ?? Boolean(error)) {
|
|
15
|
+
return (_jsx(Message, { tone: "error", children: typeof errorText === "function"
|
|
16
|
+
? errorText(getErrorMessage(error))
|
|
17
|
+
: errorText }));
|
|
18
|
+
}
|
|
19
|
+
if (isEmpty) {
|
|
20
|
+
return _jsx(Message, { children: emptyText });
|
|
21
|
+
}
|
|
22
|
+
return _jsx(_Fragment, { children: children });
|
|
23
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export type SearchableReferenceSelected = {
|
|
3
|
+
title: string;
|
|
4
|
+
/** Second line, e.g. the record's id. */
|
|
5
|
+
description?: string;
|
|
6
|
+
/** Admin route of the record; turns the title into a link. */
|
|
7
|
+
href?: string;
|
|
8
|
+
/** Label of the button that clears the selection. */
|
|
9
|
+
clearLabel?: string;
|
|
10
|
+
/** Without it the selection has no remove button. */
|
|
11
|
+
onClear?: () => void;
|
|
12
|
+
};
|
|
13
|
+
export type SearchableReferenceFieldProps<T> = {
|
|
14
|
+
/** Visible label above the field. */
|
|
15
|
+
label?: string;
|
|
16
|
+
/** Accessible name of the search input when there is no visible label. */
|
|
17
|
+
ariaLabel?: string;
|
|
18
|
+
placeholder?: string;
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
/** The text in the search input. */
|
|
21
|
+
value: string;
|
|
22
|
+
onValueChange: (value: string) => void;
|
|
23
|
+
/**
|
|
24
|
+
* The search term the results are for; default `value.trim()`. Results show
|
|
25
|
+
* only while it has at least `minQueryLength` characters.
|
|
26
|
+
*/
|
|
27
|
+
query?: string;
|
|
28
|
+
minQueryLength?: number;
|
|
29
|
+
/** Called with `query` once it stayed unchanged for `debounceMs`. */
|
|
30
|
+
onDebouncedQueryChange?: (query: string) => void;
|
|
31
|
+
/** Default 300. */
|
|
32
|
+
debounceMs?: number;
|
|
33
|
+
/** Enter in the search input. */
|
|
34
|
+
onSubmit?: () => void;
|
|
35
|
+
/** Results for the debounced query. */
|
|
36
|
+
items: readonly T[];
|
|
37
|
+
isLoading: boolean;
|
|
38
|
+
isError?: boolean;
|
|
39
|
+
getKey: (item: T) => string;
|
|
40
|
+
getLabel: (item: T) => string;
|
|
41
|
+
getDescription?: (item: T) => string | undefined;
|
|
42
|
+
/** Replaces the default label + description content of a result row. */
|
|
43
|
+
renderItem?: (item: T) => ReactNode;
|
|
44
|
+
isItemDisabled?: (item: T) => boolean;
|
|
45
|
+
onSelect: (item: T) => void;
|
|
46
|
+
/** Accessible name of the result list. */
|
|
47
|
+
listLabel?: string;
|
|
48
|
+
/** The chosen record; replaces the search input unless `keepInputWhenSelected`. */
|
|
49
|
+
selected?: SearchableReferenceSelected | null;
|
|
50
|
+
keepInputWhenSelected?: boolean;
|
|
51
|
+
/** Shown while `query` is shorter than `minQueryLength`, e.g. a hint. */
|
|
52
|
+
idleText?: ReactNode;
|
|
53
|
+
searchingText?: string;
|
|
54
|
+
emptyText?: string;
|
|
55
|
+
errorText?: string;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Search input with a result dropdown for picking one record (an order, an
|
|
59
|
+
* inventory item, an affiliate …). The input updates at once; `isLoading`
|
|
60
|
+
* shows the searching text while the query is debounced or loading, so the
|
|
61
|
+
* caller runs its query on the value from `onDebouncedQueryChange`.
|
|
62
|
+
*/
|
|
63
|
+
export declare const SearchableReferenceField: <T>({ label, ariaLabel, placeholder, disabled, value, onValueChange, query: queryProp, minQueryLength, onDebouncedQueryChange, debounceMs, onSubmit, items, isLoading, isError, getKey, getLabel, getDescription, renderItem, isItemDisabled, onSelect, listLabel, selected, keepInputWhenSelected, idleText, searchingText, emptyText, errorText, }: SearchableReferenceFieldProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, Input, Label, Text } from "@medusajs/ui";
|
|
3
|
+
import { useEffect, useId, useLayoutEffect, useRef, useState, } from "react";
|
|
4
|
+
import { Link } from "react-router-dom";
|
|
5
|
+
import { useDebouncedValue } from "../lib/use-debounced-value";
|
|
6
|
+
import { resolveReferenceResultsState } from "./reference-results-state";
|
|
7
|
+
const Message = ({ children, tone = "subtle", }) => (_jsx(Text, { className: `px-3 py-2 ${tone === "error" ? "text-ui-fg-error" : "text-ui-fg-subtle"}`, role: tone === "error" ? "alert" : undefined, size: "small", children: children }));
|
|
8
|
+
/**
|
|
9
|
+
* Search input with a result dropdown for picking one record (an order, an
|
|
10
|
+
* inventory item, an affiliate …). The input updates at once; `isLoading`
|
|
11
|
+
* shows the searching text while the query is debounced or loading, so the
|
|
12
|
+
* caller runs its query on the value from `onDebouncedQueryChange`.
|
|
13
|
+
*/
|
|
14
|
+
export const SearchableReferenceField = ({ label, ariaLabel, placeholder, disabled = false, value, onValueChange, query: queryProp, minQueryLength = 1, onDebouncedQueryChange, debounceMs = 300, onSubmit, items, isLoading, isError = false, getKey, getLabel, getDescription, renderItem, isItemDisabled, onSelect, listLabel, selected = null, keepInputWhenSelected = false, idleText, searchingText = "Suche …", emptyText = "Keine Treffer.", errorText = "Die Suche ist fehlgeschlagen.", }) => {
|
|
15
|
+
const query = queryProp ?? value.trim();
|
|
16
|
+
const debouncedQuery = useDebouncedValue(query, debounceMs);
|
|
17
|
+
// Layout effect: the caller's state updates before paint, so the stale
|
|
18
|
+
// result list never flashes for the new query.
|
|
19
|
+
useLayoutEffect(() => {
|
|
20
|
+
onDebouncedQueryChange?.(debouncedQuery);
|
|
21
|
+
// Only a new debounced query counts; the callback may change identity.
|
|
22
|
+
}, [debouncedQuery]);
|
|
23
|
+
const inputId = useId();
|
|
24
|
+
const wrapperRef = useRef(null);
|
|
25
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (!isOpen) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const closeOutside = (event) => {
|
|
31
|
+
if (!wrapperRef.current?.contains(event.target)) {
|
|
32
|
+
setIsOpen(false);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
document.addEventListener("mousedown", closeOutside);
|
|
36
|
+
return () => document.removeEventListener("mousedown", closeOutside);
|
|
37
|
+
}, [isOpen]);
|
|
38
|
+
const showInput = !selected || keepInputWhenSelected;
|
|
39
|
+
const state = resolveReferenceResultsState({
|
|
40
|
+
query,
|
|
41
|
+
minQueryLength,
|
|
42
|
+
hasIdleText: Boolean(idleText),
|
|
43
|
+
isDebouncing: debouncedQuery !== query,
|
|
44
|
+
isLoading,
|
|
45
|
+
isError,
|
|
46
|
+
itemCount: items.length,
|
|
47
|
+
});
|
|
48
|
+
const showDropdown = isOpen && !disabled && state !== "hidden";
|
|
49
|
+
const renderResults = () => {
|
|
50
|
+
if (state === "idle") {
|
|
51
|
+
return _jsx(Message, { children: idleText });
|
|
52
|
+
}
|
|
53
|
+
if (state === "searching") {
|
|
54
|
+
return _jsx(Message, { children: searchingText });
|
|
55
|
+
}
|
|
56
|
+
if (state === "error") {
|
|
57
|
+
return _jsx(Message, { tone: "error", children: errorText });
|
|
58
|
+
}
|
|
59
|
+
if (state === "empty") {
|
|
60
|
+
return _jsx(Message, { children: emptyText });
|
|
61
|
+
}
|
|
62
|
+
return (_jsx("ul", { "aria-label": listLabel, className: "flex flex-col", children: items.map((item) => (_jsx("li", { children: _jsx("button", { className: "flex w-full items-center justify-between gap-2 px-3 py-2 text-left text-sm hover:bg-ui-bg-base-hover disabled:cursor-not-allowed disabled:text-ui-fg-disabled disabled:hover:bg-transparent", disabled: disabled || isItemDisabled?.(item) === true, onClick: () => {
|
|
63
|
+
onSelect(item);
|
|
64
|
+
setIsOpen(false);
|
|
65
|
+
}, type: "button", children: renderItem ? (renderItem(item)) : (_jsxs("span", { className: "flex min-w-0 flex-col", children: [_jsx("span", { className: "truncate font-medium", children: getLabel(item) }), getDescription?.(item) ? (_jsx("span", { className: "truncate text-xs text-ui-fg-subtle", children: getDescription(item) })) : null] })) }) }, getKey(item)))) }));
|
|
66
|
+
};
|
|
67
|
+
return (_jsxs("div", { className: "grid gap-2", children: [label ? _jsx(Label, { htmlFor: inputId, children: label }) : null, selected ? (_jsxs("div", { className: "flex items-center justify-between gap-2 rounded-md border border-ui-border-base bg-ui-bg-subtle px-3 py-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx(Text, { size: "small", children: selected.href ? (_jsx(Link, { className: "text-ui-fg-interactive hover:underline", to: selected.href, children: selected.title })) : (selected.title) }), selected.description ? (_jsx(Text, { className: "truncate text-ui-fg-muted", size: "xsmall", children: selected.description })) : null] }), selected.onClear ? (_jsx(Button, { disabled: disabled, onClick: selected.onClear, size: "small", type: "button", variant: "transparent", children: selected.clearLabel })) : null] })) : null, showInput ? (_jsxs("div", { className: "relative", onBlur: (event) => {
|
|
68
|
+
const next = event.relatedTarget;
|
|
69
|
+
if (next instanceof Node && !event.currentTarget.contains(next)) {
|
|
70
|
+
setIsOpen(false);
|
|
71
|
+
}
|
|
72
|
+
}, ref: wrapperRef, children: [_jsx(Input, { "aria-label": ariaLabel, disabled: disabled, id: inputId, onChange: (event) => {
|
|
73
|
+
onValueChange(event.target.value);
|
|
74
|
+
setIsOpen(true);
|
|
75
|
+
}, onFocus: () => setIsOpen(true), onKeyDown: (event) => {
|
|
76
|
+
if (event.key === "Escape") {
|
|
77
|
+
setIsOpen(false);
|
|
78
|
+
}
|
|
79
|
+
if (event.key === "Enter" && onSubmit) {
|
|
80
|
+
event.preventDefault();
|
|
81
|
+
onSubmit();
|
|
82
|
+
}
|
|
83
|
+
}, placeholder: placeholder, value: value }), showDropdown ? (_jsx("div", { className: "absolute z-10 mt-1 w-full max-h-64 overflow-auto rounded-md border border-ui-border-base bg-ui-bg-base shadow-elevation-card-rest", children: renderResults() })) : null] })) : null] }));
|
|
84
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
type SectionHeaderProps = {
|
|
3
|
+
title: ReactNode;
|
|
4
|
+
description?: ReactNode;
|
|
5
|
+
/** Buttons at the end; below the text on narrow screens. */
|
|
6
|
+
actions?: ReactNode;
|
|
7
|
+
/** `h1` for the page's own header, `h2` (default) for a section. */
|
|
8
|
+
level?: "h1" | "h2";
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Header of a section: heading, optional subtle description and optional
|
|
12
|
+
* actions. Sits at the top of a `Container className="divide-y p-0"`.
|
|
13
|
+
*/
|
|
14
|
+
export declare const SectionHeader: ({ title, description, actions, level, }: SectionHeaderProps) => import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Heading, Text } from "@medusajs/ui";
|
|
3
|
+
/**
|
|
4
|
+
* Header of a section: heading, optional subtle description and optional
|
|
5
|
+
* actions. Sits at the top of a `Container className="divide-y p-0"`.
|
|
6
|
+
*/
|
|
7
|
+
export const SectionHeader = ({ title, description, actions, level = "h2", }) => {
|
|
8
|
+
const text = (_jsxs("div", { children: [_jsx(Heading, { level: level, children: title }), description ? (_jsx(Text, { className: "text-ui-fg-subtle", children: description })) : null] }));
|
|
9
|
+
if (!actions) {
|
|
10
|
+
return _jsx("div", { className: "px-6 py-4", children: text });
|
|
11
|
+
}
|
|
12
|
+
return (_jsxs("div", { className: "flex flex-col gap-3 px-6 py-4 sm:flex-row sm:items-start sm:justify-between", children: [text, _jsx("div", { className: "flex shrink-0 gap-2", children: actions })] }));
|
|
13
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { MappedStatus } from "./MappedStatusBadge";
|
|
2
|
+
/**
|
|
3
|
+
* The status to show for `value`: the entry of `map` (`null` hides the badge),
|
|
4
|
+
* `fallback` for a value missing from `map`, `null` for an empty value.
|
|
5
|
+
*/
|
|
6
|
+
export declare const resolveMappedStatus: (value: string | null | undefined, map: Record<string, MappedStatus | null>, fallback: MappedStatus | null) => MappedStatus | null;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The status to show for `value`: the entry of `map` (`null` hides the badge),
|
|
3
|
+
* `fallback` for a value missing from `map`, `null` for an empty value.
|
|
4
|
+
*/
|
|
5
|
+
export const resolveMappedStatus = (value, map, fallback) => {
|
|
6
|
+
if (!value) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
return Object.prototype.hasOwnProperty.call(map, value) ? map[value] : fallback;
|
|
10
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
type OffsetPaginationInput = {
|
|
2
|
+
count: number;
|
|
3
|
+
offset: number;
|
|
4
|
+
limit: number;
|
|
5
|
+
/** Highest offset the API accepts; the next page is disabled beyond it. */
|
|
6
|
+
maxOffset?: number;
|
|
7
|
+
};
|
|
8
|
+
/** Page math of an offset/limit list. */
|
|
9
|
+
export declare const getOffsetPagination: ({ count, offset, limit, maxOffset, }: OffsetPaginationInput) => {
|
|
10
|
+
pageIndex: number;
|
|
11
|
+
pageCount: number;
|
|
12
|
+
nextOffset: number;
|
|
13
|
+
previousOffset: number;
|
|
14
|
+
canPrevious: boolean;
|
|
15
|
+
canNext: boolean;
|
|
16
|
+
};
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Page math of an offset/limit list. */
|
|
2
|
+
export const getOffsetPagination = ({ count, offset, limit, maxOffset, }) => {
|
|
3
|
+
const pageIndex = Math.floor(offset / limit);
|
|
4
|
+
const pageCount = Math.max(1, Math.ceil(count / limit));
|
|
5
|
+
const nextOffset = offset + limit;
|
|
6
|
+
return {
|
|
7
|
+
pageIndex,
|
|
8
|
+
pageCount,
|
|
9
|
+
nextOffset,
|
|
10
|
+
previousOffset: Math.max(0, offset - limit),
|
|
11
|
+
canPrevious: pageIndex > 0,
|
|
12
|
+
canNext: pageIndex < pageCount - 1 &&
|
|
13
|
+
(maxOffset === undefined || nextOffset <= maxOffset),
|
|
14
|
+
};
|
|
15
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type ReferenceResultsState = "hidden" | "idle" | "searching" | "error" | "empty" | "list";
|
|
2
|
+
type ReferenceResultsInput = {
|
|
3
|
+
/** The search term the results are for. */
|
|
4
|
+
query: string;
|
|
5
|
+
minQueryLength: number;
|
|
6
|
+
/** Whether there is a hint to show while `query` is too short. */
|
|
7
|
+
hasIdleText: boolean;
|
|
8
|
+
/** The debounced query still differs from `query`. */
|
|
9
|
+
isDebouncing: boolean;
|
|
10
|
+
isLoading: boolean;
|
|
11
|
+
isError: boolean;
|
|
12
|
+
itemCount: number;
|
|
13
|
+
};
|
|
14
|
+
/** What the result dropdown of `SearchableReferenceField` shows. */
|
|
15
|
+
export declare const resolveReferenceResultsState: ({ query, minQueryLength, hasIdleText, isDebouncing, isLoading, isError, itemCount, }: ReferenceResultsInput) => ReferenceResultsState;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** What the result dropdown of `SearchableReferenceField` shows. */
|
|
2
|
+
export const resolveReferenceResultsState = ({ query, minQueryLength, hasIdleText, isDebouncing, isLoading, isError, itemCount, }) => {
|
|
3
|
+
if (query.length < minQueryLength) {
|
|
4
|
+
return hasIdleText ? "idle" : "hidden";
|
|
5
|
+
}
|
|
6
|
+
if (isDebouncing || (isLoading && !isError)) {
|
|
7
|
+
return "searching";
|
|
8
|
+
}
|
|
9
|
+
if (isError) {
|
|
10
|
+
return "error";
|
|
11
|
+
}
|
|
12
|
+
return itemCount === 0 ? "empty" : "list";
|
|
13
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface InsertMenuProps<T extends string> {
|
|
2
|
+
label: string;
|
|
3
|
+
options: readonly T[];
|
|
4
|
+
labels: Record<T, string>;
|
|
5
|
+
onSelect: (option: T) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare const InsertMenu: <T extends string>({ label, options, labels, onSelect, }: InsertMenuProps<T>) => import("react/jsx-runtime").JSX.Element | null;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Button, DropdownMenu } from "@medusajs/ui";
|
|
3
|
+
// A toolbar dropdown listing what can be inserted; nothing when there are no
|
|
4
|
+
// options.
|
|
5
|
+
export const InsertMenu = ({ label, options, labels, onSelect, }) => {
|
|
6
|
+
if (!options.length) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
return (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenu.Trigger, { asChild: true, children: _jsxs(Button, { size: "small", type: "button", variant: "secondary", children: [label, " \u25BE"] }) }), _jsx(DropdownMenu.Content, { align: "start", onCloseAutoFocus: (event) => event.preventDefault(), children: options.map((option) => (_jsx(DropdownMenu.Item, { onSelect: () => onSelect(option), children: labels[option] }, option))) })] }));
|
|
10
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface LinkPromptProps {
|
|
2
|
+
open: boolean;
|
|
3
|
+
onOpenChange: (open: boolean) => void;
|
|
4
|
+
/** Href of the link under the cursor, empty for a new one. */
|
|
5
|
+
initialHref: string;
|
|
6
|
+
onApply: (href: string) => void;
|
|
7
|
+
onRemove: () => void;
|
|
8
|
+
/** The link targets the editor accepts (`getLinkPolicy(editor)`). */
|
|
9
|
+
isAllowedHref: (href: string) => boolean;
|
|
10
|
+
/** Shown when the typed target is not accepted. */
|
|
11
|
+
invalidMessage?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare const LinkPrompt: ({ open, onOpenChange, initialHref, onApply, onRemove, isAllowedHref, invalidMessage, }: LinkPromptProps) => import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, Input, Prompt, Text } from "@medusajs/ui";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { normalizeLinkHref } from "./link-href";
|
|
5
|
+
// Asks for a link target; only what `isAllowedHref` accepts is applied.
|
|
6
|
+
export const LinkPrompt = ({ open, onOpenChange, initialHref, onApply, onRemove, isAllowedHref, invalidMessage = "Bitte eine gültige Adresse eingeben.", }) => {
|
|
7
|
+
const [value, setValue] = useState(initialHref);
|
|
8
|
+
const [error, setError] = useState(null);
|
|
9
|
+
const apply = () => {
|
|
10
|
+
const href = normalizeLinkHref(value, isAllowedHref);
|
|
11
|
+
if (!href) {
|
|
12
|
+
setError(invalidMessage);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
onApply(href);
|
|
16
|
+
};
|
|
17
|
+
return (_jsx(Prompt, { open: open, onOpenChange: onOpenChange, children: _jsxs(Prompt.Content, { children: [_jsxs(Prompt.Header, { children: [_jsx(Prompt.Title, { children: "Link" }), _jsx(Prompt.Description, { children: "Web-Adresse oder E-Mail-Adresse, auf die der markierte Text verweist." })] }), _jsxs("div", { className: "flex flex-col gap-2 px-6 pb-4", children: [_jsx(Input, { "aria-label": "Link-Adresse", autoFocus: true, onChange: (event) => {
|
|
18
|
+
setValue(event.target.value);
|
|
19
|
+
setError(null);
|
|
20
|
+
}, onKeyDown: (event) => {
|
|
21
|
+
if (event.key === "Enter") {
|
|
22
|
+
event.preventDefault();
|
|
23
|
+
apply();
|
|
24
|
+
}
|
|
25
|
+
}, placeholder: "https://", value: value }), error ? (_jsx(Text, { className: "text-ui-fg-error", role: "alert", size: "small", children: error })) : null] }), _jsxs(Prompt.Footer, { children: [initialHref ? (_jsx(Button, { onClick: onRemove, type: "button", variant: "secondary", children: "Link entfernen" })) : null, _jsx(Prompt.Cancel, { children: "Abbrechen" }), _jsx(Button, { onClick: apply, type: "button", children: "\u00DCbernehmen" })] })] }) }));
|
|
26
|
+
};
|
package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/RichTextEditor.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Editor } from "@tiptap/react";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
interface RichTextEditorProps {
|
|
4
|
+
editor: Editor;
|
|
5
|
+
/** Shown by the link prompt for a target the editor's link policy rejects. */
|
|
6
|
+
linkInvalidMessage?: string;
|
|
7
|
+
/** Added to the editor's wrapper, to scope `styles` to it. */
|
|
8
|
+
className?: string;
|
|
9
|
+
/** CSS appended to the base styles, for the owner's nodes. */
|
|
10
|
+
styles?: string;
|
|
11
|
+
/** Controls after the formatting buttons, e.g. insert menus. */
|
|
12
|
+
toolbarExtra?: ReactNode;
|
|
13
|
+
}
|
|
14
|
+
export declare const RichTextEditor: ({ editor, linkInvalidMessage, className, styles, toolbarExtra, }: RichTextEditorProps) => import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export {};
|
package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/RichTextEditor.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { EditorContent } from "@tiptap/react";
|
|
3
|
+
import { RICH_TEXT_EDITOR_STYLES } from "./editor-styles";
|
|
4
|
+
import { RichTextToolbar } from "./RichTextToolbar";
|
|
5
|
+
// Toolbar and writing area of a rich-text field. The styles are a plain
|
|
6
|
+
// stylesheet because Tailwind's reset removes list markers and node views
|
|
7
|
+
// live inside ProseMirror's own DOM.
|
|
8
|
+
export const RichTextEditor = ({ editor, linkInvalidMessage, className, styles, toolbarExtra, }) => (_jsxs("div", { className: `rte-editor${className ? ` ${className}` : ""} border-ui-border-base bg-ui-bg-base rounded-md border`, children: [_jsx("style", { children: `${RICH_TEXT_EDITOR_STYLES}${styles ?? ""}` }), _jsx(RichTextToolbar, { editor: editor, linkInvalidMessage: linkInvalidMessage, children: toolbarExtra }), _jsx(EditorContent, { editor: editor })] }));
|
package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/RichTextToolbar.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Editor } from "@tiptap/react";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
interface RichTextToolbarProps {
|
|
4
|
+
editor: Editor;
|
|
5
|
+
linkInvalidMessage?: string;
|
|
6
|
+
/** Controls of the owner, shown after the formatting buttons. */
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
export declare const RichTextToolbar: ({ editor, linkInvalidMessage, children, }: RichTextToolbarProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
package/.medusa/server/src/admin/admin-components/shared/ui/rich-text-editor/RichTextToolbar.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from "@medusajs/ui";
|
|
3
|
+
import { useEditorState } from "@tiptap/react";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { LinkPrompt } from "./LinkPrompt";
|
|
6
|
+
import { getLinkPolicy } from "./link-policy";
|
|
7
|
+
// Formatting buttons above the editor; a button appears only when the editor
|
|
8
|
+
// has the mark or node it toggles.
|
|
9
|
+
export const RichTextToolbar = ({ editor, linkInvalidMessage, children, }) => {
|
|
10
|
+
const [linkOpen, setLinkOpen] = useState(false);
|
|
11
|
+
const [linkHref, setLinkHref] = useState("");
|
|
12
|
+
const active = useEditorState({
|
|
13
|
+
editor,
|
|
14
|
+
selector: ({ editor: current }) => ({
|
|
15
|
+
bold: current?.isActive("bold") ?? false,
|
|
16
|
+
italic: current?.isActive("italic") ?? false,
|
|
17
|
+
link: current?.isActive("link") ?? false,
|
|
18
|
+
bulletList: current?.isActive("bulletList") ?? false,
|
|
19
|
+
}),
|
|
20
|
+
});
|
|
21
|
+
const { marks, nodes } = editor.schema;
|
|
22
|
+
const openLink = () => {
|
|
23
|
+
setLinkHref(editor.isActive("link")
|
|
24
|
+
? String(editor.getAttributes("link").href ?? "")
|
|
25
|
+
: "");
|
|
26
|
+
setLinkOpen(true);
|
|
27
|
+
};
|
|
28
|
+
const applyLink = (href) => {
|
|
29
|
+
const chain = editor.chain().focus();
|
|
30
|
+
if (editor.isActive("link") || !editor.state.selection.empty) {
|
|
31
|
+
chain.extendMarkRange("link").setLink({ href }).run();
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
chain
|
|
35
|
+
.insertContent({
|
|
36
|
+
type: "text",
|
|
37
|
+
text: href,
|
|
38
|
+
marks: [{ type: "link", attrs: { href } }],
|
|
39
|
+
})
|
|
40
|
+
.run();
|
|
41
|
+
}
|
|
42
|
+
setLinkOpen(false);
|
|
43
|
+
};
|
|
44
|
+
const removeLink = () => {
|
|
45
|
+
editor.chain().focus().extendMarkRange("link").unsetLink().run();
|
|
46
|
+
setLinkOpen(false);
|
|
47
|
+
};
|
|
48
|
+
return (_jsxs("div", { className: "border-ui-border-base flex flex-wrap items-center gap-2 border-b px-3 py-2", children: [marks.bold ? (_jsx(Button, { "aria-pressed": active.bold, onClick: () => editor.chain().focus().toggleBold().run(), size: "small", type: "button", variant: active.bold ? "primary" : "secondary", children: "Fett" })) : null, marks.italic ? (_jsx(Button, { "aria-pressed": active.italic, onClick: () => editor.chain().focus().toggleItalic().run(), size: "small", type: "button", variant: active.italic ? "primary" : "secondary", children: "Kursiv" })) : null, marks.link ? (_jsx(Button, { "aria-pressed": active.link, onClick: openLink, size: "small", type: "button", variant: active.link ? "primary" : "secondary", children: "Link" })) : null, nodes.bulletList ? (_jsx(Button, { "aria-pressed": active.bulletList, onClick: () => editor.chain().focus().toggleBulletList().run(), size: "small", type: "button", variant: active.bulletList ? "primary" : "secondary", children: "Aufz\u00E4hlung" })) : null, children, linkOpen ? (_jsx(LinkPrompt, { initialHref: linkHref, invalidMessage: linkInvalidMessage, isAllowedHref: getLinkPolicy(editor), onApply: applyLink, onOpenChange: setLinkOpen, onRemove: removeLink, open: true })) : null] }));
|
|
49
|
+
};
|