@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
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
import { availableSelectOptions, evalFieldCondition, isExtensionEditSection, isFieldsEditSection, isWriteFormEditSection, normalizeEditField, parseRefTarget, sectionFieldSpecs, WRITE_FORM_SECTION_ENTITY, } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
+
import { buildOptionLabels, embeddedCellLabelKey, embeddedCellOptionLabelKey, fieldLabelKey, fieldOptionLabelKey, } from "./list.js";
|
|
3
|
+
// Resolves a writeForm section's own fieldDefs/fields through the same
|
|
4
|
+
// per-field pipeline as a plain fields section, by reusing the pipeline
|
|
5
|
+
// itself rather than duplicating it: wrap fieldDefs/fields as a throwaway
|
|
6
|
+
// entityEdit screen (same "synthesize a pseudo-entity" idiom as the shims in
|
|
7
|
+
// packages/renderer/src/app/*-shim.ts) and recurse into computeEditViewModel
|
|
8
|
+
// once. Split out of computeEditViewModel's section-map to keep that
|
|
9
|
+
// function's own complexity from absorbing this branch's decision points.
|
|
10
|
+
function computeWriteFormSectionViewModel(sectionSpec, screenId, values, translate, featureName) {
|
|
11
|
+
const innerEntity = { fields: sectionSpec.fieldDefs };
|
|
12
|
+
const innerScreen = {
|
|
13
|
+
id: `${screenId}:${sectionSpec.id ?? "write-form"}`,
|
|
14
|
+
type: "entityEdit",
|
|
15
|
+
entity: WRITE_FORM_SECTION_ENTITY,
|
|
16
|
+
layout: {
|
|
17
|
+
sections: [{ kind: "fields", fields: sectionSpec.fields, columns: sectionSpec.columns }],
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
const inner = computeEditViewModel({
|
|
21
|
+
screen: innerScreen,
|
|
22
|
+
entity: innerEntity,
|
|
23
|
+
values,
|
|
24
|
+
translate,
|
|
25
|
+
featureName,
|
|
26
|
+
});
|
|
27
|
+
const innerSection = inner.sections[0];
|
|
28
|
+
const fields = innerSection?.kind === "fields" ? innerSection.fields : [];
|
|
29
|
+
return {
|
|
30
|
+
kind: "writeForm",
|
|
31
|
+
...(sectionSpec.title !== undefined && { title: translate(sectionSpec.title) }),
|
|
32
|
+
...(sectionSpec.description !== undefined && {
|
|
33
|
+
description: translate(sectionSpec.description),
|
|
34
|
+
}),
|
|
35
|
+
columns: sectionSpec.columns ?? 1,
|
|
36
|
+
fields,
|
|
37
|
+
...(sectionSpec.icon !== undefined && { icon: sectionSpec.icon }),
|
|
38
|
+
handler: sectionSpec.handler,
|
|
39
|
+
...(sectionSpec.submitLabel !== undefined && {
|
|
40
|
+
submitLabel: translate(sectionSpec.submitLabel),
|
|
41
|
+
}),
|
|
42
|
+
...(sectionSpec.actions !== undefined && { actions: sectionSpec.actions }),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function wasEmptiedByWriteExclusion(declaredFieldSpecs, remainingFields) {
|
|
46
|
+
return declaredFieldSpecs.length > 0 && remainingFields.length === 0;
|
|
47
|
+
}
|
|
48
|
+
// relatedList runs its own query — nothing here to resolve against
|
|
49
|
+
// entity/values, the spec passes through verbatim (fw#2166).
|
|
50
|
+
export function computeRelatedListSectionViewModel(sectionSpec, translate) {
|
|
51
|
+
return {
|
|
52
|
+
kind: "relatedList",
|
|
53
|
+
title: translate(sectionSpec.title),
|
|
54
|
+
query: sectionSpec.query,
|
|
55
|
+
...(sectionSpec.parentParam !== undefined && { parentParam: sectionSpec.parentParam }),
|
|
56
|
+
...(sectionSpec.parentFilter !== undefined && { parentFilter: sectionSpec.parentFilter }),
|
|
57
|
+
columns: sectionSpec.columns,
|
|
58
|
+
...(sectionSpec.entity !== undefined && { entity: sectionSpec.entity }),
|
|
59
|
+
...(sectionSpec.description !== undefined && {
|
|
60
|
+
description: translate(sectionSpec.description),
|
|
61
|
+
}),
|
|
62
|
+
...(sectionSpec.itemNoun !== undefined && { itemNoun: sectionSpec.itemNoun }),
|
|
63
|
+
...(sectionSpec.pageSize !== undefined && { pageSize: sectionSpec.pageSize }),
|
|
64
|
+
...(sectionSpec.defaultSort !== undefined && { defaultSort: sectionSpec.defaultSort }),
|
|
65
|
+
...(sectionSpec.searchable !== undefined && { searchable: sectionSpec.searchable }),
|
|
66
|
+
...(sectionSpec.facets !== undefined && { facets: sectionSpec.facets }),
|
|
67
|
+
...(sectionSpec.rowClick !== undefined && { rowClick: sectionSpec.rowClick }),
|
|
68
|
+
...(sectionSpec.rowActions !== undefined && { rowActions: sectionSpec.rowActions }),
|
|
69
|
+
...(sectionSpec.rowActionMode !== undefined && { rowActionMode: sectionSpec.rowActionMode }),
|
|
70
|
+
...(sectionSpec.groupBy !== undefined && { groupBy: sectionSpec.groupBy }),
|
|
71
|
+
...(sectionSpec.rowTone !== undefined && { rowTone: sectionSpec.rowTone }),
|
|
72
|
+
...(sectionSpec.toolbarActions !== undefined && { toolbarActions: sectionSpec.toolbarActions }),
|
|
73
|
+
...(sectionSpec.actions !== undefined && { actions: sectionSpec.actions }),
|
|
74
|
+
...(sectionSpec.emptyState !== undefined && {
|
|
75
|
+
emptyState: {
|
|
76
|
+
title: translate(sectionSpec.emptyState.title),
|
|
77
|
+
...(sectionSpec.emptyState.description !== undefined && {
|
|
78
|
+
description: translate(sectionSpec.emptyState.description),
|
|
79
|
+
}),
|
|
80
|
+
// Action stays untranslated, same convention as rowActions/
|
|
81
|
+
// toolbarActions above — the renderer's row-actions builder
|
|
82
|
+
// translates `action.label` at button-build time.
|
|
83
|
+
...(sectionSpec.emptyState.action !== undefined && {
|
|
84
|
+
action: sectionSpec.emptyState.action,
|
|
85
|
+
}),
|
|
86
|
+
},
|
|
87
|
+
}),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function translateAffix(affix, translate) {
|
|
91
|
+
return typeof affix === "string" ? translate(affix) : affix;
|
|
92
|
+
}
|
|
93
|
+
function deriveFieldAffixHints(normalized, translate) {
|
|
94
|
+
return {
|
|
95
|
+
...(normalized.placeholder !== undefined && { placeholder: translate(normalized.placeholder) }),
|
|
96
|
+
...(normalized.prefix !== undefined && {
|
|
97
|
+
prefix: translateAffix(normalized.prefix, translate),
|
|
98
|
+
}),
|
|
99
|
+
...(normalized.suffix !== undefined && {
|
|
100
|
+
suffix: translateAffix(normalized.suffix, translate),
|
|
101
|
+
}),
|
|
102
|
+
...(normalized.fillAction !== undefined && {
|
|
103
|
+
fillAction: { ...normalized.fillAction, label: translate(normalized.fillAction.label) },
|
|
104
|
+
}),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function deriveSelectOptionsQuery(fieldDef) {
|
|
108
|
+
return fieldDef.type === "select" && fieldDef.optionsQuery !== undefined
|
|
109
|
+
? {
|
|
110
|
+
selectOptionsQuery: {
|
|
111
|
+
query: fieldDef.optionsQuery,
|
|
112
|
+
payload: fieldDef.optionsQueryPayload ?? {},
|
|
113
|
+
},
|
|
114
|
+
}
|
|
115
|
+
: {};
|
|
116
|
+
}
|
|
117
|
+
function deriveSelectOptionsAvailabilityQuery(fieldDef) {
|
|
118
|
+
if (fieldDef.type === "multiSelect") {
|
|
119
|
+
return fieldDef.optionsAvailabilityQuery !== undefined
|
|
120
|
+
? {
|
|
121
|
+
selectOptionsAvailabilityQuery: { query: fieldDef.optionsAvailabilityQuery, payload: {} },
|
|
122
|
+
}
|
|
123
|
+
: {};
|
|
124
|
+
}
|
|
125
|
+
return fieldDef.type === "select" && fieldDef.optionsAvailabilityQuery !== undefined
|
|
126
|
+
? {
|
|
127
|
+
selectOptionsAvailabilityQuery: {
|
|
128
|
+
query: fieldDef.optionsAvailabilityQuery,
|
|
129
|
+
payload: fieldDef.optionsQueryPayload ?? {},
|
|
130
|
+
},
|
|
131
|
+
}
|
|
132
|
+
: {};
|
|
133
|
+
}
|
|
134
|
+
// A stored value that conditionalOptions no longer allows stays listed, so the
|
|
135
|
+
// form shows it (flagged on submit) instead of silently dropping it.
|
|
136
|
+
function selectableOptions(fieldDef, fieldName, values) {
|
|
137
|
+
if (fieldDef.type === "multiSelect")
|
|
138
|
+
return fieldDef.options;
|
|
139
|
+
if (fieldDef.type !== "select")
|
|
140
|
+
return undefined;
|
|
141
|
+
if (!fieldDef.conditionalOptions)
|
|
142
|
+
return fieldDef.options;
|
|
143
|
+
const available = availableSelectOptions(fieldDef, values);
|
|
144
|
+
const current = values[fieldName];
|
|
145
|
+
return fieldDef.options.filter((option) => available.includes(option) || option === current);
|
|
146
|
+
}
|
|
147
|
+
function deriveSelectFieldHints(fieldDef, translate, featureName, entityName, fieldName, values) {
|
|
148
|
+
const options = selectableOptions(fieldDef, fieldName, values);
|
|
149
|
+
const optionLabels = options !== undefined
|
|
150
|
+
? buildOptionLabels(translate, (value) => fieldOptionLabelKey(featureName, entityName, fieldName, value), options)
|
|
151
|
+
: undefined;
|
|
152
|
+
const declaredDisplay = fieldDef.type === "multiSelect" || fieldDef.type === "select" ? fieldDef.display : undefined;
|
|
153
|
+
// The renderer's heuristic counts options, so a filtered list would switch widgets with the discriminator.
|
|
154
|
+
const display = declaredDisplay ??
|
|
155
|
+
(fieldDef.type === "select" && fieldDef.conditionalOptions ? "dropdown" : undefined);
|
|
156
|
+
const columns = fieldDef.type === "multiSelect" ? fieldDef.columns : undefined;
|
|
157
|
+
const maxRows = fieldDef.type === "multiSelect" ? fieldDef.maxRows : undefined;
|
|
158
|
+
return {
|
|
159
|
+
...deriveSelectOptionsQuery(fieldDef),
|
|
160
|
+
...deriveSelectOptionsAvailabilityQuery(fieldDef),
|
|
161
|
+
...(options !== undefined && { options }),
|
|
162
|
+
...(optionLabels !== undefined && { optionLabels }),
|
|
163
|
+
...(display !== undefined && { display }),
|
|
164
|
+
...(columns !== undefined && { columns }),
|
|
165
|
+
...(maxRows !== undefined && { maxRows }),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function deriveTextFieldHints(fieldDef) {
|
|
169
|
+
const multiline = fieldDef.type === "text" || fieldDef.type === "longText" ? fieldDef.multiline : undefined;
|
|
170
|
+
const format = fieldDef.type === "text" ? fieldDef.format : undefined;
|
|
171
|
+
const writeOnly = fieldDef.type === "text" && fieldDef.writeOnly === true;
|
|
172
|
+
const autoComplete = fieldDef.type === "text" ? fieldDef.autoComplete : undefined;
|
|
173
|
+
return {
|
|
174
|
+
...(multiline !== undefined && { multiline }),
|
|
175
|
+
...(autoComplete !== undefined && { autoComplete }),
|
|
176
|
+
...(format !== undefined && { format }),
|
|
177
|
+
...(writeOnly && { writeOnly: true }),
|
|
178
|
+
...("sensitive" in fieldDef && fieldDef.sensitive === true && { sensitive: true }),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
function deriveDateFieldHints(fieldDef) {
|
|
182
|
+
const wallClock = fieldDef.type === "timestamp" &&
|
|
183
|
+
fieldDef.locatedBy !== undefined
|
|
184
|
+
? true
|
|
185
|
+
: undefined;
|
|
186
|
+
const dateBounds = fieldDef.type === "date" ||
|
|
187
|
+
fieldDef.type === "timestamp" ||
|
|
188
|
+
fieldDef.type === "locatedTimestamp"
|
|
189
|
+
? fieldDef
|
|
190
|
+
: undefined;
|
|
191
|
+
return {
|
|
192
|
+
...(wallClock !== undefined && { wallClock }),
|
|
193
|
+
...(dateBounds?.min !== undefined && { min: dateBounds.min }),
|
|
194
|
+
...(dateBounds?.max !== undefined && { max: dateBounds.max }),
|
|
195
|
+
...(dateBounds?.locale !== undefined && { dateLocale: dateBounds.locale }),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
function deriveNumericFieldHints(fieldDef, resolvedCurrency) {
|
|
199
|
+
const grouping = fieldDef.type === "number" ? fieldDef.grouping : undefined;
|
|
200
|
+
return {
|
|
201
|
+
...(grouping !== undefined && { grouping }),
|
|
202
|
+
...(fieldDef.type === "money" && { currency: resolvedCurrency }),
|
|
203
|
+
...(fieldDef.type === "number" && fieldDef.unit !== undefined && { unit: fieldDef.unit }),
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
// Declared reference metadata (EditFieldSpec.refEntity) takes priority over
|
|
207
|
+
// fieldDef.type — see computeEditViewModel's effectiveType, same reasoning.
|
|
208
|
+
function deriveReferenceFieldHints(fieldDef, normalized, declaredRefTarget, featureName) {
|
|
209
|
+
const refRaw = declaredRefTarget === undefined && fieldDef.type === "reference"
|
|
210
|
+
? fieldDef.entity
|
|
211
|
+
: undefined;
|
|
212
|
+
const refTarget = declaredRefTarget ?? (refRaw !== undefined ? parseRefTarget(refRaw, featureName) : undefined);
|
|
213
|
+
const refLabelField = declaredRefTarget !== undefined
|
|
214
|
+
? (normalized.refLabelField ?? "id")
|
|
215
|
+
: fieldDef.type === "reference"
|
|
216
|
+
? (fieldDef.labelField ?? "id")
|
|
217
|
+
: undefined;
|
|
218
|
+
return {
|
|
219
|
+
...(refTarget?.entityName !== undefined && { refEntity: refTarget.entityName }),
|
|
220
|
+
...(refTarget?.featureName !== undefined && { refFeature: refTarget.featureName }),
|
|
221
|
+
...(refLabelField !== undefined && { refLabelField }),
|
|
222
|
+
...deriveReferenceMultiHints(fieldDef, declaredRefTarget),
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
// Declared reference metadata has no `multiple` or `optionsQuery` concept
|
|
226
|
+
// (it targets row-meta/derived fields, always single-valued and resolved
|
|
227
|
+
// through the target entity) — only a real ReferenceFieldDef carries them.
|
|
228
|
+
function deriveReferenceMultiHints(fieldDef, declaredRefTarget) {
|
|
229
|
+
const ownReferenceDef = declaredRefTarget === undefined && fieldDef.type === "reference"
|
|
230
|
+
? fieldDef
|
|
231
|
+
: undefined;
|
|
232
|
+
const refMultiple = ownReferenceDef === undefined ? undefined : (ownReferenceDef.multiple ?? false);
|
|
233
|
+
return {
|
|
234
|
+
...(ownReferenceDef?.optionsQuery !== undefined && {
|
|
235
|
+
refOptionsQuery: ownReferenceDef.optionsQuery,
|
|
236
|
+
}),
|
|
237
|
+
...(refMultiple !== undefined && { refMultiple }),
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
// file/image: entityType/fieldName travel with the upload POST so the
|
|
241
|
+
// endpoint validates against the right field definition.
|
|
242
|
+
function isFileFieldType(fieldDef) {
|
|
243
|
+
return (fieldDef.type === "file" ||
|
|
244
|
+
fieldDef.type === "image" ||
|
|
245
|
+
fieldDef.type === "files" ||
|
|
246
|
+
fieldDef.type === "images");
|
|
247
|
+
}
|
|
248
|
+
function deriveImageHints(fieldDef) {
|
|
249
|
+
if (fieldDef.type !== "image" && fieldDef.type !== "images")
|
|
250
|
+
return {};
|
|
251
|
+
const imageVariant = Object.keys(fieldDef.variants ?? {})[0];
|
|
252
|
+
return {
|
|
253
|
+
...(imageVariant !== undefined && { imageVariant }),
|
|
254
|
+
...(fieldDef.capture !== undefined && { capture: fieldDef.capture }),
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
function deriveFileFieldHints(fieldDef, entityName, fieldName, entityId) {
|
|
258
|
+
if (!isFileFieldType(fieldDef))
|
|
259
|
+
return {};
|
|
260
|
+
const maxCount = fieldDef.type === "files" || fieldDef.type === "images" ? fieldDef.maxCount : undefined;
|
|
261
|
+
return {
|
|
262
|
+
...(fieldDef.accept !== undefined && { accept: fieldDef.accept }),
|
|
263
|
+
...(fieldDef.maxSize !== undefined && { maxSize: fieldDef.maxSize }),
|
|
264
|
+
...(maxCount !== undefined && { maxCount }),
|
|
265
|
+
entityType: entityName,
|
|
266
|
+
fieldName,
|
|
267
|
+
...(entityId !== undefined && { entityId }),
|
|
268
|
+
...deriveImageHints(fieldDef),
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
function deriveEmbeddedCellSelectHints(subField, translate, featureName, entityName, fieldName, subFieldName) {
|
|
272
|
+
if (subField.type !== "select")
|
|
273
|
+
return {};
|
|
274
|
+
const options = subField.options ?? [];
|
|
275
|
+
return {
|
|
276
|
+
options,
|
|
277
|
+
optionLabels: buildOptionLabels(translate, (value) => embeddedCellOptionLabelKey(featureName, entityName, fieldName, subFieldName, value), options),
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
function deriveEmbeddedCellReferenceHints(subField, featureName) {
|
|
281
|
+
if (subField.type !== "reference")
|
|
282
|
+
return {};
|
|
283
|
+
const target = subField.entity !== undefined ? parseRefTarget(subField.entity, featureName) : undefined;
|
|
284
|
+
return {
|
|
285
|
+
...(target !== undefined && { refEntity: target.entityName, refFeature: target.featureName }),
|
|
286
|
+
...(subField.labelField !== undefined && { refLabelField: subField.labelField }),
|
|
287
|
+
...(subField.optionsQuery !== undefined && { refOptionsQuery: subField.optionsQuery }),
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
function buildEmbeddedListCell(subFieldName, subField, translate, featureName, entityName, fieldName, listSpec) {
|
|
291
|
+
return {
|
|
292
|
+
field: subFieldName,
|
|
293
|
+
label: translate(embeddedCellLabelKey(featureName, entityName, fieldName, subFieldName)),
|
|
294
|
+
type: subField.type,
|
|
295
|
+
required: subField.required === true,
|
|
296
|
+
...deriveEmbeddedCellSelectHints(subField, translate, featureName, entityName, fieldName, subFieldName),
|
|
297
|
+
...deriveEmbeddedCellReferenceHints(subField, featureName),
|
|
298
|
+
...(subField.type === "decimal" && subField.scale !== undefined && { scale: subField.scale }),
|
|
299
|
+
...(subField.type === "select" &&
|
|
300
|
+
subField.display !== undefined && { display: subField.display }),
|
|
301
|
+
...(listSpec?.readOnlyCells?.includes(subFieldName) === true && { readOnly: true }),
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
// Embedded-LIST field (`multiple: true`) — per-cell metadata for a renderer
|
|
305
|
+
// to draw one row per array item (invoice-positions-style table). A plain
|
|
306
|
+
// (non-list) embedded field emits none of this; the renderer tells the two
|
|
307
|
+
// apart by whether embeddedListCells is set, not by `type` (which stays
|
|
308
|
+
// "embedded" either way).
|
|
309
|
+
function deriveEmbeddedListHints(fieldDef, translate, featureName, entityName, fieldName, resolvedCurrency, listSpec) {
|
|
310
|
+
const isEmbeddedList = fieldDef.type === "embedded" &&
|
|
311
|
+
fieldDef.multiple === true;
|
|
312
|
+
const embeddedListDef = isEmbeddedList
|
|
313
|
+
? fieldDef
|
|
314
|
+
: undefined;
|
|
315
|
+
const embeddedListCells = embeddedListDef !== undefined
|
|
316
|
+
? Object.entries(embeddedListDef.schema).map(([subFieldName, subField]) => buildEmbeddedListCell(subFieldName, subField, translate, featureName, entityName, fieldName, listSpec))
|
|
317
|
+
: undefined;
|
|
318
|
+
return {
|
|
319
|
+
...(embeddedListCells !== undefined && { embeddedListCells }),
|
|
320
|
+
...(embeddedListDef?.minItems !== undefined && {
|
|
321
|
+
embeddedListMinItems: embeddedListDef.minItems,
|
|
322
|
+
}),
|
|
323
|
+
...(embeddedListDef?.maxItems !== undefined && {
|
|
324
|
+
embeddedListMaxItems: embeddedListDef.maxItems,
|
|
325
|
+
}),
|
|
326
|
+
...(embeddedListDef?.derived !== undefined && {
|
|
327
|
+
embeddedListDerived: embeddedListDef.derived,
|
|
328
|
+
}),
|
|
329
|
+
...(embeddedListDef?.totals !== undefined && {
|
|
330
|
+
embeddedListTotals: embeddedListDef.totals,
|
|
331
|
+
}),
|
|
332
|
+
// Currency lives on the head aggregate (entity.defaultCurrency), not per
|
|
333
|
+
// row — one value for the whole embedded list.
|
|
334
|
+
...(embeddedListDef !== undefined && { embeddedListCurrency: resolvedCurrency }),
|
|
335
|
+
...(embeddedListDef !== undefined &&
|
|
336
|
+
listSpec?.fixedRows === true && { embeddedListFixedRows: true }),
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
function buildExtensionSectionViewModel(sectionSpec, translate) {
|
|
340
|
+
const entityNameOverride = sectionSpec.entityName?.trim();
|
|
341
|
+
return {
|
|
342
|
+
kind: "extension",
|
|
343
|
+
...(sectionSpec.id !== undefined && { id: sectionSpec.id }),
|
|
344
|
+
title: translate(sectionSpec.title),
|
|
345
|
+
component: sectionSpec.component,
|
|
346
|
+
contributesToFormSubmit: sectionSpec.contributesToFormSubmit === true,
|
|
347
|
+
// Blank override must fall back to the host value: the renderer's `??`
|
|
348
|
+
// would otherwise pass "" through to the mounted extension.
|
|
349
|
+
...(entityNameOverride !== undefined &&
|
|
350
|
+
entityNameOverride.length > 0 && { entityName: entityNameOverride }),
|
|
351
|
+
...(sectionSpec.actions !== undefined && { actions: sectionSpec.actions }),
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
// Pure transform from screen-def + entity-def + row-values to the flat
|
|
355
|
+
// section/field tree the renderer draws. FieldConditions are evaluated here
|
|
356
|
+
// so the renderer never re-runs them during React render.
|
|
357
|
+
export function computeEditViewModel(input) {
|
|
358
|
+
const { screen, entity, values, translate, featureName, mode, entityId } = input;
|
|
359
|
+
const excludedFields = new Set(mode === undefined ? [] : screen.writeExcludedFields?.[mode]);
|
|
360
|
+
const isHiddenByExclusion = (fieldSpec) => mode === "create" && excludedFields.has(normalizeEditField(fieldSpec).field);
|
|
361
|
+
const sections = screen.layout.sections.map((sectionSpec) => {
|
|
362
|
+
if (isExtensionEditSection(sectionSpec)) {
|
|
363
|
+
return buildExtensionSectionViewModel(sectionSpec, translate);
|
|
364
|
+
}
|
|
365
|
+
if (isWriteFormEditSection(sectionSpec)) {
|
|
366
|
+
return computeWriteFormSectionViewModel(sectionSpec, screen.id, values, translate, featureName);
|
|
367
|
+
}
|
|
368
|
+
if (!isFieldsEditSection(sectionSpec)) {
|
|
369
|
+
return computeRelatedListSectionViewModel(sectionSpec, translate);
|
|
370
|
+
}
|
|
371
|
+
// `groups` flattens into the same per-field pipeline as plain `fields`;
|
|
372
|
+
// the group structure below just re-groups the computed views by name.
|
|
373
|
+
const declaredFieldSpecs = sectionFieldSpecs(sectionSpec);
|
|
374
|
+
const fields = declaredFieldSpecs
|
|
375
|
+
.filter((fieldSpec) => !isHiddenByExclusion(fieldSpec))
|
|
376
|
+
.map((fieldSpec) => {
|
|
377
|
+
const normalized = normalizeEditField(fieldSpec);
|
|
378
|
+
const fieldDef = entity.fields[normalized.field];
|
|
379
|
+
if (!fieldDef) {
|
|
380
|
+
throw new Error(`computeEditViewModel: screen "${screen.id}" references unknown field "${normalized.field}" on entity "${screen.entity}"`);
|
|
381
|
+
}
|
|
382
|
+
// Declared reference metadata (EditFieldSpec.refEntity) — for
|
|
383
|
+
// projectionDetail fields, which have no EntityDefinition field to
|
|
384
|
+
// carry a real "reference" type. Takes priority over fieldDef.type
|
|
385
|
+
// below so it also fires against the pseudo-entity that hardcodes
|
|
386
|
+
// every field as "text" (projection-detail-shim) — real entityEdit
|
|
387
|
+
// screens never set this, so their fieldDef.type === "reference"
|
|
388
|
+
// branch is unaffected.
|
|
389
|
+
// A real non-text field (e.g. a `reference` with `multiple`) keeps its own
|
|
390
|
+
// type and hints, as documented on EditFieldSpec.refEntity; the shim's
|
|
391
|
+
// pseudo-entity only ever declares "text".
|
|
392
|
+
const declaredRefTarget = normalized.refEntity !== undefined && fieldDef.type === "text"
|
|
393
|
+
? parseRefTarget(normalized.refEntity, featureName)
|
|
394
|
+
: undefined;
|
|
395
|
+
const effectiveType = declaredRefTarget !== undefined ? "reference" : fieldDef.type;
|
|
396
|
+
const label = translate(screen.fieldLabels?.[normalized.field] ??
|
|
397
|
+
fieldLabelKey(featureName, screen.entity, normalized.field));
|
|
398
|
+
const visible = evalCondition(normalized.visible, true, values);
|
|
399
|
+
// `readOnly` (camelCase) is the name on both sides: EditFieldSpec
|
|
400
|
+
// in the engine, and the view-model emitted here. One convention
|
|
401
|
+
// through the stack beats translating at the boundary.
|
|
402
|
+
const readOnly = (mode === "update" && excludedFields.has(normalized.field)) ||
|
|
403
|
+
evalCondition(normalized.readOnly, false, values);
|
|
404
|
+
// `required` on the field-spec overrides the entity-default. A
|
|
405
|
+
// field that's required at the entity-level but marked required:
|
|
406
|
+
// false on the screen (e.g. a soft-onboarding wizard that
|
|
407
|
+
// collects less up-front) respects the screen override.
|
|
408
|
+
const entityRequired = fieldDef.required === true;
|
|
409
|
+
const required = evalCondition(normalized.required, entityRequired, values);
|
|
410
|
+
// ponytail: "EUR" mirrors DEFAULT_CURRENCIES[0] from
|
|
411
|
+
// framework/src/engine/field-helpers.ts — headless has no dependency
|
|
412
|
+
// on that module, so the literal is duplicated here instead of
|
|
413
|
+
// importing it just for one fallback string.
|
|
414
|
+
const resolvedCurrency = entity.defaultCurrency ?? "EUR";
|
|
415
|
+
const selectHints = deriveSelectFieldHints(fieldDef, translate, featureName, screen.entity, normalized.field, values);
|
|
416
|
+
const textHints = deriveTextFieldHints(fieldDef);
|
|
417
|
+
const dateHints = deriveDateFieldHints(fieldDef);
|
|
418
|
+
const numericHints = deriveNumericFieldHints(fieldDef, resolvedCurrency);
|
|
419
|
+
const referenceHints = deriveReferenceFieldHints(fieldDef, normalized, declaredRefTarget, featureName);
|
|
420
|
+
const fileHints = deriveFileFieldHints(fieldDef, screen.entity, normalized.field, entityId);
|
|
421
|
+
const embeddedListHints = deriveEmbeddedListHints(fieldDef, translate, featureName, screen.entity, normalized.field, resolvedCurrency, normalized.embeddedList);
|
|
422
|
+
const view = {
|
|
423
|
+
field: normalized.field,
|
|
424
|
+
label,
|
|
425
|
+
type: effectiveType,
|
|
426
|
+
value: values[normalized.field],
|
|
427
|
+
visible,
|
|
428
|
+
readOnly,
|
|
429
|
+
required,
|
|
430
|
+
...(normalized.span !== undefined && { span: normalized.span }),
|
|
431
|
+
...(normalized.renderer !== undefined && { renderer: normalized.renderer }),
|
|
432
|
+
...selectHints,
|
|
433
|
+
...textHints,
|
|
434
|
+
...dateHints,
|
|
435
|
+
...numericHints,
|
|
436
|
+
...referenceHints,
|
|
437
|
+
...fileHints,
|
|
438
|
+
...(normalized.icon !== undefined && { icon: normalized.icon }),
|
|
439
|
+
...deriveFieldAffixHints(normalized, translate),
|
|
440
|
+
...embeddedListHints,
|
|
441
|
+
};
|
|
442
|
+
return view;
|
|
443
|
+
});
|
|
444
|
+
// The boot-validator rejects declared-empty sections (screens.ts), but a
|
|
445
|
+
// create-excluded field list can still empty one here: then `visible` is false.
|
|
446
|
+
const visible = fields.some((field) => field.visible);
|
|
447
|
+
// Tabs mode renders this section as its own panel, where two columns reads
|
|
448
|
+
// better than the single-column default a stacked form keeps. Applies to
|
|
449
|
+
// entityEdit tabs as well since fw#3134, not just projectionDetail.
|
|
450
|
+
const defaultColumns = screen.layout.mode === "tabs" ? 2 : 1;
|
|
451
|
+
const groups = sectionSpec.groups
|
|
452
|
+
?.map((group) => ({ ...group, fields: group.fields.filter((f) => !isHiddenByExclusion(f)) }))
|
|
453
|
+
.filter((group) => group.fields.length > 0)
|
|
454
|
+
.map((group) => ({
|
|
455
|
+
title: translate(group.title),
|
|
456
|
+
columns: group.columns ?? 2,
|
|
457
|
+
fields: group.fields.map((fieldSpec) => {
|
|
458
|
+
const fieldName = normalizeEditField(fieldSpec).field;
|
|
459
|
+
const fieldView = fields.find((f) => f.field === fieldName);
|
|
460
|
+
if (fieldView === undefined) {
|
|
461
|
+
throw new Error(`computeEditViewModel: screen "${screen.id}" group "${group.title}" references field ` +
|
|
462
|
+
`"${fieldName}" that failed to resolve.`);
|
|
463
|
+
}
|
|
464
|
+
return fieldView;
|
|
465
|
+
}),
|
|
466
|
+
}));
|
|
467
|
+
return {
|
|
468
|
+
kind: "fields",
|
|
469
|
+
...(sectionSpec.id !== undefined && { id: sectionSpec.id }),
|
|
470
|
+
visible,
|
|
471
|
+
emptiedByWriteExclusion: wasEmptiedByWriteExclusion(declaredFieldSpecs, fields),
|
|
472
|
+
// Untitled section (flat form) → no h3; translate only when set.
|
|
473
|
+
...(sectionSpec.title !== undefined && { title: translate(sectionSpec.title) }),
|
|
474
|
+
...(sectionSpec.description !== undefined && {
|
|
475
|
+
description: translate(sectionSpec.description),
|
|
476
|
+
}),
|
|
477
|
+
...(sectionSpec.subtitle !== undefined && { subtitle: translate(sectionSpec.subtitle) }),
|
|
478
|
+
columns: sectionSpec.columns ?? defaultColumns,
|
|
479
|
+
fields,
|
|
480
|
+
...(groups !== undefined && { groups }),
|
|
481
|
+
...(sectionSpec.icon !== undefined && { icon: sectionSpec.icon }),
|
|
482
|
+
...(sectionSpec.actions !== undefined && { actions: sectionSpec.actions }),
|
|
483
|
+
};
|
|
484
|
+
});
|
|
485
|
+
const idValue = values["id"];
|
|
486
|
+
const id = typeof idValue === "string" ? idValue : null;
|
|
487
|
+
return {
|
|
488
|
+
screenId: screen.id,
|
|
489
|
+
entityName: screen.entity,
|
|
490
|
+
id,
|
|
491
|
+
sections,
|
|
492
|
+
...(screen.slots && { slots: screen.slots }),
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
// Resolves a FieldCondition against the current row values.
|
|
496
|
+
// `undefined` means "not declared" — caller substitutes the default.
|
|
497
|
+
function evalCondition(condition, fallback, values) {
|
|
498
|
+
if (condition === undefined)
|
|
499
|
+
return fallback;
|
|
500
|
+
return evalFieldCondition(condition, values);
|
|
501
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { EmbeddedDerivedCellDef } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
+
import type { FieldIssue } from "../dispatcher/index.ts";
|
|
3
|
+
export type EmbeddedDerivedOp = EmbeddedDerivedCellDef["op"];
|
|
4
|
+
export type { DerivedCellRoundingTarget } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
5
|
+
export { computeDerivedCellValue, roundDerivedCellValue, } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
6
|
+
/** Sums a numeric/money/decimal column across all rows. Non-numeric or
|
|
7
|
+
* missing values count as 0. Money columns are minor-unit integers —
|
|
8
|
+
* the sum stays in minor units, never rounds through a major-unit float. */
|
|
9
|
+
export declare function sumEmbeddedListColumn(rows: readonly Readonly<Record<string, unknown>>[], field: string): number;
|
|
10
|
+
export type EmbeddedListIssueGroups = {
|
|
11
|
+
/** Issues at exactly `listField` — e.g. min/max row-count violations. */
|
|
12
|
+
readonly listIssues: readonly FieldIssue[];
|
|
13
|
+
/** Issues at exactly `${listField}.${rowIndex}` — a row-level check
|
|
14
|
+
* (e.g. "row incomplete") that isn't attributable to one cell. */
|
|
15
|
+
readonly rowIssues: Readonly<Record<number, readonly FieldIssue[]>>;
|
|
16
|
+
/** Issues at exactly `${listField}.${rowIndex}.${cellField}`, keyed
|
|
17
|
+
* `${rowIndex}.${cellField}` (not the full path — the caller already
|
|
18
|
+
* knows listField). */
|
|
19
|
+
readonly cellIssues: Readonly<Record<string, readonly FieldIssue[]>>;
|
|
20
|
+
};
|
|
21
|
+
/** Buckets a flat issues-by-path map (FormSnapshot.errors shape — see
|
|
22
|
+
* packages/renderer/src/headless/form/zod-bridge.ts groupIssuesByPath) into the
|
|
23
|
+
* three levels an embedded-list widget renders. Only keys that are
|
|
24
|
+
* exactly `listField`, `listField.N`, or `listField.N.subfield` are
|
|
25
|
+
* claimed; unrelated keys (other top-level fields, or deeper nesting
|
|
26
|
+
* than this field ever produces) are ignored. */
|
|
27
|
+
export declare function groupEmbeddedListIssues(allIssues: Readonly<Record<string, readonly FieldIssue[]>>, listField: string): EmbeddedListIssueGroups;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Canonical implementation moved to packages/framework/src/engine/embedded-derived.ts
|
|
2
|
+
// (the write-schema preprocess needs it server-side too).
|
|
3
|
+
export { computeDerivedCellValue, roundDerivedCellValue, } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
4
|
+
/** Sums a numeric/money/decimal column across all rows. Non-numeric or
|
|
5
|
+
* missing values count as 0. Money columns are minor-unit integers —
|
|
6
|
+
* the sum stays in minor units, never rounds through a major-unit float. */
|
|
7
|
+
export function sumEmbeddedListColumn(rows, field) {
|
|
8
|
+
let sum = 0;
|
|
9
|
+
for (const row of rows) {
|
|
10
|
+
const value = row[field];
|
|
11
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
12
|
+
sum += value;
|
|
13
|
+
}
|
|
14
|
+
return sum;
|
|
15
|
+
}
|
|
16
|
+
/** Buckets a flat issues-by-path map (FormSnapshot.errors shape — see
|
|
17
|
+
* packages/renderer/src/headless/form/zod-bridge.ts groupIssuesByPath) into the
|
|
18
|
+
* three levels an embedded-list widget renders. Only keys that are
|
|
19
|
+
* exactly `listField`, `listField.N`, or `listField.N.subfield` are
|
|
20
|
+
* claimed; unrelated keys (other top-level fields, or deeper nesting
|
|
21
|
+
* than this field ever produces) are ignored. */
|
|
22
|
+
export function groupEmbeddedListIssues(allIssues, listField) {
|
|
23
|
+
const listIssues = [];
|
|
24
|
+
const rowIssues = {};
|
|
25
|
+
const cellIssues = {};
|
|
26
|
+
const prefix = `${listField}.`;
|
|
27
|
+
for (const [path, issues] of Object.entries(allIssues)) {
|
|
28
|
+
if (path === listField) {
|
|
29
|
+
listIssues.push(...issues);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (!path.startsWith(prefix))
|
|
33
|
+
continue;
|
|
34
|
+
const rest = path.slice(prefix.length);
|
|
35
|
+
const segments = rest.split(".");
|
|
36
|
+
if (segments.length === 1) {
|
|
37
|
+
const rowIndex = parsePureRowIndex(segments[0]);
|
|
38
|
+
if (rowIndex === undefined)
|
|
39
|
+
continue;
|
|
40
|
+
rowIssues[rowIndex] = issues;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (segments.length === 2) {
|
|
44
|
+
const rowIndex = parsePureRowIndex(segments[0]);
|
|
45
|
+
if (rowIndex === undefined)
|
|
46
|
+
continue;
|
|
47
|
+
const cellField = segments[1];
|
|
48
|
+
cellIssues[`${rowIndex}.${cellField}`] = issues;
|
|
49
|
+
}
|
|
50
|
+
// Deeper than `listField.N.subfield` — not a shape this field ever
|
|
51
|
+
// produces; ignore rather than misattribute to a cell.
|
|
52
|
+
}
|
|
53
|
+
return { listIssues, rowIssues, cellIssues };
|
|
54
|
+
}
|
|
55
|
+
function parsePureRowIndex(segment) {
|
|
56
|
+
if (segment === undefined || segment.length === 0)
|
|
57
|
+
return undefined;
|
|
58
|
+
for (const char of segment) {
|
|
59
|
+
if (char < "0" || char > "9")
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
return Number(segment);
|
|
63
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { ComputeEditViewModelInput, EditFormMode } from "./edit.ts";
|
|
2
|
+
export { computeEditViewModel, computeRelatedListSectionViewModel } from "./edit.ts";
|
|
3
|
+
export type { DerivedCellRoundingTarget, EmbeddedDerivedOp, EmbeddedListIssueGroups, } from "./embedded-list.ts";
|
|
4
|
+
export { computeDerivedCellValue, groupEmbeddedListIssues, roundDerivedCellValue, sumEmbeddedListColumn, } from "./embedded-list.ts";
|
|
5
|
+
export type { ComputeListViewModelInput } from "./list.ts";
|
|
6
|
+
export { buildOptionLabels, computeListViewModel, embeddedCellLabelKey, embeddedCellOptionLabelKey, fieldLabelKey, fieldOptionLabelKey, fieldOptionLabelKeyPrefix, } from "./list.ts";
|
|
7
|
+
export type { CellLink, CellLinkItem, EditExtensionSectionViewModel, EditFieldSpec, EditFieldsSectionViewModel, EditFieldViewModel, EditRelatedListSectionViewModel, EditSectionSpec, EditSectionViewModel, EditViewModel, EditWriteFormSectionViewModel, EmbeddedListCellViewModel, FieldConditionCtx, FieldRenderer, ListColumnFileDisplay, ListColumnSpec, ListColumnViewModel, ListRowViewModel, ListViewModel, RuntimeCellLink, RuntimeCellLinkItems, RuntimeRenderer, ScreenSlots, Translate, } from "./types.ts";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { computeEditViewModel, computeRelatedListSectionViewModel } from "./edit.js";
|
|
2
|
+
export { computeDerivedCellValue, groupEmbeddedListIssues, roundDerivedCellValue, sumEmbeddedListColumn, } from "./embedded-list.js";
|
|
3
|
+
export { buildOptionLabels, computeListViewModel, embeddedCellLabelKey, embeddedCellOptionLabelKey, fieldLabelKey, fieldOptionLabelKey, fieldOptionLabelKeyPrefix, } from "./list.js";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { FieldDefinition } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
+
import type { ListColumnFileDisplay, ListColumnViewModel } from "./types.ts";
|
|
3
|
+
export declare function deriveListFileDisplay(fieldDef: FieldDefinition, renderer: ListColumnViewModel["renderer"]): ListColumnFileDisplay | undefined;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
function firstVariantKey(fieldDef) {
|
|
2
|
+
return Object.keys(fieldDef.variants ?? {})[0];
|
|
3
|
+
}
|
|
4
|
+
function fromFormatSpec(renderer) {
|
|
5
|
+
if (typeof renderer !== "object" || renderer === null || !("format" in renderer)) {
|
|
6
|
+
return undefined;
|
|
7
|
+
}
|
|
8
|
+
if (renderer.format === "file")
|
|
9
|
+
return { kind: "file" };
|
|
10
|
+
if (renderer.format !== "image")
|
|
11
|
+
return undefined;
|
|
12
|
+
return renderer.variant === undefined
|
|
13
|
+
? { kind: "image" }
|
|
14
|
+
: { kind: "image", variant: renderer.variant };
|
|
15
|
+
}
|
|
16
|
+
function fromFieldType(fieldDef) {
|
|
17
|
+
if (fieldDef.type === "file" || fieldDef.type === "files")
|
|
18
|
+
return { kind: "file" };
|
|
19
|
+
if (fieldDef.type !== "image" && fieldDef.type !== "images")
|
|
20
|
+
return undefined;
|
|
21
|
+
const variant = firstVariantKey(fieldDef);
|
|
22
|
+
return variant === undefined ? { kind: "image" } : { kind: "image", variant };
|
|
23
|
+
}
|
|
24
|
+
// An explicit `{ format: "image" | "file" }` renderer wins over the field type.
|
|
25
|
+
export function deriveListFileDisplay(fieldDef, renderer) {
|
|
26
|
+
return fromFormatSpec(renderer) ?? fromFieldType(fieldDef);
|
|
27
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { EntityDefinition, EntityListScreenDefinition } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
+
import type { ListViewModel, Translate } from "./types.ts";
|
|
3
|
+
export type ComputeListViewModelInput = {
|
|
4
|
+
readonly screen: EntityListScreenDefinition;
|
|
5
|
+
readonly entity: EntityDefinition;
|
|
6
|
+
readonly rows: readonly Readonly<Record<string, unknown>>[];
|
|
7
|
+
readonly translate: Translate;
|
|
8
|
+
readonly featureName: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function computeListViewModel(input: ComputeListViewModelInput): ListViewModel;
|
|
11
|
+
export declare function fieldLabelKey(featureName: string, entityName: string, fieldName: string): string;
|
|
12
|
+
export declare function fieldOptionLabelKeyPrefix(featureName: string, entityName: string, fieldName: string): string;
|
|
13
|
+
export declare function fieldOptionLabelKey(featureName: string, entityName: string, fieldName: string, value: string): string;
|
|
14
|
+
export declare function embeddedCellLabelKey(featureName: string, entityName: string, fieldName: string, subFieldName: string): string;
|
|
15
|
+
export declare function embeddedCellOptionLabelKey(featureName: string, entityName: string, fieldName: string, subFieldName: string, value: string): string;
|
|
16
|
+
export declare function buildOptionLabels(translate: (key: string, params?: Readonly<Record<string, unknown>>) => string, keyFor: (value: string) => string, options: readonly string[]): Readonly<Record<string, string>>;
|