@hartl-services/medusa-base 2.5.0 → 2.6.1
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 +4519 -1447
- package/.medusa/server/src/admin/index.mjs +4521 -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 +2 -2
- 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/complete-cart-participants.js +4 -8
- package/README.md +427 -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
|
@@ -8,6 +8,29 @@ const initialEntry = (setting) => {
|
|
|
8
8
|
return setting.value === null ? "" : String(setting.value);
|
|
9
9
|
};
|
|
10
10
|
export const initialSettingsDraft = (settings) => Object.fromEntries(settings.map((setting) => [setting.key, initialEntry(setting)]));
|
|
11
|
+
const HEX_COLOR = /^#[0-9a-fA-F]{6}$/;
|
|
12
|
+
/** `#rrggbb` (either case); the server stores it lowercase. */
|
|
13
|
+
export const isHexColor = (value) => HEX_COLOR.test(value);
|
|
14
|
+
/** Colors are typed and sent lowercase; surrounding spaces are dropped. */
|
|
15
|
+
export const normalizeColorInput = (value) => value.trim().toLowerCase();
|
|
16
|
+
/**
|
|
17
|
+
* Splits the settings (in their given order) into consecutive runs of the
|
|
18
|
+
* same `group`; a new section starts whenever the group differs from the
|
|
19
|
+
* previous setting's group.
|
|
20
|
+
*/
|
|
21
|
+
export const groupSettings = (settings) => {
|
|
22
|
+
const sections = [];
|
|
23
|
+
for (const setting of settings) {
|
|
24
|
+
const last = sections[sections.length - 1];
|
|
25
|
+
if (last && last.group === setting.group) {
|
|
26
|
+
last.settings.push(setting);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
sections.push({ group: setting.group, settings: [setting] });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return sections;
|
|
33
|
+
};
|
|
11
34
|
const outsideBounds = (setting, value) => (setting.min !== null && value < setting.min) ||
|
|
12
35
|
(setting.max !== null && value > setting.max);
|
|
13
36
|
const numberEntryValue = (entry) => {
|
|
@@ -16,10 +39,16 @@ const numberEntryValue = (entry) => {
|
|
|
16
39
|
};
|
|
17
40
|
/**
|
|
18
41
|
* Keys whose draft value cannot be sent: unparsable, not a number or
|
|
19
|
-
* outside min/max
|
|
42
|
+
* outside min/max, or a color that is not `#rrggbb`. Saving is disabled while any key is listed.
|
|
20
43
|
*/
|
|
21
44
|
export const invalidDraftKeys = (settings, draft, unparsable = []) => settings
|
|
22
45
|
.filter((setting) => {
|
|
46
|
+
if (setting.type === "color") {
|
|
47
|
+
const entry = draft[setting.key];
|
|
48
|
+
return (typeof entry === "string" &&
|
|
49
|
+
entry.trim() !== "" &&
|
|
50
|
+
!isHexColor(entry.trim()));
|
|
51
|
+
}
|
|
23
52
|
if (setting.type !== "number") {
|
|
24
53
|
return false;
|
|
25
54
|
}
|
|
@@ -78,6 +107,9 @@ export const changedSettingValues = (settings, draft, unparsable = []) => {
|
|
|
78
107
|
values[setting.key] = value;
|
|
79
108
|
}
|
|
80
109
|
}
|
|
110
|
+
else if (setting.type === "color") {
|
|
111
|
+
values[setting.key] = normalizeColorInput(text);
|
|
112
|
+
}
|
|
81
113
|
else {
|
|
82
114
|
values[setting.key] = text;
|
|
83
115
|
}
|
|
@@ -54,6 +54,9 @@ export declare const texts: {
|
|
|
54
54
|
invalidates: (labels: string) => string;
|
|
55
55
|
required: string;
|
|
56
56
|
invalidNumber: string;
|
|
57
|
+
invalidColor: string;
|
|
58
|
+
colorPlaceholder: string;
|
|
59
|
+
colorPickLabel: (label: string) => string;
|
|
57
60
|
outOfRange: string;
|
|
58
61
|
numberMin: (min: number) => string;
|
|
59
62
|
numberMax: (max: number) => string;
|
|
@@ -54,6 +54,9 @@ export const texts = {
|
|
|
54
54
|
invalidates: (labels) => `Beim Ändern muss ${labels} neu eingegeben werden.`,
|
|
55
55
|
required: "Pflichtfeld",
|
|
56
56
|
invalidNumber: "Bitte eine gültige Zahl eingeben.",
|
|
57
|
+
invalidColor: "Bitte eine Hex-Farbe wie #1a2b3c eingeben.",
|
|
58
|
+
colorPlaceholder: "Standard",
|
|
59
|
+
colorPickLabel: (label) => `${label} auswählen`,
|
|
57
60
|
outOfRange: "Der Wert liegt außerhalb des erlaubten Bereichs.",
|
|
58
61
|
numberMin: (min) => `Mindestens ${min}.`,
|
|
59
62
|
numberMax: (max) => `Höchstens ${max}.`,
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entry of `@hartl-services/medusa-base/admin-components` (built by
|
|
3
|
+
* `tsconfig.admin-components.json` into
|
|
4
|
+
* `.medusa/server/src/admin/admin-components`). Not an Admin extension: routes and widgets live in `routes/`.
|
|
5
|
+
*
|
|
6
|
+
* Other plugins compose these into their own Admin page. Everything here
|
|
7
|
+
* uses the host Admin's React, React Query, React Router and `@medusajs/ui`.
|
|
8
|
+
* `shared/ui` and `shared/lib` hold the building blocks every plugin reuses.
|
|
9
|
+
*/
|
|
10
|
+
export { PluginPageShell } from "./features/plugin-features/components/PluginPageShell";
|
|
11
|
+
export { PluginFeatureSections } from "./features/plugin-features/components/PluginFeatureSections";
|
|
12
|
+
export { PluginFeatureDisabledNotice, PluginFeatureGate, } from "./features/plugin-features/components/PluginFeatureGate";
|
|
13
|
+
export { usePluginFeature } from "./features/plugin-features/hooks/usePluginFeatures";
|
|
14
|
+
export { usePluginFeatureEnabled, type PluginFeatureEnabledState, } from "./features/plugin-features/hooks/usePluginFeatureEnabled";
|
|
15
|
+
export { pluginFeatureKeys } from "./features/plugin-features/queries/pluginFeatureKeys";
|
|
16
|
+
export { sdk } from "./shared/lib/sdk";
|
|
17
|
+
export { getErrorMessage } from "./shared/lib/errors";
|
|
18
|
+
export { ADMIN_DASH, ADMIN_LOCALE, formatAmount, formatDate, formatDateTime, getTodayInputDate, type FormatDateOptions, } from "./shared/lib/format";
|
|
19
|
+
export { dateFromInputValue, dateTimeFromInputValue, inputValueFromDate, inputValueFromDateTime, } from "./shared/lib/date-input";
|
|
20
|
+
export { validateFile } from "./shared/lib/file-validation";
|
|
21
|
+
export { fetchPdfObjectUrl } from "./shared/lib/pdf";
|
|
22
|
+
export { usePdfPreview, type PdfPreviewState } from "./shared/lib/use-pdf-preview";
|
|
23
|
+
export { useDebouncedValue } from "./shared/lib/use-debounced-value";
|
|
24
|
+
export { AdminDatePicker } from "./shared/ui/AdminDatePicker";
|
|
25
|
+
export { DateRangeFilter } from "./shared/ui/DateRangeFilter";
|
|
26
|
+
export { FilePickerButton } from "./shared/ui/FilePickerButton";
|
|
27
|
+
export { BackLink } from "./shared/ui/BackLink";
|
|
28
|
+
export { MappedStatusBadge, type MappedStatus } from "./shared/ui/MappedStatusBadge";
|
|
29
|
+
export { OffsetTablePagination } from "./shared/ui/OffsetTablePagination";
|
|
30
|
+
export { PdfPreviewModal } from "./shared/ui/PdfPreviewModal";
|
|
31
|
+
export { PluginFeatureRoute } from "./shared/ui/PluginFeatureRoute";
|
|
32
|
+
export { QueryState } from "./shared/ui/QueryState";
|
|
33
|
+
export { SearchableReferenceField, type SearchableReferenceFieldProps, type SearchableReferenceSelected, } from "./shared/ui/SearchableReferenceField";
|
|
34
|
+
export { SectionHeader } from "./shared/ui/SectionHeader";
|
|
35
|
+
export { Extension, filterSlashItems, InsertMenu, isDefaultAllowedHref, Mark, mergeAttributes, Node, NodeSelection, NodeViewContent, NodeViewWrapper, normalizeLinkHref, Plugin, PluginKey, ReactNodeViewRenderer, RichTextEditor, TextSelection, useEditorState, useRichTextEditor, } from "./shared/ui/rich-text-editor";
|
|
36
|
+
export type { AnyExtension, ChainedCommands, Editor, JSONContent, NestedContainer, NodeViewProps, Range, RichTextEditorConfig, SlashContext, SlashItem, } from "./shared/ui/rich-text-editor";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entry of `@hartl-services/medusa-base/admin-components` (built by
|
|
3
|
+
* `tsconfig.admin-components.json` into
|
|
4
|
+
* `.medusa/server/src/admin/admin-components`). Not an Admin extension: routes and widgets live in `routes/`.
|
|
5
|
+
*
|
|
6
|
+
* Other plugins compose these into their own Admin page. Everything here
|
|
7
|
+
* uses the host Admin's React, React Query, React Router and `@medusajs/ui`.
|
|
8
|
+
* `shared/ui` and `shared/lib` hold the building blocks every plugin reuses.
|
|
9
|
+
*/
|
|
10
|
+
export { PluginPageShell } from "./features/plugin-features/components/PluginPageShell";
|
|
11
|
+
export { PluginFeatureSections } from "./features/plugin-features/components/PluginFeatureSections";
|
|
12
|
+
export { PluginFeatureDisabledNotice, PluginFeatureGate, } from "./features/plugin-features/components/PluginFeatureGate";
|
|
13
|
+
export { usePluginFeature } from "./features/plugin-features/hooks/usePluginFeatures";
|
|
14
|
+
export { usePluginFeatureEnabled, } from "./features/plugin-features/hooks/usePluginFeatureEnabled";
|
|
15
|
+
export { pluginFeatureKeys } from "./features/plugin-features/queries/pluginFeatureKeys";
|
|
16
|
+
export { sdk } from "./shared/lib/sdk";
|
|
17
|
+
export { getErrorMessage } from "./shared/lib/errors";
|
|
18
|
+
export { ADMIN_DASH, ADMIN_LOCALE, formatAmount, formatDate, formatDateTime, getTodayInputDate, } from "./shared/lib/format";
|
|
19
|
+
export { dateFromInputValue, dateTimeFromInputValue, inputValueFromDate, inputValueFromDateTime, } from "./shared/lib/date-input";
|
|
20
|
+
export { validateFile } from "./shared/lib/file-validation";
|
|
21
|
+
export { fetchPdfObjectUrl } from "./shared/lib/pdf";
|
|
22
|
+
export { usePdfPreview } from "./shared/lib/use-pdf-preview";
|
|
23
|
+
export { useDebouncedValue } from "./shared/lib/use-debounced-value";
|
|
24
|
+
// Shared UI
|
|
25
|
+
export { AdminDatePicker } from "./shared/ui/AdminDatePicker";
|
|
26
|
+
export { DateRangeFilter } from "./shared/ui/DateRangeFilter";
|
|
27
|
+
export { FilePickerButton } from "./shared/ui/FilePickerButton";
|
|
28
|
+
export { BackLink } from "./shared/ui/BackLink";
|
|
29
|
+
export { MappedStatusBadge } from "./shared/ui/MappedStatusBadge";
|
|
30
|
+
export { OffsetTablePagination } from "./shared/ui/OffsetTablePagination";
|
|
31
|
+
export { PdfPreviewModal } from "./shared/ui/PdfPreviewModal";
|
|
32
|
+
export { PluginFeatureRoute } from "./shared/ui/PluginFeatureRoute";
|
|
33
|
+
export { QueryState } from "./shared/ui/QueryState";
|
|
34
|
+
export { SearchableReferenceField, } from "./shared/ui/SearchableReferenceField";
|
|
35
|
+
export { SectionHeader } from "./shared/ui/SectionHeader";
|
|
36
|
+
// Rich-text editor
|
|
37
|
+
export { Extension, filterSlashItems, InsertMenu, isDefaultAllowedHref, Mark, mergeAttributes, Node, NodeSelection, NodeViewContent, NodeViewWrapper, normalizeLinkHref, Plugin, PluginKey, ReactNodeViewRenderer, RichTextEditor, TextSelection, useEditorState, useRichTextEditor, } from "./shared/ui/rich-text-editor";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Local `Date` at midnight of a "yyyy-mm-dd" string; `null` if empty or not a real date. */
|
|
2
|
+
export declare const dateFromInputValue: (value: string | null | undefined) => Date | null;
|
|
3
|
+
/** "yyyy-mm-dd" of a local `Date`; "" for none or an invalid date. */
|
|
4
|
+
export declare const inputValueFromDate: (date: Date | null | undefined) => string;
|
|
5
|
+
/** Local `Date` of a "yyyy-mm-ddThh:mm" string (`datetime-local` format); `null` if empty or invalid. */
|
|
6
|
+
export declare const dateTimeFromInputValue: (value: string | null | undefined) => Date | null;
|
|
7
|
+
/** "yyyy-mm-ddThh:mm" of a local `Date`; "" for none or an invalid date. */
|
|
8
|
+
export declare const inputValueFromDateTime: (date: Date | null | undefined) => string;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversion between the `yyyy-mm-dd` / `yyyy-mm-ddThh:mm` strings that
|
|
3
|
+
* callers keep as state and the `Date` values of the `DatePicker`. The
|
|
4
|
+
* `DatePicker` reads and emits local dates (local getters, local midnight), so
|
|
5
|
+
* these helpers are always local; a calendar-date string stays the same day
|
|
6
|
+
* regardless of the time zone.
|
|
7
|
+
*/
|
|
8
|
+
const DATE_PATTERN = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
9
|
+
const DATE_TIME_PATTERN = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})$/;
|
|
10
|
+
const pad = (value, length = 2) => String(value).padStart(length, "0");
|
|
11
|
+
const build = ([year, month, day, hour = 0, minute = 0]) => {
|
|
12
|
+
const date = new Date(year, month - 1, day, hour, minute);
|
|
13
|
+
const matches = date.getFullYear() === year &&
|
|
14
|
+
date.getMonth() === month - 1 &&
|
|
15
|
+
date.getDate() === day &&
|
|
16
|
+
date.getHours() === hour &&
|
|
17
|
+
date.getMinutes() === minute;
|
|
18
|
+
return matches ? date : null;
|
|
19
|
+
};
|
|
20
|
+
/** Local `Date` at midnight of a "yyyy-mm-dd" string; `null` if empty or not a real date. */
|
|
21
|
+
export const dateFromInputValue = (value) => {
|
|
22
|
+
const match = value ? DATE_PATTERN.exec(value) : null;
|
|
23
|
+
return match ? build(match.slice(1).map(Number)) : null;
|
|
24
|
+
};
|
|
25
|
+
/** "yyyy-mm-dd" of a local `Date`; "" for none or an invalid date. */
|
|
26
|
+
export const inputValueFromDate = (date) => {
|
|
27
|
+
if (!date || Number.isNaN(date.getTime())) {
|
|
28
|
+
return "";
|
|
29
|
+
}
|
|
30
|
+
return `${pad(date.getFullYear(), 4)}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
|
31
|
+
};
|
|
32
|
+
/** Local `Date` of a "yyyy-mm-ddThh:mm" string (`datetime-local` format); `null` if empty or invalid. */
|
|
33
|
+
export const dateTimeFromInputValue = (value) => {
|
|
34
|
+
const match = value ? DATE_TIME_PATTERN.exec(value) : null;
|
|
35
|
+
return match ? build(match.slice(1).map(Number)) : null;
|
|
36
|
+
};
|
|
37
|
+
/** "yyyy-mm-ddThh:mm" of a local `Date`; "" for none or an invalid date. */
|
|
38
|
+
export const inputValueFromDateTime = (date) => {
|
|
39
|
+
if (!date || Number.isNaN(date.getTime())) {
|
|
40
|
+
return "";
|
|
41
|
+
}
|
|
42
|
+
return `${inputValueFromDate(date)}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
|
43
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts a human-readable message from an unknown thrown value / failed
|
|
3
|
+
* response. Returns `undefined` when nothing usable is found so callers can
|
|
4
|
+
* fall back to a localized "unknown error" string instead of a hard-coded one.
|
|
5
|
+
* With a `fallback` argument the result is always a string.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getErrorMessage(error: unknown): string | undefined;
|
|
8
|
+
export declare function getErrorMessage(error: unknown, fallback: string): string;
|
|
9
|
+
export declare function getErrorMessage(error: unknown, fallback?: string): string | undefined;
|
package/{dist/admin-components → .medusa/server/src/admin/admin-components/shared}/lib/errors.js
RENAMED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*/
|
|
6
|
-
export const getErrorMessage = (error) => {
|
|
1
|
+
export function getErrorMessage(error, fallback) {
|
|
2
|
+
return extractErrorMessage(error) ?? fallback;
|
|
3
|
+
}
|
|
4
|
+
const extractErrorMessage = (error) => {
|
|
7
5
|
if (error instanceof Error && error.message) {
|
|
8
6
|
return error.message;
|
|
9
7
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
type FileSelection = {
|
|
2
|
+
name: string;
|
|
3
|
+
size: number;
|
|
4
|
+
type: string;
|
|
5
|
+
};
|
|
6
|
+
type FileValidationOptions = {
|
|
7
|
+
maxBytes: number;
|
|
8
|
+
/** Allowed MIME types. */
|
|
9
|
+
types: string[];
|
|
10
|
+
/**
|
|
11
|
+
* Allowed file extensions incl. dot (`".pdf"`). When set, the name must end
|
|
12
|
+
* with one of them and an empty MIME type is tolerated (browsers often do
|
|
13
|
+
* not know it); without it the MIME type must match exactly.
|
|
14
|
+
*/
|
|
15
|
+
extensions?: string[];
|
|
16
|
+
messages: {
|
|
17
|
+
wrongType: string;
|
|
18
|
+
empty: string;
|
|
19
|
+
tooLarge: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
/** Why `file` is not acceptable (German message from `messages`); `null` = valid. */
|
|
23
|
+
export declare const validateFile: (file: FileSelection, { maxBytes, types, extensions, messages }: FileValidationOptions) => string | null;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Why `file` is not acceptable (German message from `messages`); `null` = valid. */
|
|
2
|
+
export const validateFile = (file, { maxBytes, types, extensions, messages }) => {
|
|
3
|
+
const typeMatches = extensions
|
|
4
|
+
? file.type === "" || types.includes(file.type)
|
|
5
|
+
: types.includes(file.type);
|
|
6
|
+
const name = file.name.toLowerCase();
|
|
7
|
+
const extensionMatches = !extensions || extensions.some((extension) => name.endsWith(extension));
|
|
8
|
+
if (!typeMatches || !extensionMatches) {
|
|
9
|
+
return messages.wrongType;
|
|
10
|
+
}
|
|
11
|
+
if (file.size === 0) {
|
|
12
|
+
return messages.empty;
|
|
13
|
+
}
|
|
14
|
+
if (file.size > maxBytes) {
|
|
15
|
+
return messages.tooLarge;
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Admin surface of the Hartl Services plugins is German-only even though
|
|
3
|
+
* Medusa Admin supports runtime language selection. All `Intl` formatting is
|
|
4
|
+
* pinned to this locale so it matches the bundled German texts.
|
|
5
|
+
*/
|
|
6
|
+
export declare const ADMIN_LOCALE = "de-AT";
|
|
7
|
+
/** Shown for a missing or unparsable value. */
|
|
8
|
+
export declare const ADMIN_DASH = "-";
|
|
9
|
+
export type FormatDateOptions = {
|
|
10
|
+
/**
|
|
11
|
+
* Format in UTC. Use it for values stored at UTC midnight (e.g. batch
|
|
12
|
+
* expiry dates); otherwise viewers west of UTC see the previous day.
|
|
13
|
+
*/
|
|
14
|
+
timeZone?: "UTC";
|
|
15
|
+
};
|
|
16
|
+
/** "09.10.2026"; `ADMIN_DASH` for an empty or invalid value. */
|
|
17
|
+
export declare const formatDate: (value: string | number | Date | null | undefined, options?: FormatDateOptions) => string;
|
|
18
|
+
/** "09.10.2026, 12:30"; `ADMIN_DASH` for an empty or invalid value. */
|
|
19
|
+
export declare const formatDateTime: (value: string | number | Date | null | undefined, options?: FormatDateOptions) => string;
|
|
20
|
+
/**
|
|
21
|
+
* "€ 20,00" for the given ISO 4217 code (any case). `ADMIN_DASH` without an
|
|
22
|
+
* amount; "20 XYZ" (raw amount and upper-case code) when the amount is not a
|
|
23
|
+
* number or the code is unknown to `Intl`.
|
|
24
|
+
*/
|
|
25
|
+
export declare const formatAmount: (amount: number | string | null | undefined, currencyCode: string) => string;
|
|
26
|
+
/**
|
|
27
|
+
* Today as `yyyy-mm-dd` for `<input type="date">`. By default the viewer's
|
|
28
|
+
* local day; `utc: true` for values that are stored at UTC midnight.
|
|
29
|
+
*/
|
|
30
|
+
export declare const getTodayInputDate: (options?: {
|
|
31
|
+
utc?: boolean;
|
|
32
|
+
}) => string;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Admin surface of the Hartl Services plugins is German-only even though
|
|
3
|
+
* Medusa Admin supports runtime language selection. All `Intl` formatting is
|
|
4
|
+
* pinned to this locale so it matches the bundled German texts.
|
|
5
|
+
*/
|
|
6
|
+
export const ADMIN_LOCALE = "de-AT";
|
|
7
|
+
/** Shown for a missing or unparsable value. */
|
|
8
|
+
export const ADMIN_DASH = "-";
|
|
9
|
+
const toDate = (value) => {
|
|
10
|
+
if (value === null || value === undefined || value === "") {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
const date = new Date(value);
|
|
14
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
15
|
+
};
|
|
16
|
+
/** "09.10.2026"; `ADMIN_DASH` for an empty or invalid value. */
|
|
17
|
+
export const formatDate = (value, options = {}) => {
|
|
18
|
+
const date = toDate(value);
|
|
19
|
+
return date
|
|
20
|
+
? new Intl.DateTimeFormat(ADMIN_LOCALE, {
|
|
21
|
+
year: "numeric",
|
|
22
|
+
month: "2-digit",
|
|
23
|
+
day: "2-digit",
|
|
24
|
+
...(options.timeZone ? { timeZone: options.timeZone } : {}),
|
|
25
|
+
}).format(date)
|
|
26
|
+
: ADMIN_DASH;
|
|
27
|
+
};
|
|
28
|
+
/** "09.10.2026, 12:30"; `ADMIN_DASH` for an empty or invalid value. */
|
|
29
|
+
export const formatDateTime = (value, options = {}) => {
|
|
30
|
+
const date = toDate(value);
|
|
31
|
+
return date
|
|
32
|
+
? new Intl.DateTimeFormat(ADMIN_LOCALE, {
|
|
33
|
+
year: "numeric",
|
|
34
|
+
month: "2-digit",
|
|
35
|
+
day: "2-digit",
|
|
36
|
+
hour: "2-digit",
|
|
37
|
+
minute: "2-digit",
|
|
38
|
+
...(options.timeZone ? { timeZone: options.timeZone } : {}),
|
|
39
|
+
}).format(date)
|
|
40
|
+
: ADMIN_DASH;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* "€ 20,00" for the given ISO 4217 code (any case). `ADMIN_DASH` without an
|
|
44
|
+
* amount; "20 XYZ" (raw amount and upper-case code) when the amount is not a
|
|
45
|
+
* number or the code is unknown to `Intl`.
|
|
46
|
+
*/
|
|
47
|
+
export const formatAmount = (amount, currencyCode) => {
|
|
48
|
+
if (amount === null || amount === undefined || amount === "") {
|
|
49
|
+
return ADMIN_DASH;
|
|
50
|
+
}
|
|
51
|
+
const code = currencyCode.toUpperCase();
|
|
52
|
+
const value = Number(amount);
|
|
53
|
+
if (!Number.isFinite(value)) {
|
|
54
|
+
return `${amount} ${code}`;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
return new Intl.NumberFormat(ADMIN_LOCALE, {
|
|
58
|
+
style: "currency",
|
|
59
|
+
currency: code,
|
|
60
|
+
}).format(value);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return `${amount} ${code}`;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Today as `yyyy-mm-dd` for `<input type="date">`. By default the viewer's
|
|
68
|
+
* local day; `utc: true` for values that are stored at UTC midnight.
|
|
69
|
+
*/
|
|
70
|
+
export const getTodayInputDate = (options = {}) => {
|
|
71
|
+
const now = new Date();
|
|
72
|
+
if (options.utc) {
|
|
73
|
+
return now.toISOString().slice(0, 10);
|
|
74
|
+
}
|
|
75
|
+
const timezoneOffsetMs = now.getTimezoneOffset() * 60 * 1000;
|
|
76
|
+
return new Date(now.getTime() - timezoneOffsetMs).toISOString().slice(0, 10);
|
|
77
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure bookkeeping of `usePdfPreview`: the object URL currently shown and a
|
|
3
|
+
* request counter, so a response that arrives after the preview was closed or
|
|
4
|
+
* replaced is discarded (and its object URL revoked).
|
|
5
|
+
*/
|
|
6
|
+
export type PdfPreviewTracker = {
|
|
7
|
+
/** Starts a request: revokes the shown URL and returns its id. */
|
|
8
|
+
begin: () => number;
|
|
9
|
+
/** Takes over `url` if `requestId` is still the latest, else revokes it. */
|
|
10
|
+
accept: (requestId: number, url: string) => boolean;
|
|
11
|
+
/** True while `requestId` is the latest request. */
|
|
12
|
+
isCurrent: (requestId: number) => boolean;
|
|
13
|
+
/** Invalidates pending requests and revokes the shown URL. */
|
|
14
|
+
reset: () => void;
|
|
15
|
+
};
|
|
16
|
+
export declare const createPdfPreviewTracker: (revoke?: (url: string) => void) => PdfPreviewTracker;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const createPdfPreviewTracker = (revoke = (url) => URL.revokeObjectURL(url)) => {
|
|
2
|
+
let latest = 0;
|
|
3
|
+
let current = null;
|
|
4
|
+
const release = () => {
|
|
5
|
+
if (current) {
|
|
6
|
+
revoke(current);
|
|
7
|
+
current = null;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
return {
|
|
11
|
+
begin: () => {
|
|
12
|
+
release();
|
|
13
|
+
latest += 1;
|
|
14
|
+
return latest;
|
|
15
|
+
},
|
|
16
|
+
accept: (requestId, url) => {
|
|
17
|
+
if (requestId !== latest) {
|
|
18
|
+
revoke(url);
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
release();
|
|
22
|
+
current = url;
|
|
23
|
+
return true;
|
|
24
|
+
},
|
|
25
|
+
isCurrent: (requestId) => requestId === latest,
|
|
26
|
+
reset: () => {
|
|
27
|
+
latest += 1;
|
|
28
|
+
release();
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetches a PDF through the SDK, which adds the Admin session or bearer token
|
|
3
|
+
* (so it works for both supported Admin auth modes), and returns an object
|
|
4
|
+
* URL for an `<iframe>`. The caller must `URL.revokeObjectURL` it.
|
|
5
|
+
*/
|
|
6
|
+
export declare const fetchPdfObjectUrl: (path: string) => Promise<string>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { sdk } from "./sdk";
|
|
2
|
+
/**
|
|
3
|
+
* Fetches a PDF through the SDK, which adds the Admin session or bearer token
|
|
4
|
+
* (so it works for both supported Admin auth modes), and returns an object
|
|
5
|
+
* URL for an `<iframe>`. The caller must `URL.revokeObjectURL` it.
|
|
6
|
+
*/
|
|
7
|
+
export const fetchPdfObjectUrl = async (path) => {
|
|
8
|
+
const response = await sdk.client.fetch(path, {
|
|
9
|
+
headers: { accept: "application/pdf" },
|
|
10
|
+
});
|
|
11
|
+
const pdf = await response.blob();
|
|
12
|
+
return URL.createObjectURL(pdf);
|
|
13
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
/** `value` once it has stayed unchanged for `delayMs`. */
|
|
3
|
+
export const useDebouncedValue = (value, delayMs) => {
|
|
4
|
+
const [debounced, setDebounced] = useState(value);
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
const timer = window.setTimeout(() => setDebounced(value), delayMs);
|
|
7
|
+
return () => window.clearTimeout(timer);
|
|
8
|
+
}, [value, delayMs]);
|
|
9
|
+
return debounced;
|
|
10
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type PdfPreviewState = {
|
|
2
|
+
isOpen: boolean;
|
|
3
|
+
/** Object URL of the loaded PDF; `null` until loaded. */
|
|
4
|
+
url: string | null;
|
|
5
|
+
isLoading: boolean;
|
|
6
|
+
/** Message of a failed load. */
|
|
7
|
+
error: string | null;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* State for a `PdfPreviewModal`. `open(load, errorMessage)` runs `load`
|
|
11
|
+
* (e.g. `fetchPdfObjectUrl(path)`) and shows the result. A response that
|
|
12
|
+
* arrives after `close()` or a newer `open()` is dropped; the object URL is
|
|
13
|
+
* revoked on close, on replacement and on unmount.
|
|
14
|
+
*/
|
|
15
|
+
export declare const usePdfPreview: () => {
|
|
16
|
+
open: (load: () => Promise<string>, errorMessage: string) => Promise<void>;
|
|
17
|
+
close: () => void;
|
|
18
|
+
isOpen: boolean;
|
|
19
|
+
/** Object URL of the loaded PDF; `null` until loaded. */
|
|
20
|
+
url: string | null;
|
|
21
|
+
isLoading: boolean;
|
|
22
|
+
/** Message of a failed load. */
|
|
23
|
+
error: string | null;
|
|
24
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
+
import { createPdfPreviewTracker } from "./pdf-preview";
|
|
3
|
+
const CLOSED = {
|
|
4
|
+
isOpen: false,
|
|
5
|
+
url: null,
|
|
6
|
+
isLoading: false,
|
|
7
|
+
error: null,
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* State for a `PdfPreviewModal`. `open(load, errorMessage)` runs `load`
|
|
11
|
+
* (e.g. `fetchPdfObjectUrl(path)`) and shows the result. A response that
|
|
12
|
+
* arrives after `close()` or a newer `open()` is dropped; the object URL is
|
|
13
|
+
* revoked on close, on replacement and on unmount.
|
|
14
|
+
*/
|
|
15
|
+
export const usePdfPreview = () => {
|
|
16
|
+
const [state, setState] = useState(CLOSED);
|
|
17
|
+
const tracker = useRef(createPdfPreviewTracker());
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
const current = tracker.current;
|
|
20
|
+
return () => current.reset();
|
|
21
|
+
}, []);
|
|
22
|
+
const open = useCallback(async (load, errorMessage) => {
|
|
23
|
+
const requestId = tracker.current.begin();
|
|
24
|
+
setState({ isOpen: true, url: null, isLoading: true, error: null });
|
|
25
|
+
try {
|
|
26
|
+
const url = await load();
|
|
27
|
+
if (tracker.current.accept(requestId, url)) {
|
|
28
|
+
setState({ isOpen: true, url, isLoading: false, error: null });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
if (tracker.current.isCurrent(requestId)) {
|
|
33
|
+
setState({
|
|
34
|
+
isOpen: true,
|
|
35
|
+
url: null,
|
|
36
|
+
isLoading: false,
|
|
37
|
+
error: errorMessage,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}, []);
|
|
42
|
+
const close = useCallback(() => {
|
|
43
|
+
tracker.current.reset();
|
|
44
|
+
setState(CLOSED);
|
|
45
|
+
}, []);
|
|
46
|
+
return { ...state, open, close };
|
|
47
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { DatePicker } from "@medusajs/ui";
|
|
2
|
+
import type { ComponentProps } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* DatePicker follows the dashboard user's language; the shop formats dates as de-AT everywhere.
|
|
5
|
+
* The upstream picker ignores outside `value` changes from one date to another (only a reset
|
|
6
|
+
* to empty works): a caller that must update it externally passes a `key`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const AdminDatePicker: (props: ComponentProps<typeof DatePicker>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { DatePicker, I18nProvider } from "@medusajs/ui";
|
|
3
|
+
import { ADMIN_LOCALE } from "../lib/format";
|
|
4
|
+
/**
|
|
5
|
+
* DatePicker follows the dashboard user's language; the shop formats dates as de-AT everywhere.
|
|
6
|
+
* The upstream picker ignores outside `value` changes from one date to another (only a reset
|
|
7
|
+
* to empty works): a caller that must update it externally passes a `key`.
|
|
8
|
+
*/
|
|
9
|
+
export const AdminDatePicker = (props) => (_jsx(I18nProvider, { locale: ADMIN_LOCALE, children: _jsx(DatePicker, { ...props }) }));
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type BackLinkProps = {
|
|
2
|
+
to: string;
|
|
3
|
+
/** Text after the arrow icon, e.g. "Zurück zu E-Mail". */
|
|
4
|
+
label: string;
|
|
5
|
+
};
|
|
6
|
+
/** Arrow + "Zurück …" link above a sub-page. */
|
|
7
|
+
export declare const BackLink: ({ to, label }: BackLinkProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ArrowLongLeft } from "@medusajs/icons";
|
|
3
|
+
import { Link } from "react-router-dom";
|
|
4
|
+
/** Arrow + "Zurück …" link above a sub-page. */
|
|
5
|
+
export const BackLink = ({ to, label }) => (_jsx("div", { children: _jsxs(Link, { to: to, className: "text-ui-fg-subtle hover:text-ui-fg-base txt-compact-small-plus inline-flex items-center gap-x-1", children: [_jsx(ArrowLongLeft, { "aria-hidden": "true" }), label] }) }));
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
type DateRange = {
|
|
2
|
+
from: string;
|
|
3
|
+
to: string;
|
|
4
|
+
};
|
|
5
|
+
type DateRangeFilterProps = {
|
|
6
|
+
/** `yyyy-mm-dd` (local calendar date). */
|
|
7
|
+
from: string;
|
|
8
|
+
to: string;
|
|
9
|
+
onChange: (range: DateRange) => void;
|
|
10
|
+
fromLabel?: string;
|
|
11
|
+
toLabel?: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Two labelled date pickers ("Von" / "Bis"). Renders the two fields as a
|
|
15
|
+
* fragment, so the caller decides the layout (grid, flex row, form). The
|
|
16
|
+
* upstream picker ignores outside value changes; a caller that resets the
|
|
17
|
+
* range externally passes a `key`.
|
|
18
|
+
*/
|
|
19
|
+
export declare const DateRangeFilter: ({ from, to, onChange, fromLabel, toLabel, }: DateRangeFilterProps) => import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Label } from "@medusajs/ui";
|
|
3
|
+
import { useId } from "react";
|
|
4
|
+
import { dateFromInputValue, inputValueFromDate } from "../lib/date-input";
|
|
5
|
+
import { AdminDatePicker } from "./AdminDatePicker";
|
|
6
|
+
/**
|
|
7
|
+
* Two labelled date pickers ("Von" / "Bis"). Renders the two fields as a
|
|
8
|
+
* fragment, so the caller decides the layout (grid, flex row, form). The
|
|
9
|
+
* upstream picker ignores outside value changes; a caller that resets the
|
|
10
|
+
* range externally passes a `key`.
|
|
11
|
+
*/
|
|
12
|
+
export const DateRangeFilter = ({ from, to, onChange, fromLabel = "Von", toLabel = "Bis", }) => {
|
|
13
|
+
const id = useId();
|
|
14
|
+
const fromLabelId = `${id}-from-label`;
|
|
15
|
+
const toLabelId = `${id}-to-label`;
|
|
16
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "grid gap-2", children: [_jsx(Label, { id: fromLabelId, children: fromLabel }), _jsx(AdminDatePicker, { "aria-labelledby": fromLabelId, value: dateFromInputValue(from), onChange: (date) => onChange({ from: inputValueFromDate(date), to }) })] }), _jsxs("div", { className: "grid gap-2", children: [_jsx(Label, { id: toLabelId, children: toLabel }), _jsx(AdminDatePicker, { "aria-labelledby": toLabelId, value: dateFromInputValue(to), onChange: (date) => onChange({ from, to: inputValueFromDate(date) }) })] })] }));
|
|
17
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type FilePickerButtonProps = {
|
|
2
|
+
/** Value of the input's `accept` attribute. */
|
|
3
|
+
accept: string;
|
|
4
|
+
label: string;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
isLoading?: boolean;
|
|
7
|
+
/** Id of the hidden input (for a `Label htmlFor`). */
|
|
8
|
+
id?: string;
|
|
9
|
+
"aria-describedby"?: string;
|
|
10
|
+
onFileSelected: (file: File) => void;
|
|
11
|
+
};
|
|
12
|
+
/** Button that opens the file dialog; the native input stays hidden. */
|
|
13
|
+
export declare const FilePickerButton: ({ accept, label, disabled, isLoading, id, "aria-describedby": describedBy, onFileSelected, }: FilePickerButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export {};
|