@endora-commerce/admin-kit 0.0.0-stage → 0.100.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/LICENSE +21 -0
- package/README.md +212 -2
- package/dist/components/FileDropzone.d.ts +13 -0
- package/dist/components/FileDropzone.d.ts.map +1 -0
- package/dist/components/FileDropzone.js +39 -0
- package/dist/components/FileDropzone.js.map +1 -0
- package/dist/components/PaginationFooter.d.ts +25 -0
- package/dist/components/PaginationFooter.d.ts.map +1 -0
- package/dist/components/PaginationFooter.js +33 -0
- package/dist/components/PaginationFooter.js.map +1 -0
- package/dist/components/ResponsiveTable.d.ts +26 -0
- package/dist/components/ResponsiveTable.d.ts.map +1 -0
- package/dist/components/ResponsiveTable.js +34 -0
- package/dist/components/ResponsiveTable.js.map +1 -0
- package/dist/components/RowActionMenu.d.ts +40 -0
- package/dist/components/RowActionMenu.d.ts.map +1 -0
- package/dist/components/RowActionMenu.js +15 -0
- package/dist/components/RowActionMenu.js.map +1 -0
- package/dist/components/StickyFormActions.d.ts +10 -0
- package/dist/components/StickyFormActions.d.ts.map +1 -0
- package/dist/components/StickyFormActions.js +10 -0
- package/dist/components/StickyFormActions.js.map +1 -0
- package/dist/components/TouchReorderButtons.d.ts +13 -0
- package/dist/components/TouchReorderButtons.d.ts.map +1 -0
- package/dist/components/TouchReorderButtons.js +12 -0
- package/dist/components/TouchReorderButtons.js.map +1 -0
- package/dist/components/admin-user-picker/AdminUserPicker.d.ts +14 -0
- package/dist/components/admin-user-picker/AdminUserPicker.d.ts.map +1 -0
- package/dist/components/admin-user-picker/AdminUserPicker.js +68 -0
- package/dist/components/admin-user-picker/AdminUserPicker.js.map +1 -0
- package/dist/components/asset-picker/AssetFieldPicker.d.ts +32 -0
- package/dist/components/asset-picker/AssetFieldPicker.d.ts.map +1 -0
- package/dist/components/asset-picker/AssetFieldPicker.js +42 -0
- package/dist/components/asset-picker/AssetFieldPicker.js.map +1 -0
- package/dist/components/asset-picker/AssetPicker.d.ts +31 -0
- package/dist/components/asset-picker/AssetPicker.d.ts.map +1 -0
- package/dist/components/asset-picker/AssetPicker.js +68 -0
- package/dist/components/asset-picker/AssetPicker.js.map +1 -0
- package/dist/components/asset-picker/AssetUploader.d.ts +15 -0
- package/dist/components/asset-picker/AssetUploader.d.ts.map +1 -0
- package/dist/components/asset-picker/AssetUploader.js +61 -0
- package/dist/components/asset-picker/AssetUploader.js.map +1 -0
- package/dist/components/asset-picker/assets-api.d.ts +49 -0
- package/dist/components/asset-picker/assets-api.d.ts.map +1 -0
- package/dist/components/asset-picker/assets-api.js +67 -0
- package/dist/components/asset-picker/assets-api.js.map +1 -0
- package/dist/components/category-picker/CategorySelect.d.ts +14 -0
- package/dist/components/category-picker/CategorySelect.d.ts.map +1 -0
- package/dist/components/category-picker/CategorySelect.js +41 -0
- package/dist/components/category-picker/CategorySelect.js.map +1 -0
- package/dist/components/category-tree-picker/CategoryTreeNodeRow.d.ts +18 -0
- package/dist/components/category-tree-picker/CategoryTreeNodeRow.d.ts.map +1 -0
- package/dist/components/category-tree-picker/CategoryTreeNodeRow.js +19 -0
- package/dist/components/category-tree-picker/CategoryTreeNodeRow.js.map +1 -0
- package/dist/components/category-tree-picker/CategoryTreePicker.d.ts +23 -0
- package/dist/components/category-tree-picker/CategoryTreePicker.d.ts.map +1 -0
- package/dist/components/category-tree-picker/CategoryTreePicker.js +82 -0
- package/dist/components/category-tree-picker/CategoryTreePicker.js.map +1 -0
- package/dist/components/category-tree-picker/category-tree-utils.d.ts +35 -0
- package/dist/components/category-tree-picker/category-tree-utils.d.ts.map +1 -0
- package/dist/components/category-tree-picker/category-tree-utils.js +140 -0
- package/dist/components/category-tree-picker/category-tree-utils.js.map +1 -0
- package/dist/components/category-tree-picker/index.d.ts +4 -0
- package/dist/components/category-tree-picker/index.d.ts.map +1 -0
- package/dist/components/category-tree-picker/index.js +2 -0
- package/dist/components/category-tree-picker/index.js.map +1 -0
- package/dist/components/charts/echart.d.ts +17 -0
- package/dist/components/charts/echart.d.ts.map +1 -0
- package/dist/components/charts/echart.js +61 -0
- package/dist/components/charts/echart.js.map +1 -0
- package/dist/components/cms-picker/CmsBlockPicker.d.ts +14 -0
- package/dist/components/cms-picker/CmsBlockPicker.d.ts.map +1 -0
- package/dist/components/cms-picker/CmsBlockPicker.js +40 -0
- package/dist/components/cms-picker/CmsBlockPicker.js.map +1 -0
- package/dist/components/cms-picker/CmsPagePicker.d.ts +15 -0
- package/dist/components/cms-picker/CmsPagePicker.d.ts.map +1 -0
- package/dist/components/cms-picker/CmsPagePicker.js +80 -0
- package/dist/components/cms-picker/CmsPagePicker.js.map +1 -0
- package/dist/components/content-language-tabs/ContentLanguageTabs.d.ts +30 -0
- package/dist/components/content-language-tabs/ContentLanguageTabs.d.ts.map +1 -0
- package/dist/components/content-language-tabs/ContentLanguageTabs.js +14 -0
- package/dist/components/content-language-tabs/ContentLanguageTabs.js.map +1 -0
- package/dist/components/country-select/CountrySelect.d.ts +29 -0
- package/dist/components/country-select/CountrySelect.d.ts.map +1 -0
- package/dist/components/country-select/CountrySelect.js +40 -0
- package/dist/components/country-select/CountrySelect.js.map +1 -0
- package/dist/components/country-select/index.d.ts +3 -0
- package/dist/components/country-select/index.d.ts.map +1 -0
- package/dist/components/country-select/index.js +3 -0
- package/dist/components/country-select/index.js.map +1 -0
- package/dist/components/country-select/useCountriesQuery.d.ts +12 -0
- package/dist/components/country-select/useCountriesQuery.d.ts.map +1 -0
- package/dist/components/country-select/useCountriesQuery.js +69 -0
- package/dist/components/country-select/useCountriesQuery.js.map +1 -0
- package/dist/components/custom-field-values/CustomFieldValuesPanel.d.ts +48 -0
- package/dist/components/custom-field-values/CustomFieldValuesPanel.d.ts.map +1 -0
- package/dist/components/custom-field-values/CustomFieldValuesPanel.js +122 -0
- package/dist/components/custom-field-values/CustomFieldValuesPanel.js.map +1 -0
- package/dist/components/customer-group-picker/CustomerGroupPicker.d.ts +14 -0
- package/dist/components/customer-group-picker/CustomerGroupPicker.d.ts.map +1 -0
- package/dist/components/customer-group-picker/CustomerGroupPicker.js +36 -0
- package/dist/components/customer-group-picker/CustomerGroupPicker.js.map +1 -0
- package/dist/components/customer-picker/CustomerPicker.d.ts +18 -0
- package/dist/components/customer-picker/CustomerPicker.d.ts.map +1 -0
- package/dist/components/customer-picker/CustomerPicker.js +85 -0
- package/dist/components/customer-picker/CustomerPicker.js.map +1 -0
- package/dist/components/dictionary-picker/CountryPicker.d.ts +26 -0
- package/dist/components/dictionary-picker/CountryPicker.d.ts.map +1 -0
- package/dist/components/dictionary-picker/CountryPicker.js +29 -0
- package/dist/components/dictionary-picker/CountryPicker.js.map +1 -0
- package/dist/components/dictionary-picker/CurrencyPicker.d.ts +17 -0
- package/dist/components/dictionary-picker/CurrencyPicker.d.ts.map +1 -0
- package/dist/components/dictionary-picker/CurrencyPicker.js +29 -0
- package/dist/components/dictionary-picker/CurrencyPicker.js.map +1 -0
- package/dist/components/dictionary-picker/dictionary-api.d.ts +21 -0
- package/dist/components/dictionary-picker/dictionary-api.d.ts.map +1 -0
- package/dist/components/dictionary-picker/dictionary-api.js +26 -0
- package/dist/components/dictionary-picker/dictionary-api.js.map +1 -0
- package/dist/components/dictionary-picker/index.d.ts +4 -0
- package/dist/components/dictionary-picker/index.d.ts.map +1 -0
- package/dist/components/dictionary-picker/index.js +4 -0
- package/dist/components/dictionary-picker/index.js.map +1 -0
- package/dist/components/fulfilment-strategy-picker/FulfilmentStrategyPicker.d.ts +49 -0
- package/dist/components/fulfilment-strategy-picker/FulfilmentStrategyPicker.d.ts.map +1 -0
- package/dist/components/fulfilment-strategy-picker/FulfilmentStrategyPicker.js +43 -0
- package/dist/components/fulfilment-strategy-picker/FulfilmentStrategyPicker.js.map +1 -0
- package/dist/components/hooks/useFocusTrap.d.ts +6 -0
- package/dist/components/hooks/useFocusTrap.d.ts.map +1 -0
- package/dist/components/hooks/useFocusTrap.js +41 -0
- package/dist/components/hooks/useFocusTrap.js.map +1 -0
- package/dist/components/hooks/useViewportTier.d.ts +7 -0
- package/dist/components/hooks/useViewportTier.d.ts.map +1 -0
- package/dist/components/hooks/useViewportTier.js +23 -0
- package/dist/components/hooks/useViewportTier.js.map +1 -0
- package/dist/components/index.d.ts +101 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +63 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/organization-picker/OrganizationPicker.d.ts +28 -0
- package/dist/components/organization-picker/OrganizationPicker.d.ts.map +1 -0
- package/dist/components/organization-picker/OrganizationPicker.js +35 -0
- package/dist/components/organization-picker/OrganizationPicker.js.map +1 -0
- package/dist/components/organization-picker/OrganizationPickerMulti.d.ts +32 -0
- package/dist/components/organization-picker/OrganizationPickerMulti.d.ts.map +1 -0
- package/dist/components/organization-picker/OrganizationPickerMulti.js +55 -0
- package/dist/components/organization-picker/OrganizationPickerMulti.js.map +1 -0
- package/dist/components/organization-picker/OrganizationStatusBadge.d.ts +7 -0
- package/dist/components/organization-picker/OrganizationStatusBadge.d.ts.map +1 -0
- package/dist/components/organization-picker/OrganizationStatusBadge.js +33 -0
- package/dist/components/organization-picker/OrganizationStatusBadge.js.map +1 -0
- package/dist/components/organization-picker/useOrganizationsQuery.d.ts +33 -0
- package/dist/components/organization-picker/useOrganizationsQuery.d.ts.map +1 -0
- package/dist/components/organization-picker/useOrganizationsQuery.js +92 -0
- package/dist/components/organization-picker/useOrganizationsQuery.js.map +1 -0
- package/dist/components/payment-method-availability/MethodAvailabilityCell.d.ts +38 -0
- package/dist/components/payment-method-availability/MethodAvailabilityCell.d.ts.map +1 -0
- package/dist/components/payment-method-availability/MethodAvailabilityCell.js +50 -0
- package/dist/components/payment-method-availability/MethodAvailabilityCell.js.map +1 -0
- package/dist/components/product-picker/ProductPicker.d.ts +22 -0
- package/dist/components/product-picker/ProductPicker.d.ts.map +1 -0
- package/dist/components/product-picker/ProductPicker.js +143 -0
- package/dist/components/product-picker/ProductPicker.js.map +1 -0
- package/dist/components/reorder/ReorderAnnouncer.d.ts +29 -0
- package/dist/components/reorder/ReorderAnnouncer.d.ts.map +1 -0
- package/dist/components/reorder/ReorderAnnouncer.js +6 -0
- package/dist/components/reorder/ReorderAnnouncer.js.map +1 -0
- package/dist/components/reorder/useReorderList.d.ts +121 -0
- package/dist/components/reorder/useReorderList.d.ts.map +1 -0
- package/dist/components/reorder/useReorderList.js +241 -0
- package/dist/components/reorder/useReorderList.js.map +1 -0
- package/dist/components/rule-builder/RuleBuilder.d.ts +105 -0
- package/dist/components/rule-builder/RuleBuilder.d.ts.map +1 -0
- package/dist/components/rule-builder/RuleBuilder.js +138 -0
- package/dist/components/rule-builder/RuleBuilder.js.map +1 -0
- package/dist/components/sales-channel-picker/SalesChannelPicker.d.ts +15 -0
- package/dist/components/sales-channel-picker/SalesChannelPicker.d.ts.map +1 -0
- package/dist/components/sales-channel-picker/SalesChannelPicker.js +79 -0
- package/dist/components/sales-channel-picker/SalesChannelPicker.js.map +1 -0
- package/dist/components/scope-notice/ScopeNotice.d.ts +33 -0
- package/dist/components/scope-notice/ScopeNotice.d.ts.map +1 -0
- package/dist/components/scope-notice/ScopeNotice.js +11 -0
- package/dist/components/scope-notice/ScopeNotice.js.map +1 -0
- package/dist/components/scope-picker/ScopePicker.d.ts +28 -0
- package/dist/components/scope-picker/ScopePicker.d.ts.map +1 -0
- package/dist/components/scope-picker/ScopePicker.js +114 -0
- package/dist/components/scope-picker/ScopePicker.js.map +1 -0
- package/dist/components/scope-picker/sales-channels-api.d.ts +19 -0
- package/dist/components/scope-picker/sales-channels-api.d.ts.map +1 -0
- package/dist/components/scope-picker/sales-channels-api.js +30 -0
- package/dist/components/scope-picker/sales-channels-api.js.map +1 -0
- package/dist/components/status-transition-graph/StatusTransitionGraph.d.ts +26 -0
- package/dist/components/status-transition-graph/StatusTransitionGraph.d.ts.map +1 -0
- package/dist/components/status-transition-graph/StatusTransitionGraph.js +241 -0
- package/dist/components/status-transition-graph/StatusTransitionGraph.js.map +1 -0
- package/dist/components/status-transition-graph/index.d.ts +3 -0
- package/dist/components/status-transition-graph/index.d.ts.map +1 -0
- package/dist/components/status-transition-graph/index.js +2 -0
- package/dist/components/status-transition-graph/index.js.map +1 -0
- package/dist/contributions/index.d.ts +44 -0
- package/dist/contributions/index.d.ts.map +1 -0
- package/dist/contributions/index.js +42 -0
- package/dist/contributions/index.js.map +1 -0
- package/dist/contributions/zone-component.d.ts +70 -0
- package/dist/contributions/zone-component.d.ts.map +1 -0
- package/dist/contributions/zone-component.js +26 -0
- package/dist/contributions/zone-component.js.map +1 -0
- package/dist/field-protection/FieldProtectionPricePanel.d.ts +26 -0
- package/dist/field-protection/FieldProtectionPricePanel.d.ts.map +1 -0
- package/dist/field-protection/FieldProtectionPricePanel.js +14 -0
- package/dist/field-protection/FieldProtectionPricePanel.js.map +1 -0
- package/dist/field-protection/FieldProtectionSummary.d.ts +18 -0
- package/dist/field-protection/FieldProtectionSummary.d.ts.map +1 -0
- package/dist/field-protection/FieldProtectionSummary.js +18 -0
- package/dist/field-protection/FieldProtectionSummary.js.map +1 -0
- package/dist/field-protection/FieldProtectionToggle.d.ts +36 -0
- package/dist/field-protection/FieldProtectionToggle.d.ts.map +1 -0
- package/dist/field-protection/FieldProtectionToggle.js +30 -0
- package/dist/field-protection/FieldProtectionToggle.js.map +1 -0
- package/dist/field-protection/describe-path.d.ts +27 -0
- package/dist/field-protection/describe-path.d.ts.map +1 -0
- package/dist/field-protection/describe-path.js +28 -0
- package/dist/field-protection/describe-path.js.map +1 -0
- package/dist/field-protection/index.d.ts +46 -0
- package/dist/field-protection/index.d.ts.map +1 -0
- package/dist/field-protection/index.js +41 -0
- package/dist/field-protection/index.js.map +1 -0
- package/dist/field-protection/types.d.ts +93 -0
- package/dist/field-protection/types.d.ts.map +1 -0
- package/dist/field-protection/types.js +2 -0
- package/dist/field-protection/types.js.map +1 -0
- package/dist/field-protection/use-field-protection.d.ts +27 -0
- package/dist/field-protection/use-field-protection.d.ts.map +1 -0
- package/dist/field-protection/use-field-protection.js +149 -0
- package/dist/field-protection/use-field-protection.js.map +1 -0
- package/dist/i18n/TranslationProvider.d.ts +27 -0
- package/dist/i18n/TranslationProvider.d.ts.map +1 -0
- package/dist/i18n/TranslationProvider.js +130 -0
- package/dist/i18n/TranslationProvider.js.map +1 -0
- package/dist/i18n/app-language-context.d.ts +8 -0
- package/dist/i18n/app-language-context.d.ts.map +1 -0
- package/dist/i18n/app-language-context.js +13 -0
- package/dist/i18n/app-language-context.js.map +1 -0
- package/dist/i18n/index.d.ts +29 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +25 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/interpolate.d.ts +2 -0
- package/dist/i18n/interpolate.d.ts.map +1 -0
- package/dist/i18n/interpolate.js +10 -0
- package/dist/i18n/interpolate.js.map +1 -0
- package/dist/i18n/language-storage.d.ts +16 -0
- package/dist/i18n/language-storage.d.ts.map +1 -0
- package/dist/i18n/language-storage.js +26 -0
- package/dist/i18n/language-storage.js.map +1 -0
- package/dist/i18n/resolver.d.ts +19 -0
- package/dist/i18n/resolver.d.ts.map +1 -0
- package/dist/i18n/resolver.js +23 -0
- package/dist/i18n/resolver.js.map +1 -0
- package/dist/i18n/types.d.ts +12 -0
- package/dist/i18n/types.d.ts.map +1 -0
- package/dist/i18n/types.js +7 -0
- package/dist/i18n/types.js.map +1 -0
- package/dist/i18n/useTranslation.d.ts +2 -0
- package/dist/i18n/useTranslation.d.ts.map +1 -0
- package/dist/i18n/useTranslation.js +16 -0
- package/dist/i18n/useTranslation.js.map +1 -0
- package/dist/lib/admin-actions/icon-map.d.ts +3 -0
- package/dist/lib/admin-actions/icon-map.d.ts.map +1 -0
- package/dist/lib/admin-actions/icon-map.js +115 -0
- package/dist/lib/admin-actions/icon-map.js.map +1 -0
- package/dist/lib/api-client.d.ts +55 -0
- package/dist/lib/api-client.d.ts.map +1 -0
- package/dist/lib/api-client.js +89 -0
- package/dist/lib/api-client.js.map +1 -0
- package/dist/lib/asset-url.d.ts +32 -0
- package/dist/lib/asset-url.d.ts.map +1 -0
- package/dist/lib/asset-url.js +42 -0
- package/dist/lib/asset-url.js.map +1 -0
- package/dist/lib/auth.d.ts +92 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +133 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/format.d.ts +2 -0
- package/dist/lib/format.d.ts.map +1 -0
- package/dist/lib/format.js +9 -0
- package/dist/lib/format.js.map +1 -0
- package/dist/lib/index.d.ts +46 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +41 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/invoice-email-outcome.d.ts +53 -0
- package/dist/lib/invoice-email-outcome.d.ts.map +1 -0
- package/dist/lib/invoice-email-outcome.js +43 -0
- package/dist/lib/invoice-email-outcome.js.map +1 -0
- package/dist/lib/module-presence/ModulePresenceProvider.d.ts +49 -0
- package/dist/lib/module-presence/ModulePresenceProvider.d.ts.map +1 -0
- package/dist/lib/module-presence/ModulePresenceProvider.js +73 -0
- package/dist/lib/module-presence/ModulePresenceProvider.js.map +1 -0
- package/dist/lib/module-presence/api.d.ts +15 -0
- package/dist/lib/module-presence/api.d.ts.map +1 -0
- package/dist/lib/module-presence/api.js +25 -0
- package/dist/lib/module-presence/api.js.map +1 -0
- package/dist/lib/module-presence/index.d.ts +3 -0
- package/dist/lib/module-presence/index.d.ts.map +1 -0
- package/dist/lib/module-presence/index.js +3 -0
- package/dist/lib/module-presence/index.js.map +1 -0
- package/dist/lib/money.d.ts +22 -0
- package/dist/lib/money.d.ts.map +1 -0
- package/dist/lib/money.js +51 -0
- package/dist/lib/money.js.map +1 -0
- package/dist/lib/page-size-options.d.ts +15 -0
- package/dist/lib/page-size-options.d.ts.map +1 -0
- package/dist/lib/page-size-options.js +14 -0
- package/dist/lib/page-size-options.js.map +1 -0
- package/dist/lib/status-color.d.ts +32 -0
- package/dist/lib/status-color.d.ts.map +1 -0
- package/dist/lib/status-color.js +24 -0
- package/dist/lib/status-color.js.map +1 -0
- package/dist/lib/surface-visibility.d.ts +70 -0
- package/dist/lib/surface-visibility.d.ts.map +1 -0
- package/dist/lib/surface-visibility.js +37 -0
- package/dist/lib/surface-visibility.js.map +1 -0
- package/dist/lib/text-normalization.d.ts +56 -0
- package/dist/lib/text-normalization.d.ts.map +1 -0
- package/dist/lib/text-normalization.js +59 -0
- package/dist/lib/text-normalization.js.map +1 -0
- package/dist/lib/use-page-size-preference.d.ts +29 -0
- package/dist/lib/use-page-size-preference.d.ts.map +1 -0
- package/dist/lib/use-page-size-preference.js +61 -0
- package/dist/lib/use-page-size-preference.js.map +1 -0
- package/dist/lib/use-unsaved-changes-prompt.d.ts +23 -0
- package/dist/lib/use-unsaved-changes-prompt.d.ts.map +1 -0
- package/dist/lib/use-unsaved-changes-prompt.js +75 -0
- package/dist/lib/use-unsaved-changes-prompt.js.map +1 -0
- package/dist/lib/utils.d.ts +9 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +12 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/lib/uuid.d.ts +8 -0
- package/dist/lib/uuid.d.ts.map +1 -0
- package/dist/lib/uuid.js +18 -0
- package/dist/lib/uuid.js.map +1 -0
- package/dist/ui/alert.d.ts +12 -0
- package/dist/ui/alert.d.ts.map +1 -0
- package/dist/ui/alert.js +22 -0
- package/dist/ui/alert.js.map +1 -0
- package/dist/ui/badge.d.ts +10 -0
- package/dist/ui/badge.d.ts.map +1 -0
- package/dist/ui/badge.js +21 -0
- package/dist/ui/badge.js.map +1 -0
- package/dist/ui/button.d.ts +12 -0
- package/dist/ui/button.d.ts.map +1 -0
- package/dist/ui/button.js +31 -0
- package/dist/ui/button.js.map +1 -0
- package/dist/ui/card.d.ts +8 -0
- package/dist/ui/card.d.ts.map +1 -0
- package/dist/ui/card.js +16 -0
- package/dist/ui/card.js.map +1 -0
- package/dist/ui/checkbox.d.ts +8 -0
- package/dist/ui/checkbox.d.ts.map +1 -0
- package/dist/ui/checkbox.js +11 -0
- package/dist/ui/checkbox.js.map +1 -0
- package/dist/ui/color-picker.d.ts +23 -0
- package/dist/ui/color-picker.d.ts.map +1 -0
- package/dist/ui/color-picker.js +76 -0
- package/dist/ui/color-picker.js.map +1 -0
- package/dist/ui/combobox.d.ts +68 -0
- package/dist/ui/combobox.d.ts.map +1 -0
- package/dist/ui/combobox.js +182 -0
- package/dist/ui/combobox.js.map +1 -0
- package/dist/ui/dropdown-menu.d.ts +26 -0
- package/dist/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/ui/dropdown-menu.js +38 -0
- package/dist/ui/dropdown-menu.js.map +1 -0
- package/dist/ui/index.d.ts +47 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +38 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/input.d.ts +3 -0
- package/dist/ui/input.d.ts.map +1 -0
- package/dist/ui/input.js +8 -0
- package/dist/ui/input.js.map +1 -0
- package/dist/ui/label.d.ts +4 -0
- package/dist/ui/label.d.ts.map +1 -0
- package/dist/ui/label.js +9 -0
- package/dist/ui/label.js.map +1 -0
- package/dist/ui/multi-select.d.ts +32 -0
- package/dist/ui/multi-select.d.ts.map +1 -0
- package/dist/ui/multi-select.js +63 -0
- package/dist/ui/multi-select.js.map +1 -0
- package/dist/ui/page-header.d.ts +21 -0
- package/dist/ui/page-header.d.ts.map +1 -0
- package/dist/ui/page-header.js +9 -0
- package/dist/ui/page-header.js.map +1 -0
- package/dist/ui/route-tabs.d.ts +58 -0
- package/dist/ui/route-tabs.d.ts.map +1 -0
- package/dist/ui/route-tabs.js +34 -0
- package/dist/ui/route-tabs.js.map +1 -0
- package/dist/ui/save-button-group.d.ts +27 -0
- package/dist/ui/save-button-group.d.ts.map +1 -0
- package/dist/ui/save-button-group.js +44 -0
- package/dist/ui/save-button-group.js.map +1 -0
- package/dist/ui/section.d.ts +20 -0
- package/dist/ui/section.d.ts.map +1 -0
- package/dist/ui/section.js +7 -0
- package/dist/ui/section.js.map +1 -0
- package/dist/ui/select.d.ts +10 -0
- package/dist/ui/select.d.ts.map +1 -0
- package/dist/ui/select.js +15 -0
- package/dist/ui/select.js.map +1 -0
- package/dist/ui/separator.d.ts +3 -0
- package/dist/ui/separator.d.ts.map +1 -0
- package/dist/ui/separator.js +7 -0
- package/dist/ui/separator.js.map +1 -0
- package/dist/ui/table.d.ts +10 -0
- package/dist/ui/table.d.ts.map +1 -0
- package/dist/ui/table.js +20 -0
- package/dist/ui/table.js.map +1 -0
- package/dist/ui/textarea.d.ts +3 -0
- package/dist/ui/textarea.d.ts.map +1 -0
- package/dist/ui/textarea.js +8 -0
- package/dist/ui/textarea.js.map +1 -0
- package/dist/zones/AdminContributionsProvider.d.ts +72 -0
- package/dist/zones/AdminContributionsProvider.d.ts.map +1 -0
- package/dist/zones/AdminContributionsProvider.js +63 -0
- package/dist/zones/AdminContributionsProvider.js.map +1 -0
- package/dist/zones/AdminZone.d.ts +30 -0
- package/dist/zones/AdminZone.d.ts.map +1 -0
- package/dist/zones/AdminZone.js +59 -0
- package/dist/zones/AdminZone.js.map +1 -0
- package/dist/zones/RouteTabsZone.d.ts +62 -0
- package/dist/zones/RouteTabsZone.d.ts.map +1 -0
- package/dist/zones/RouteTabsZone.js +25 -0
- package/dist/zones/RouteTabsZone.js.map +1 -0
- package/dist/zones/ZoneErrorBoundary.d.ts +36 -0
- package/dist/zones/ZoneErrorBoundary.d.ts.map +1 -0
- package/dist/zones/ZoneErrorBoundary.js +44 -0
- package/dist/zones/ZoneErrorBoundary.js.map +1 -0
- package/dist/zones/index.d.ts +31 -0
- package/dist/zones/index.d.ts.map +1 -0
- package/dist/zones/index.js +27 -0
- package/dist/zones/index.js.map +1 -0
- package/dist/zones/use-admin-zone.d.ts +32 -0
- package/dist/zones/use-admin-zone.d.ts.map +1 -0
- package/dist/zones/use-admin-zone.js +96 -0
- package/dist/zones/use-admin-zone.js.map +1 -0
- package/package.json +94 -3
- package/tailwind.css +14 -0
- package/theme.css +2056 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { ApiError, apiClient } from '../../lib/api-client.js';
|
|
4
|
+
import { Combobox } from '../../ui/combobox.js';
|
|
5
|
+
function adminUserLabel(u) {
|
|
6
|
+
const name = `${u.firstName} ${u.lastName}`.trim();
|
|
7
|
+
return name.length > 0 ? name : u.email;
|
|
8
|
+
}
|
|
9
|
+
const SEARCH_DEBOUNCE_MS = 250;
|
|
10
|
+
const DEFAULT_PAGE_SIZE = 20;
|
|
11
|
+
export function AdminUserPicker(props) {
|
|
12
|
+
const [cache, setCache] = useState(() => new Map());
|
|
13
|
+
const [options, setOptions] = useState([]);
|
|
14
|
+
const [searching, setSearching] = useState(false);
|
|
15
|
+
const [error, setError] = useState(null);
|
|
16
|
+
const timerRef = useRef(null);
|
|
17
|
+
const seqRef = useRef(0);
|
|
18
|
+
useEffect(() => () => {
|
|
19
|
+
if (timerRef.current !== null)
|
|
20
|
+
clearTimeout(timerRef.current);
|
|
21
|
+
}, []);
|
|
22
|
+
const runSearch = useCallback(async (query, seq) => {
|
|
23
|
+
setSearching(true);
|
|
24
|
+
setError(null);
|
|
25
|
+
try {
|
|
26
|
+
const params = new URLSearchParams();
|
|
27
|
+
params.set('pageSize', String(DEFAULT_PAGE_SIZE));
|
|
28
|
+
const trimmed = query.trim();
|
|
29
|
+
if (trimmed.length > 0)
|
|
30
|
+
params.set('q', trimmed);
|
|
31
|
+
const res = await apiClient.get(`/api/v1/admin/admin-users?${params.toString()}`);
|
|
32
|
+
if (seq !== seqRef.current)
|
|
33
|
+
return;
|
|
34
|
+
setCache((prev) => {
|
|
35
|
+
const next = new Map(prev);
|
|
36
|
+
for (const u of res.data)
|
|
37
|
+
next.set(u.id, u);
|
|
38
|
+
return next;
|
|
39
|
+
});
|
|
40
|
+
setOptions(res.data.map((u) => ({ value: u.id, label: adminUserLabel(u), description: u.email })));
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (seq !== seqRef.current)
|
|
44
|
+
return;
|
|
45
|
+
setError(err instanceof ApiError ? err.envelope.error.message : 'Search failed.');
|
|
46
|
+
setOptions([]);
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
if (seq === seqRef.current)
|
|
50
|
+
setSearching(false);
|
|
51
|
+
}
|
|
52
|
+
}, []);
|
|
53
|
+
const handleSearchChange = useCallback((query) => {
|
|
54
|
+
if (timerRef.current !== null)
|
|
55
|
+
clearTimeout(timerRef.current);
|
|
56
|
+
const seq = ++seqRef.current;
|
|
57
|
+
timerRef.current = setTimeout(() => void runSearch(query, seq), SEARCH_DEBOUNCE_MS);
|
|
58
|
+
}, [runSearch]);
|
|
59
|
+
const selectedLabel = useMemo(() => {
|
|
60
|
+
if (!props.value)
|
|
61
|
+
return '';
|
|
62
|
+
const u = cache.get(props.value);
|
|
63
|
+
return u ? adminUserLabel(u) : '';
|
|
64
|
+
}, [props.value, cache]);
|
|
65
|
+
const emptyMessage = props.emptyMessage ?? error ?? (searching ? 'Searching…' : 'No matching admin users.');
|
|
66
|
+
return (_jsx(Combobox, { options: options, value: props.value, onChange: props.onChange, onSearchChange: handleSearchChange, manualFilter: true, loading: searching, clearable: props.clearable ?? true, disabled: props.disabled ?? false, placeholder: props.placeholder ?? 'Search admin users by name or email…', emptyMessage: emptyMessage, ariaLabel: props.ariaLabel ?? 'Select admin user', id: props.id ?? '', className: props.className ?? '', selectedLabel: selectedLabel }));
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=AdminUserPicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminUserPicker.js","sourceRoot":"","sources":["../../../src/components/admin-user-picker/AdminUserPicker.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AAC1F,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAuB,MAAM,sBAAsB,CAAC;AAkBrE,SAAS,cAAc,CAAC,CAAmB;IACzC,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;IACnD,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1C,CAAC;AAcD,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAC/B,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAE7B,MAAM,UAAU,eAAe,CAAC,KAA2B;IACzD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgC,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IACnF,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAA2B,EAAE,CAAC,CAAC;IACrE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAExD,MAAM,QAAQ,GAAG,MAAM,CAAuC,IAAI,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACzB,SAAS,CAAC,GAAG,EAAE,CAAC,GAAS,EAAE;QACzB,IAAI,QAAQ,CAAC,OAAO,KAAK,IAAI;YAAE,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAChE,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,EAAE,KAAa,EAAE,GAAW,EAAiB,EAAE;QAChF,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;YACrC,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC;YAClD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;YAC7B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;gBAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YACjD,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,CAC7B,6BAA6B,MAAM,CAAC,QAAQ,EAAE,EAAE,CACjD,CAAC;YACF,IAAI,GAAG,KAAK,MAAM,CAAC,OAAO;gBAAE,OAAO;YACnC,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE;gBAChB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC3B,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,IAAI;oBAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;gBAC5C,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CAAC;YACH,UAAU,CACR,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CACvF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,KAAK,MAAM,CAAC,OAAO;gBAAE,OAAO;YACnC,QAAQ,CAAC,GAAG,YAAY,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;YAClF,UAAU,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;gBAAS,CAAC;YACT,IAAI,GAAG,KAAK,MAAM,CAAC,OAAO;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,kBAAkB,GAAG,WAAW,CACpC,CAAC,KAAa,EAAQ,EAAE;QACtB,IAAI,QAAQ,CAAC,OAAO,KAAK,IAAI;YAAE,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC9D,MAAM,GAAG,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC;QAC7B,QAAQ,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,kBAAkB,CAAC,CAAC;IACtF,CAAC,EACD,CAAC,SAAS,CAAC,CACZ,CAAC;IAEF,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE;QACjC,IAAI,CAAC,KAAK,CAAC,KAAK;YAAE,OAAO,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACjC,OAAO,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IAEzB,MAAM,YAAY,GAChB,KAAK,CAAC,YAAY,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC;IAEzF,OAAO,CACL,KAAC,QAAQ,IACP,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,cAAc,EAAE,kBAAkB,EAClC,YAAY,QACZ,OAAO,EAAE,SAAS,EAClB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI,EAClC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAK,EACjC,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,sCAAsC,EACxE,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,mBAAmB,EACjD,EAAE,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,EAClB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,EAAE,EAChC,aAAa,EAAE,aAAa,GAC5B,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Field-style asset picker.
|
|
4
|
+
*
|
|
5
|
+
* Replaces "paste an asset UUID" inputs: shows the chosen asset's label /
|
|
6
|
+
* filename in a read-only field with a button that toggles the existing
|
|
7
|
+
* Assets-Library grid picker (search + optional inline upload). The
|
|
8
|
+
* committed value is the asset UUID; for a pre-existing value the asset's
|
|
9
|
+
* filename is resolved once so editors see a friendly name instead of a
|
|
10
|
+
* bare UUID.
|
|
11
|
+
*
|
|
12
|
+
* **Published by feature 091's P4c**, with the rest of the asset cluster.
|
|
13
|
+
* `admin-kit-surface.md` R6's stated limit was *"a picker whose module
|
|
14
|
+
* knowledge is a component"*, and this was its worked example: it renders
|
|
15
|
+
* `assets_library`' `AssetPicker`, so there looked to be no request to rebuild.
|
|
16
|
+
* `admin-component-contribution.md` Z1.1 measured one level deeper and found
|
|
17
|
+
* that `AssetPicker` holds no module knowledge either — one `GET` and three
|
|
18
|
+
* contract types. Both moved together, so the reach is repaired rather than
|
|
19
|
+
* reclassified.
|
|
20
|
+
*/
|
|
21
|
+
export interface AssetFieldPickerProps {
|
|
22
|
+
value: string;
|
|
23
|
+
onChange: (assetId: string) => void;
|
|
24
|
+
acceptMimePrefix?: 'image/' | 'video/';
|
|
25
|
+
allowUpload?: boolean;
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
id?: string;
|
|
28
|
+
placeholder?: string;
|
|
29
|
+
ariaLabel?: string;
|
|
30
|
+
}
|
|
31
|
+
export declare function AssetFieldPicker(props: AssetFieldPickerProps): ReactNode;
|
|
32
|
+
//# sourceMappingURL=AssetFieldPicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetFieldPicker.d.ts","sourceRoot":"","sources":["../../../src/components/asset-picker/AssetFieldPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAQ5D;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,gBAAgB,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,SAAS,CA4ExE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { X } from 'lucide-react';
|
|
4
|
+
import { Button } from '../../ui/button.js';
|
|
5
|
+
import { Input } from '../../ui/input.js';
|
|
6
|
+
import { AssetPicker } from './AssetPicker.js';
|
|
7
|
+
import { fetchAssetDetail } from './assets-api.js';
|
|
8
|
+
export function AssetFieldPicker(props) {
|
|
9
|
+
const { value, onChange } = props;
|
|
10
|
+
const [open, setOpen] = useState(false);
|
|
11
|
+
const [label, setLabel] = useState(null);
|
|
12
|
+
// Resolve a friendly name for a value the user didn't pick this session
|
|
13
|
+
// (e.g. when editing an existing record).
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (!value) {
|
|
16
|
+
setLabel(null);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
let alive = true;
|
|
20
|
+
void fetchAssetDetail(value)
|
|
21
|
+
.then((a) => {
|
|
22
|
+
if (alive)
|
|
23
|
+
setLabel(a.label ?? a.filename);
|
|
24
|
+
})
|
|
25
|
+
.catch(() => {
|
|
26
|
+
/* unknown / deleted asset — fall back to showing the raw id */
|
|
27
|
+
});
|
|
28
|
+
return () => {
|
|
29
|
+
alive = false;
|
|
30
|
+
};
|
|
31
|
+
}, [value]);
|
|
32
|
+
const onPick = (asset) => {
|
|
33
|
+
onChange(asset.id);
|
|
34
|
+
setLabel(asset.label ?? asset.filename);
|
|
35
|
+
setOpen(false);
|
|
36
|
+
};
|
|
37
|
+
return (_jsxs("div", { className: "space-y-2", children: [open ? (_jsx(AssetPicker, { ...(props.acceptMimePrefix ? { acceptMimePrefix: props.acceptMimePrefix } : {}), allowUpload: props.allowUpload ?? false, onSelect: onPick, onClose: () => setOpen(false) })) : null, _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Input, { ...(props.id ? { id: props.id } : {}), value: label ?? value, readOnly: true, placeholder: props.placeholder ?? 'No asset selected', "aria-label": props.ariaLabel ?? 'Selected asset', className: label ? '' : 'font-mono' }), value && !props.disabled ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => {
|
|
38
|
+
onChange('');
|
|
39
|
+
setLabel(null);
|
|
40
|
+
}, "aria-label": "Clear asset", children: _jsx(X, { className: "size-4", "aria-hidden": "true" }) })) : null, _jsx(Button, { type: "button", variant: "outline", size: "sm", disabled: props.disabled ?? false, onClick: () => setOpen((v) => !v), children: value ? 'Change' : 'Choose' })] })] }));
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=AssetFieldPicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetFieldPicker.js","sourceRoot":"","sources":["../../../src/components/asset-picker/AssetFieldPicker.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { AssetDetail, AssetSummary } from '@endora-commerce/contracts';
|
|
3
|
+
/**
|
|
4
|
+
* **Its copy is `core`'s, not `assets_library`'s** (R-1, 2026-08-31). The
|
|
5
|
+
* component used to call `useTranslation('assets_library')`, which R6 rules is
|
|
6
|
+
* module knowledge for the same reason an admin API client is: the bundle behind
|
|
7
|
+
* a namespace is shipped by a module package the kit does not and may not depend
|
|
8
|
+
* on, resolved at runtime by string, and a renamed key renders `core.<key>` at
|
|
9
|
+
* the operator rather than failing to compile. `Close`, `Loading…` and `Search`
|
|
10
|
+
* are concepts `core` already names, so this reads those; the picker's own three
|
|
11
|
+
* strings moved into `core` under `assetPicker.*`.
|
|
12
|
+
*
|
|
13
|
+
* **The request is built here** (feature 091, P4c). Until this component moved
|
|
14
|
+
* into the kit it called `assets_library`' own admin API client, which is a
|
|
15
|
+
* reach out of the platform's frontend into a module's admin code.
|
|
16
|
+
* `AssetSummary` and `AssetDetail` are `@endora-commerce/contracts`', so only
|
|
17
|
+
* the one `GET` is rebuilt; the shape is the module's published one and is not
|
|
18
|
+
* duplicated.
|
|
19
|
+
*/
|
|
20
|
+
export interface AssetPickerProps {
|
|
21
|
+
/** Filter the picker grid by MIME prefix — e.g. 'image/' for images-only. */
|
|
22
|
+
acceptMimePrefix?: 'image/' | 'video/' | undefined;
|
|
23
|
+
/** Whether to render the inline upload affordance below the grid. */
|
|
24
|
+
allowUpload?: boolean;
|
|
25
|
+
/** Asset chosen → caller resolves any related entity wiring. */
|
|
26
|
+
onSelect: (asset: AssetSummary | AssetDetail) => void;
|
|
27
|
+
/** Optional close handler when used inside an expandable region. */
|
|
28
|
+
onClose?: () => void;
|
|
29
|
+
}
|
|
30
|
+
export declare function AssetPicker(props: AssetPickerProps): ReactNode;
|
|
31
|
+
//# sourceMappingURL=AssetPicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetPicker.d.ts","sourceRoot":"","sources":["../../../src/components/asset-picker/AssetPicker.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAU5E;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IACnD,qEAAqE;IACrE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gEAAgE;IAChE,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,GAAG,WAAW,KAAK,IAAI,CAAC;IACtD,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,SAAS,CAyH9D"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Asset picker — feature 013 / US1.
|
|
3
|
+
// Browse + search + (optional) inline upload, returning a chosen AssetSummary
|
|
4
|
+
// to the caller via onSelect. Renders inline (collapsible card) rather than
|
|
5
|
+
// as a modal because the admin app has no Dialog primitive yet.
|
|
6
|
+
import { useEffect, useState } from 'react';
|
|
7
|
+
import { Button } from '../../ui/button.js';
|
|
8
|
+
import { Card, CardContent } from '../../ui/card.js';
|
|
9
|
+
import { Input } from '../../ui/input.js';
|
|
10
|
+
import { Alert, AlertDescription } from '../../ui/alert.js';
|
|
11
|
+
import { useTranslation } from '../../i18n/useTranslation.js';
|
|
12
|
+
import { toAbsoluteAssetUrl } from '../../lib/index.js';
|
|
13
|
+
import { AssetUploader } from './AssetUploader.js';
|
|
14
|
+
import { listAssets } from './assets-api.js';
|
|
15
|
+
export function AssetPicker(props) {
|
|
16
|
+
const t = useTranslation('core');
|
|
17
|
+
const [q, setQ] = useState('');
|
|
18
|
+
const [items, setItems] = useState([]);
|
|
19
|
+
const [loading, setLoading] = useState(false);
|
|
20
|
+
const [error, setError] = useState(null);
|
|
21
|
+
const reload = () => {
|
|
22
|
+
setLoading(true);
|
|
23
|
+
setError(null);
|
|
24
|
+
listAssets({
|
|
25
|
+
folderId: null,
|
|
26
|
+
...(q ? { q } : {}),
|
|
27
|
+
...(props.acceptMimePrefix ? { mime: props.acceptMimePrefix } : {}),
|
|
28
|
+
limit: 24,
|
|
29
|
+
})
|
|
30
|
+
.then((res) => setItems(res.data))
|
|
31
|
+
.catch((e) => setError(e instanceof Error ? e.message : String(e)))
|
|
32
|
+
.finally(() => setLoading(false));
|
|
33
|
+
};
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
reload();
|
|
36
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
37
|
+
}, [props.acceptMimePrefix]);
|
|
38
|
+
return (_jsx(Card, { className: "border-2 border-primary/40", children: _jsxs(CardContent, { className: "space-y-3 pt-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Input, { value: q, placeholder: t('assetPicker.searchPlaceholder'), onChange: (e) => setQ(e.target.value), onKeyDown: (e) => {
|
|
39
|
+
if (e.key === 'Enter')
|
|
40
|
+
reload();
|
|
41
|
+
} }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: reload, children: t('common.action.search') }), props.onClose ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: props.onClose, children: t('common.action.close') })) : null] }), error ? (_jsx(Alert, { variant: "destructive", children: _jsx(AlertDescription, { children: error }) })) : null, loading ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('common.state.loading') })) : items.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('assetPicker.empty') })) : (_jsx("div", { className: "grid grid-cols-2 gap-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6", children: items.map((a) => (_jsxs("button", { type: "button", onClick: () => props.onSelect(a), className: "group relative overflow-hidden rounded-md border bg-muted/30 p-1 text-left transition hover:border-primary", title: a.filename, children: [a.mimeType.startsWith('image/') ? (
|
|
42
|
+
// eslint-disable-next-line jsx-a11y/alt-text
|
|
43
|
+
_jsx("img", { src: toAbsoluteAssetUrl(a.url), className: "aspect-square w-full rounded object-cover", loading: "lazy" })) : (_jsx("div", { className: "flex aspect-square w-full items-center justify-center rounded bg-muted text-xs text-muted-foreground", children: a.mimeType })), _jsx("div", { className: "mt-1 truncate text-xs", children: a.label ?? a.filename })] }, a.id))) })), props.allowUpload ? (_jsxs("div", { className: "border-t pt-3", children: [_jsx("p", { className: "mb-1 text-sm font-medium", children: t('assetPicker.uploadNew') }), _jsx(AssetUploader, { ...(props.acceptMimePrefix !== undefined
|
|
44
|
+
? { acceptPrefix: props.acceptMimePrefix }
|
|
45
|
+
: {}), onUploaded: (a) => {
|
|
46
|
+
// Newly-uploaded asset goes into the grid AND is selected.
|
|
47
|
+
setItems((prev) => [
|
|
48
|
+
{
|
|
49
|
+
id: a.id,
|
|
50
|
+
folderId: a.folderId,
|
|
51
|
+
filename: a.filename,
|
|
52
|
+
label: a.label,
|
|
53
|
+
mimeType: a.mimeType,
|
|
54
|
+
sizeBytes: a.sizeBytes,
|
|
55
|
+
visibility: a.visibility,
|
|
56
|
+
storageBackend: a.storageBackend,
|
|
57
|
+
url: a.url,
|
|
58
|
+
createdAt: a.createdAt,
|
|
59
|
+
updatedAt: a.updatedAt,
|
|
60
|
+
deletedAt: a.deletedAt,
|
|
61
|
+
pendingCleanup: a.pendingCleanup,
|
|
62
|
+
},
|
|
63
|
+
...prev,
|
|
64
|
+
]);
|
|
65
|
+
props.onSelect(a);
|
|
66
|
+
} })] })) : null] }) }));
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=AssetPicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetPicker.js","sourceRoot":"","sources":["../../../src/components/asset-picker/AssetPicker.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { AssetDetail } from '@endora-commerce/contracts';
|
|
3
|
+
import { type AssetUploadFields } from './assets-api.js';
|
|
4
|
+
export interface AssetUploaderProps {
|
|
5
|
+
/** File MIME prefix to accept — e.g. 'image/' for image-only inputs. */
|
|
6
|
+
acceptPrefix?: 'image/' | 'video/' | undefined;
|
|
7
|
+
/** Default upload fields (folder, label, visibility). */
|
|
8
|
+
defaults?: AssetUploadFields;
|
|
9
|
+
/** Called after a successful upload. */
|
|
10
|
+
onUploaded: (asset: AssetDetail) => void;
|
|
11
|
+
/** Optional inline label for the trigger button. */
|
|
12
|
+
triggerLabel?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function AssetUploader({ acceptPrefix, defaults, onUploaded, triggerLabel, }: AssetUploaderProps): ReactNode;
|
|
15
|
+
//# sourceMappingURL=AssetUploader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetUploader.d.ts","sourceRoot":"","sources":["../../../src/components/asset-picker/AssetUploader.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAsD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC3F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAI9D,OAAO,EAAe,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEtE,MAAM,WAAW,kBAAkB;IACjC,wEAAwE;IACxE,YAAY,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC/C,yDAAyD;IACzD,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,wCAAwC;IACxC,UAAU,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACzC,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,aAAa,CAAC,EAC5B,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,YAAY,GACb,EAAE,kBAAkB,GAAG,SAAS,CAsFhC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Drag-and-drop / file-input uploader — feature 013 / US1.
|
|
3
|
+
// Streams a single file to the Library and emits the resulting AssetDetail on
|
|
4
|
+
// success. The request is the kit's own since feature 091's P4c — see
|
|
5
|
+
// `./assets-api.ts` — and so is the copy, under `core`'s `assetPicker.upload.*`:
|
|
6
|
+
// R-1 (2026-08-31) rules a translation namespace to be module knowledge, so a
|
|
7
|
+
// kit component may not name `assets_library`'s bundle. `AssetPicker`'s header
|
|
8
|
+
// carries the reasoning.
|
|
9
|
+
import { useRef, useState } from 'react';
|
|
10
|
+
import { Button } from '../../ui/button.js';
|
|
11
|
+
import { Alert, AlertDescription } from '../../ui/alert.js';
|
|
12
|
+
import { useTranslation } from '../../i18n/useTranslation.js';
|
|
13
|
+
import { uploadAsset } from './assets-api.js';
|
|
14
|
+
export function AssetUploader({ acceptPrefix, defaults, onUploaded, triggerLabel, }) {
|
|
15
|
+
const t = useTranslation('core');
|
|
16
|
+
const [busy, setBusy] = useState(false);
|
|
17
|
+
const [error, setError] = useState(null);
|
|
18
|
+
const [dragHover, setDragHover] = useState(false);
|
|
19
|
+
const fileInput = useRef(null);
|
|
20
|
+
const handleFile = async (file) => {
|
|
21
|
+
setError(null);
|
|
22
|
+
if (acceptPrefix && !file.type.startsWith(acceptPrefix)) {
|
|
23
|
+
setError(t('assetPicker.upload.error.wrongType', {
|
|
24
|
+
expected: acceptPrefix.replace('/', ''),
|
|
25
|
+
actual: file.type || file.name,
|
|
26
|
+
}));
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
setBusy(true);
|
|
30
|
+
try {
|
|
31
|
+
const asset = await uploadAsset(file, defaults ?? {});
|
|
32
|
+
onUploaded(asset);
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
setBusy(false);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const onChange = (e) => {
|
|
42
|
+
const f = e.target.files?.[0];
|
|
43
|
+
if (f)
|
|
44
|
+
void handleFile(f);
|
|
45
|
+
if (fileInput.current)
|
|
46
|
+
fileInput.current.value = '';
|
|
47
|
+
};
|
|
48
|
+
const onDrop = (e) => {
|
|
49
|
+
e.preventDefault();
|
|
50
|
+
setDragHover(false);
|
|
51
|
+
const f = e.dataTransfer?.files?.[0];
|
|
52
|
+
if (f)
|
|
53
|
+
void handleFile(f);
|
|
54
|
+
};
|
|
55
|
+
const accept = acceptPrefix ? (acceptPrefix === 'image/' ? 'image/*' : 'video/*') : undefined;
|
|
56
|
+
return (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { onDragOver: (e) => {
|
|
57
|
+
e.preventDefault();
|
|
58
|
+
setDragHover(true);
|
|
59
|
+
}, onDragLeave: () => setDragHover(false), onDrop: onDrop, className: `rounded-md border-2 border-dashed p-4 text-center text-sm ${dragHover ? 'border-primary bg-primary/5' : 'border-muted-foreground/30'}`, "aria-label": t('assetPicker.upload.dropAria'), children: [_jsx("input", { ref: fileInput, type: "file", className: "hidden", accept: accept, onChange: onChange }), _jsx("p", { className: "text-muted-foreground", children: busy ? t('assetPicker.upload.uploading') : t('assetPicker.upload.dropCopy') }), _jsx(Button, { type: "button", variant: "outline", size: "sm", className: "mt-2", disabled: busy, onClick: () => fileInput.current?.click(), children: busy ? t('assetPicker.upload.uploading') : (triggerLabel ?? t('assetPicker.upload.trigger')) })] }), error ? (_jsx(Alert, { variant: "destructive", children: _jsx(AlertDescription, { children: error }) })) : null] }));
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=AssetUploader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetUploader.js","sourceRoot":"","sources":["../../../src/components/asset-picker/AssetUploader.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { AssetDetail, ListAssetsResponse } from '@endora-commerce/contracts';
|
|
2
|
+
/**
|
|
3
|
+
* The three Assets-Library requests the kit's asset components make, and the
|
|
4
|
+
* one a consumer needs to turn a stored asset id into something renderable.
|
|
5
|
+
*
|
|
6
|
+
* **The requests are built here** (feature 091, P4c). Until this landed the
|
|
7
|
+
* asset components called `assets_library`' own admin API client, which is a
|
|
8
|
+
* reach out of the platform's frontend into a module's admin code, and
|
|
9
|
+
* `admin-kit-surface.md` R6 refused to publish them for it. P2 settled that an
|
|
10
|
+
* HTTP path and a `@endora-commerce/contracts` schema are **not** module
|
|
11
|
+
* knowledge — a module's *code* is — and Z1.1 measured that the asset cluster is
|
|
12
|
+
* that same shape one component deeper. So the path is rebuilt and the shapes
|
|
13
|
+
* are the owner's published ones, not duplicated.
|
|
14
|
+
*/
|
|
15
|
+
export interface AssetListQuery {
|
|
16
|
+
/** `null` — the library root ("Unsorted"); a UUID — that folder. */
|
|
17
|
+
folderId?: string | null;
|
|
18
|
+
q?: string;
|
|
19
|
+
mime?: string;
|
|
20
|
+
visibility?: 'public' | 'private';
|
|
21
|
+
cursor?: string;
|
|
22
|
+
limit?: number;
|
|
23
|
+
}
|
|
24
|
+
export declare function listAssets(query: AssetListQuery): Promise<ListAssetsResponse>;
|
|
25
|
+
/**
|
|
26
|
+
* Resolve one asset id to its metadata.
|
|
27
|
+
*
|
|
28
|
+
* Published on `./components` beside the components that call it because five
|
|
29
|
+
* screens outside `assets_library` do exactly this and nothing else with that
|
|
30
|
+
* module's client — a stored id has to become a filename or a URL before it can
|
|
31
|
+
* be rendered.
|
|
32
|
+
*/
|
|
33
|
+
export declare function fetchAssetDetail(id: string): Promise<AssetDetail>;
|
|
34
|
+
export interface AssetUploadFields {
|
|
35
|
+
/** UUID of the target folder, or null for "Unsorted". */
|
|
36
|
+
folderId?: string | null;
|
|
37
|
+
label?: string | null;
|
|
38
|
+
visibility?: 'public' | 'private';
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Upload a single file via multipart/form-data.
|
|
42
|
+
*
|
|
43
|
+
* The typed `apiClient` is JSON-only, so multipart goes through a direct
|
|
44
|
+
* `fetch` over the same published origin. Visibility / folderId / label are
|
|
45
|
+
* sent as fields BEFORE the file part so the server-side pipeline picks them up
|
|
46
|
+
* before finalising the asset.
|
|
47
|
+
*/
|
|
48
|
+
export declare function uploadAsset(file: File, fields?: AssetUploadFields): Promise<AssetDetail>;
|
|
49
|
+
//# sourceMappingURL=assets-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assets-api.d.ts","sourceRoot":"","sources":["../../../src/components/asset-picker/assets-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAOlF;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,cAAc;IAC7B,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAY7E;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAGvE;AAED,MAAM,WAAW,iBAAiB;IAChC,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;CACnC;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,IAAI,EACV,MAAM,GAAE,iBAAsB,GAC7B,OAAO,CAAC,WAAW,CAAC,CAqBtB"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// `apiClient` and `apiBaseUrl` come through the kit's published `lib` **barrel**
|
|
2
|
+
// rather than through `../../lib/api-client.js` — see the note in
|
|
3
|
+
// `../sales-channel-picker/SalesChannelPicker.tsx`: the barrel is the only
|
|
4
|
+
// spelling `vi.mock` can name from outside the package.
|
|
5
|
+
import { apiBaseUrl, apiClient } from '../../lib/index.js';
|
|
6
|
+
export function listAssets(query) {
|
|
7
|
+
const params = new URLSearchParams();
|
|
8
|
+
if (query.folderId !== undefined && query.folderId !== null) {
|
|
9
|
+
params.set('folderId', query.folderId);
|
|
10
|
+
}
|
|
11
|
+
if (query.q)
|
|
12
|
+
params.set('q', query.q);
|
|
13
|
+
if (query.mime)
|
|
14
|
+
params.set('mime', query.mime);
|
|
15
|
+
if (query.visibility)
|
|
16
|
+
params.set('visibility', query.visibility);
|
|
17
|
+
if (query.cursor)
|
|
18
|
+
params.set('cursor', query.cursor);
|
|
19
|
+
if (query.limit !== undefined)
|
|
20
|
+
params.set('limit', String(query.limit));
|
|
21
|
+
const qs = params.toString();
|
|
22
|
+
return apiClient.get(`/api/v1/admin/assets${qs ? `?${qs}` : ''}`);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Resolve one asset id to its metadata.
|
|
26
|
+
*
|
|
27
|
+
* Published on `./components` beside the components that call it because five
|
|
28
|
+
* screens outside `assets_library` do exactly this and nothing else with that
|
|
29
|
+
* module's client — a stored id has to become a filename or a URL before it can
|
|
30
|
+
* be rendered.
|
|
31
|
+
*/
|
|
32
|
+
export async function fetchAssetDetail(id) {
|
|
33
|
+
const out = await apiClient.get(`/api/v1/admin/assets/${id}`);
|
|
34
|
+
return out.data;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Upload a single file via multipart/form-data.
|
|
38
|
+
*
|
|
39
|
+
* The typed `apiClient` is JSON-only, so multipart goes through a direct
|
|
40
|
+
* `fetch` over the same published origin. Visibility / folderId / label are
|
|
41
|
+
* sent as fields BEFORE the file part so the server-side pipeline picks them up
|
|
42
|
+
* before finalising the asset.
|
|
43
|
+
*/
|
|
44
|
+
export async function uploadAsset(file, fields = {}) {
|
|
45
|
+
const fd = new FormData();
|
|
46
|
+
if (fields.visibility)
|
|
47
|
+
fd.append('visibility', fields.visibility);
|
|
48
|
+
if (fields.folderId !== undefined && fields.folderId !== null) {
|
|
49
|
+
fd.append('folderId', fields.folderId);
|
|
50
|
+
}
|
|
51
|
+
if (fields.label !== undefined && fields.label !== null) {
|
|
52
|
+
fd.append('label', fields.label);
|
|
53
|
+
}
|
|
54
|
+
fd.append('file', file, file.name);
|
|
55
|
+
const r = await fetch(`${apiBaseUrl.replace(/\/+$/, '')}/api/v1/admin/assets`, {
|
|
56
|
+
method: 'POST',
|
|
57
|
+
credentials: 'include',
|
|
58
|
+
body: fd,
|
|
59
|
+
});
|
|
60
|
+
if (!r.ok) {
|
|
61
|
+
const text = await r.text();
|
|
62
|
+
throw new Error(`Upload failed (${r.status}): ${text}`);
|
|
63
|
+
}
|
|
64
|
+
const json = (await r.json());
|
|
65
|
+
return json.data;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=assets-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assets-api.js","sourceRoot":"","sources":["../../../src/components/asset-picker/assets-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export interface CategorySelectProps {
|
|
3
|
+
value: string | null;
|
|
4
|
+
onChange: (categoryId: string | null) => void;
|
|
5
|
+
placeholder?: string;
|
|
6
|
+
emptyMessage?: string;
|
|
7
|
+
clearable?: boolean;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
ariaLabel?: string;
|
|
10
|
+
id?: string;
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function CategorySelect(props: CategorySelectProps): ReactNode;
|
|
14
|
+
//# sourceMappingURL=CategorySelect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CategorySelect.d.ts","sourceRoot":"","sources":["../../../src/components/category-picker/CategorySelect.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAyBrE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,SAAS,CAoDpE"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
3
|
+
import { ApiError, apiClient } from '../../lib/api-client.js';
|
|
4
|
+
import { useAppLanguage } from '../../i18n/app-language-context.js';
|
|
5
|
+
import { Combobox } from '../../ui/combobox.js';
|
|
6
|
+
export function CategorySelect(props) {
|
|
7
|
+
const { language } = useAppLanguage();
|
|
8
|
+
const [categories, setCategories] = useState([]);
|
|
9
|
+
const [loading, setLoading] = useState(true);
|
|
10
|
+
const [error, setError] = useState(null);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
let alive = true;
|
|
13
|
+
setLoading(true);
|
|
14
|
+
apiClient
|
|
15
|
+
.get('/api/v1/admin/catalog/categories')
|
|
16
|
+
.then((res) => {
|
|
17
|
+
if (!alive)
|
|
18
|
+
return;
|
|
19
|
+
setCategories(res.data);
|
|
20
|
+
})
|
|
21
|
+
.catch((err) => {
|
|
22
|
+
if (!alive)
|
|
23
|
+
return;
|
|
24
|
+
setError(err instanceof ApiError ? err.envelope.error.message : 'Failed to load categories.');
|
|
25
|
+
})
|
|
26
|
+
.finally(() => {
|
|
27
|
+
if (alive)
|
|
28
|
+
setLoading(false);
|
|
29
|
+
});
|
|
30
|
+
return () => {
|
|
31
|
+
alive = false;
|
|
32
|
+
};
|
|
33
|
+
}, []);
|
|
34
|
+
const options = useMemo(() => {
|
|
35
|
+
const labelFor = (c) => c.name[language] ?? c.name['en-US'] ?? Object.values(c.name)[0] ?? c.slug;
|
|
36
|
+
return categories.map((c) => ({ value: c.id, label: labelFor(c), description: c.slug }));
|
|
37
|
+
}, [categories, language]);
|
|
38
|
+
const emptyMessage = props.emptyMessage ?? error ?? 'No categories.';
|
|
39
|
+
return (_jsx(Combobox, { options: options, value: props.value, onChange: props.onChange, loading: loading, clearable: props.clearable ?? true, disabled: props.disabled ?? false, placeholder: props.placeholder ?? 'Select a category…', emptyMessage: emptyMessage, ariaLabel: props.ariaLabel ?? 'Select category', id: props.id ?? '', className: props.className ?? '' }));
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=CategorySelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CategorySelect.js","sourceRoot":"","sources":["../../../src/components/category-picker/CategorySelect.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type CategoryTreeNode } from './category-tree-utils.js';
|
|
3
|
+
interface CategoryTreeNodeRowProps {
|
|
4
|
+
node: CategoryTreeNode;
|
|
5
|
+
locale: string;
|
|
6
|
+
checked: boolean;
|
|
7
|
+
indeterminate?: boolean;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
hasChildren: boolean;
|
|
10
|
+
expanded: boolean;
|
|
11
|
+
onToggleExpand: () => void;
|
|
12
|
+
onToggleSelect: () => void;
|
|
13
|
+
expandLabel: string;
|
|
14
|
+
collapseLabel: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function CategoryTreeNodeRow(props: CategoryTreeNodeRowProps): ReactNode;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=CategoryTreeNodeRow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CategoryTreeNodeRow.d.ts","sourceRoot":"","sources":["../../../src/components/category-tree-picker/CategoryTreeNodeRow.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAK1D,OAAO,EAA2B,KAAK,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE1F,UAAU,wBAAwB;IAChC,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,SAAS,CAwD9E"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef } from 'react';
|
|
3
|
+
import { ChevronDown, ChevronRight } from 'lucide-react';
|
|
4
|
+
import { Button } from '../../ui/button.js';
|
|
5
|
+
import { Checkbox } from '../../ui/checkbox.js';
|
|
6
|
+
import { cn } from '../../lib/utils.js';
|
|
7
|
+
import { pickCategoryDisplayName } from './category-tree-utils.js';
|
|
8
|
+
export function CategoryTreeNodeRow(props) {
|
|
9
|
+
const label = pickCategoryDisplayName(props.node.category.name, props.node.category.slug, props.locale);
|
|
10
|
+
const indeterminate = props.indeterminate === true && !props.checked;
|
|
11
|
+
const checkboxRef = useRef(null);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (checkboxRef.current) {
|
|
14
|
+
checkboxRef.current.indeterminate = indeterminate;
|
|
15
|
+
}
|
|
16
|
+
}, [indeterminate, props.checked]);
|
|
17
|
+
return (_jsxs("div", { className: cn('flex items-center gap-1 rounded-sm py-1 pr-2', indeterminate && 'bg-primary/5'), style: { paddingLeft: `${props.node.depth * 16 + 4}px` }, children: [props.hasChildren ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "h-7 w-7 shrink-0 p-0", disabled: props.disabled, "aria-expanded": props.expanded, "aria-label": props.expanded ? props.collapseLabel : props.expandLabel, onClick: props.onToggleExpand, children: props.expanded ? _jsx(ChevronDown, { size: 16 }) : _jsx(ChevronRight, { size: 16 }) })) : (_jsx("span", { className: "inline-block h-7 w-7 shrink-0", "aria-hidden": true })), _jsx(Checkbox, { ref: checkboxRef, checked: props.checked, disabled: props.disabled, "aria-checked": indeterminate ? 'mixed' : props.checked, "aria-label": label, title: label, onChange: () => props.onToggleSelect() }), _jsx("span", { className: cn('truncate text-sm', indeterminate && 'font-medium text-foreground'), title: label, children: label })] }));
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=CategoryTreeNodeRow.js.map
|