@cosmicdrift/kumiko-renderer 0.374.0 → 0.377.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/app/action-form-support.d.ts +9 -2
- package/dist/app/action-form-support.js +24 -2
- package/dist/app/client-actions.d.ts +2 -2
- package/dist/app/column-renderers.js +1 -1
- package/dist/app/config-edit-shim.js +1 -1
- package/dist/app/content-preview.js +1 -6
- package/dist/app/custom-screens.js +1 -1
- package/dist/app/dashboard-body.d.ts +1 -1
- package/dist/app/entity-list-expanded-row.d.ts +1 -1
- package/dist/app/form-schema.d.ts +1 -1
- package/dist/app/form-schema.js +2 -2
- package/dist/app/kumiko-screen.d.ts +1 -1
- package/dist/app/kumiko-screen.js +7 -6
- package/dist/app/list-empty-content.d.ts +1 -1
- package/dist/app/list-facets.d.ts +1 -1
- package/dist/app/nav.js +2 -2
- package/dist/app/query-state-banners.d.ts +1 -1
- package/dist/app/reference-link.d.ts +1 -1
- package/dist/app/row-actions.d.ts +1 -1
- package/dist/app/secret-mint-body.d.ts +1 -1
- package/dist/app/secrets-edit-body.d.ts +1 -1
- package/dist/app/use-record-actions.d.ts +1 -1
- package/dist/app/write-failed-error.d.ts +1 -1
- package/dist/components/availability-options-select.d.ts +1 -1
- package/dist/components/embedded-list-field.d.ts +1 -1
- package/dist/components/embedded-list-field.js +1 -1
- package/dist/components/file-list-field.d.ts +1 -1
- package/dist/components/grid-cell-for-field.d.ts +1 -1
- package/dist/components/multi-select-checkboxes.d.ts +1 -1
- package/dist/components/multi-select-checkboxes.js +1 -1
- package/dist/components/query-options-select.d.ts +1 -1
- package/dist/components/related-list-section.d.ts +1 -1
- package/dist/components/render-edit-logic.d.ts +1 -1
- package/dist/components/render-edit-types.d.ts +2 -2
- package/dist/components/render-edit.d.ts +1 -1
- package/dist/components/render-edit.js +4 -2
- package/dist/components/render-field.d.ts +1 -1
- package/dist/components/render-field.js +4 -1
- package/dist/components/render-list.d.ts +1 -1
- package/dist/components/render-list.js +20 -4
- package/dist/components/write-form-section.d.ts +1 -1
- package/dist/components/write-form-section.js +1 -1
- package/dist/context/dispatcher-context.d.ts +1 -1
- package/dist/format-when.js +1 -1
- package/dist/headless/apex/css.d.ts +3 -0
- package/dist/headless/apex/css.js +298 -0
- package/dist/headless/apex/index.d.ts +236 -0
- package/dist/headless/apex/index.js +377 -0
- package/dist/headless/apex/lightbox.d.ts +4 -0
- package/dist/headless/apex/lightbox.js +81 -0
- package/dist/headless/contracts/asset.d.ts +15 -0
- package/dist/headless/contracts/asset.js +17 -0
- package/dist/headless/contracts/index.d.ts +3 -0
- package/dist/headless/contracts/index.js +1 -0
- package/dist/headless/contracts/locale.d.ts +7 -0
- package/dist/headless/contracts/locale.js +11 -0
- package/dist/headless/contracts/primitives.d.ts +93 -0
- package/dist/headless/contracts/primitives.js +21 -0
- package/dist/headless/dispatcher/index.d.ts +2 -0
- package/dist/headless/dispatcher/index.js +1 -0
- package/dist/headless/dispatcher/types.d.ts +86 -0
- package/dist/headless/dispatcher/types.js +34 -0
- package/dist/headless/form/form-controller.d.ts +2 -0
- package/dist/headless/form/form-controller.js +409 -0
- package/dist/headless/form/index.d.ts +3 -0
- package/dist/headless/form/index.js +2 -0
- package/dist/headless/form/types.d.ts +76 -0
- package/dist/headless/form/types.js +1 -0
- package/dist/headless/form/zod-bridge.d.ts +10 -0
- package/dist/headless/form/zod-bridge.js +103 -0
- package/dist/headless/format/document-values.d.ts +12 -0
- package/dist/headless/format/document-values.js +70 -0
- package/dist/headless/format/escape.d.ts +5 -0
- package/dist/headless/format/escape.js +75 -0
- package/dist/headless/format/html-template.d.ts +9 -0
- package/dist/headless/format/html-template.js +39 -0
- package/dist/headless/format/index.d.ts +12 -0
- package/dist/headless/format/index.js +237 -0
- package/dist/headless/format/money.d.ts +3 -0
- package/dist/headless/format/money.js +39 -0
- package/dist/headless/index.d.ts +14 -0
- package/dist/headless/index.js +9 -0
- package/dist/headless/locale-routing/index.d.ts +41 -0
- package/dist/headless/locale-routing/index.js +145 -0
- package/dist/headless/nav/index.d.ts +2 -0
- package/dist/headless/nav/index.js +1 -0
- package/dist/headless/nav/resolve.d.ts +2 -0
- package/dist/headless/nav/resolve.js +71 -0
- package/dist/headless/nav/types.d.ts +26 -0
- package/dist/headless/nav/types.js +1 -0
- package/dist/headless/store/create-store.d.ts +2 -0
- package/dist/headless/store/create-store.js +43 -0
- package/dist/headless/store/equality.d.ts +1 -0
- package/dist/headless/store/equality.js +34 -0
- package/dist/headless/store/index.d.ts +3 -0
- package/dist/headless/store/index.js +2 -0
- package/dist/headless/store/types.d.ts +7 -0
- package/dist/headless/store/types.js +10 -0
- package/dist/headless/view-model/edit.d.ts +18 -0
- package/dist/headless/view-model/edit.js +501 -0
- package/dist/headless/view-model/embedded-list.d.ts +27 -0
- package/dist/headless/view-model/embedded-list.js +63 -0
- package/dist/headless/view-model/index.d.ts +7 -0
- package/dist/headless/view-model/index.js +3 -0
- package/dist/headless/view-model/list-file-display.d.ts +3 -0
- package/dist/headless/view-model/list-file-display.js +27 -0
- package/dist/headless/view-model/list.d.ts +16 -0
- package/dist/headless/view-model/list.js +229 -0
- package/dist/headless/view-model/types.d.ts +382 -0
- package/dist/headless/view-model/types.js +1 -0
- package/dist/hooks/use-ai-text.d.ts +1 -1
- package/dist/hooks/use-form.d.ts +1 -1
- package/dist/hooks/use-form.js +1 -1
- package/dist/hooks/use-mutation.d.ts +1 -1
- package/dist/hooks/use-query.d.ts +1 -1
- package/dist/hooks/use-store.d.ts +1 -1
- package/dist/hooks/use-store.js +7 -7
- package/dist/hooks/use-stream-handler.d.ts +1 -1
- package/dist/i18n.d.ts +1 -1
- package/dist/i18n.js +1 -1
- package/dist/index.js +4 -4
- package/dist/live/csrf.d.ts +2 -0
- package/dist/live/csrf.js +60 -0
- package/dist/live/dispatcher-live.d.ts +7 -0
- package/dist/live/dispatcher-live.js +286 -0
- package/dist/live/envelopes.d.ts +101 -0
- package/dist/live/envelopes.js +35 -0
- package/dist/live/error-mapping.d.ts +16 -0
- package/dist/live/error-mapping.js +82 -0
- package/dist/live/index.d.ts +7 -0
- package/dist/live/index.js +5 -0
- package/dist/live/locale.d.ts +2 -0
- package/dist/live/locale.js +25 -0
- package/dist/live/sse-stream.d.ts +14 -0
- package/dist/live/sse-stream.js +128 -0
- package/dist/primitives.d.ts +35 -36
- package/dist/primitives.js +1 -1
- package/dist/session/session-ended.d.ts +1 -1
- package/dist/tokens.d.ts +3 -4
- package/dist/tokens.js +4 -5
- package/dist/web/app/app-schema-boot.d.ts +19 -0
- package/dist/web/app/app-schema-boot.js +124 -0
- package/dist/web/app/browser-locale.d.ts +22 -0
- package/dist/web/app/browser-locale.js +78 -0
- package/dist/web/app/client-plugin.d.ts +106 -0
- package/dist/web/app/client-plugin.js +12 -0
- package/dist/web/app/create-app.d.ts +104 -0
- package/dist/web/app/create-app.js +498 -0
- package/dist/web/app/create-public-surface.d.ts +36 -0
- package/dist/web/app/create-public-surface.js +40 -0
- package/dist/web/app/dashboard-body.d.ts +3 -0
- package/dist/web/app/dashboard-body.js +865 -0
- package/dist/web/app/dashboard-refresh.d.ts +6 -0
- package/dist/web/app/dashboard-refresh.js +15 -0
- package/dist/web/app/document-lang-sync.d.ts +4 -0
- package/dist/web/app/document-lang-sync.js +27 -0
- package/dist/web/app/draft-storage.d.ts +11 -0
- package/dist/web/app/draft-storage.js +53 -0
- package/dist/web/app/nav-providers-context.d.ts +13 -0
- package/dist/web/app/nav-providers-context.js +18 -0
- package/dist/web/app/nav.d.ts +40 -0
- package/dist/web/app/nav.js +231 -0
- package/dist/web/app/plain-content-editor.d.ts +3 -0
- package/dist/web/app/plain-content-editor.js +30 -0
- package/dist/web/app/relative-time.d.ts +10 -0
- package/dist/web/app/relative-time.js +56 -0
- package/dist/web/app/resolvers-context.d.ts +12 -0
- package/dist/web/app/resolvers-context.js +10 -0
- package/dist/web/app/rich-content-editor.d.ts +3 -0
- package/dist/web/app/rich-content-editor.js +15 -0
- package/dist/web/app/root-error-fallback.d.ts +2 -0
- package/dist/web/app/root-error-fallback.js +21 -0
- package/dist/web/app/screen-error-fallback.d.ts +6 -0
- package/dist/web/app/screen-error-fallback.js +17 -0
- package/dist/web/app/tiptap-editor.d.ts +3 -0
- package/dist/web/app/tiptap-editor.js +120 -0
- package/dist/web/app/toast-action-notifier.d.ts +5 -0
- package/dist/web/app/toast-action-notifier.js +17 -0
- package/dist/web/components/config-cascade.d.ts +13 -0
- package/dist/web/components/config-cascade.js +155 -0
- package/dist/web/components/config-source-badge.d.ts +6 -0
- package/dist/web/components/config-source-badge.js +55 -0
- package/dist/web/default-color-scheme.d.ts +2 -0
- package/dist/web/default-color-scheme.js +3 -0
- package/dist/web/icons.d.ts +94 -0
- package/dist/web/icons.js +100 -0
- package/dist/web/index.d.ts +78 -0
- package/dist/web/index.js +53 -0
- package/dist/web/layout/app-layout.d.ts +21 -0
- package/dist/web/layout/app-layout.js +8 -0
- package/dist/web/layout/avatar.d.ts +12 -0
- package/dist/web/layout/avatar.js +63 -0
- package/dist/web/layout/default-app-shell.d.ts +41 -0
- package/dist/web/layout/default-app-shell.js +16 -0
- package/dist/web/layout/editor-panel.d.ts +10 -0
- package/dist/web/layout/editor-panel.js +29 -0
- package/dist/web/layout/fill-classes.d.ts +9 -0
- package/dist/web/layout/fill-classes.js +15 -0
- package/dist/web/layout/filter-app-schema-navs.d.ts +7 -0
- package/dist/web/layout/filter-app-schema-navs.js +68 -0
- package/dist/web/layout/header-action-group.d.ts +6 -0
- package/dist/web/layout/header-action-group.js +8 -0
- package/dist/web/layout/header-overflow-menu.d.ts +4 -0
- package/dist/web/layout/header-overflow-menu.js +8 -0
- package/dist/web/layout/language-menu-items.d.ts +8 -0
- package/dist/web/layout/language-menu-items.js +16 -0
- package/dist/web/layout/language-switcher.d.ts +25 -0
- package/dist/web/layout/language-switcher.js +46 -0
- package/dist/web/layout/nav-tree.d.ts +19 -0
- package/dist/web/layout/nav-tree.js +536 -0
- package/dist/web/layout/page-header-slot.d.ts +25 -0
- package/dist/web/layout/page-header-slot.js +50 -0
- package/dist/web/layout/profile-menu.d.ts +13 -0
- package/dist/web/layout/profile-menu.js +6 -0
- package/dist/web/layout/shell-breadcrumb.d.ts +11 -0
- package/dist/web/layout/shell-breadcrumb.js +34 -0
- package/dist/web/layout/shell-header.d.ts +12 -0
- package/dist/web/layout/shell-header.js +159 -0
- package/dist/web/layout/sidebar-brand.d.ts +15 -0
- package/dist/web/layout/sidebar-brand.js +9 -0
- package/dist/web/layout/sidebar-panel.d.ts +41 -0
- package/dist/web/layout/sidebar-panel.js +107 -0
- package/dist/web/layout/sidebar-user.d.ts +8 -0
- package/dist/web/layout/sidebar-user.js +17 -0
- package/dist/web/layout/sidebar.d.ts +17 -0
- package/dist/web/layout/sidebar.js +11 -0
- package/dist/web/layout/target-resolver-stub.d.ts +13 -0
- package/dist/web/layout/target-resolver-stub.js +61 -0
- package/dist/web/layout/target-url.d.ts +12 -0
- package/dist/web/layout/target-url.js +77 -0
- package/dist/web/layout/theme-label.d.ts +15 -0
- package/dist/web/layout/theme-label.js +35 -0
- package/dist/web/layout/theme-menu-item.d.ts +12 -0
- package/dist/web/layout/theme-menu-item.js +16 -0
- package/dist/web/layout/theme-toggle.d.ts +17 -0
- package/dist/web/layout/theme-toggle.js +22 -0
- package/dist/web/layout/topbar.d.ts +8 -0
- package/dist/web/layout/topbar.js +4 -0
- package/dist/web/layout/workspace-shell.d.ts +63 -0
- package/dist/web/layout/workspace-shell.js +220 -0
- package/dist/web/layout/workspace-switcher.d.ts +15 -0
- package/dist/web/layout/workspace-switcher.js +36 -0
- package/dist/web/lib/accept-attr.d.ts +1 -0
- package/dist/web/lib/accept-attr.js +6 -0
- package/dist/web/lib/clamp.d.ts +1 -0
- package/dist/web/lib/clamp.js +3 -0
- package/dist/web/lib/cn.d.ts +6 -0
- package/dist/web/lib/cn.js +9 -0
- package/dist/web/lib/download.d.ts +2 -0
- package/dist/web/lib/download.js +24 -0
- package/dist/web/lib/file-ref-download.d.ts +15 -0
- package/dist/web/lib/file-ref-download.js +62 -0
- package/dist/web/lib/file-upload-form-data.d.ts +7 -0
- package/dist/web/lib/file-upload-form-data.js +11 -0
- package/dist/web/lib/resize-image.d.ts +1 -0
- package/dist/web/lib/resize-image.js +66 -0
- package/dist/web/lib/upload-file-ref.d.ts +9 -0
- package/dist/web/lib/upload-file-ref.js +29 -0
- package/dist/web/primitives/action-menu.d.ts +34 -0
- package/dist/web/primitives/action-menu.js +30 -0
- package/dist/web/primitives/calendar-popover.d.ts +13 -0
- package/dist/web/primitives/calendar-popover.js +76 -0
- package/dist/web/primitives/combobox.d.ts +56 -0
- package/dist/web/primitives/combobox.js +127 -0
- package/dist/web/primitives/date-field.d.ts +18 -0
- package/dist/web/primitives/date-field.js +74 -0
- package/dist/web/primitives/date-input.d.ts +1 -0
- package/dist/web/primitives/date-input.js +5 -0
- package/dist/web/primitives/date-parse.d.ts +11 -0
- package/dist/web/primitives/date-parse.js +159 -0
- package/dist/web/primitives/dialog.d.ts +3 -0
- package/dist/web/primitives/dialog.js +42 -0
- package/dist/web/primitives/drawer.d.ts +3 -0
- package/dist/web/primitives/drawer.js +17 -0
- package/dist/web/primitives/dropdown-menu.d.ts +15 -0
- package/dist/web/primitives/dropdown-menu.js +56 -0
- package/dist/web/primitives/embedded-list-input.d.ts +9 -0
- package/dist/web/primitives/embedded-list-input.js +382 -0
- package/dist/web/primitives/file-thumbnail.d.ts +25 -0
- package/dist/web/primitives/file-thumbnail.js +90 -0
- package/dist/web/primitives/file-upload.d.ts +21 -0
- package/dist/web/primitives/file-upload.js +56 -0
- package/dist/web/primitives/index.d.ts +34 -0
- package/dist/web/primitives/index.js +2021 -0
- package/dist/web/primitives/json-view.d.ts +7 -0
- package/dist/web/primitives/json-view.js +84 -0
- package/dist/web/primitives/layout.d.ts +27 -0
- package/dist/web/primitives/layout.js +30 -0
- package/dist/web/primitives/lightbox.d.ts +3 -0
- package/dist/web/primitives/lightbox.js +36 -0
- package/dist/web/primitives/locale-number.d.ts +2 -0
- package/dist/web/primitives/locale-number.js +54 -0
- package/dist/web/primitives/located-timestamp-input.d.ts +22 -0
- package/dist/web/primitives/located-timestamp-input.js +22 -0
- package/dist/web/primitives/metric.d.ts +5 -0
- package/dist/web/primitives/metric.js +18 -0
- package/dist/web/primitives/modal-shell.d.ts +17 -0
- package/dist/web/primitives/modal-shell.js +9 -0
- package/dist/web/primitives/modal.d.ts +3 -0
- package/dist/web/primitives/modal.js +13 -0
- package/dist/web/primitives/money-input.d.ts +18 -0
- package/dist/web/primitives/money-input.js +122 -0
- package/dist/web/primitives/narrow-pinned-footer.d.ts +12 -0
- package/dist/web/primitives/narrow-pinned-footer.js +153 -0
- package/dist/web/primitives/number-input.d.ts +18 -0
- package/dist/web/primitives/number-input.js +53 -0
- package/dist/web/primitives/option-groups.d.ts +11 -0
- package/dist/web/primitives/option-groups.js +27 -0
- package/dist/web/primitives/page-header.d.ts +3 -0
- package/dist/web/primitives/page-header.js +52 -0
- package/dist/web/primitives/promo-panel.d.ts +3 -0
- package/dist/web/primitives/promo-panel.js +11 -0
- package/dist/web/primitives/segmented-select.d.ts +21 -0
- package/dist/web/primitives/segmented-select.js +62 -0
- package/dist/web/primitives/share-actions.d.ts +4 -0
- package/dist/web/primitives/share-actions.js +56 -0
- package/dist/web/primitives/status-badge.d.ts +3 -0
- package/dist/web/primitives/status-badge.js +5 -0
- package/dist/web/primitives/sticky-action-bar.d.ts +5 -0
- package/dist/web/primitives/sticky-action-bar.js +15 -0
- package/dist/web/primitives/tabs.d.ts +3 -0
- package/dist/web/primitives/tabs.js +107 -0
- package/dist/web/primitives/timestamp-input.d.ts +27 -0
- package/dist/web/primitives/timestamp-input.js +87 -0
- package/dist/web/primitives/toast.d.ts +19 -0
- package/dist/web/primitives/toast.js +63 -0
- package/dist/web/primitives/tz-input.d.ts +11 -0
- package/dist/web/primitives/tz-input.js +8 -0
- package/dist/web/primitives/tz-options.d.ts +4 -0
- package/dist/web/primitives/tz-options.js +17 -0
- package/dist/web/primitives/use-keyboard-inset.d.ts +1 -0
- package/dist/web/primitives/use-keyboard-inset.js +28 -0
- package/dist/web/primitives/use-narrow-viewport.d.ts +4 -0
- package/dist/web/primitives/use-narrow-viewport.js +46 -0
- package/dist/web/react-css-custom-properties.d.ts +6 -0
- package/dist/web/react-css-custom-properties.js +1 -0
- package/dist/web/sse/live-events.d.ts +15 -0
- package/dist/web/sse/live-events.js +148 -0
- package/dist/web/theme-plugin.d.ts +41 -0
- package/dist/web/theme-plugin.js +123 -0
- package/dist/web/tokens.d.ts +24 -0
- package/dist/web/tokens.js +203 -0
- package/dist/web/ui/avatar.d.ts +11 -0
- package/dist/web/ui/avatar.js +25 -0
- package/dist/web/ui/badge.d.ts +9 -0
- package/dist/web/ui/badge.js +26 -0
- package/dist/web/ui/breadcrumb.d.ts +11 -0
- package/dist/web/ui/breadcrumb.js +29 -0
- package/dist/web/ui/button.d.ts +10 -0
- package/dist/web/ui/button.js +37 -0
- package/dist/web/ui/checkbox.d.ts +4 -0
- package/dist/web/ui/checkbox.js +11 -0
- package/dist/web/ui/input.d.ts +3 -0
- package/dist/web/ui/input.js +8 -0
- package/dist/web/ui/label.d.ts +4 -0
- package/dist/web/ui/label.js +10 -0
- package/dist/web/ui/resizable.d.ts +7 -0
- package/dist/web/ui/resizable.js +16 -0
- package/dist/web/ui/separator.d.ts +4 -0
- package/dist/web/ui/separator.js +10 -0
- package/dist/web/ui/sheet.d.ts +14 -0
- package/dist/web/ui/sheet.js +42 -0
- package/dist/web/ui/sidebar.d.ts +73 -0
- package/dist/web/ui/sidebar.js +211 -0
- package/dist/web/ui/skeleton.d.ts +2 -0
- package/dist/web/ui/skeleton.js +7 -0
- package/dist/web/ui/switch.d.ts +6 -0
- package/dist/web/ui/switch.js +10 -0
- package/dist/web/ui/table.d.ts +10 -0
- package/dist/web/ui/table.js +30 -0
- package/dist/web/ui/tabs.d.ts +11 -0
- package/dist/web/ui/tabs.js +31 -0
- package/dist/web/ui/textarea.d.ts +3 -0
- package/dist/web/ui/textarea.js +8 -0
- package/dist/web/ui/tooltip.d.ts +7 -0
- package/dist/web/ui/tooltip.js +19 -0
- package/dist/web/ui/use-mobile.d.ts +1 -0
- package/dist/web/ui/use-mobile.js +16 -0
- package/dist/web/version/update-checker.d.ts +9 -0
- package/dist/web/version/update-checker.js +88 -0
- package/dist/web/widgets/ai-text-field.d.ts +36 -0
- package/dist/web/widgets/ai-text-field.js +137 -0
- package/dist/web/widgets/chart-window.d.ts +58 -0
- package/dist/web/widgets/chart-window.js +190 -0
- package/dist/web/widgets/charts.d.ts +208 -0
- package/dist/web/widgets/charts.js +685 -0
- package/dist/web/widgets/collapsible-section.d.ts +10 -0
- package/dist/web/widgets/collapsible-section.js +17 -0
- package/dist/web/widgets/dashboard-list.d.ts +21 -0
- package/dist/web/widgets/dashboard-list.js +45 -0
- package/dist/web/widgets/detail-list.d.ts +15 -0
- package/dist/web/widgets/detail-list.js +8 -0
- package/dist/web/widgets/drawer.d.ts +65 -0
- package/dist/web/widgets/drawer.js +142 -0
- package/dist/web/widgets/feed-list.d.ts +13 -0
- package/dist/web/widgets/feed-list.js +9 -0
- package/dist/web/widgets/floating-panel.d.ts +30 -0
- package/dist/web/widgets/floating-panel.js +242 -0
- package/dist/web/widgets/form-fields.d.ts +93 -0
- package/dist/web/widgets/form-fields.js +50 -0
- package/dist/web/widgets/index.d.ts +27 -0
- package/dist/web/widgets/index.js +30 -0
- package/dist/web/widgets/infinity-list.d.ts +46 -0
- package/dist/web/widgets/infinity-list.js +211 -0
- package/dist/web/widgets/mode-switch.d.ts +21 -0
- package/dist/web/widgets/mode-switch.js +25 -0
- package/dist/web/widgets/photo-slots.d.ts +29 -0
- package/dist/web/widgets/photo-slots.js +52 -0
- package/dist/web/widgets/plan-card.d.ts +36 -0
- package/dist/web/widgets/plan-card.js +13 -0
- package/dist/web/widgets/progress-bar.d.ts +19 -0
- package/dist/web/widgets/progress-bar.js +24 -0
- package/dist/web/widgets/progress-list.d.ts +19 -0
- package/dist/web/widgets/progress-list.js +11 -0
- package/dist/web/widgets/public-shell.d.ts +22 -0
- package/dist/web/widgets/public-shell.js +15 -0
- package/dist/web/widgets/query-table.d.ts +29 -0
- package/dist/web/widgets/query-table.js +30 -0
- package/dist/web/widgets/result-panel.d.ts +69 -0
- package/dist/web/widgets/result-panel.js +30 -0
- package/dist/web/widgets/section-card.d.ts +12 -0
- package/dist/web/widgets/section-card.js +9 -0
- package/dist/web/widgets/sheet-parts.d.ts +9 -0
- package/dist/web/widgets/sheet-parts.js +11 -0
- package/dist/web/widgets/side-by-side-table.d.ts +31 -0
- package/dist/web/widgets/side-by-side-table.js +11 -0
- package/dist/web/widgets/stat.d.ts +54 -0
- package/dist/web/widgets/stat.js +65 -0
- package/dist/web/widgets/states.d.ts +23 -0
- package/dist/web/widgets/states.js +20 -0
- package/dist/web/widgets/status-badge.d.ts +15 -0
- package/dist/web/widgets/status-badge.js +24 -0
- package/dist/web/widgets/step-bar.d.ts +35 -0
- package/dist/web/widgets/step-bar.js +60 -0
- package/dist/web/widgets/upload-zone.d.ts +24 -0
- package/dist/web/widgets/upload-zone.js +108 -0
- package/dist/web/widgets/use-draft.d.ts +20 -0
- package/dist/web/widgets/use-draft.js +21 -0
- package/dist/web/widgets/use-pointer-drag.d.ts +21 -0
- package/dist/web/widgets/use-pointer-drag.js +53 -0
- package/package.json +105 -7
- package/src/changes.json +53 -0
- package/src/web/fonts/OFL.txt +93 -0
- package/src/web/fonts/ibm-plex-mono-latin-400.woff2 +0 -0
- package/src/web/fonts/ibm-plex-mono-latin-500.woff2 +0 -0
- package/src/web/fonts/ibm-plex-mono-latin-ext-400.woff2 +0 -0
- package/src/web/fonts/ibm-plex-mono-latin-ext-500.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-400.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-500.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-600.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-ext-400.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-ext-500.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-ext-600.woff2 +0 -0
- package/src/web/styles.css +401 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @cosmicdrift/kumiko-renderer
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
React renderer for Kumiko screens: primitives contract, hooks, `KumikoScreen`, navigation and SSE abstractions. The root entry has no DOM and no `EventSource`; the subpaths add the web bindings (`/web`), UI logic (`/headless`) and the HTTP dispatcher (`/live`).
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -8,6 +8,6 @@ Platform-agnostic React renderer for Kumiko screens: primitives contract, hooks,
|
|
|
8
8
|
bun add @cosmicdrift/kumiko-renderer
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Import the browser bindings from `@cosmicdrift/kumiko-renderer/web`.
|
|
12
12
|
|
|
13
13
|
Documentation: https://kumiko.rocks
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ActionFormLoad } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
-
import type { DispatcherError, Translate } from "@cosmicdrift/kumiko-headless";
|
|
1
|
+
import type { ActionFormLoad, ActionFormSuccessFact } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
3
2
|
import { type ReactNode } from "react";
|
|
3
|
+
import type { DispatcherError, Translate } from "../headless/index.ts";
|
|
4
4
|
/** Record id of a `load` form: the route path id, else the drawer prefill `id`
|
|
5
5
|
* (the clicked row), else the URL `id` param. Only the id is read from these
|
|
6
6
|
* sources, never another value. */
|
|
@@ -42,10 +42,17 @@ export type ResolvedSuccessLink = {
|
|
|
42
42
|
readonly href: string;
|
|
43
43
|
readonly onPress: () => void;
|
|
44
44
|
};
|
|
45
|
+
export type ResolvedSuccessFact = {
|
|
46
|
+
readonly key: string;
|
|
47
|
+
readonly label: string;
|
|
48
|
+
readonly lines: readonly string[];
|
|
49
|
+
};
|
|
45
50
|
export type ActionFormSuccessState = {
|
|
46
51
|
readonly text: string;
|
|
47
52
|
readonly links: readonly ResolvedSuccessLink[];
|
|
53
|
+
readonly facts: readonly ResolvedSuccessFact[];
|
|
48
54
|
};
|
|
55
|
+
export declare function resolveSuccessFacts(facts: readonly ActionFormSuccessFact[] | undefined, data: unknown, translate: (key: string) => string, locale: string): readonly ResolvedSuccessFact[];
|
|
49
56
|
export declare function ActionFormSuccessBanner({ success, }: {
|
|
50
57
|
readonly success: ActionFormSuccessState;
|
|
51
58
|
}): ReactNode;
|
|
@@ -68,7 +68,29 @@ export function ActionFormLoadStatus({ state, screenId, translate, }) {
|
|
|
68
68
|
return (_jsxs(Banner, { padded: true, variant: "error", testId: "kumiko-screen-action-form-missing-id", children: ["Screen ", _jsx(Text, { variant: "code", children: screenId }), " (actionForm with load) needs a record id in the path or the clicked row."] }));
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
+
function factLine(entry, locale) {
|
|
72
|
+
if (typeof entry === "number")
|
|
73
|
+
return entry.toLocaleString(locale);
|
|
74
|
+
if (typeof entry === "string")
|
|
75
|
+
return entry;
|
|
76
|
+
if (typeof entry === "object" && entry !== null && "label" in entry) {
|
|
77
|
+
return typeof entry.label === "string" ? entry.label : undefined;
|
|
78
|
+
}
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
export function resolveSuccessFacts(facts, data, translate, locale) {
|
|
82
|
+
const resolved = [];
|
|
83
|
+
(facts ?? []).forEach((fact, index) => {
|
|
84
|
+
const value = propertyOf(data, fact.field);
|
|
85
|
+
const entries = Array.isArray(value) ? value : [value];
|
|
86
|
+
const lines = entries.flatMap((entry) => factLine(entry, locale) ?? []);
|
|
87
|
+
if (lines.length > 0) {
|
|
88
|
+
resolved.push({ key: String(index), label: translate(fact.label), lines });
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
return resolved;
|
|
92
|
+
}
|
|
71
93
|
export function ActionFormSuccessBanner({ success, }) {
|
|
72
|
-
const { Banner, Link } = usePrimitives();
|
|
73
|
-
return (_jsxs(Banner, { variant: "info", testId: "action-form-success", children: [success.text, success.links.map((link) => (_jsx(Link, { href: link.href, onPress: link.onPress, className: "ml-2 underline", testId: `action-form-success-link-${link.key}`, children: link.label }, link.key)))] }));
|
|
94
|
+
const { Banner, Link, Text } = usePrimitives();
|
|
95
|
+
return (_jsxs(Banner, { variant: "info", testId: "action-form-success", children: [success.text, success.facts.map((fact) => (_jsxs(Text, { testId: `action-form-success-fact-${fact.key}`, children: [fact.label, ": ", fact.lines.join(", ")] }, fact.key))), success.links.map((link) => (_jsx(Link, { href: link.href, onPress: link.onPress, className: "ml-2 underline", testId: `action-form-success-link-${link.key}`, children: link.label }, link.key)))] }));
|
|
74
96
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { RowActionClientAction } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
-
import type { Translate } from "@cosmicdrift/kumiko-headless";
|
|
3
2
|
import { type ReactNode } from "react";
|
|
3
|
+
import type { Translate } from "../headless/index.ts";
|
|
4
4
|
export type ClientActionOutcome = {
|
|
5
5
|
readonly ok: true;
|
|
6
6
|
}
|
|
@@ -16,7 +16,7 @@ export type ActionNotice = {
|
|
|
16
16
|
readonly text: string;
|
|
17
17
|
};
|
|
18
18
|
/** Shows the outcome of a client action. The platform layer provides it
|
|
19
|
-
* (renderer
|
|
19
|
+
* (renderer/web: a toast); without one a failure is thrown to the action
|
|
20
20
|
* host's own error surface and a success stays silent. */
|
|
21
21
|
export type ActionNotifier = (notice: ActionNotice) => void;
|
|
22
22
|
export type ClientActionRuntime = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
// Column-Renderer-Map: client-side Lookup für ListColumn-Spalten die im
|
|
3
3
|
// Schema einen PlatformComponent-Renderer (`{ react: { __component: "Name" } }`)
|
|
4
|
-
// statt einer String-Funktion angeben. createKumikoApp im renderer
|
|
4
|
+
// statt einer String-Funktion angeben. createKumikoApp im renderer/web sammelt
|
|
5
5
|
// alle clientFeatures.columnRenderers und mountet den Provider; der DataTable-
|
|
6
6
|
// Cell-Renderer schlägt den Component über `useColumnRenderer(name)` nach.
|
|
7
7
|
//
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
// zukünftiger Boot-Validator die schema.entities-Map cross-referenziert,
|
|
13
13
|
// brechen die Type-Lies hier silent. Dann ist Zeit für eine echte
|
|
14
14
|
// RenderConfigEdit-Komponente die direkt fields nimmt.
|
|
15
|
-
import { I18N_KEY_PARAM } from "@cosmicdrift/kumiko-headless";
|
|
16
15
|
import * as z from "zod";
|
|
16
|
+
import { I18N_KEY_PARAM } from "../headless/index.js";
|
|
17
17
|
const CONFIG_EDIT_PSEUDO_ENTITY = "__config-edit__";
|
|
18
18
|
/** Baut eine minimale EntityDefinition aus den Inline-Fields des
|
|
19
19
|
* ConfigEdit-Screens. RenderEdit + computeEditViewModel iterieren
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
// Read-only render of a content editor's format with the collection's
|
|
3
|
-
// example variableSchema values substituted in for `{{name}}` — reuses the
|
|
4
|
-
// same registered editor the collection edits with (readOnly), so "rich"
|
|
5
|
-
// renders formatted HTML and "plain"/"markdown" render as text through the
|
|
6
|
-
// exact same component, no separate render path per format.
|
|
7
|
-
import { escapeHtmlAttr } from "@cosmicdrift/kumiko-headless";
|
|
8
2
|
import { useId } from "react";
|
|
3
|
+
import { escapeHtmlAttr } from "../headless/index.js";
|
|
9
4
|
import { useContentEditor } from "./content-editors.js";
|
|
10
5
|
const VARIABLE_PATTERN = /\{\{\s*(\w+)\s*\}\}/g;
|
|
11
6
|
const noop = () => { };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
// Custom-Screen-Components-Map: client-side Lookup für Screens vom Typ
|
|
3
3
|
// `custom`. KumikoScreen schaut hier nach `screen.id` (oder qn) und
|
|
4
|
-
// rendert die passende Component. createKumikoApp im renderer
|
|
4
|
+
// rendert die passende Component. createKumikoApp im renderer/web sammelt
|
|
5
5
|
// alle clientFeatures.components und mountet den Provider; Tests die
|
|
6
6
|
// einzelne Custom-Screens prüfen wollen, mounten den Provider direkt.
|
|
7
7
|
import { createContext, useContext } from "react";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DashboardScreenDefinition } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
-
import type { Translate } from "@cosmicdrift/kumiko-headless";
|
|
3
2
|
import { type ComponentType, type ReactNode } from "react";
|
|
3
|
+
import type { Translate } from "../headless/index.ts";
|
|
4
4
|
export type DashboardBodyProps = {
|
|
5
5
|
readonly featureName: string;
|
|
6
6
|
readonly screen: DashboardScreenDefinition;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { RowActionDrawer } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
-
import type { EditRelatedListSectionViewModel, ListRowViewModel, Translate } from "@cosmicdrift/kumiko-headless";
|
|
3
2
|
import { type ReactNode } from "react";
|
|
3
|
+
import type { EditRelatedListSectionViewModel, ListRowViewModel, Translate } from "../headless/index.ts";
|
|
4
4
|
export declare function EntityListExpandedRow({ section, row, featureName, translate, expansionNonce, openDrawer, onAfterWrite, onSubListInvalidated, }: {
|
|
5
5
|
readonly section: EditRelatedListSectionViewModel;
|
|
6
6
|
readonly row: ListRowViewModel;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { EntityDefinition, EntityEditScreenDefinition } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
-
import { type EditFormMode } from "@cosmicdrift/kumiko-headless";
|
|
3
2
|
import * as z from "zod";
|
|
3
|
+
import { type EditFormMode } from "../headless/index.ts";
|
|
4
4
|
export declare function isPresent(value: unknown): boolean;
|
|
5
5
|
export declare const REQUIRED_FIELD_I18N_KEY = "kumiko.validation.required";
|
|
6
6
|
export declare const OPTION_NOT_AVAILABLE_I18N_KEY = "kumiko.validation.optionNotAvailable";
|
package/dist/app/form-schema.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { evalFieldCondition, findUnavailableSelectOptions, isUnchangedValue, NO_WIDGET_FIELD_TYPES, } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
-
import { I18N_KEY_PARAM } from "@cosmicdrift/kumiko-headless";
|
|
3
2
|
import * as z from "zod";
|
|
3
|
+
import { I18N_KEY_PARAM } from "../headless/index.js";
|
|
4
4
|
import { layoutEditFields } from "./layout-fields.js";
|
|
5
5
|
// `required` means "has a value", not "is truthy" — `false` and `0` count
|
|
6
6
|
// as present, only the actually-empty representations don't.
|
|
@@ -103,7 +103,7 @@ export function buildFormSchema(entity, screen, verb, unchangedFrom) {
|
|
|
103
103
|
code: "custom",
|
|
104
104
|
path: [spec.field],
|
|
105
105
|
message: `"${spec.field}" is required.`,
|
|
106
|
-
// I18N_KEY_PARAM override, see packages/
|
|
106
|
+
// I18N_KEY_PARAM override, see packages/renderer/src/headless/form/zod-bridge.ts.
|
|
107
107
|
params: { [I18N_KEY_PARAM]: REQUIRED_FIELD_I18N_KEY },
|
|
108
108
|
});
|
|
109
109
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ScreenDefinition } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
-
import type { FormValues, ListRowViewModel, Translate } from "@cosmicdrift/kumiko-headless";
|
|
3
2
|
import { type ReactNode } from "react";
|
|
3
|
+
import type { FormValues, ListRowViewModel, Translate } from "../headless/index.ts";
|
|
4
4
|
import { type ListSort } from "../hooks/use-list-url-state.ts";
|
|
5
5
|
import type { FeatureSchema } from "./feature-schema.ts";
|
|
6
6
|
import { qualifyScreenId } from "./qualify-screen-id.ts";
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { evalFieldCondition, isRecordLocked, isWriteFormEditSection, metricField, parseRefTarget, } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
3
|
-
import { applyFormatSpec, buildOptionLabels, computeRelatedListSectionViewModel, fieldLabelKey, fieldOptionLabelKey, isSafeHref, } from "@cosmicdrift/kumiko-headless";
|
|
4
3
|
import { resolveActionIcon } from "@cosmicdrift/kumiko-types/action-icon";
|
|
5
4
|
import { TENANT_CURRENCY_CONFIG_KEY } from "@cosmicdrift/kumiko-types/fields";
|
|
6
5
|
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
@@ -14,6 +13,7 @@ import { useDispatcher, useOptionalDispatcher } from "../context/dispatcher-cont
|
|
|
14
13
|
import { useIsEmbeddedScreen } from "../context/embedded-screen-context.js";
|
|
15
14
|
import { useUserRoles } from "../context/user-roles-context.js";
|
|
16
15
|
import { useOptionalCurrentUser } from "../current-user.js";
|
|
16
|
+
import { applyFormatSpec, buildOptionLabels, computeRelatedListSectionViewModel, fieldLabelKey, fieldOptionLabelKey, isSafeHref, } from "../headless/index.js";
|
|
17
17
|
import { REFERENCE_LIST_LOOKUP_LIMIT } from "../hooks/reference-limits.js";
|
|
18
18
|
import { PAGE_SIZE_OPTIONS, useListUrlState } from "../hooks/use-list-url-state.js";
|
|
19
19
|
import { useQuery } from "../hooks/use-query.js";
|
|
@@ -24,7 +24,7 @@ import { PageHeaderSlotAvailableProvider, usePageHeaderCompact, usePageHeaderSlo
|
|
|
24
24
|
import { statusToneForOptionTone, statusToneForValue, usePrimitives, } from "../primitives.js";
|
|
25
25
|
import { screenFillsHeight } from "../screen-fills-height.js";
|
|
26
26
|
import { actionFormSubmittableFields, synthesizeActionFormEntity, synthesizeActionFormScreen, } from "./action-form-shim.js";
|
|
27
|
-
import { ActionFormLoadStatus, ActionFormSuccessBanner, isSecretFormField, resolveActionFormRecordId, useActionFormLoad, } from "./action-form-support.js";
|
|
27
|
+
import { ActionFormLoadStatus, ActionFormSuccessBanner, isSecretFormField, resolveActionFormRecordId, resolveSuccessFacts, useActionFormLoad, } from "./action-form-support.js";
|
|
28
28
|
import { useAppFeatures } from "./app-features-context.js";
|
|
29
29
|
import { useClientActionRuntime } from "./client-actions.js";
|
|
30
30
|
import { buildConfigEditSchema, synthesizeConfigEditEntity, synthesizeConfigEditScreen, } from "./config-edit-shim.js";
|
|
@@ -190,12 +190,12 @@ function renderScreenBody({ schema, screen, translate, entityId, onRowClick, onC
|
|
|
190
190
|
}
|
|
191
191
|
// Injection-Body für dashboard-Screens: die Panel-Implementierung (StatCard,
|
|
192
192
|
// Charts) ist plattform-spezifisch und kommt aus dem DashboardBody-Context
|
|
193
|
-
// (renderer
|
|
193
|
+
// (renderer/web registriert die Web-Variante in createKumikoApp).
|
|
194
194
|
function DashboardScreenBody({ featureName, screen, translate, }) {
|
|
195
195
|
const { Banner, Text } = usePrimitives();
|
|
196
196
|
const Body = useDashboardBody();
|
|
197
197
|
if (Body === undefined) {
|
|
198
|
-
return (_jsxs(Banner, { padded: true, variant: "info", testId: "kumiko-screen-dashboard-placeholder", children: ["Dashboard screen ", _jsx(Text, { variant: "code", children: screen.id }), " \u2014
|
|
198
|
+
return (_jsxs(Banner, { padded: true, variant: "info", testId: "kumiko-screen-dashboard-placeholder", children: ["Dashboard screen ", _jsx(Text, { variant: "code", children: screen.id }), " \u2014 no dashboard body registered (createKumikoApp from ", _jsx(Text, { variant: "code", children: "kumiko-renderer/web" }), " wires it automatically)."] }));
|
|
199
199
|
}
|
|
200
200
|
return (_jsx(Body, { featureName: featureName, screen: screen, ...(translate !== undefined && { translate }) }));
|
|
201
201
|
}
|
|
@@ -1448,7 +1448,7 @@ function EntityListBody({ schema, screen, entity, translate, onRowClick, }) {
|
|
|
1448
1448
|
const runNavigate = useCallback((action, row) => {
|
|
1449
1449
|
if (action.entity !== undefined) {
|
|
1450
1450
|
// Entity-Targets (fw#2228) lösen sich erst in der NavApi-Impl gegen
|
|
1451
|
-
// ALLE Features auf (resolveTarget in renderer
|
|
1451
|
+
// ALLE Features auf (resolveTarget in renderer/web/nav.tsx) — dieses
|
|
1452
1452
|
// Package kennt nur `schema` (das eine aufrufende Feature) und kann
|
|
1453
1453
|
// detailFor cross-feature nicht selbst nachschlagen.
|
|
1454
1454
|
const explicit = action.entityId !== undefined ? String(row.values[action.entityId] ?? "") : undefined;
|
|
@@ -2573,13 +2573,14 @@ function ActionFormBody({ schema, screen, translate, entityId, initialOverrides,
|
|
|
2573
2573
|
return;
|
|
2574
2574
|
}
|
|
2575
2575
|
if (screen.redirect === undefined) {
|
|
2576
|
-
const hasSuccessLinks = (screen.successLinks?.length ?? 0) > 0;
|
|
2576
|
+
const hasSuccessLinks = (screen.successLinks?.length ?? 0) > 0 || (screen.successFacts?.length ?? 0) > 0;
|
|
2577
2577
|
const publish = (text) => {
|
|
2578
2578
|
if (successSequence.current !== sequence)
|
|
2579
2579
|
return;
|
|
2580
2580
|
setSuccess({
|
|
2581
2581
|
text,
|
|
2582
2582
|
links: resolveSuccessLinks(screen.successLinks, result.data, schema, appFeatures, nav, effectiveTranslate),
|
|
2583
|
+
facts: resolveSuccessFacts(screen.successFacts, result.data, effectiveTranslate, locale),
|
|
2583
2584
|
});
|
|
2584
2585
|
};
|
|
2585
2586
|
const messageKey = screen.successMessage;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ListEmptyStateSpec } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
-
import type { Translate } from "@cosmicdrift/kumiko-headless";
|
|
3
2
|
import type { ListEmptyStateContent } from "../components/list-empty-state.tsx";
|
|
3
|
+
import type { Translate } from "../headless/index.ts";
|
|
4
4
|
import { buildRecordActions } from "./row-actions.ts";
|
|
5
5
|
type ActionBindings = Pick<Parameters<typeof buildRecordActions>[0], "nav" | "host" | "dispatcher" | "openDrawer" | "onWriteSuccess" | "clientActions">;
|
|
6
6
|
export declare function useListEmptyContent(spec: ListEmptyStateSpec | undefined, translate: Translate, bindings: ActionBindings): ListEmptyStateContent | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EntityListFacetConfig, ListFacetSpec } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
-
import type { Translate } from "
|
|
2
|
+
import type { Translate } from "../headless/index.ts";
|
|
3
3
|
import type { DataTableFacet, DataTableFacetChip } from "../primitives.tsx";
|
|
4
4
|
export type ResolvedFacetSpec = {
|
|
5
5
|
readonly field: string;
|
package/dist/app/nav.js
CHANGED
|
@@ -76,7 +76,7 @@ export function hasDetailScreen(features, entity) {
|
|
|
76
76
|
}
|
|
77
77
|
// Resolves a NavTarget to the ScreenTarget form navigate/replace/hrefFor
|
|
78
78
|
// operate on. Pure — no context, no I/O — so callers can use it outside
|
|
79
|
-
// React too (see resolve-at-NavApi-build alternative in renderer
|
|
79
|
+
// React too (see resolve-at-NavApi-build alternative in renderer/web).
|
|
80
80
|
export function resolveTarget(features, target) {
|
|
81
81
|
if ("screenId" in target)
|
|
82
82
|
return target;
|
|
@@ -151,7 +151,7 @@ export function useOptionalNav() {
|
|
|
151
151
|
export function useNav() {
|
|
152
152
|
const api = useContext(NavContext);
|
|
153
153
|
if (api === undefined) {
|
|
154
|
-
throw new Error("useNav: no <NavProvider> mounted above this component. Plattform-Packages (z.B. @cosmicdrift/kumiko-renderer
|
|
154
|
+
throw new Error("useNav: no <NavProvider> mounted above this component. Plattform-Packages (z.B. @cosmicdrift/kumiko-renderer/web) liefern eine Default-Impl über createKumikoApp.");
|
|
155
155
|
}
|
|
156
156
|
return api;
|
|
157
157
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { DispatcherError, Translate } from "@cosmicdrift/kumiko-headless";
|
|
2
1
|
import type { ReactNode } from "react";
|
|
2
|
+
import type { DispatcherError, Translate } from "../headless/index.ts";
|
|
3
3
|
export declare function QueryLoadingBanner(): ReactNode;
|
|
4
4
|
export declare function QueryErrorBanner({ error, translate, onRetry, }: {
|
|
5
5
|
readonly error: DispatcherError;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CellLink } from "
|
|
1
|
+
import type { CellLink } from "../headless/index.ts";
|
|
2
2
|
/** Link to a referenced record's detail screen, or undefined when there is no
|
|
3
3
|
* navigation, the user may not open that screen, or no detail screen exists. */
|
|
4
4
|
export type ReferenceLinkResolver = (refEntity: string, id: string) => CellLink | undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { EntityEditScreenDefinition, RelatedListToolbarAction, RowAction, RowActionClientAction, RowActionDrawer, RowActionNavigate, RowActionWriteHandler, RowFieldExtractor, ToolbarAction } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
-
import type { Dispatcher, ListRowViewModel, Translate } from "@cosmicdrift/kumiko-headless";
|
|
3
2
|
import type { RenderEditAction } from "../components/render-edit-types.ts";
|
|
4
3
|
import type { ToolbarActionButton } from "../components/render-list.tsx";
|
|
4
|
+
import type { Dispatcher, ListRowViewModel, Translate } from "../headless/index.ts";
|
|
5
5
|
import type { DataTableRowAction } from "../primitives.tsx";
|
|
6
6
|
import { type ClientActionRuntime } from "./client-actions.tsx";
|
|
7
7
|
import type { NavApi } from "./nav.tsx";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SecretMintScreenDefinition } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
-
import type { Translate } from "@cosmicdrift/kumiko-headless";
|
|
3
2
|
import { type ReactNode } from "react";
|
|
3
|
+
import type { Translate } from "../headless/index.ts";
|
|
4
4
|
import type { FeatureSchema } from "./feature-schema.ts";
|
|
5
5
|
export type SecretMintBodyProps = {
|
|
6
6
|
readonly schema: FeatureSchema;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SecretsEditScreenDefinition } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
-
import type { Translate } from "@cosmicdrift/kumiko-headless";
|
|
3
2
|
import { type ReactNode } from "react";
|
|
3
|
+
import type { Translate } from "../headless/index.ts";
|
|
4
4
|
export type SecretsEditBodyProps = {
|
|
5
5
|
readonly screen: SecretsEditScreenDefinition;
|
|
6
6
|
readonly translate?: Translate;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { RowAction } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
-
import type { Translate } from "@cosmicdrift/kumiko-headless";
|
|
3
2
|
import type { RenderEditAction } from "../components/render-edit-types.ts";
|
|
3
|
+
import type { Translate } from "../headless/index.ts";
|
|
4
4
|
/** Header actions on a record shown by a screen that has no drawer host
|
|
5
5
|
* (dashboards): writeHandler, navigate and clientAction, `onWriteSuccess` after a success. */
|
|
6
6
|
export declare function useRecordActions(options: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DispatcherError } from "
|
|
1
|
+
import type { DispatcherError } from "../headless/index.ts";
|
|
2
2
|
export declare class WriteFailedError extends Error {
|
|
3
3
|
readonly dispatcherError: DispatcherError;
|
|
4
4
|
constructor(error: DispatcherError, message: string);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { EditFieldViewModel } from "@cosmicdrift/kumiko-headless";
|
|
2
1
|
import type { OptionsQueryPayload } from "@cosmicdrift/kumiko-types/fields";
|
|
3
2
|
import { type ReactNode } from "react";
|
|
3
|
+
import type { EditFieldViewModel } from "../headless/index.ts";
|
|
4
4
|
export type SelectOptionEntry = {
|
|
5
5
|
readonly value: string;
|
|
6
6
|
readonly label: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { EditFieldViewModel, FieldIssue } from "@cosmicdrift/kumiko-headless";
|
|
2
1
|
import { type ReactNode } from "react";
|
|
2
|
+
import type { EditFieldViewModel, FieldIssue } from "../headless/index.ts";
|
|
3
3
|
export type EmbeddedListFieldProps = {
|
|
4
4
|
readonly field: EditFieldViewModel;
|
|
5
5
|
readonly id: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { computeDerivedCellValue, currencyDecimals, groupEmbeddedListIssues, roundDerivedCellValue, sumEmbeddedListColumn, } from "@cosmicdrift/kumiko-headless";
|
|
3
2
|
import { useState } from "react";
|
|
3
|
+
import { computeDerivedCellValue, currencyDecimals, groupEmbeddedListIssues, roundDerivedCellValue, sumEmbeddedListColumn, } from "../headless/index.js";
|
|
4
4
|
import { REFERENCE_COMBOBOX_LIMIT } from "../hooks/reference-limits.js";
|
|
5
5
|
import { useQuery } from "../hooks/use-query.js";
|
|
6
6
|
import { referenceOptionSource } from "../hooks/use-reference-lookup.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { EditFieldViewModel } from "@cosmicdrift/kumiko-headless";
|
|
2
1
|
import type { ReactNode } from "react";
|
|
2
|
+
import type { EditFieldViewModel } from "../headless/index.ts";
|
|
3
3
|
export type FileListFieldProps = {
|
|
4
4
|
readonly field: EditFieldViewModel;
|
|
5
5
|
readonly id: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { EditFieldViewModel, FieldIssue } from "@cosmicdrift/kumiko-headless";
|
|
2
1
|
import type { ReactNode } from "react";
|
|
2
|
+
import type { EditFieldViewModel, FieldIssue } from "../headless/index.ts";
|
|
3
3
|
import type { FieldCellWidth, FieldProps, usePrimitives } from "../primitives.tsx";
|
|
4
4
|
export type GridCellForFieldProps = {
|
|
5
5
|
readonly field: EditFieldViewModel;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { EditFieldViewModel } from "@cosmicdrift/kumiko-headless";
|
|
2
1
|
import type { ReactNode } from "react";
|
|
2
|
+
import type { EditFieldViewModel } from "../headless/index.ts";
|
|
3
3
|
export type MultiSelectCheckboxOption = {
|
|
4
4
|
readonly value: string;
|
|
5
5
|
readonly label: string;
|
|
@@ -5,7 +5,7 @@ import { usePrimitives } from "../primitives.js";
|
|
|
5
5
|
// as a visible checkbox plus a select-all toggle, built purely from the
|
|
6
6
|
// platform-neutral Primitives contract (Grid/GridCell/Field/Input kind
|
|
7
7
|
// "boolean", the same primitive `case "boolean"` uses in render-field.tsx).
|
|
8
|
-
// No renderer
|
|
8
|
+
// No renderer/web import here — this file must stay usable from Expo too.
|
|
9
9
|
export function MultiSelectCheckboxes({ field, id, options, value, onChange, }) {
|
|
10
10
|
const { Grid, GridCell, Field, Input, Button } = usePrimitives();
|
|
11
11
|
const t = useTranslation();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { EditFieldViewModel } from "@cosmicdrift/kumiko-headless";
|
|
2
1
|
import { type OptionsQueryPayload } from "@cosmicdrift/kumiko-types/fields";
|
|
3
2
|
import { type ReactNode } from "react";
|
|
3
|
+
import type { EditFieldViewModel } from "../headless/index.ts";
|
|
4
4
|
type ResolvedOptionsQueryPayload = Readonly<Record<string, string | number | boolean>>;
|
|
5
5
|
export declare function resolveOptionsQueryPayload(payload: OptionsQueryPayload, row: Readonly<Record<string, unknown>>): ResolvedOptionsQueryPayload;
|
|
6
6
|
type QueryOptionsSelectProps = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { RowActionDrawer } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
-
import type { EditRelatedListSectionViewModel, Translate } from "@cosmicdrift/kumiko-headless";
|
|
3
2
|
import { type ReactNode } from "react";
|
|
3
|
+
import type { EditRelatedListSectionViewModel, Translate } from "../headless/index.ts";
|
|
4
4
|
export declare function RelatedListSection({ section, parentId, record, featureName, translate, hideTitle, grow, onOpenDrawer, actions, embedded, onAfterWrite, refreshToken, }: {
|
|
5
5
|
readonly section: EditRelatedListSectionViewModel;
|
|
6
6
|
readonly parentId: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DispatcherError, EditFieldViewModel, EditSectionViewModel, SubmitResult } from "
|
|
1
|
+
import type { DispatcherError, EditFieldViewModel, EditSectionViewModel, SubmitResult } from "../headless/index.ts";
|
|
2
2
|
export declare function hasEditableSection(sections: readonly EditSectionViewModel[]): boolean;
|
|
3
3
|
export declare function resolveExtensionEntityId(entityIdProp: string | null | undefined, vmId: string | null): string | null;
|
|
4
4
|
export declare function shouldNotifyCaller(result: SubmitResult<unknown>, extensionsPersisted: boolean): boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ActionFormFooterAction, EntityDefinition, EntityEditScreenDefinition, IconKey, RowAction, RowActionDrawer } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
-
import type { DispatcherError, FormSnapshot, FormValues, SubmitResult, Translate } from "@cosmicdrift/kumiko-headless";
|
|
3
2
|
import type { ReactNode } from "react";
|
|
4
3
|
import type * as z from "zod";
|
|
4
|
+
import type { DispatcherError, FormSnapshot, FormValues, SubmitResult, Translate } from "../headless/index.ts";
|
|
5
5
|
export type RenderEditProps<TValues extends FormValues, TCtx = unknown> = {
|
|
6
6
|
readonly screen: EntityEditScreenDefinition;
|
|
7
7
|
/** Screen id used for the `screen:<id>.title`/`.subtitle` lookups and as the
|
|
@@ -59,7 +59,7 @@ export type RenderEditProps<TValues extends FormValues, TCtx = unknown> = {
|
|
|
59
59
|
/** Copy-link action (issue #912) — only set in update mode (create mode
|
|
60
60
|
* has no entity id yet, hence no permalink). The callback is already fully
|
|
61
61
|
* bound (URL building + clipboard happen outside, in
|
|
62
|
-
* `@cosmicdrift/kumiko-renderer
|
|
62
|
+
* `@cosmicdrift/kumiko-renderer/web`'s RoutedScreen — this platform-neutral
|
|
63
63
|
* package must not touch `navigator`/`window`, see
|
|
64
64
|
* guard-renderer-boundaries). undefined = no button. */
|
|
65
65
|
readonly onCopyLink?: () => Promise<void> | void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FormValues } from "
|
|
1
|
+
import type { FormValues } from "../headless/index.ts";
|
|
2
2
|
import type { RenderEditProps } from "./render-edit-types.ts";
|
|
3
3
|
export type { RenderEditAction, RenderEditChangeState, RenderEditControls, RenderEditProps, } from "./render-edit-types.ts";
|
|
4
4
|
import { type ReactNode } from "react";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { evalFieldCondition, isFieldsEditSection, normalizeEditField, PROJECTION_DETAIL_ENTITY, sectionFieldSpecs, } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
3
|
-
import { computeEditViewModel, groupIssuesByPath, relevantFieldIssues, zodErrorToFieldIssues, } from "@cosmicdrift/kumiko-headless";
|
|
4
3
|
import { propertyOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
4
|
+
import { computeEditViewModel, groupIssuesByPath, relevantFieldIssues, zodErrorToFieldIssues, } from "../headless/index.js";
|
|
5
5
|
import { RenderEditActionButton } from "./render-edit-action-button.js";
|
|
6
6
|
import { AllFieldsRequiredProvider } from "./render-field.js";
|
|
7
7
|
import { useActionMenuItems } from "./use-action-menu-items.js";
|
|
@@ -1075,6 +1075,7 @@ export function RenderEdit(props) {
|
|
|
1075
1075
|
wizardBackRef.current = isWizard ? handleWizardBack : () => { };
|
|
1076
1076
|
// Screen forms (entityEdit/actionForm filling the shell height) drop the card;
|
|
1077
1077
|
// the title then lives in the shell header when the shell offers a slot.
|
|
1078
|
+
const rootIssues = snapshot.errors[ROOT_ISSUE_PATH] ?? [];
|
|
1078
1079
|
const isScreenForm = fillScreenHeight === true && hideSectionTitles !== true && !insideDrawer;
|
|
1079
1080
|
const titleInShell = PageHeader !== undefined &&
|
|
1080
1081
|
pageHeaderSlotAvailable &&
|
|
@@ -1480,7 +1481,8 @@ export function RenderEdit(props) {
|
|
|
1480
1481
|
onReload();
|
|
1481
1482
|
setFormError(null);
|
|
1482
1483
|
setExtraDeleteIssues([]);
|
|
1483
|
-
}, testId: "render-edit-form-error-reload", children: translate("kumiko.actions.reload") })) : undefined, children: [_jsx(Text, { testId: "render-edit-form-error-key", children: translate(formError.i18nKey, formError.i18nParams) }),
|
|
1484
|
+
}, testId: "render-edit-form-error-reload", children: translate("kumiko.actions.reload") })) : undefined, children: [_jsx(Text, { testId: "render-edit-form-error-key", children: translate(formError.i18nKey, formError.i18nParams) }), rootIssues.map((issue) => (_jsx(Text, { testId: "render-edit-form-error-root", children: translate(issue.i18nKey, issue.params) }, `${issue.path}:${issue.i18nKey}`))), extraDeleteIssues.map((issue) => (_jsx(Text, { testId: "render-edit-form-error-extra", children: translate(issue.i18nKey, issue.params) }, `${issue.path}:${issue.i18nKey}`)))] })), formError === null &&
|
|
1485
|
+
rootIssues.map((issue) => (_jsx(Banner, { variant: "error", testId: "render-edit-root-issue", children: _jsx(Text, { children: translate(issue.i18nKey, issue.params) }) }, issue.i18nKey))), extensionErrorKey !== null && (_jsx(Banner, { variant: "error", testId: "render-edit-extension-error", children: _jsx(Text, { testId: "render-edit-extension-error-key", children: translate(extensionErrorKey) }) })), actionError !== null && (_jsx(Banner, { variant: "error", testId: "render-edit-action-error", children: actionError })), onDelete !== undefined && (_jsx(Dialog, { open: confirmDeleteOpen, onOpenChange: setConfirmDeleteOpen, title: translate("kumiko.actions.delete-confirm"), confirmLabel: translate("kumiko.actions.delete"), variant: "danger", onConfirm: async () => {
|
|
1484
1486
|
const rejection = await onDelete();
|
|
1485
1487
|
// A rejected delete (e.g. a preDelete hook) carries its reason in
|
|
1486
1488
|
// the field issues; the top-level key is only "validation failed".
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type EditFieldViewModel, type FieldIssue } from "@cosmicdrift/kumiko-headless";
|
|
2
1
|
import { type ReactNode } from "react";
|
|
2
|
+
import { type EditFieldViewModel, type FieldIssue } from "../headless/index.ts";
|
|
3
3
|
import { type FieldProps } from "../primitives.tsx";
|
|
4
4
|
export type RenderFieldProps = {
|
|
5
5
|
readonly field: EditFieldViewModel;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { isFormatSpec, SYSTEM_REFERENCE_LABELS, } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
3
|
-
import { applyFormatSpec, currencyDecimals, EMPTY_VALUE_PLACEHOLDER, } from "@cosmicdrift/kumiko-headless";
|
|
4
3
|
import { propertyOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
5
4
|
import { createContext, Fragment, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
|
|
6
5
|
import { useAppFeatures } from "../app/app-features-context.js";
|
|
@@ -12,6 +11,7 @@ import { evalRowExtractor } from "../app/row-actions.js";
|
|
|
12
11
|
import { screenAccessAllows } from "../app/screen-access.js";
|
|
13
12
|
import { useOptionalDispatcher } from "../context/dispatcher-context.js";
|
|
14
13
|
import { useUserRoles } from "../context/user-roles-context.js";
|
|
14
|
+
import { applyFormatSpec, currencyDecimals, EMPTY_VALUE_PLACEHOLDER, } from "../headless/index.js";
|
|
15
15
|
import { REFERENCE_COMBOBOX_LIMIT } from "../hooks/reference-limits.js";
|
|
16
16
|
import { useQuery } from "../hooks/use-query.js";
|
|
17
17
|
import { referenceOptionSource } from "../hooks/use-reference-lookup.js";
|
|
@@ -494,6 +494,9 @@ function renderInput({ field, id, hasError, onChange, Input, appLocale, Banner,
|
|
|
494
494
|
if (field.type === "text" && field.format === "password") {
|
|
495
495
|
return (_jsx(Input, { kind: "password", ...common, value: stringValue(field.value), onChange: (v) => onChange(v) }));
|
|
496
496
|
}
|
|
497
|
+
if (field.type === "text" && field.format === "month") {
|
|
498
|
+
return (_jsx(Input, { kind: "month", ...common, value: stringValue(field.value), onChange: (v) => onChange(v) }));
|
|
499
|
+
}
|
|
497
500
|
// text + unknown scalar type → text input. If TextFieldDef.multiline
|
|
498
501
|
// is set (the view-model carries it), the renderer switches to
|
|
499
502
|
// textarea. longText always renders a textarea — that's the point of
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { EntityDefinition, EntityListScreenDefinition, IconKey } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
-
import type { ListRowViewModel, Translate } from "@cosmicdrift/kumiko-headless";
|
|
3
2
|
import { type ReactNode } from "react";
|
|
3
|
+
import type { ListRowViewModel, Translate } from "../headless/index.ts";
|
|
4
4
|
import type { ListSort } from "../hooks/use-list-url-state.ts";
|
|
5
5
|
import { type DataTableDateRangeFacet, type DataTableFacet, type DataTableProps, type DataTableRowAction, type DataTableRowActionMode, type DataTableRowGrouping } from "../primitives.tsx";
|
|
6
6
|
import { type ListEmptyStateContent } from "./list-empty-state.tsx";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { computeListViewModel, EMPTY_VALUE_PLACEHOLDER } from "@cosmicdrift/kumiko-headless";
|
|
3
2
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
3
|
import { extensionSectionName, useExtensionSectionComponent } from "../app/extension-sections.js";
|
|
5
4
|
import { useReferenceLinkResolver } from "../app/reference-link.js";
|
|
5
|
+
import { computeListViewModel, EMPTY_VALUE_PLACEHOLDER } from "../headless/index.js";
|
|
6
6
|
import { useReferenceLookup } from "../hooks/use-reference-lookup.js";
|
|
7
7
|
import { useTranslation } from "../i18n.js";
|
|
8
8
|
import { usePageHeaderCompact, usePageHeaderSlotAvailable } from "../page-header-slot.js";
|
|
@@ -104,7 +104,7 @@ export function RenderList(props) {
|
|
|
104
104
|
const labelField = col.refLabelField ?? "id";
|
|
105
105
|
const refEntity = col.refEntity ?? "";
|
|
106
106
|
// Only a row the user can see is linkable: resolved by the server
|
|
107
|
-
// eagerload or by the lookup query. A multi-reference
|
|
107
|
+
// eagerload or by the lookup query. A multi-reference links per entry via linkItemsFor.
|
|
108
108
|
const linkFor = (value, row) => {
|
|
109
109
|
if (value === null || value === undefined || value === "" || Array.isArray(value)) {
|
|
110
110
|
return undefined;
|
|
@@ -118,6 +118,22 @@ export function RenderList(props) {
|
|
|
118
118
|
map?.has(id);
|
|
119
119
|
return resolved === true ? resolveReferenceLink(refEntity, id) : undefined;
|
|
120
120
|
};
|
|
121
|
+
const linkItemsFor = (value, row) => {
|
|
122
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
123
|
+
return undefined;
|
|
124
|
+
const eagerloaded = eagerloadedRef(row, col.field);
|
|
125
|
+
const eagerById = new Map(Array.isArray(eagerloaded) ? eagerloaded.map((r) => [String(r["id"]), r]) : []);
|
|
126
|
+
return value.map((v) => {
|
|
127
|
+
const id = String(v);
|
|
128
|
+
const target = eagerById.get(id);
|
|
129
|
+
const label = String(target?.[labelField] ?? map?.get(id) ?? id);
|
|
130
|
+
// Only a row the user can see is linkable: server eagerload or lookup query.
|
|
131
|
+
const link = target !== undefined || map?.has(id) === true
|
|
132
|
+
? resolveReferenceLink(refEntity, id)
|
|
133
|
+
: undefined;
|
|
134
|
+
return { id, label, ...(link !== undefined && { link }) };
|
|
135
|
+
});
|
|
136
|
+
};
|
|
121
137
|
const renderer = (value, row) => {
|
|
122
138
|
// Tier 2.7e Server-Eagerload: wenn der Server _refs mit-
|
|
123
139
|
// schickt, lesen wir den Display-Wert direkt aus der
|
|
@@ -142,7 +158,7 @@ export function RenderList(props) {
|
|
|
142
158
|
const idStr = String(value);
|
|
143
159
|
return map?.get(idStr) ?? idStr;
|
|
144
160
|
};
|
|
145
|
-
return { ...col, renderer, linkFor };
|
|
161
|
+
return { ...col, renderer, linkFor, linkItemsFor };
|
|
146
162
|
});
|
|
147
163
|
}, [vm.columns, referenceColumns, referenceLookups, resolveReferenceLink]);
|
|
148
164
|
const enrichedVm = useMemo(() => ({
|
|
@@ -190,7 +206,7 @@ export function RenderList(props) {
|
|
|
190
206
|
// Wenn weder onCreate noch ein Override gegeben ist, fällt die
|
|
191
207
|
// DataTable auf den DataTable-Default zurück (`kumiko.list.no-entries`).
|
|
192
208
|
const composedEmptyState = emptyState ??
|
|
193
|
-
(onCreate !== undefined || emptyContent !== undefined || narrowed ? (_jsx(ListEmptyStateBody, { content: emptyContent, narrowed: narrowed, translate: translate, createButton: onCreate !== undefined && !narrowed ? (_jsx(Button, { variant: "primary", icon: "plus", onClick: onCreate, testId: "render-list-empty-create", children: effectiveCreateLabel })) : undefined })) : undefined);
|
|
209
|
+
(onCreate !== undefined || emptyContent !== undefined || narrowed ? (_jsx(ListEmptyStateBody, { content: emptyContent, narrowed: narrowed, translate: translate, createButton: onCreate !== undefined && !narrowed && !createInPageHeader ? (_jsx(Button, { variant: "primary", icon: "plus", onClick: onCreate, testId: "render-list-empty-create", children: effectiveCreateLabel })) : undefined })) : undefined);
|
|
194
210
|
// Title-Resolution: ein konventioneller i18n-Key `screen:<id>.title`.
|
|
195
211
|
// Wenn das Bundle den Key kennt, schöner Titel; sonst kommt der
|
|
196
212
|
// screenId selber raus (kein "Untitled"-Fallback — der App-Dev sieht
|