@elytracms/studio 0.0.92 → 0.0.94
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/convex/analytics-cost.test.ts +817 -0
- package/convex/asset-alt-migration.test.ts +127 -0
- package/convex/asset-replace.test.ts +168 -0
- package/convex/asset-revalidate.test.ts +6 -6
- package/convex/assets.ts +41 -5
- package/convex/auth.ts +5 -2
- package/convex/authority.ts +35 -11
- package/convex/cms.ts +25 -11
- package/convex/contract-parity.test.ts +25 -3
- package/convex/delivery.ts +12 -9
- package/convex/document-revalidate.test.ts +10 -12
- package/convex/guard.ts +9 -7
- package/convex/http-routes.test.ts +18 -8
- package/convex/http.ts +23 -17
- package/convex/ingest.test.ts +326 -0
- package/convex/ingest.ts +281 -0
- package/convex/invites.ts +13 -5
- package/convex/members.ts +10 -4
- package/convex/orphan-hydration.test.ts +116 -0
- package/convex/rail-write-parity.test.ts +11 -8
- package/convex/record-functions.ts +325 -0
- package/convex/records.test.ts +156 -0
- package/convex/redirect-migration.test.ts +205 -0
- package/convex/redirect-revalidate.test.ts +5 -1
- package/convex/redirects.ts +120 -79
- package/convex/role-policy.test.ts +315 -0
- package/convex/roles.ts +83 -0
- package/convex/schema.ts +36 -0
- package/convex/triggers.ts +21 -1
- package/dist/addon.d.ts +71 -0
- package/dist/addon.js +67 -0
- package/dist/addon.js.map +1 -0
- package/dist/components/account/account-settings.js +2 -2
- package/dist/components/account/account-settings.js.map +1 -1
- package/dist/components/account/credential-panel.js +2 -2
- package/dist/components/account/credential-panel.js.map +1 -1
- package/dist/components/account/self-account-schema.d.ts +6 -15
- package/dist/components/account/self-account-schema.js +52 -34
- package/dist/components/account/self-account-schema.js.map +1 -1
- package/dist/components/account/self-account-view-source.d.ts +1 -1
- package/dist/components/account/self-account-view-source.js +6 -4
- package/dist/components/account/self-account-view-source.js.map +1 -1
- package/dist/components/ai/ai-chat-panel-lazy.js +1 -1
- package/dist/components/ai/ai-chat-panel-lazy.js.map +1 -1
- package/dist/components/ai/ai-chat-panel.js +6 -6
- package/dist/components/ai/ai-chat-panel.js.map +1 -1
- package/dist/components/ai/ai-cms-panel.js +2 -2
- package/dist/components/ai/ai-cms-panel.js.map +1 -1
- package/dist/components/ai/ai-panel-toggle.js +4 -4
- package/dist/components/ai/ai-panel-toggle.js.map +1 -1
- package/dist/components/ai/chat-ui.js +2 -2
- package/dist/components/ai/chat-ui.js.map +1 -1
- package/dist/components/ai/proposal-card.d.ts +2 -2
- package/dist/components/ai/proposal-card.js +4 -3
- package/dist/components/ai/proposal-card.js.map +1 -1
- package/dist/components/ai/proposal-issues.js +2 -2
- package/dist/components/ai/proposal-issues.js.map +1 -1
- package/dist/components/ai/translate-document-action.js +2 -2
- package/dist/components/ai/translate-document-action.js.map +1 -1
- package/dist/components/ai/translate-document-dialog.js +10 -8
- package/dist/components/ai/translate-document-dialog.js.map +1 -1
- package/dist/components/ai/translate-skipped.d.ts +19 -0
- package/dist/components/ai/translate-skipped.js +46 -0
- package/dist/components/ai/translate-skipped.js.map +1 -0
- package/dist/components/app-views/default-modules.d.ts +50 -2
- package/dist/components/app-views/default-modules.js +65 -20
- package/dist/components/app-views/default-modules.js.map +1 -1
- package/dist/components/app-views/module.d.ts +53 -3
- package/dist/components/app-views/module.js +14 -7
- package/dist/components/app-views/module.js.map +1 -1
- package/dist/components/app-views/sidebar.js +1 -1
- package/dist/components/app-views/sidebar.js.map +1 -1
- package/dist/components/app-views/studio-config.d.ts +11 -2
- package/dist/components/app-views/studio-config.js.map +1 -1
- package/dist/components/assets/asset-detail.js +20 -10
- package/dist/components/assets/asset-detail.js.map +1 -1
- package/dist/components/assets/asset-grid.js +2 -2
- package/dist/components/assets/asset-grid.js.map +1 -1
- package/dist/components/assets/asset-metadata.d.ts +15 -4
- package/dist/components/assets/asset-metadata.js +15 -2
- package/dist/components/assets/asset-metadata.js.map +1 -1
- package/dist/components/assets/asset-search.js +4 -1
- package/dist/components/assets/asset-search.js.map +1 -1
- package/dist/components/assets/asset-selection.d.ts +0 -8
- package/dist/components/assets/asset-selection.js +4 -23
- package/dist/components/assets/asset-selection.js.map +1 -1
- package/dist/components/assets/asset-thumb.js +6 -5
- package/dist/components/assets/asset-thumb.js.map +1 -1
- package/dist/components/assets/assets-collection-view-source.d.ts +5 -5
- package/dist/components/assets/assets-collection-view-source.js +9 -5
- package/dist/components/assets/assets-collection-view-source.js.map +1 -1
- package/dist/components/assets/assets-module.js +1 -1
- package/dist/components/assets/assets-module.js.map +1 -1
- package/dist/components/assets/assets-store.d.ts +16 -2
- package/dist/components/assets/assets-store.js +28 -6
- package/dist/components/assets/assets-store.js.map +1 -1
- package/dist/components/assets/assets-view-preference.js +1 -1
- package/dist/components/assets/assets-view-preference.js.map +1 -1
- package/dist/components/assets/replace-file.d.ts +22 -0
- package/dist/components/assets/replace-file.js +59 -0
- package/dist/components/assets/replace-file.js.map +1 -0
- package/dist/components/auth-context.d.ts +1 -1
- package/dist/components/auth-context.js +6 -6
- package/dist/components/auth-context.js.map +1 -1
- package/dist/components/builder/blocks-model.d.ts +15 -27
- package/dist/components/builder/blocks-model.js +38 -44
- package/dist/components/builder/blocks-model.js.map +1 -1
- package/dist/components/builder/blocks-panel.d.ts +8 -4
- package/dist/components/builder/blocks-panel.js +10 -9
- package/dist/components/builder/blocks-panel.js.map +1 -1
- package/dist/components/builder/builder-store.d.ts +104 -15
- package/dist/components/builder/builder-store.js +157 -32
- package/dist/components/builder/builder-store.js.map +1 -1
- package/dist/components/builder/canvas-body.d.ts +30 -0
- package/dist/components/builder/canvas-body.js +38 -0
- package/dist/components/builder/canvas-body.js.map +1 -0
- package/dist/components/builder/canvas-breakpoints.js +1 -1
- package/dist/components/builder/canvas-breakpoints.js.map +1 -1
- package/dist/components/builder/canvas-chrome-css.js +7 -0
- package/dist/components/builder/canvas-chrome-css.js.map +1 -1
- package/dist/components/builder/canvas-dnd.d.ts +9 -9
- package/dist/components/builder/canvas-dnd.js +6 -6
- package/dist/components/builder/canvas-dnd.js.map +1 -1
- package/dist/components/builder/canvas-inline-editing.d.ts +1 -1
- package/dist/components/builder/canvas-inline-editing.js.map +1 -1
- package/dist/components/builder/canvas-overlay-geometry.d.ts +1 -1
- package/dist/components/builder/canvas-overlay-geometry.js.map +1 -1
- package/dist/components/builder/canvas-render-context.d.ts +28 -20
- package/dist/components/builder/canvas-render-context.js +46 -47
- package/dist/components/builder/canvas-render-context.js.map +1 -1
- package/dist/components/builder/canvas-runs.d.ts +45 -0
- package/dist/components/builder/canvas-runs.js +51 -0
- package/dist/components/builder/canvas-runs.js.map +1 -0
- package/dist/components/builder/canvas-theme-notice.js +2 -2
- package/dist/components/builder/canvas-theme-notice.js.map +1 -1
- package/dist/components/builder/canvas.js +35 -8
- package/dist/components/builder/canvas.js.map +1 -1
- package/dist/components/builder/clipboard-actions.d.ts +16 -1
- package/dist/components/builder/clipboard-actions.js +48 -11
- package/dist/components/builder/clipboard-actions.js.map +1 -1
- package/dist/components/builder/composition-field-editor-lazy.js +1 -1
- package/dist/components/builder/composition-field-editor-lazy.js.map +1 -1
- package/dist/components/builder/composition-field-editor.d.ts +4 -16
- package/dist/components/builder/composition-field-editor.js +32 -43
- package/dist/components/builder/composition-field-editor.js.map +1 -1
- package/dist/components/builder/delete-key.d.ts +5 -0
- package/dist/components/builder/delete-key.js +4 -0
- package/dist/components/builder/delete-key.js.map +1 -1
- package/dist/components/builder/drag-session.d.ts +1 -1
- package/dist/components/builder/drag-session.js.map +1 -1
- package/dist/components/builder/fixture-thumbnail.js +1 -1
- package/dist/components/builder/fixture-thumbnail.js.map +1 -1
- package/dist/components/builder/insert-context.d.ts +18 -26
- package/dist/components/builder/insert-context.js +47 -94
- package/dist/components/builder/insert-context.js.map +1 -1
- package/dist/components/builder/layout-inspector.js +1 -1
- package/dist/components/builder/layout-inspector.js.map +1 -1
- package/dist/components/builder/node-title.js +1 -1
- package/dist/components/builder/node-title.js.map +1 -1
- package/dist/components/builder/page-tree.d.ts +4 -4
- package/dist/components/builder/page-tree.js +8 -8
- package/dist/components/builder/page-tree.js.map +1 -1
- package/dist/components/builder/placement-refusal.d.ts +18 -0
- package/dist/components/builder/placement-refusal.js +46 -0
- package/dist/components/builder/placement-refusal.js.map +1 -0
- package/dist/components/builder/property-inspector.js +8 -4
- package/dist/components/builder/property-inspector.js.map +1 -1
- package/dist/components/builder/reuse-context.js +68 -30
- package/dist/components/builder/reuse-context.js.map +1 -1
- package/dist/components/builder/reuse.d.ts +79 -1
- package/dist/components/builder/reuse.js +70 -3
- package/dist/components/builder/reuse.js.map +1 -1
- package/dist/components/builder/rich-text-toolbar.js +1 -1
- package/dist/components/builder/rich-text-toolbar.js.map +1 -1
- package/dist/components/builder/run-inspector.d.ts +11 -0
- package/dist/components/builder/run-inspector.js +33 -0
- package/dist/components/builder/run-inspector.js.map +1 -0
- package/dist/components/builder/selection-overlay.js +3 -3
- package/dist/components/builder/selection-overlay.js.map +1 -1
- package/dist/components/builder/spacing-handles.d.ts +2 -2
- package/dist/components/builder/spacing-handles.js +3 -3
- package/dist/components/builder/spacing-handles.js.map +1 -1
- package/dist/components/cms/asset-field.d.ts +38 -1
- package/dist/components/cms/asset-field.js +184 -60
- package/dist/components/cms/asset-field.js.map +1 -1
- package/dist/components/cms/asset-picker-core.d.ts +16 -0
- package/dist/components/cms/asset-picker-core.js +20 -0
- package/dist/components/cms/asset-picker-core.js.map +1 -1
- package/dist/components/cms/asset-picker.js +14 -20
- package/dist/components/cms/asset-picker.js.map +1 -1
- package/dist/components/cms/bulk-actions.d.ts +4 -20
- package/dist/components/cms/bulk-actions.js +5 -26
- package/dist/components/cms/bulk-actions.js.map +1 -1
- package/dist/components/cms/bulk-bar.d.ts +2 -2
- package/dist/components/cms/bulk-bar.js +2 -2
- package/dist/components/cms/bulk-bar.js.map +1 -1
- package/dist/components/cms/cell-edit.d.ts +1 -1
- package/dist/components/cms/cell-edit.js +1 -1
- package/dist/components/cms/cell-edit.js.map +1 -1
- package/dist/components/cms/cell.d.ts +1 -1
- package/dist/components/cms/cell.js +3 -3
- package/dist/components/cms/cell.js.map +1 -1
- package/dist/components/cms/cms-index.js +2 -2
- package/dist/components/cms/cms-index.js.map +1 -1
- package/dist/components/cms/cms-labels.js +2 -2
- package/dist/components/cms/cms-labels.js.map +1 -1
- package/dist/components/cms/cms-store.d.ts +7 -6
- package/dist/components/cms/cms-store.js +23 -43
- package/dist/components/cms/cms-store.js.map +1 -1
- package/dist/components/cms/collection-table.js +7 -7
- package/dist/components/cms/collection-table.js.map +1 -1
- package/dist/components/cms/detail-editor.d.ts +5 -2
- package/dist/components/cms/detail-editor.js +20 -15
- package/dist/components/cms/detail-editor.js.map +1 -1
- package/dist/components/cms/details-pane.js +1 -1
- package/dist/components/cms/details-pane.js.map +1 -1
- package/dist/components/cms/doc-state.js +1 -1
- package/dist/components/cms/doc-state.js.map +1 -1
- package/dist/components/cms/document-diff-view.d.ts +3 -1
- package/dist/components/cms/document-diff-view.js +17 -12
- package/dist/components/cms/document-diff-view.js.map +1 -1
- package/dist/components/cms/document-editor-context.js +1 -1
- package/dist/components/cms/document-editor-context.js.map +1 -1
- package/dist/components/cms/document-staging.js +1 -1
- package/dist/components/cms/document-staging.js.map +1 -1
- package/dist/components/cms/document-url-path.js +2 -2
- package/dist/components/cms/document-url-path.js.map +1 -1
- package/dist/components/cms/duplicate-document.d.ts +1 -1
- package/dist/components/cms/duplicate-document.js.map +1 -1
- package/dist/components/cms/editable-cell.js +3 -3
- package/dist/components/cms/editable-cell.js.map +1 -1
- package/dist/components/cms/field-anchors.d.ts +7 -4
- package/dist/components/cms/field-anchors.js +9 -7
- package/dist/components/cms/field-anchors.js.map +1 -1
- package/dist/components/cms/field-collaboration.d.ts +1 -1
- package/dist/components/cms/field-collaboration.js +1 -1
- package/dist/components/cms/field-collaboration.js.map +1 -1
- package/dist/components/cms/field-connection.d.ts +1 -1
- package/dist/components/cms/field-connection.js +2 -2
- package/dist/components/cms/field-connection.js.map +1 -1
- package/dist/components/cms/field-control-lib.d.ts +15 -1
- package/dist/components/cms/field-control-lib.js +23 -4
- package/dist/components/cms/field-control-lib.js.map +1 -1
- package/dist/components/cms/field-control.js +4 -4
- package/dist/components/cms/field-control.js.map +1 -1
- package/dist/components/cms/field-renderer.d.ts +1 -1
- package/dist/components/cms/field-renderer.js +2 -2
- package/dist/components/cms/field-renderer.js.map +1 -1
- package/dist/components/cms/filter-builder.d.ts +1 -1
- package/dist/components/cms/filter-builder.js +3 -3
- package/dist/components/cms/filter-builder.js.map +1 -1
- package/dist/components/cms/gate-validation.d.ts +21 -30
- package/dist/components/cms/gate-validation.js +11 -32
- package/dist/components/cms/gate-validation.js.map +1 -1
- package/dist/components/cms/import-export.js +2 -2
- package/dist/components/cms/import-export.js.map +1 -1
- package/dist/components/cms/issue-copy.js +1 -1
- package/dist/components/cms/issue-copy.js.map +1 -1
- package/dist/components/cms/issues-pane.js +3 -3
- package/dist/components/cms/issues-pane.js.map +1 -1
- package/dist/components/cms/object-array-field.js +6 -6
- package/dist/components/cms/object-array-field.js.map +1 -1
- package/dist/components/cms/prop-fields.d.ts +7 -2
- package/dist/components/cms/prop-fields.js +14 -7
- package/dist/components/cms/prop-fields.js.map +1 -1
- package/dist/components/cms/reference-confirm.d.ts +1 -1
- package/dist/components/cms/reference-confirm.js +2 -2
- package/dist/components/cms/reference-confirm.js.map +1 -1
- package/dist/components/cms/relation-picker.js +2 -2
- package/dist/components/cms/relation-picker.js.map +1 -1
- package/dist/components/cms/rich-text/block-style.js +1 -1
- package/dist/components/cms/rich-text/block-style.js.map +1 -1
- package/dist/components/cms/rich-text/component-embed.js +4 -4
- package/dist/components/cms/rich-text/component-embed.js.map +1 -1
- package/dist/components/cms/rich-text/editor.js +3 -3
- package/dist/components/cms/rich-text/editor.js.map +1 -1
- package/dist/components/cms/rich-text/embed-picker.d.ts +1 -1
- package/dist/components/cms/rich-text/embed-picker.js +3 -3
- package/dist/components/cms/rich-text/embed-picker.js.map +1 -1
- package/dist/components/cms/rich-text/embed-props.js +3 -3
- package/dist/components/cms/rich-text/embed-props.js.map +1 -1
- package/dist/components/cms/rich-text/extensions.js +1 -1
- package/dist/components/cms/rich-text/extensions.js.map +1 -1
- package/dist/components/cms/rich-text/font-size-control.d.ts +1 -1
- package/dist/components/cms/rich-text/font-size-control.js +2 -2
- package/dist/components/cms/rich-text/font-size-control.js.map +1 -1
- package/dist/components/cms/rich-text/insert.d.ts +20 -9
- package/dist/components/cms/rich-text/insert.js +25 -17
- package/dist/components/cms/rich-text/insert.js.map +1 -1
- package/dist/components/cms/rich-text/lazy.js +1 -1
- package/dist/components/cms/rich-text/lazy.js.map +1 -1
- package/dist/components/cms/rich-text/link-control.js +2 -2
- package/dist/components/cms/rich-text/link-control.js.map +1 -1
- package/dist/components/cms/rich-text/slash-command.js +3 -3
- package/dist/components/cms/rich-text/slash-command.js.map +1 -1
- package/dist/components/cms/rich-text/toolbar.js +1 -1
- package/dist/components/cms/rich-text/toolbar.js.map +1 -1
- package/dist/components/cms/rich-text/unknown-node.js +2 -2
- package/dist/components/cms/rich-text/unknown-node.js.map +1 -1
- package/dist/components/cms/rich-text-preview.js +2 -2
- package/dist/components/cms/rich-text-preview.js.map +1 -1
- package/dist/components/cms/row-actions.d.ts +1 -1
- package/dist/components/cms/row-actions.js.map +1 -1
- package/dist/components/cms/scalar-value-editor.d.ts +1 -1
- package/dist/components/cms/scalar-value-editor.js +2 -2
- package/dist/components/cms/scalar-value-editor.js.map +1 -1
- package/dist/components/cms/use-discard-controller.d.ts +1 -1
- package/dist/components/cms/use-discard-controller.js +1 -1
- package/dist/components/cms/use-discard-controller.js.map +1 -1
- package/dist/components/cms/use-document-draft.d.ts +7 -1
- package/dist/components/cms/use-document-draft.js +16 -2
- package/dist/components/cms/use-document-draft.js.map +1 -1
- package/dist/components/cms/use-document-versions.js +1 -1
- package/dist/components/cms/use-document-versions.js.map +1 -1
- package/dist/components/cms/use-field-focus.d.ts +1 -1
- package/dist/components/cms/use-field-focus.js +2 -2
- package/dist/components/cms/use-field-focus.js.map +1 -1
- package/dist/components/cms/use-live-url.d.ts +1 -1
- package/dist/components/cms/use-live-url.js +3 -3
- package/dist/components/cms/use-live-url.js.map +1 -1
- package/dist/components/cms/use-publish-controller.d.ts +2 -3
- package/dist/components/cms/use-publish-controller.js +8 -20
- package/dist/components/cms/use-publish-controller.js.map +1 -1
- package/dist/components/cms/use-published-perspective.d.ts +1 -1
- package/dist/components/cms/use-published-perspective.js.map +1 -1
- package/dist/components/cms/use-restore-version.d.ts +1 -1
- package/dist/components/cms/use-restore-version.js +1 -1
- package/dist/components/cms/use-restore-version.js.map +1 -1
- package/dist/components/cms/version-compare-lazy.js +1 -1
- package/dist/components/cms/version-compare-lazy.js.map +1 -1
- package/dist/components/cms/version-compare.js +1 -1
- package/dist/components/cms/version-compare.js.map +1 -1
- package/dist/components/cms/versions-pane.js +11 -4
- package/dist/components/cms/versions-pane.js.map +1 -1
- package/dist/components/cms/view-bar.js +3 -3
- package/dist/components/cms/view-bar.js.map +1 -1
- package/dist/components/collection-view/cms-collection-view-source.d.ts +1 -1
- package/dist/components/collection-view/cms-collection-view-source.js +5 -3
- package/dist/components/collection-view/cms-collection-view-source.js.map +1 -1
- package/dist/components/collection-view/collection-view-context.d.ts +1 -1
- package/dist/components/collection-view/collection-view-context.js +1 -1
- package/dist/components/collection-view/collection-view-context.js.map +1 -1
- package/dist/components/collection-view/collection-view-surface.d.ts +13 -0
- package/dist/components/collection-view/collection-view-surface.js +18 -0
- package/dist/components/collection-view/collection-view-surface.js.map +1 -0
- package/dist/components/components/component-detail.js +10 -10
- package/dist/components/components/component-detail.js.map +1 -1
- package/dist/components/components/component-preview.d.ts +2 -2
- package/dist/components/components/component-preview.js +5 -5
- package/dist/components/components/component-preview.js.map +1 -1
- package/dist/components/components/component-status.d.ts +1 -1
- package/dist/components/components/component-status.js +1 -1
- package/dist/components/components/component-status.js.map +1 -1
- package/dist/components/components/components-index.js +2 -2
- package/dist/components/components/components-index.js.map +1 -1
- package/dist/components/components/field-inspector.js +1 -1
- package/dist/components/components/field-inspector.js.map +1 -1
- package/dist/components/components/registry-browser.js +3 -3
- package/dist/components/components/registry-browser.js.map +1 -1
- package/dist/components/components/taxonomy.d.ts +1 -1
- package/dist/components/components/taxonomy.js.map +1 -1
- package/dist/components/components/transfer-dialog.js +4 -3
- package/dist/components/components/transfer-dialog.js.map +1 -1
- package/dist/components/components/transfer.d.ts +10 -10
- package/dist/components/components/transfer.js +13 -12
- package/dist/components/components/transfer.js.map +1 -1
- package/dist/components/current-user-menu.js +1 -1
- package/dist/components/current-user-menu.js.map +1 -1
- package/dist/components/delivery-health-banner.js +2 -2
- package/dist/components/delivery-health-banner.js.map +1 -1
- package/dist/components/deployment-setup-gate.js +3 -3
- package/dist/components/deployment-setup-gate.js.map +1 -1
- package/dist/components/dev-login-badge.js +2 -2
- package/dist/components/dev-login-badge.js.map +1 -1
- package/dist/components/guards.js +1 -1
- package/dist/components/guards.js.map +1 -1
- package/dist/components/inspector/document-panes.d.ts +54 -0
- package/dist/components/inspector/document-panes.js +41 -0
- package/dist/components/inspector/document-panes.js.map +1 -0
- package/dist/components/inspector/inspector-sidebar.js +1 -1
- package/dist/components/inspector/inspector-sidebar.js.map +1 -1
- package/dist/components/nav-issues-registry.d.ts +53 -0
- package/dist/components/nav-issues-registry.js +69 -0
- package/dist/components/nav-issues-registry.js.map +1 -0
- package/dist/components/nav-issues.js +4 -4
- package/dist/components/nav-issues.js.map +1 -1
- package/dist/components/operation-error.d.ts +1 -1
- package/dist/components/operation-error.js +4 -4
- package/dist/components/operation-error.js.map +1 -1
- package/dist/components/playground-badge.js +2 -2
- package/dist/components/playground-badge.js.map +1 -1
- package/dist/components/project-list.js +3 -3
- package/dist/components/project-list.js.map +1 -1
- package/dist/components/project-session.d.ts +2 -2
- package/dist/components/project-session.js +5 -5
- package/dist/components/project-session.js.map +1 -1
- package/dist/components/project-switcher.js +2 -2
- package/dist/components/project-switcher.js.map +1 -1
- package/dist/components/rail-store-status.js +1 -1
- package/dist/components/rail-store-status.js.map +1 -1
- package/dist/components/rail-view-source.d.ts +6 -5
- package/dist/components/rail-view-source.js +4 -3
- package/dist/components/rail-view-source.js.map +1 -1
- package/dist/components/records/record-lens.d.ts +51 -0
- package/dist/components/records/record-lens.js +156 -0
- package/dist/components/records/record-lens.js.map +1 -0
- package/dist/components/records/record-rail.d.ts +86 -0
- package/dist/components/records/record-rail.js +241 -0
- package/dist/components/records/record-rail.js.map +1 -0
- package/dist/components/redirects/redirects-schema.js +1 -1
- package/dist/components/redirects/redirects-schema.js.map +1 -1
- package/dist/components/references/references-panel.js +2 -2
- package/dist/components/references/references-panel.js.map +1 -1
- package/dist/components/section-nav.js +27 -11
- package/dist/components/section-nav.js.map +1 -1
- package/dist/components/section-state.js +2 -2
- package/dist/components/section-state.js.map +1 -1
- package/dist/components/section-surface.js +2 -2
- package/dist/components/section-surface.js.map +1 -1
- package/dist/components/session-expired-overlay.js +3 -3
- package/dist/components/session-expired-overlay.js.map +1 -1
- package/dist/components/settings-form.js +1 -1
- package/dist/components/settings-form.js.map +1 -1
- package/dist/components/sign-in-needed-badge.js +1 -1
- package/dist/components/sign-in-needed-badge.js.map +1 -1
- package/dist/components/sign-in-view.d.ts +2 -2
- package/dist/components/sign-in-view.js +5 -5
- package/dist/components/sign-in-view.js.map +1 -1
- package/dist/components/studio-context.js +3 -3
- package/dist/components/studio-context.js.map +1 -1
- package/dist/components/studio-project-screen.js +30 -3
- package/dist/components/studio-project-screen.js.map +1 -1
- package/dist/components/studio-shell.js +6 -5
- package/dist/components/studio-shell.js.map +1 -1
- package/dist/components/theme-context.d.ts +1 -1
- package/dist/components/theme-context.js +2 -2
- package/dist/components/theme-context.js.map +1 -1
- package/dist/components/use-hydration-phase.d.ts +1 -1
- package/dist/components/use-hydration-phase.js +1 -1
- package/dist/components/use-hydration-phase.js.map +1 -1
- package/dist/components/users/invite-user-bar.d.ts +27 -0
- package/dist/components/users/invite-user-bar.js +25 -9
- package/dist/components/users/invite-user-bar.js.map +1 -1
- package/dist/components/users/role-policy-drift-issues.d.ts +38 -0
- package/dist/components/users/role-policy-drift-issues.js +71 -0
- package/dist/components/users/role-policy-drift-issues.js.map +1 -0
- package/dist/components/users/users-collection-view-source.d.ts +1 -1
- package/dist/components/users/users-collection-view-source.js +4 -2
- package/dist/components/users/users-collection-view-source.js.map +1 -1
- package/dist/components/users/users-module.js +1 -1
- package/dist/components/users/users-module.js.map +1 -1
- package/dist/components/users/users-schema.d.ts +10 -1
- package/dist/components/users/users-schema.js +45 -25
- package/dist/components/users/users-schema.js.map +1 -1
- package/dist/components/users/users-store.js +3 -3
- package/dist/components/users/users-store.js.map +1 -1
- package/dist/components/workspace-projects.d.ts +1 -1
- package/dist/components/workspace-projects.js +1 -1
- package/dist/components/workspace-projects.js.map +1 -1
- package/dist/lib/ai/apply-content.js +56 -116
- package/dist/lib/ai/apply-content.js.map +1 -1
- package/dist/lib/ai/chat-context.d.ts +8 -0
- package/dist/lib/ai/chat-context.js +37 -6
- package/dist/lib/ai/chat-context.js.map +1 -1
- package/dist/lib/ai/chat-state.d.ts +6 -0
- package/dist/lib/ai/chat-state.js.map +1 -1
- package/dist/lib/ai/constraints.d.ts +20 -5
- package/dist/lib/ai/constraints.js +125 -33
- package/dist/lib/ai/constraints.js.map +1 -1
- package/dist/lib/ai/fake-provider.d.ts +16 -3
- package/dist/lib/ai/fake-provider.js +22 -6
- package/dist/lib/ai/fake-provider.js.map +1 -1
- package/dist/lib/ai/index.d.ts +3 -1
- package/dist/lib/ai/index.js +3 -1
- package/dist/lib/ai/index.js.map +1 -1
- package/dist/lib/ai/leash.d.ts +34 -0
- package/dist/lib/ai/leash.js +28 -0
- package/dist/lib/ai/leash.js.map +1 -0
- package/dist/lib/ai/node-handler.d.ts +1 -1
- package/dist/lib/ai/node-handler.js.map +1 -1
- package/dist/lib/ai/rich-text-input.d.ts +8 -8
- package/dist/lib/ai/rich-text-input.js +2 -1
- package/dist/lib/ai/rich-text-input.js.map +1 -1
- package/dist/lib/ai/rich-text-translate.d.ts +27 -4
- package/dist/lib/ai/rich-text-translate.js +28 -10
- package/dist/lib/ai/rich-text-translate.js.map +1 -1
- package/dist/lib/ai/shape.d.ts +13 -13
- package/dist/lib/ai/shape.js +69 -93
- package/dist/lib/ai/shape.js.map +1 -1
- package/dist/lib/ai/tools.d.ts +36 -41
- package/dist/lib/ai/tools.js +83 -87
- package/dist/lib/ai/tools.js.map +1 -1
- package/dist/lib/ai/translate-document.d.ts +32 -4
- package/dist/lib/ai/translate-document.js +145 -47
- package/dist/lib/ai/translate-document.js.map +1 -1
- package/dist/lib/ai/types.d.ts +34 -23
- package/dist/lib/ai/types.js.map +1 -1
- package/dist/lib/ai/update-fields.d.ts +15 -12
- package/dist/lib/ai/update-fields.js +112 -188
- package/dist/lib/ai/update-fields.js.map +1 -1
- package/dist/lib/ai/writer-form.d.ts +116 -0
- package/dist/lib/ai/writer-form.js +429 -0
- package/dist/lib/ai/writer-form.js.map +1 -0
- package/dist/lib/assets/upload.d.ts +31 -2
- package/dist/lib/assets/upload.js +61 -6
- package/dist/lib/assets/upload.js.map +1 -1
- package/dist/lib/clipboard/os-clipboard.d.ts +10 -2
- package/dist/lib/clipboard/os-clipboard.js +8 -4
- package/dist/lib/clipboard/os-clipboard.js.map +1 -1
- package/dist/lib/clipboard/paste-issues.js +1 -1
- package/dist/lib/clipboard/paste-issues.js.map +1 -1
- package/dist/lib/clipboard/paste-target.d.ts +18 -9
- package/dist/lib/clipboard/paste-target.js +10 -9
- package/dist/lib/clipboard/paste-target.js.map +1 -1
- package/dist/lib/cms/field-patch.d.ts +0 -10
- package/dist/lib/cms/field-patch.js +4 -30
- package/dist/lib/cms/field-patch.js.map +1 -1
- package/dist/lib/cms/published-documents.js +1 -1
- package/dist/lib/cms/published-documents.js.map +1 -1
- package/dist/lib/cms-views/view-model.d.ts +9 -9
- package/dist/lib/cms-views/view-model.js +2 -2
- package/dist/lib/cms-views/view-model.js.map +1 -1
- package/dist/lib/collection-view/collection-view-source.d.ts +14 -5
- package/dist/lib/collection-view/collection-view-source.js.map +1 -1
- package/dist/lib/data/collection-content.js +3 -2
- package/dist/lib/data/collection-content.js.map +1 -1
- package/dist/lib/data/content-session-refresh.d.ts +1 -1
- package/dist/lib/data/content-session-refresh.js.map +1 -1
- package/dist/lib/data/playground-unload-guard.d.ts +1 -1
- package/dist/lib/data/playground-unload-guard.js +1 -1
- package/dist/lib/data/playground-unload-guard.js.map +1 -1
- package/dist/lib/dnd/drop-rules.d.ts +25 -31
- package/dist/lib/dnd/drop-rules.js +53 -59
- package/dist/lib/dnd/drop-rules.js.map +1 -1
- package/dist/lib/engine-version.d.ts +1 -1
- package/dist/lib/engine-version.js +1 -1
- package/dist/lib/engine-version.js.map +1 -1
- package/dist/lib/i18n/i18n.js +1 -1
- package/dist/lib/i18n/i18n.js.map +1 -1
- package/dist/lib/i18n/messages.de.js +44 -3
- package/dist/lib/i18n/messages.de.js.map +1 -1
- package/dist/lib/i18n/messages.en.d.ts +38 -2
- package/dist/lib/i18n/messages.en.js +51 -3
- package/dist/lib/i18n/messages.en.js.map +1 -1
- package/dist/lib/operations/project-runtime-config.d.ts +34 -6
- package/dist/lib/operations/project-runtime-config.js +50 -10
- package/dist/lib/operations/project-runtime-config.js.map +1 -1
- package/dist/lib/operations/publish-with-revision.d.ts +33 -1
- package/dist/lib/operations/publish-with-revision.js +32 -0
- package/dist/lib/operations/publish-with-revision.js.map +1 -1
- package/dist/lib/operations/runtime-validator.d.ts +19 -68
- package/dist/lib/operations/runtime-validator.js +12 -138
- package/dist/lib/operations/runtime-validator.js.map +1 -1
- package/dist/lib/operations/studio-operations.d.ts +17 -2
- package/dist/lib/operations/studio-operations.js +18 -11
- package/dist/lib/operations/studio-operations.js.map +1 -1
- package/dist/lib/persistence/convex-adapter.d.ts +16 -3
- package/dist/lib/persistence/convex-adapter.js +83 -47
- package/dist/lib/persistence/convex-adapter.js.map +1 -1
- package/dist/lib/persistence/index.js +14 -1
- package/dist/lib/persistence/index.js.map +1 -1
- package/dist/lib/persona/labels.js +4 -2
- package/dist/lib/persona/labels.js.map +1 -1
- package/dist/lib/query/operations-query.d.ts +1 -1
- package/dist/lib/query/operations-query.js +1 -1
- package/dist/lib/query/operations-query.js.map +1 -1
- package/dist/lib/references/reference-model.js +1 -1
- package/dist/lib/references/reference-model.js.map +1 -1
- package/dist/lib/references/references-store.js +1 -1
- package/dist/lib/references/references-store.js.map +1 -1
- package/dist/lib/workspace/index.d.ts +14 -11
- package/dist/lib/workspace/index.js +20 -24
- package/dist/lib/workspace/index.js.map +1 -1
- package/dist/mount.d.ts +28 -0
- package/dist/mount.js +27 -0
- package/dist/mount.js.map +1 -0
- package/dist/router/root.js +10 -10
- package/dist/router/root.js.map +1 -1
- package/dist/ui/badge.d.ts +1 -1
- package/dist/ui/button.d.ts +2 -2
- package/package.json +15 -11
- package/dist/components/cms/cms-composition-validators.d.ts +0 -16
- package/dist/components/cms/cms-composition-validators.js +0 -133
- package/dist/components/cms/cms-composition-validators.js.map +0 -1
- package/dist/components/cms/publish-clean.d.ts +0 -28
- package/dist/components/cms/publish-clean.js +0 -38
- package/dist/components/cms/publish-clean.js.map +0 -1
- package/dist/components/redirects/redirects-collection-view-source.d.ts +0 -53
- package/dist/components/redirects/redirects-collection-view-source.js +0 -146
- package/dist/components/redirects/redirects-collection-view-source.js.map +0 -1
- package/dist/components/redirects/redirects-module.d.ts +0 -21
- package/dist/components/redirects/redirects-module.js +0 -40
- package/dist/components/redirects/redirects-module.js.map +0 -1
- package/dist/components/redirects/redirects-store.d.ts +0 -68
- package/dist/components/redirects/redirects-store.js +0 -132
- package/dist/components/redirects/redirects-store.js.map +0 -1
- package/dist/lib/assets/asset-placements.d.ts +0 -28
- package/dist/lib/assets/asset-placements.js +0 -83
- package/dist/lib/assets/asset-placements.js.map +0 -1
|
@@ -1,42 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { cleanHiddenForPublish } from './publish-clean.js';
|
|
1
|
+
import { getStudioRegistry } from '../../lib/registry/index.js';
|
|
2
|
+
import { canonicalValidateOptions } from '@elytracms/core/validation';
|
|
4
3
|
export function gateValidateOptions(input) {
|
|
5
|
-
return {
|
|
4
|
+
return canonicalValidateOptions({ locales: input.localeConfig }, getStudioRegistry().registry, {
|
|
6
5
|
store: input.store,
|
|
7
|
-
localeConfig: input.localeConfig,
|
|
8
|
-
// EC-188/EC-189: the composition + rich-text-embed leashes, injected so
|
|
9
|
-
// `cms-core` stays free of `project-graph` and `rich-text`. These are what the
|
|
10
|
-
// operations layer could never supply on its own — it has no registry — and
|
|
11
|
-
// the reason the canonical validator is injected downward rather than rebuilt
|
|
12
|
-
// there. Since EC-547 both injected validators unwrap the converged v2 block
|
|
13
|
-
// sequence (`{ version: 2, content }`) and validate its component nodes —
|
|
14
|
-
// top-level and nested in typography — with the same field `allow` leash.
|
|
15
|
-
validateComposition,
|
|
16
|
-
validateRichTextEmbeds,
|
|
17
6
|
isPublished: input.isPublished,
|
|
18
7
|
...(input.findAsset ? { findAsset: input.findAsset } : {}),
|
|
19
|
-
|
|
20
|
-
// — component props through the session's manifests — and judges what publishing
|
|
21
|
-
// would snapshot (the SAME hidden strip `doPublish` / bulk publish apply), so a
|
|
22
|
-
// strict reuse embed of an unpublished target is a blocking error through this one
|
|
23
|
-
// general path (the detail editor's special case is gone) and a hidden relation
|
|
24
|
-
// neither warns nor blocks.
|
|
25
|
-
lookupManifest: studioManifestLookup(),
|
|
26
|
-
publishedForm: (collection, document) => cleanHiddenForPublish(collection, document, undefined, input.localeConfig),
|
|
27
|
-
};
|
|
8
|
+
});
|
|
28
9
|
}
|
|
29
10
|
/**
|
|
30
|
-
* EC-588 A2 — THE asset-library oracle for the option bag, derived from the
|
|
31
|
-
* store: a record lookup over the loaded library.
|
|
11
|
+
* EC-588 A2 — THE asset-library oracle for the session's option bag, derived from the
|
|
12
|
+
* assets store: a record lookup over the loaded library.
|
|
32
13
|
*
|
|
33
|
-
* Absent — so the validator checks neither existence nor `accept` — when no
|
|
34
|
-
* mounted (a fixture-only session) AND while it is loading or errored
|
|
35
|
-
* is no truthful answer to "which record is this?".
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* while the library is unready is the "validation bound to the operation" question,
|
|
39
|
-
* left to EC-595.
|
|
14
|
+
* Absent — so the display validator checks neither existence nor `accept` — when no
|
|
15
|
+
* library is mounted (a fixture-only session) AND while it is loading or errored: there
|
|
16
|
+
* is no truthful answer to "which record is this?" yet. The PUBLISH gate does not read
|
|
17
|
+
* this: it prefetches through the operation's adapter and refuses visibly when the
|
|
18
|
+
* library cannot be read (EC-595 A2, ruled 1f).
|
|
40
19
|
*/
|
|
41
20
|
export function assetLibraryOracle(library) {
|
|
42
21
|
if (!library || library.status !== 'ready')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate-validation.js","sourceRoot":"","sources":["../../../src/components/cms/gate-validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"gate-validation.js","sourceRoot":"","sources":["../../../src/components/cms/gate-validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AA4CrE,MAAM,UAAU,mBAAmB,CAAC,KAA0B;IAC5D,OAAO,wBAAwB,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,YAAY,EAAE,EAAE,iBAAiB,EAAE,CAAC,QAAQ,EAAE;QAC7F,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3D,CAAC,CAAA;AACJ,CAAC;AAQD;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAiC;IAClE,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO;QAAE,OAAO,SAAS,CAAA;IAC5D,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;IACtE,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;AAC7B,CAAC","sourcesContent":["import { getStudioRegistry } from '../../lib/registry'\nimport { canonicalValidateOptions } from '@elytracms/core/validation'\nimport type {\n DocumentRef,\n DocumentStore,\n LocaleConfig,\n ValidateDocumentOptions,\n} from '@elytracms/core/cms-core'\nimport type { AssetRecord } from '@elytracms/core/persistence'\n\n/** The asset-library oracle the bag carries (EC-588): the record for an id, or `undefined`. */\nexport type FindAsset = NonNullable<ValidateDocumentOptions['findAsset']>\n\n/**\n * THE option bag of the studio SESSION (EC-497, AD-497a) — since EC-582 a caller of the\n * one canonical validator in core (`canonicalValidateOptions`,\n * `@elytracms/core/validation`), which the runtime publish gate, a headless embedder and\n * the CLI build from too. The session passes ITS project's registry — the active one,\n * because the session IS the active project (the runtime gate resolves the OPERATION's\n * project instead, `lib/operations/runtime-validator.ts`).\n *\n * The contract, in one line: **surfaces differ in what they DO with the issues, never in\n * what they validated with.** Publish filters by severity, cell edit filters by field +\n * locale, the AI paths take `introducedErrors` (after − before) — all start from the\n * identical list.\n *\n * **Out of contract by declaration:** the assets and redirects rails. They validate\n * synthetic, non-`cmsDocuments` collections against their own registries with no session\n * store, and their writes go through `operations.assets.*` / `operations.redirects.*` — a\n * different entity, not a weaker check of this one.\n */\nexport interface GateValidationInput {\n /** The session document store, with the document under judgement swapped in. */\n store: DocumentStore\n localeConfig: LocaleConfig\n /** Published-ness from the version POINTER (EC-224) — never a flat state flag. */\n isPublished: (ref: DocumentRef) => boolean\n /**\n * The real asset library oracle (EC-588: returns the record, so the validator checks\n * existence AND the field's `accept`); absent where no library is mounted or ready —\n * see {@link assetLibraryOracle}.\n */\n findAsset?: FindAsset\n}\n\nexport function gateValidateOptions(input: GateValidationInput): ValidateDocumentOptions {\n return canonicalValidateOptions({ locales: input.localeConfig }, getStudioRegistry().registry, {\n store: input.store,\n isPublished: input.isPublished,\n ...(input.findAsset ? { findAsset: input.findAsset } : {}),\n })\n}\n\n/** The slice of the assets store the oracle is derived from (`AssetsStore` satisfies it). */\nexport interface AssetLibraryState {\n status: 'loading' | 'ready' | 'error'\n assets: readonly AssetRecord[]\n}\n\n/**\n * EC-588 A2 — THE asset-library oracle for the session's option bag, derived from the\n * assets store: a record lookup over the loaded library.\n *\n * Absent — so the display validator checks neither existence nor `accept` — when no\n * library is mounted (a fixture-only session) AND while it is loading or errored: there\n * is no truthful answer to \"which record is this?\" yet. The PUBLISH gate does not read\n * this: it prefetches through the operation's adapter and refuses visibly when the\n * library cannot be read (EC-595 A2, ruled 1f).\n */\nexport function assetLibraryOracle(library: AssetLibraryState | null): FindAsset | undefined {\n if (!library || library.status !== 'ready') return undefined\n const byId = new Map(library.assets.map((asset) => [asset.id, asset]))\n return (id) => byId.get(id)\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from 'react';
|
|
3
3
|
import { Badge, Button, Code, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Stack, Text, } from '@elytracms/studio/ui';
|
|
4
|
-
import { translate } from '
|
|
5
|
-
import { cmsValidationIssueMessage } from '
|
|
4
|
+
import { translate } from '../../lib/i18n/index.js';
|
|
5
|
+
import { cmsValidationIssueMessage } from '../../lib/persona/labels.js';
|
|
6
6
|
import { useCollectionView } from '../collection-view/collection-view-context.js';
|
|
7
7
|
/** Import collection data from JSON with validation + error reporting (brief §8.4, EC-079). */
|
|
8
8
|
export function ImportDialog({ collectionId, open, onOpenChange, }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-export.js","sourceRoot":"","sources":["../../../src/components/cms/import-export.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EACL,KAAK,EACL,MAAM,EACN,IAAI,EACJ,MAAM,EACN,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,KAAK,EACL,IAAI,GACL,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"import-export.js","sourceRoot":"","sources":["../../../src/components/cms/import-export.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EACL,KAAK,EACL,MAAM,EACN,IAAI,EACJ,MAAM,EACN,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,KAAK,EACL,IAAI,GACL,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAA;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAA;AAG9E,+FAA+F;AAC/F,MAAM,UAAU,YAAY,CAAC,EAC3B,YAAY,EACZ,IAAI,EACJ,YAAY,GAKb;IACC,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAA;IAClC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IACpC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAsB,IAAI,CAAC,CAAA;IAC/D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAA;IAEjE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,CAAC,EAAE,CAAC,CAAA;YACX,SAAS,CAAC,IAAI,CAAC,CAAA;YACf,aAAa,CAAC,IAAI,CAAC,CAAA;QACrB,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEV,SAAS,SAAS;QAChB,aAAa,CAAC,IAAI,CAAC,CAAA;QACnB,IAAI,MAAe,CAAA;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,aAAa,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC,CAAA;YAClD,OAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;QACvD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,CAAA;QACtD,IAAI,OAAO;YAAE,SAAS,CAAC,OAAO,CAAC,CAAA;IACjC,CAAC;IAED,OAAO,CACL,KAAC,MAAM,IAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,YAC5C,MAAC,aAAa,IAAC,SAAS,EAAC,UAAU,aACjC,MAAC,YAAY,eACX,KAAC,WAAW,cAAE,SAAS,CAAC,kBAAkB,CAAC,GAAe,EAC1D,MAAC,iBAAiB,uDACoB,KAAC,IAAI,IAAC,IAAI,EAAC,OAAO,YAAE,YAAY,GAAQ,wEAE1D,IACP,EAEf,mBACE,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EACxC,IAAI,EAAE,CAAC,EACP,WAAW,EAAC,sDAAsD,EAClE,SAAS,EAAC,8LAA8L,GACxM,EAED,UAAU,CAAC,CAAC,CAAC,CACZ,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,SAAS,EAAC,kBAAkB,YACzC,UAAU,GACN,CACR,CAAC,CAAC,CAAC,IAAI,EAEP,MAAM,CAAC,CAAC,CAAC,CACR,MAAC,KAAK,IAAC,GAAG,EAAC,GAAG,EAAC,SAAS,EAAC,qCAAqC,aAC5D,KAAC,KAAK,IAAC,OAAO,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,YACrD,SAAS,CAAC,qBAAqB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,GACpD,EACP,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC5B,MAAC,KAAK,IAAC,GAAG,EAAC,GAAG,aACZ,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,YACzB,SAAS,CAAC,qBAAqB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,GAC/D,EACN,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAC7B,MAAC,IAAI,IAAsB,IAAI,EAAC,IAAI,EAAC,SAAS,EAAC,kBAAkB,aAC/D,KAAC,IAAI,IAAC,IAAI,EAAC,OAAO,YAAE,CAAC,CAAC,EAAE,GAAQ,aAAG,GAAG,EACrC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,KAFxD,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAGlB,CACR,CAAC,IACI,CACT,CAAC,CAAC,CAAC,IAAI,IACF,CACT,CAAC,CAAC,CAAC,IAAI,EAER,MAAC,YAAY,eACX,KAAC,MAAM,IAAC,OAAO,EAAC,OAAO,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,YACvD,SAAS,CAAC,cAAc,CAAC,GACnB,EACT,KAAC,MAAM,IAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,YAC/C,SAAS,CAAC,oBAAoB,CAAC,GACzB,IACI,IACD,GACT,CACV,CAAA;AACH,CAAC","sourcesContent":["import { useEffect, useState } from 'react'\nimport {\n Badge,\n Button,\n Code,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Stack,\n Text,\n} from '@elytracms/studio/ui'\nimport { translate } from '../../lib/i18n'\nimport { cmsValidationIssueMessage } from '../../lib/persona/labels'\nimport { useCollectionView } from '../collection-view/collection-view-context'\nimport type { ImportReport } from './cms-store'\n\n/** Import collection data from JSON with validation + error reporting (brief §8.4, EC-079). */\nexport function ImportDialog({\n collectionId,\n open,\n onOpenChange,\n}: {\n collectionId: string\n open: boolean\n onOpenChange: (open: boolean) => void\n}) {\n const source = useCollectionView()\n const [text, setText] = useState('')\n const [report, setReport] = useState<ImportReport | null>(null)\n const [parseError, setParseError] = useState<string | null>(null)\n\n useEffect(() => {\n if (open) {\n setText('')\n setReport(null)\n setParseError(null)\n }\n }, [open])\n\n function runImport() {\n setParseError(null)\n let parsed: unknown\n try {\n parsed = JSON.parse(text)\n } catch {\n setParseError(translate('cms.import.invalidJson'))\n return\n }\n const items = Array.isArray(parsed) ? parsed : [parsed]\n const outcome = source.imports?.importDocuments(items)\n if (outcome) setReport(outcome)\n }\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-lg\">\n <DialogHeader>\n <DialogTitle>{translate('cms.import.title')}</DialogTitle>\n <DialogDescription>\n Paste a JSON array of documents for <Code tone=\"muted\">{collectionId}</Code>. Each is\n validated against the collection schema before import.\n </DialogDescription>\n </DialogHeader>\n\n <textarea\n value={text}\n onChange={(e) => setText(e.target.value)}\n rows={8}\n placeholder='[{ \"id\": \"post-x\", \"values\": { \"slug\": \"x\" }, ... }]'\n className=\"w-full rounded-md border border-input bg-background p-2.5 font-mono text-xs text-foreground shadow-sm focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/40 outline-none\"\n />\n\n {parseError ? (\n <Text size=\"sm\" className=\"text-destructive\">\n {parseError}\n </Text>\n ) : null}\n\n {report ? (\n <Stack gap=\"2\" className=\"rounded-md border border-border p-3\">\n <Badge variant={report.added > 0 ? 'success' : 'outline'}>\n {translate('cms.import.imported', { count: report.added })}\n </Badge>\n {report.rejected.length > 0 ? (\n <Stack gap=\"1\">\n <Text size=\"xs\" tone=\"muted\">\n {translate('cms.import.rejected', { count: report.rejected.length })}\n </Text>\n {report.rejected.map((r, i) => (\n <Text key={`${r.id}-${i}`} size=\"xs\" className=\"text-destructive\">\n <Code tone=\"muted\">{r.id}</Code> —{' '}\n {r.issues[0] ? cmsValidationIssueMessage(r.issues[0]) : undefined}\n </Text>\n ))}\n </Stack>\n ) : null}\n </Stack>\n ) : null}\n\n <DialogFooter>\n <Button variant=\"ghost\" onClick={() => onOpenChange(false)}>\n {translate('common.close')}\n </Button>\n <Button onClick={runImport} disabled={!text.trim()}>\n {translate('cms.import.confirm')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseDocumentFieldPath } from '
|
|
1
|
+
import { parseDocumentFieldPath } from '../../lib/references/index.js';
|
|
2
2
|
import { resolveFieldDefAtPath } from './field-anchors.js';
|
|
3
3
|
/** The last non-index token of a path (`links/3/badge/text` → `text`). */
|
|
4
4
|
function lastNameToken(tokens) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issue-copy.js","sourceRoot":"","sources":["../../../src/components/cms/issue-copy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"issue-copy.js","sourceRoot":"","sources":["../../../src/components/cms/issue-copy.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CmsValidationIssue, CollectionDef, FieldDef } from '@elytracms/core/cms-core'\nimport { parseDocumentFieldPath } from '../../lib/references'\nimport { resolveFieldDefAtPath } from './field-anchors'\n\n/**\n * EC-443 — the pure copy/jump decisions behind the Issues pane. No React, no\n * catalog access: {@link issueJumpTarget} turns a structured issue into the\n * anchor path + deepest resolvable field def the jump link needs, and\n * {@link issueBodyDescriptor} maps an issue code to a localized body template\n * (catalog key + params) where the full body is derivable from `code` +\n * `path`/`meta` alone. Codes whose core message carries underivable detail\n * (e.g. `invalid-field-value`'s per-check phrasing, `custom-validation`'s\n * config-authored text) return `null` — the pane then shows the raw English\n * core message, an HONEST fallback, never a blank.\n */\n\n/** Where an issue's jump link lands + what it is called. */\nexport interface IssueJumpTarget {\n /** The `FIELD_PATH_ATTR` anchor path (`links/3/badge/text`), locale stripped. */\n path: string\n /** The content locale the issue belongs to (`localized/<locale>/…` paths). */\n locale?: string\n /** The deepest field def resolvable along the path (label source), if any. */\n fieldDef: FieldDef | null\n /** The last named path token — the label fallback when no def resolves. */\n leaf: string\n}\n\n/** The last non-index token of a path (`links/3/badge/text` → `text`). */\nfunction lastNameToken(tokens: readonly string[]): string {\n for (let i = tokens.length - 1; i >= 0; i--) {\n const token = tokens[i]!\n if (!/^\\d+$/.test(token)) return token\n }\n return tokens[tokens.length - 1] ?? ''\n}\n\n/**\n * Derive the jump target from an issue's structured `path` (the full document\n * index path — `['documents', <key>, 'values'|'localized', …]` from\n * `validateDocument`, or a bare `[<field>]` from studio-built issues like the\n * EC-300 embed errors). The FULL path wins (so a nested issue lands on the\n * exact control — `meta.field` carries only the LEAF name and must never be\n * mistaken for a top-level field); `meta.field` is the fallback for bare\n * paths, and only when it names a real top-level field. `null` → no jump link\n * (document-scoped issues).\n */\nexport function issueJumpTarget(\n collection: CollectionDef,\n issue: CmsValidationIssue,\n): IssueJumpTarget | null {\n const tokens = issue.path.map(String)\n const relative = tokens[0] === 'documents' ? tokens.slice(2) : tokens\n const parsed = parseDocumentFieldPath(relative.join('/'))\n if (parsed && collection.fields.some((f) => f.name === parsed.field)) {\n const pathTokens = [parsed.field, ...parsed.rest]\n return {\n path: pathTokens.join('/'),\n ...(parsed.locale !== undefined ? { locale: parsed.locale } : {}),\n fieldDef: resolveFieldDefAtPath(collection, parsed.field, parsed.rest),\n leaf: lastNameToken(pathTokens),\n }\n }\n const metaField = typeof issue.meta?.field === 'string' ? issue.meta.field : undefined\n const topLevel = metaField ? collection.fields.find((f) => f.name === metaField) : undefined\n if (topLevel) {\n return { path: topLevel.name, fieldDef: topLevel, leaf: topLevel.name }\n }\n return null\n}\n\n/** A localized issue body: the catalog key + its substitution params. */\nexport interface IssueBodyDescriptor {\n key: string\n vars: Record<string, string | number>\n}\n\n/**\n * The code → body-template mapping (see module doc for the fallback contract).\n * `fieldLabelText` is the resolved (localized) label of the deepest field along\n * the issue path — supplied by the caller so this stays catalog-free and pure.\n */\nexport function issueBodyDescriptor(\n issue: CmsValidationIssue,\n fieldLabelText: string,\n): IssueBodyDescriptor | null {\n switch (issue.code) {\n case 'missing-required-field':\n return { key: 'cms.issueBody.missing-required-field', vars: { field: fieldLabelText } }\n case 'missing-localized-value': {\n const locale = typeof issue.meta?.locale === 'string' ? issue.meta.locale : undefined\n if (locale === undefined) return null\n return issue.severity === 'error'\n ? {\n key: 'cms.issueBody.missing-localized-value.default',\n vars: { field: fieldLabelText, locale },\n }\n : {\n key: 'cms.issueBody.missing-localized-value.fallback',\n vars: { field: fieldLabelText, locale },\n }\n }\n case 'unknown-asset': {\n const asset = typeof issue.meta?.asset === 'string' ? issue.meta.asset : undefined\n if (asset === undefined) return null\n return { key: 'cms.issueBody.unknown-asset', vars: { field: fieldLabelText, asset } }\n }\n case 'document-nesting-depth': {\n const depth = typeof issue.meta?.depth === 'number' ? issue.meta.depth : undefined\n const limit = typeof issue.meta?.limit === 'number' ? issue.meta.limit : undefined\n if (depth === undefined || limit === undefined) return null\n return {\n key:\n issue.severity === 'error'\n ? 'cms.issueBody.document-nesting-depth.error'\n : 'cms.issueBody.document-nesting-depth.warning',\n vars: { depth, limit },\n }\n }\n case 'hierarchy-cycle':\n return { key: 'cms.issueBody.hierarchy-cycle', vars: {} }\n default:\n return null\n }\n}\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { CircleCheck } from 'lucide-react';
|
|
3
3
|
import { Button, Row, Stack, Text } from '@elytracms/studio/ui';
|
|
4
|
-
import { cn } from '
|
|
5
|
-
import { cmsIssueLabel, cmsValidationIssueMessage } from '
|
|
6
|
-
import { translate } from '
|
|
4
|
+
import { cn } from '../../lib/utils.js';
|
|
5
|
+
import { cmsIssueLabel, cmsValidationIssueMessage } from '../../lib/persona/labels.js';
|
|
6
|
+
import { translate } from '../../lib/i18n/index.js';
|
|
7
7
|
import { issueSeverityIcon, issueSeverityStyle } from '../issue-severity.js';
|
|
8
8
|
import { fieldLabel } from './cms-labels.js';
|
|
9
9
|
import { issueBodyDescriptor, issueJumpTarget } from './issue-copy.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issues-pane.js","sourceRoot":"","sources":["../../../src/components/cms/issues-pane.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAC/D,OAAO,EAAE,EAAE,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"issues-pane.js","sourceRoot":"","sources":["../../../src/components/cms/issues-pane.tsx"],"names":[],"mappings":"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","sourcesContent":["import { CircleCheck } from 'lucide-react'\nimport type { CmsValidationIssue, CollectionDef } from '@elytracms/core/cms-core'\nimport { Button, Row, Stack, Text } from '@elytracms/studio/ui'\nimport { cn } from '../../lib/utils'\nimport { cmsIssueLabel, cmsValidationIssueMessage } from '../../lib/persona/labels'\nimport { translate } from '../../lib/i18n'\nimport { issueSeverityIcon, issueSeverityStyle } from '../issue-severity'\nimport { fieldLabel } from './cms-labels'\nimport { issueBodyDescriptor, issueJumpTarget } from './issue-copy'\n\n/**\n * EC-283 — the document-scoped validation surface.\n *\n * Lists every {@link CmsValidationIssue} for the open draft in the right\n * `InspectorSidebar` (the document-scoped equivalent of the amputated builder's\n * validation sidebar, EC-069). Field-level issues stay inline on the field too;\n * here they additionally list with a jump-to-field action. Document-level issues\n * that carry no field path (e.g. the EC-260 nesting-depth warning) have no\n * other home — this is theirs.\n *\n * EC-443: the jump carries the issue's FULL parsed path (`issueJumpTarget`), so\n * a nested finding (`links/3/badge/text`) lands on the exact control — the link\n * names the deepest resolvable field's localized label, never a raw leaf token\n * when a def resolves. Card copy is localized studio-side: the title via\n * `cmsIssueLabel` (catalog-routed), the body via the `issueBodyDescriptor`\n * template where one exists — it is PERSONA copy, naming the field by its localized\n * label rather than its raw name, so it keeps precedence — else the issue's own\n * message, localized through `cmsValidationIssueMessage` (EC-487) and degrading to\n * the producer's English only for an issue that carries no catalog key.\n *\n * Persona boundary (EC-192): rows show the plain-language `cmsIssueLabel`; the raw\n * `code` rides along in `title=` for engineers, never as visible copy.\n */\nexport function IssuesPane({\n issues,\n collection,\n onJumpToField,\n}: {\n issues: readonly CmsValidationIssue[]\n collection: CollectionDef\n /** Receives the EC-443 anchor path (`links/3/badge/text`) + the issue's locale. */\n onJumpToField: (fieldPath: string, locale?: string) => void\n}) {\n if (issues.length === 0) {\n return (\n <Stack gap=\"2\" align=\"center\" className=\"px-4 py-10 text-center\">\n <CircleCheck className=\"size-5 text-success\" aria-hidden />\n <Text size=\"sm\" weight=\"medium\">\n {translate('cms.issues.none')}\n </Text>\n <Text size=\"xs\" tone=\"muted\">\n {translate('cms.issues.satisfied')}\n </Text>\n </Stack>\n )\n }\n\n return (\n <Stack gap=\"1\" className=\"p-2\">\n {issues.map((issue, i) => (\n <IssueRow\n key={`${issue.code}:${issue.path.join('/')}:${i}`}\n issue={issue}\n collection={collection}\n onJumpToField={onJumpToField}\n />\n ))}\n </Stack>\n )\n}\n\nfunction IssueRow({\n issue,\n collection,\n onJumpToField,\n}: {\n issue: CmsValidationIssue\n collection: CollectionDef\n onJumpToField: (fieldPath: string, locale?: string) => void\n}) {\n const jump = issueJumpTarget(collection, issue)\n // The (localized) name of the offending field: the deepest resolvable def's\n // `form.label`, degrading to the leaf path token / `meta.field` raw name.\n const fieldName =\n jump !== null\n ? jump.fieldDef !== null\n ? fieldLabel(jump.fieldDef)\n : jump.leaf\n : typeof issue.meta?.field === 'string'\n ? issue.meta.field\n : ''\n const body = issueBodyDescriptor(issue, fieldName)\n // EC-507: the pane's own treatment, now imported from the one home rather than\n // inlined here. The tint carries to the GLYPH only — the title inherits and the\n // body stays `muted`, as this surface has always rendered them.\n const style = issueSeverityStyle(issue.severity)\n const Icon = issueSeverityIcon(issue.severity)\n\n return (\n <Stack gap=\"1\" className={cn('rounded-md border px-2.5 py-2', style.card)}>\n <Row gap=\"2\" align=\"start\">\n <Icon className={cn('mt-0.5 size-3.5 shrink-0', style.text)} aria-hidden />\n <Stack gap=\"1\" className=\"min-w-0\">\n <Text size=\"xs\" weight=\"semibold\" title={issue.code}>\n {cmsIssueLabel(issue.code, issue.severity)}\n </Text>\n <Text size=\"xs\" tone=\"muted\">\n {body !== null ? translate(body.key, body.vars) : cmsValidationIssueMessage(issue)}\n </Text>\n </Stack>\n </Row>\n {jump !== null ? (\n <Row className=\"pl-[1.375rem]\">\n <Button\n size=\"sm\"\n variant=\"link\"\n className=\"h-auto p-0 text-xs\"\n onClick={() => onJumpToField(jump.path, jump.locale)}\n >\n {translate('cms.issues.goToField', { field: fieldName })}\n </Button>\n </Row>\n ) : null}\n </Stack>\n )\n}\n"]}
|
|
@@ -3,12 +3,12 @@ import { ChevronDown, ChevronUp, GripVertical, MoreHorizontal, Plus, Trash2 } fr
|
|
|
3
3
|
import { createContext, useContext, useEffect, useRef, useState } from 'react';
|
|
4
4
|
import { isFieldHidden, seedObjectItem } from '@elytracms/core/cms-core';
|
|
5
5
|
import { Button, Card, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, FIELD_PATH_ATTR, Field, Row, Stack, Text, } from '@elytracms/studio/ui';
|
|
6
|
-
import { cn } from '
|
|
7
|
-
import { localizedLabel, translate } from '
|
|
6
|
+
import { cn } from '../../lib/utils.js';
|
|
7
|
+
import { localizedLabel, translate } from '../../lib/i18n/index.js';
|
|
8
8
|
import { fieldLabel } from './cms-labels.js';
|
|
9
9
|
import { FieldPathContext, isPathWithin, useFieldFocusRequest, useFieldPath, } from './field-anchors.js';
|
|
10
10
|
import { FieldControl } from './field-control.js';
|
|
11
|
-
import { depthRail, depthTint, isTabularObjectType, objectItemSummary, reorder } from './field-control-lib.js';
|
|
11
|
+
import { depthRail, depthTint, isSubFieldReadOnly, isTabularObjectType, objectItemSummary, reorder, tableColumnsOf, } from './field-control-lib.js';
|
|
12
12
|
/**
|
|
13
13
|
* The object / repeater field controls (EC-253, legibility-rebuilt EC-305) —
|
|
14
14
|
* split from `field-control.tsx` (EC-330). {@link ObjectField} dispatches by
|
|
@@ -109,7 +109,7 @@ export function ObjectItemForm({ fields, value, onChange, readOnly, idPrefix, })
|
|
|
109
109
|
return null;
|
|
110
110
|
const subId = `${idPrefix}-${sub.name}`;
|
|
111
111
|
const subPath = itemPath === null ? undefined : `${itemPath}/${sub.name}`;
|
|
112
|
-
return (_jsx(Field, { htmlFor: subId, fieldPath: subPath, className: cn('transition-shadow', subPath !== undefined && focus?.path === subPath && `${FOCUS_RING_CLASS} p-2`), hint: localizedLabel(sub.form?.description) || undefined, label: _jsxs(Row, { gap: "2", children: [_jsx("span", { children: fieldLabel(sub) }), sub.validation?.required ? _jsx("span", { className: "text-destructive", children: "*" }) : null] }), children: _jsx(FieldPathContext.Provider, { value: subPath ?? null, children: _jsx(FieldControl, { id: subId, field: sub, value: value[sub.name], readOnly: readOnly, onChange: (next) => {
|
|
112
|
+
return (_jsx(Field, { htmlFor: subId, fieldPath: subPath, className: cn('transition-shadow', subPath !== undefined && focus?.path === subPath && `${FOCUS_RING_CLASS} p-2`), hint: localizedLabel(sub.form?.description) || undefined, label: _jsxs(Row, { gap: "2", children: [_jsx("span", { children: fieldLabel(sub) }), sub.validation?.required ? _jsx("span", { className: "text-destructive", children: "*" }) : null] }), children: _jsx(FieldPathContext.Provider, { value: subPath ?? null, children: _jsx(FieldControl, { id: subId, field: sub, value: value[sub.name], readOnly: isSubFieldReadOnly(readOnly, sub), onChange: (next) => {
|
|
113
113
|
const updated = { ...value };
|
|
114
114
|
if (next === undefined)
|
|
115
115
|
delete updated[sub.name];
|
|
@@ -219,7 +219,7 @@ function ObjectTableField({ field, value, onChange, readOnly, id, depth }) {
|
|
|
219
219
|
// cell — `links/3/href` — is always the deepest possible anchor here).
|
|
220
220
|
const parentPath = useFieldPath();
|
|
221
221
|
const focus = useFieldFocusRequest();
|
|
222
|
-
const cols = field
|
|
222
|
+
const cols = tableColumnsOf(field);
|
|
223
223
|
const span = cols.length + (readOnly ? 0 : 2);
|
|
224
224
|
return (_jsxs("div", { className: cn('overflow-hidden rounded-md border border-border border-l-2', depthRail(depth), depthTint(depth)), children: [_jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { children: _jsxs("tr", { className: "border-b border-border/60 bg-muted/30 text-left", children: [!readOnly ? _jsx("th", { className: "w-7" }) : null, cols.map((c) => (_jsxs("th", { className: "px-2 py-1.5 text-xs font-medium text-muted-foreground", children: [fieldLabel(c), c.validation?.required ? _jsx("span", { className: "text-destructive", children: " *" }) : null] }, c.name))), !readOnly ? _jsx("th", { className: "w-9" }) : null] }) }), _jsx("tbody", { children: items.length === 0 ? (_jsx("tr", { children: _jsx("td", { colSpan: span, className: "px-2 py-2 text-muted-foreground", children: _jsx(Text, { size: "sm", tone: "subtle", children: translate('cms.field.noItems') }) }) })) : (items.map((item, i) => {
|
|
225
225
|
const key = keys[i] ?? i;
|
|
@@ -243,7 +243,7 @@ function ObjectTableField({ field, value, onChange, readOnly, id, depth }) {
|
|
|
243
243
|
const cellPath = itemPath === undefined ? undefined : `${itemPath}/${c.name}`;
|
|
244
244
|
return (_jsx("td", { ...(cellPath !== undefined ? { [FIELD_PATH_ATTR]: cellPath } : {}), className: cn('px-2 py-1', cellPath !== undefined && focus?.path === cellPath
|
|
245
245
|
? 'bg-primary/5 ring-2 ring-inset ring-primary/70'
|
|
246
|
-
: ''), children: _jsx(FieldControl, { id: `${id}-${i}-${c.name}`, field: c, value: record[c.name], readOnly: readOnly, onChange: (next) => {
|
|
246
|
+
: ''), children: _jsx(FieldControl, { id: `${id}-${i}-${c.name}`, field: c, value: record[c.name], readOnly: isSubFieldReadOnly(readOnly, c), onChange: (next) => {
|
|
247
247
|
const updated = { ...record };
|
|
248
248
|
if (next === undefined)
|
|
249
249
|
delete updated[c.name];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object-array-field.js","sourceRoot":"","sources":["../../../src/components/cms/object-array-field.tsx"],"names":[],"mappings":"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","sourcesContent":["import { ChevronDown, ChevronUp, GripVertical, MoreHorizontal, Plus, Trash2 } from 'lucide-react'\nimport { createContext, useContext, useEffect, useRef, useState } from 'react'\nimport type { FieldDef, ObjectFieldDef } from '@elytracms/core/cms-core'\nimport { isFieldHidden, seedObjectItem } from '@elytracms/core/cms-core'\nimport {\n Button,\n Card,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n FIELD_PATH_ATTR,\n Field,\n Row,\n Stack,\n Text,\n} from '@elytracms/studio/ui'\nimport { cn } from '@elytracms/studio/lib/utils'\nimport { localizedLabel, translate } from '@elytracms/studio/lib/i18n'\nimport { fieldLabel } from './cms-labels'\nimport {\n FieldPathContext,\n isPathWithin,\n useFieldFocusRequest,\n useFieldPath,\n} from './field-anchors'\nimport { FieldControl } from './field-control'\nimport { depthRail, depthTint, isTabularObjectType, objectItemSummary, reorder } from './field-control-lib'\n\n/**\n * The object / repeater field controls (EC-253, legibility-rebuilt EC-305) —\n * split from `field-control.tsx` (EC-330). {@link ObjectField} dispatches by\n * shape (single card / editable table / card list); {@link ObjectItemForm} is\n * the recursive subfield form the asset-field family reuses for per-use\n * sub-fields and asset metadata. Cells and subfields render through\n * `FieldControl`, so any subfield type — including a nested repeater — works\n * for free.\n *\n * EC-443 path anchors: inside a stamped surface (a non-null `FieldPathContext`,\n * provided by the document form) every item card / table row / subfield row\n * stamps its `FIELD_PATH_ATTR` anchor (`links/3`, `links/3/badge/text` — the\n * ONE convention defined on the attribute in `ui/field.tsx`), a collapsed card\n * auto-expands when the active focus request targets a path within it, and the\n * exact requested control ring-highlights. All decisions come from the pure\n * helpers in `field-anchors.ts`.\n */\n\n/** The EC-443 ring on the exact jump target (mirrors the top-level row ring). */\nconst FOCUS_RING_CLASS = 'rounded-md bg-primary/5 ring-2 ring-primary/70'\n\nfunction asRecord(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {}\n}\n\n// EC-305: nested-array depth, propagated via context so each array level can encode\n// its depth (rail colour + tint) without prop-drilling through FieldControl's many\n// branches. The detail editor renders top-level fields with the default depth 0.\nconst ArrayDepthContext = createContext(0)\nconst useArrayDepth = () => useContext(ArrayDepthContext)\n\n/**\n * Shared array state for an object repeater (EC-253/EC-294/EC-305): the value-only\n * items + a parallel stable-key list kept in lockstep through every structural op\n * (the EC-253 C2 key↔value lock), add/remove/move, and native drag-reorder. Used by\n * both the card list (B) and the table (C) so they behave identically.\n */\nfunction useObjectArray(field: ObjectFieldDef, value: unknown, onChange: (value: unknown) => void) {\n const items = Array.isArray(value) ? (value as Record<string, unknown>[]) : []\n const seq = useRef(0)\n const keysRef = useRef<number[]>([])\n if (keysRef.current.length !== items.length) {\n keysRef.current = items.map((_, i) => keysRef.current[i] ?? seq.current++)\n }\n const keys = keysRef.current\n const commit = (nextItems: Record<string, unknown>[], nextKeys: number[]) => {\n keysRef.current = nextKeys\n onChange(nextItems)\n }\n const move = (from: number, to: number) => commit(reorder(items, from, to), reorder(keys, from, to))\n const removeAt = (i: number) =>\n commit(items.filter((_, j) => j !== i), keys.filter((_, j) => j !== i))\n const addItem = (): number => {\n // EC-581: the one seeding rule (core `seedObjectItem`) — nested defaults included.\n const seed = seedObjectItem(field.fields)\n const key = seq.current++\n commit([...items, seed], [...keys, key])\n return key\n }\n const setItem = (i: number, updated: Record<string, unknown>) => {\n const nextItems = items.slice()\n nextItems[i] = updated\n commit(nextItems, keys)\n }\n const [dragIndex, setDragIndex] = useState<number | null>(null)\n const [overIndex, setOverIndex] = useState<number | null>(null)\n const endDrag = () => {\n setDragIndex(null)\n setOverIndex(null)\n }\n const drop = (to: number) => {\n if (dragIndex !== null && dragIndex !== to) move(dragIndex, to)\n endDrag()\n }\n return { items, keys, move, removeAt, addItem, setItem, dragIndex, overIndex, setDragIndex, setOverIndex, endDrag, drop }\n}\n\n/**\n * (E) Chrome reduction: the per-row move/remove controls collapse into one hover/\n * focus overflow menu, so a row reads as content, not a six-button toolbar. Drag is\n * the primary reorder; the arrows stay here for keyboard/a11y.\n */\nfunction ItemOverflowMenu({\n index,\n count,\n onMove,\n onRemove,\n}: {\n index: number\n count: number\n onMove: (from: number, to: number) => void\n onRemove: () => void\n}) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"sm\" aria-label={translate('cms.field.itemActions')}>\n <MoreHorizontal className=\"size-3.5\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem disabled={index === 0} onClick={() => onMove(index, index - 1)}>\n <ChevronUp /> {translate('cms.field.moveUp')}\n </DropdownMenuItem>\n <DropdownMenuItem disabled={index === count - 1} onClick={() => onMove(index, index + 1)}>\n <ChevronDown /> {translate('cms.field.moveDown')}\n </DropdownMenuItem>\n <DropdownMenuItem onClick={onRemove}>\n <Trash2 /> {translate('common.remove')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\n/**\n * The nested subfield form for one object item (EC-253). Reuses {@link FieldControl}\n * recursively, so any subfield type — including a nested object/repeater — works for\n * free. Writing a subfield merges it back into the item and bubbles the new item up.\n * EC-443: each subfield row stamps its path anchor (`<itemPath>/<sub>`), rings when\n * it is the exact focus target, and provides its path down for deeper nesting.\n */\nexport function ObjectItemForm({\n fields,\n value,\n onChange,\n readOnly,\n idPrefix,\n}: {\n fields: readonly FieldDef[]\n value: Record<string, unknown>\n onChange: (value: Record<string, unknown>) => void\n readOnly: boolean\n idPrefix: string\n}) {\n const itemPath = useFieldPath()\n const focus = useFieldFocusRequest()\n return (\n <Stack gap=\"3\" className=\"mt-2\">\n {fields.map((sub) => {\n // EC-273: a conditionally-hidden subfield (its predicate keys off the item's\n // own sibling values) is omitted — e.g. a discriminated link's `href` shows\n // only when `linkType === 'href'`. Re-evaluated as the item is edited.\n if (isFieldHidden(sub, { values: value })) return null\n const subId = `${idPrefix}-${sub.name}`\n const subPath = itemPath === null ? undefined : `${itemPath}/${sub.name}`\n return (\n <Field\n key={sub.name}\n htmlFor={subId}\n fieldPath={subPath}\n className={cn(\n 'transition-shadow',\n subPath !== undefined && focus?.path === subPath && `${FOCUS_RING_CLASS} p-2`,\n )}\n hint={localizedLabel(sub.form?.description) || undefined}\n label={\n <Row gap=\"2\">\n <span>{fieldLabel(sub)}</span>\n {sub.validation?.required ? <span className=\"text-destructive\">*</span> : null}\n </Row>\n }\n >\n <FieldPathContext.Provider value={subPath ?? null}>\n <FieldControl\n id={subId}\n field={sub}\n value={value[sub.name]}\n readOnly={readOnly}\n onChange={(next) => {\n const updated = { ...value }\n if (next === undefined) delete updated[sub.name]\n else updated[sub.name] = next\n onChange(updated)\n }}\n />\n </FieldPathContext.Provider>\n </Field>\n )\n })}\n </Stack>\n )\n}\n\n/**\n * Object / repeater field control (EC-253), legibility-rebuilt (EC-305). A single\n * object (`multiple: false`) renders a depth-encoded card; an array (`'many'`)\n * dispatches by shape: a **flat** object type (all scalar subfields) → a compact\n * editable TABLE (C); a richer/nested type → a card list with depth encoding (B),\n * summary-first collapse (D), and reduced per-row chrome (E). Editing stays in the\n * shared field form — no canvas escape (unlike `blocks`) — so props and document\n * fields share this control. Depth flows via {@link ArrayDepthContext}.\n */\nexport function ObjectField({\n field,\n value,\n onChange,\n readOnly,\n id,\n}: {\n field: ObjectFieldDef\n value: unknown\n onChange: (value: unknown) => void\n readOnly: boolean\n id: string\n}) {\n const depth = useArrayDepth()\n if (field.multiple === false) {\n return (\n <Card className={cn('border-l-2 p-3', depthRail(depth), depthTint(depth))}>\n <ArrayDepthContext.Provider value={depth + 1}>\n <ObjectItemForm\n fields={field.fields}\n value={asRecord(value)}\n readOnly={readOnly}\n idPrefix={id}\n onChange={onChange}\n />\n </ArrayDepthContext.Provider>\n </Card>\n )\n }\n const props = { field, value, onChange, readOnly, id, depth }\n return isTabularObjectType(field) ? <ObjectTableField {...props} /> : <ObjectCardList {...props} />\n}\n\ninterface ObjectArrayProps {\n field: ObjectFieldDef\n value: unknown\n onChange: (value: unknown) => void\n readOnly: boolean\n id: string\n depth: number\n}\n\n/**\n * (B + D + E) The card list for a nested/rich object array: depth-encoded cards\n * (coloured rail + tint), items collapsed by default to a scannable summary outline\n * (D), accordion expansion (open one → collapse siblings), and the per-row controls\n * collapsed into one overflow menu (E). Drag-to-reorder; arrows live in the menu for\n * a11y. Nested arrays render one depth deeper via the context provider.\n */\nfunction ObjectCardList({ field, value, onChange, readOnly, id, depth }: ObjectArrayProps) {\n const arr = useObjectArray(field, value, onChange)\n const { items, keys } = arr\n const parentPath = useFieldPath()\n const focus = useFieldFocusRequest()\n // (D) Default COLLAPSED: track which keys are EXPANDED (empty = all collapsed).\n // (B) Accordion: expanding one collapses the siblings.\n const [expandedKeys, setExpandedKeys] = useState<ReadonlySet<number>>(() => new Set())\n const toggle = (key: number) =>\n setExpandedKeys((prev) => {\n if (prev.has(key)) {\n const next = new Set(prev)\n next.delete(key)\n return next\n }\n return new Set([key])\n })\n const allExpanded = items.length > 0 && keys.every((k) => expandedKeys.has(k))\n const onAdd = () => setExpandedKeys(new Set([arr.addItem()]))\n // EC-443: a jump-to-field targeting a path INSIDE one of these items expands\n // that item (accordion semantics, like a manual open) so the deeper anchors can\n // render — nested levels cascade, each level's effect firing once its card\n // mounts. Keyed on the request nonce so re-clicking the same issue re-expands\n // a manually re-collapsed item.\n const focusPath = focus?.path\n const focusNonce = focus?.nonce\n useEffect(() => {\n if (parentPath === null || focusPath === undefined) return\n const index = items.findIndex((_, i) => isPathWithin(`${parentPath}/${i}`, focusPath))\n if (index < 0) return\n const key = keys[index]\n if (key !== undefined) setExpandedKeys(new Set([key]))\n // Deps: keys/items stay in lockstep (the C2 key↔value lock) — `items.length`\n // captures the structure; item-content identity must NOT re-trigger expansion.\n }, [focusNonce, focusPath, parentPath, items.length])\n return (\n <ArrayDepthContext.Provider value={depth + 1}>\n <Stack gap=\"2\">\n {items.length > 1 && !readOnly ? (\n <Row justify=\"end\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setExpandedKeys(allExpanded ? new Set() : new Set(keys))}\n >\n {translate(allExpanded ? 'cms.field.collapseAll' : 'cms.field.expandAll')}\n </Button>\n </Row>\n ) : null}\n {items.length === 0 ? (\n <Text size=\"sm\" tone=\"subtle\">\n {translate('cms.field.noItems')}\n </Text>\n ) : (\n items.map((item, i) => {\n // keysRef is reconciled to items.length, so keys[i] is always present;\n // `?? i` only satisfies noUncheckedIndexedAccess (never taken at runtime).\n const key = keys[i] ?? i\n const record = asRecord(item)\n const isExpanded = expandedKeys.has(key)\n // EC-443: the item's path anchor — stamped even while collapsed, so a\n // degraded jump can still land (and ring) on the closed card.\n const itemPath = parentPath === null ? undefined : `${parentPath}/${i}`\n return (\n <Card\n key={key}\n {...(itemPath !== undefined ? { [FIELD_PATH_ATTR]: itemPath } : {})}\n onDragOver={(e) => {\n if (arr.dragIndex === null) return\n e.preventDefault()\n if (arr.overIndex !== i) arr.setOverIndex(i)\n }}\n onDrop={() => arr.drop(i)}\n className={cn(\n 'border-l-2 p-0',\n depthRail(depth),\n depthTint(depth),\n arr.dragIndex === i ? 'opacity-50' : '',\n arr.overIndex === i && arr.dragIndex !== null && arr.dragIndex !== i\n ? 'border-l-primary ring-1 ring-primary/40'\n : '',\n itemPath !== undefined && focus?.path === itemPath\n ? 'ring-2 ring-primary/70'\n : '',\n )}\n >\n <Row className=\"select-none border-b border-border/60 bg-muted/20 px-2 py-1.5\">\n {!readOnly ? (\n <span\n draggable\n onDragStart={(e) => {\n e.dataTransfer.effectAllowed = 'move'\n e.dataTransfer.setData('text/plain', String(i))\n arr.setDragIndex(i)\n }}\n onDragEnd={arr.endDrag}\n aria-label={translate('cms.field.dragToReorder')}\n className=\"cursor-grab text-muted-foreground/50 hover:text-muted-foreground active:cursor-grabbing\"\n >\n <GripVertical className=\"size-3.5\" />\n </span>\n ) : null}\n <button\n type=\"button\"\n onClick={() => toggle(key)}\n aria-expanded={isExpanded}\n className=\"flex min-w-0 flex-1 items-center gap-1.5 text-left\"\n >\n <ChevronDown\n className={cn(\n 'size-3.5 shrink-0 text-muted-foreground transition-transform',\n isExpanded ? '' : '-rotate-90',\n )}\n aria-hidden\n />\n <Text size=\"sm\" className=\"min-w-0 truncate font-medium\">\n {objectItemSummary(field.fields, record, i)}\n </Text>\n </button>\n {!readOnly ? (\n <ItemOverflowMenu\n index={i}\n count={items.length}\n onMove={arr.move}\n onRemove={() => arr.removeAt(i)}\n />\n ) : null}\n </Row>\n {isExpanded ? (\n <div className=\"px-3 pb-3\">\n <FieldPathContext.Provider value={itemPath ?? null}>\n <ObjectItemForm\n fields={field.fields}\n value={record}\n readOnly={readOnly}\n idPrefix={`${id}-${i}`}\n onChange={(updated) => arr.setItem(i, updated)}\n />\n </FieldPathContext.Provider>\n </div>\n ) : null}\n </Card>\n )\n })\n )}\n {!readOnly ? (\n <Button variant=\"outline\" size=\"sm\" onClick={onAdd}>\n <Plus className=\"size-3\" /> {translate('cms.field.addItem')}\n </Button>\n ) : null}\n </Stack>\n </ArrayDepthContext.Provider>\n )\n}\n\n/**\n * (C) A compact editable table for a FLAT object array — columns are the scalar\n * subfields, one row per item. Kills the card-stack sprawl for the commonest case\n * (option lists, opening hours, social links). Drag-reorder + an overflow menu per\n * row; cells reuse {@link FieldControl} so each subfield keeps its native control.\n */\nfunction ObjectTableField({ field, value, onChange, readOnly, id, depth }: ObjectArrayProps) {\n const arr = useObjectArray(field, value, onChange)\n const { items, keys } = arr\n // EC-443: rows/cells stamp path anchors too (a tabular type is flat, so the\n // cell — `links/3/href` — is always the deepest possible anchor here).\n const parentPath = useFieldPath()\n const focus = useFieldFocusRequest()\n const cols = field.fields\n const span = cols.length + (readOnly ? 0 : 2)\n return (\n <div className={cn('overflow-hidden rounded-md border border-border border-l-2', depthRail(depth), depthTint(depth))}>\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border/60 bg-muted/30 text-left\">\n {!readOnly ? <th className=\"w-7\" /> : null}\n {cols.map((c) => (\n <th key={c.name} className=\"px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n {fieldLabel(c)}\n {c.validation?.required ? <span className=\"text-destructive\"> *</span> : null}\n </th>\n ))}\n {!readOnly ? <th className=\"w-9\" /> : null}\n </tr>\n </thead>\n <tbody>\n {items.length === 0 ? (\n <tr>\n <td colSpan={span} className=\"px-2 py-2 text-muted-foreground\">\n <Text size=\"sm\" tone=\"subtle\">\n {translate('cms.field.noItems')}\n </Text>\n </td>\n </tr>\n ) : (\n items.map((item, i) => {\n const key = keys[i] ?? i\n const record = asRecord(item)\n const itemPath = parentPath === null ? undefined : `${parentPath}/${i}`\n return (\n <tr\n key={key}\n {...(itemPath !== undefined ? { [FIELD_PATH_ATTR]: itemPath } : {})}\n onDragOver={(e) => {\n if (arr.dragIndex === null) return\n e.preventDefault()\n if (arr.overIndex !== i) arr.setOverIndex(i)\n }}\n onDrop={() => arr.drop(i)}\n className={cn(\n 'border-b border-border/40 align-top last:border-0',\n arr.dragIndex === i ? 'opacity-50' : '',\n arr.overIndex === i && arr.dragIndex !== null && arr.dragIndex !== i\n ? 'bg-primary/5'\n : '',\n itemPath !== undefined && focus?.path === itemPath\n ? 'ring-2 ring-inset ring-primary/70'\n : '',\n )}\n >\n {!readOnly ? (\n <td className=\"px-1 py-1\">\n <span\n draggable\n onDragStart={(e) => {\n e.dataTransfer.effectAllowed = 'move'\n e.dataTransfer.setData('text/plain', String(i))\n arr.setDragIndex(i)\n }}\n onDragEnd={arr.endDrag}\n aria-label={translate('cms.field.dragToReorder')}\n className=\"inline-flex cursor-grab text-muted-foreground/50 hover:text-muted-foreground active:cursor-grabbing\"\n >\n <GripVertical className=\"size-3.5\" />\n </span>\n </td>\n ) : null}\n {cols.map((c) => {\n const cellPath = itemPath === undefined ? undefined : `${itemPath}/${c.name}`\n return (\n <td\n key={c.name}\n {...(cellPath !== undefined ? { [FIELD_PATH_ATTR]: cellPath } : {})}\n className={cn(\n 'px-2 py-1',\n cellPath !== undefined && focus?.path === cellPath\n ? 'bg-primary/5 ring-2 ring-inset ring-primary/70'\n : '',\n )}\n >\n <FieldControl\n id={`${id}-${i}-${c.name}`}\n field={c}\n value={record[c.name]}\n readOnly={readOnly}\n onChange={(next) => {\n const updated = { ...record }\n if (next === undefined) delete updated[c.name]\n else updated[c.name] = next\n arr.setItem(i, updated)\n }}\n />\n </td>\n )\n })}\n {!readOnly ? (\n <td className=\"px-1 py-1\">\n <ItemOverflowMenu\n index={i}\n count={items.length}\n onMove={arr.move}\n onRemove={() => arr.removeAt(i)}\n />\n </td>\n ) : null}\n </tr>\n )\n })\n )}\n </tbody>\n </table>\n {!readOnly ? (\n <div className=\"border-t border-border/60 p-1.5\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => arr.addItem()}>\n <Plus className=\"size-3\" /> {translate('common.add')}\n </Button>\n </div>\n ) : null}\n </div>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"file":"object-array-field.js","sourceRoot":"","sources":["../../../src/components/cms/object-array-field.tsx"],"names":[],"mappings":"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","sourcesContent":["import { ChevronDown, ChevronUp, GripVertical, MoreHorizontal, Plus, Trash2 } from 'lucide-react'\nimport { createContext, useContext, useEffect, useRef, useState } from 'react'\nimport type { FieldDef, ObjectFieldDef } from '@elytracms/core/cms-core'\nimport { isFieldHidden, seedObjectItem } from '@elytracms/core/cms-core'\nimport {\n Button,\n Card,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n FIELD_PATH_ATTR,\n Field,\n Row,\n Stack,\n Text,\n} from '@elytracms/studio/ui'\nimport { cn } from '../../lib/utils'\nimport { localizedLabel, translate } from '../../lib/i18n'\nimport { fieldLabel } from './cms-labels'\nimport {\n FieldPathContext,\n isPathWithin,\n useFieldFocusRequest,\n useFieldPath,\n} from './field-anchors'\nimport { FieldControl } from './field-control'\nimport {\n depthRail,\n depthTint,\n isSubFieldReadOnly,\n isTabularObjectType,\n objectItemSummary,\n reorder,\n tableColumnsOf,\n} from './field-control-lib'\n\n/**\n * The object / repeater field controls (EC-253, legibility-rebuilt EC-305) —\n * split from `field-control.tsx` (EC-330). {@link ObjectField} dispatches by\n * shape (single card / editable table / card list); {@link ObjectItemForm} is\n * the recursive subfield form the asset-field family reuses for per-use\n * sub-fields and asset metadata. Cells and subfields render through\n * `FieldControl`, so any subfield type — including a nested repeater — works\n * for free.\n *\n * EC-443 path anchors: inside a stamped surface (a non-null `FieldPathContext`,\n * provided by the document form) every item card / table row / subfield row\n * stamps its `FIELD_PATH_ATTR` anchor (`links/3`, `links/3/badge/text` — the\n * ONE convention defined on the attribute in `ui/field.tsx`), a collapsed card\n * auto-expands when the active focus request targets a path within it, and the\n * exact requested control ring-highlights. All decisions come from the pure\n * helpers in `field-anchors.ts`.\n */\n\n/** The EC-443 ring on the exact jump target (mirrors the top-level row ring). */\nconst FOCUS_RING_CLASS = 'rounded-md bg-primary/5 ring-2 ring-primary/70'\n\nfunction asRecord(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {}\n}\n\n// EC-305: nested-array depth, propagated via context so each array level can encode\n// its depth (rail colour + tint) without prop-drilling through FieldControl's many\n// branches. The detail editor renders top-level fields with the default depth 0.\nconst ArrayDepthContext = createContext(0)\nconst useArrayDepth = () => useContext(ArrayDepthContext)\n\n/**\n * Shared array state for an object repeater (EC-253/EC-294/EC-305): the value-only\n * items + a parallel stable-key list kept in lockstep through every structural op\n * (the EC-253 C2 key↔value lock), add/remove/move, and native drag-reorder. Used by\n * both the card list (B) and the table (C) so they behave identically.\n */\nfunction useObjectArray(field: ObjectFieldDef, value: unknown, onChange: (value: unknown) => void) {\n const items = Array.isArray(value) ? (value as Record<string, unknown>[]) : []\n const seq = useRef(0)\n const keysRef = useRef<number[]>([])\n if (keysRef.current.length !== items.length) {\n keysRef.current = items.map((_, i) => keysRef.current[i] ?? seq.current++)\n }\n const keys = keysRef.current\n const commit = (nextItems: Record<string, unknown>[], nextKeys: number[]) => {\n keysRef.current = nextKeys\n onChange(nextItems)\n }\n const move = (from: number, to: number) => commit(reorder(items, from, to), reorder(keys, from, to))\n const removeAt = (i: number) =>\n commit(items.filter((_, j) => j !== i), keys.filter((_, j) => j !== i))\n const addItem = (): number => {\n // EC-581: the one seeding rule (core `seedObjectItem`) — nested defaults included.\n const seed = seedObjectItem(field.fields)\n const key = seq.current++\n commit([...items, seed], [...keys, key])\n return key\n }\n const setItem = (i: number, updated: Record<string, unknown>) => {\n const nextItems = items.slice()\n nextItems[i] = updated\n commit(nextItems, keys)\n }\n const [dragIndex, setDragIndex] = useState<number | null>(null)\n const [overIndex, setOverIndex] = useState<number | null>(null)\n const endDrag = () => {\n setDragIndex(null)\n setOverIndex(null)\n }\n const drop = (to: number) => {\n if (dragIndex !== null && dragIndex !== to) move(dragIndex, to)\n endDrag()\n }\n return { items, keys, move, removeAt, addItem, setItem, dragIndex, overIndex, setDragIndex, setOverIndex, endDrag, drop }\n}\n\n/**\n * (E) Chrome reduction: the per-row move/remove controls collapse into one hover/\n * focus overflow menu, so a row reads as content, not a six-button toolbar. Drag is\n * the primary reorder; the arrows stay here for keyboard/a11y.\n */\nfunction ItemOverflowMenu({\n index,\n count,\n onMove,\n onRemove,\n}: {\n index: number\n count: number\n onMove: (from: number, to: number) => void\n onRemove: () => void\n}) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"sm\" aria-label={translate('cms.field.itemActions')}>\n <MoreHorizontal className=\"size-3.5\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem disabled={index === 0} onClick={() => onMove(index, index - 1)}>\n <ChevronUp /> {translate('cms.field.moveUp')}\n </DropdownMenuItem>\n <DropdownMenuItem disabled={index === count - 1} onClick={() => onMove(index, index + 1)}>\n <ChevronDown /> {translate('cms.field.moveDown')}\n </DropdownMenuItem>\n <DropdownMenuItem onClick={onRemove}>\n <Trash2 /> {translate('common.remove')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\n/**\n * The nested subfield form for one object item (EC-253). Reuses {@link FieldControl}\n * recursively, so any subfield type — including a nested object/repeater — works for\n * free. Writing a subfield merges it back into the item and bubbles the new item up.\n * EC-443: each subfield row stamps its path anchor (`<itemPath>/<sub>`), rings when\n * it is the exact focus target, and provides its path down for deeper nesting.\n */\nexport function ObjectItemForm({\n fields,\n value,\n onChange,\n readOnly,\n idPrefix,\n}: {\n fields: readonly FieldDef[]\n value: Record<string, unknown>\n onChange: (value: Record<string, unknown>) => void\n readOnly: boolean\n idPrefix: string\n}) {\n const itemPath = useFieldPath()\n const focus = useFieldFocusRequest()\n return (\n <Stack gap=\"3\" className=\"mt-2\">\n {fields.map((sub) => {\n // EC-273: a conditionally-hidden subfield (its predicate keys off the item's\n // own sibling values) is omitted — e.g. a discriminated link's `href` shows\n // only when `linkType === 'href'`. Re-evaluated as the item is edited.\n if (isFieldHidden(sub, { values: value })) return null\n const subId = `${idPrefix}-${sub.name}`\n const subPath = itemPath === null ? undefined : `${itemPath}/${sub.name}`\n return (\n <Field\n key={sub.name}\n htmlFor={subId}\n fieldPath={subPath}\n className={cn(\n 'transition-shadow',\n subPath !== undefined && focus?.path === subPath && `${FOCUS_RING_CLASS} p-2`,\n )}\n hint={localizedLabel(sub.form?.description) || undefined}\n label={\n <Row gap=\"2\">\n <span>{fieldLabel(sub)}</span>\n {sub.validation?.required ? <span className=\"text-destructive\">*</span> : null}\n </Row>\n }\n >\n <FieldPathContext.Provider value={subPath ?? null}>\n <FieldControl\n id={subId}\n field={sub}\n value={value[sub.name]}\n readOnly={isSubFieldReadOnly(readOnly, sub)}\n onChange={(next) => {\n const updated = { ...value }\n if (next === undefined) delete updated[sub.name]\n else updated[sub.name] = next\n onChange(updated)\n }}\n />\n </FieldPathContext.Provider>\n </Field>\n )\n })}\n </Stack>\n )\n}\n\n/**\n * Object / repeater field control (EC-253), legibility-rebuilt (EC-305). A single\n * object (`multiple: false`) renders a depth-encoded card; an array (`'many'`)\n * dispatches by shape: a **flat** object type (all scalar subfields) → a compact\n * editable TABLE (C); a richer/nested type → a card list with depth encoding (B),\n * summary-first collapse (D), and reduced per-row chrome (E). Editing stays in the\n * shared field form — no canvas escape (unlike `blocks`) — so props and document\n * fields share this control. Depth flows via {@link ArrayDepthContext}.\n */\nexport function ObjectField({\n field,\n value,\n onChange,\n readOnly,\n id,\n}: {\n field: ObjectFieldDef\n value: unknown\n onChange: (value: unknown) => void\n readOnly: boolean\n id: string\n}) {\n const depth = useArrayDepth()\n if (field.multiple === false) {\n return (\n <Card className={cn('border-l-2 p-3', depthRail(depth), depthTint(depth))}>\n <ArrayDepthContext.Provider value={depth + 1}>\n <ObjectItemForm\n fields={field.fields}\n value={asRecord(value)}\n readOnly={readOnly}\n idPrefix={id}\n onChange={onChange}\n />\n </ArrayDepthContext.Provider>\n </Card>\n )\n }\n const props = { field, value, onChange, readOnly, id, depth }\n return isTabularObjectType(field) ? <ObjectTableField {...props} /> : <ObjectCardList {...props} />\n}\n\ninterface ObjectArrayProps {\n field: ObjectFieldDef\n value: unknown\n onChange: (value: unknown) => void\n readOnly: boolean\n id: string\n depth: number\n}\n\n/**\n * (B + D + E) The card list for a nested/rich object array: depth-encoded cards\n * (coloured rail + tint), items collapsed by default to a scannable summary outline\n * (D), accordion expansion (open one → collapse siblings), and the per-row controls\n * collapsed into one overflow menu (E). Drag-to-reorder; arrows live in the menu for\n * a11y. Nested arrays render one depth deeper via the context provider.\n */\nfunction ObjectCardList({ field, value, onChange, readOnly, id, depth }: ObjectArrayProps) {\n const arr = useObjectArray(field, value, onChange)\n const { items, keys } = arr\n const parentPath = useFieldPath()\n const focus = useFieldFocusRequest()\n // (D) Default COLLAPSED: track which keys are EXPANDED (empty = all collapsed).\n // (B) Accordion: expanding one collapses the siblings.\n const [expandedKeys, setExpandedKeys] = useState<ReadonlySet<number>>(() => new Set())\n const toggle = (key: number) =>\n setExpandedKeys((prev) => {\n if (prev.has(key)) {\n const next = new Set(prev)\n next.delete(key)\n return next\n }\n return new Set([key])\n })\n const allExpanded = items.length > 0 && keys.every((k) => expandedKeys.has(k))\n const onAdd = () => setExpandedKeys(new Set([arr.addItem()]))\n // EC-443: a jump-to-field targeting a path INSIDE one of these items expands\n // that item (accordion semantics, like a manual open) so the deeper anchors can\n // render — nested levels cascade, each level's effect firing once its card\n // mounts. Keyed on the request nonce so re-clicking the same issue re-expands\n // a manually re-collapsed item.\n const focusPath = focus?.path\n const focusNonce = focus?.nonce\n useEffect(() => {\n if (parentPath === null || focusPath === undefined) return\n const index = items.findIndex((_, i) => isPathWithin(`${parentPath}/${i}`, focusPath))\n if (index < 0) return\n const key = keys[index]\n if (key !== undefined) setExpandedKeys(new Set([key]))\n // Deps: keys/items stay in lockstep (the C2 key↔value lock) — `items.length`\n // captures the structure; item-content identity must NOT re-trigger expansion.\n }, [focusNonce, focusPath, parentPath, items.length])\n return (\n <ArrayDepthContext.Provider value={depth + 1}>\n <Stack gap=\"2\">\n {items.length > 1 && !readOnly ? (\n <Row justify=\"end\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setExpandedKeys(allExpanded ? new Set() : new Set(keys))}\n >\n {translate(allExpanded ? 'cms.field.collapseAll' : 'cms.field.expandAll')}\n </Button>\n </Row>\n ) : null}\n {items.length === 0 ? (\n <Text size=\"sm\" tone=\"subtle\">\n {translate('cms.field.noItems')}\n </Text>\n ) : (\n items.map((item, i) => {\n // keysRef is reconciled to items.length, so keys[i] is always present;\n // `?? i` only satisfies noUncheckedIndexedAccess (never taken at runtime).\n const key = keys[i] ?? i\n const record = asRecord(item)\n const isExpanded = expandedKeys.has(key)\n // EC-443: the item's path anchor — stamped even while collapsed, so a\n // degraded jump can still land (and ring) on the closed card.\n const itemPath = parentPath === null ? undefined : `${parentPath}/${i}`\n return (\n <Card\n key={key}\n {...(itemPath !== undefined ? { [FIELD_PATH_ATTR]: itemPath } : {})}\n onDragOver={(e) => {\n if (arr.dragIndex === null) return\n e.preventDefault()\n if (arr.overIndex !== i) arr.setOverIndex(i)\n }}\n onDrop={() => arr.drop(i)}\n className={cn(\n 'border-l-2 p-0',\n depthRail(depth),\n depthTint(depth),\n arr.dragIndex === i ? 'opacity-50' : '',\n arr.overIndex === i && arr.dragIndex !== null && arr.dragIndex !== i\n ? 'border-l-primary ring-1 ring-primary/40'\n : '',\n itemPath !== undefined && focus?.path === itemPath\n ? 'ring-2 ring-primary/70'\n : '',\n )}\n >\n <Row className=\"select-none border-b border-border/60 bg-muted/20 px-2 py-1.5\">\n {!readOnly ? (\n <span\n draggable\n onDragStart={(e) => {\n e.dataTransfer.effectAllowed = 'move'\n e.dataTransfer.setData('text/plain', String(i))\n arr.setDragIndex(i)\n }}\n onDragEnd={arr.endDrag}\n aria-label={translate('cms.field.dragToReorder')}\n className=\"cursor-grab text-muted-foreground/50 hover:text-muted-foreground active:cursor-grabbing\"\n >\n <GripVertical className=\"size-3.5\" />\n </span>\n ) : null}\n <button\n type=\"button\"\n onClick={() => toggle(key)}\n aria-expanded={isExpanded}\n className=\"flex min-w-0 flex-1 items-center gap-1.5 text-left\"\n >\n <ChevronDown\n className={cn(\n 'size-3.5 shrink-0 text-muted-foreground transition-transform',\n isExpanded ? '' : '-rotate-90',\n )}\n aria-hidden\n />\n <Text size=\"sm\" className=\"min-w-0 truncate font-medium\">\n {objectItemSummary(field.fields, record, i)}\n </Text>\n </button>\n {!readOnly ? (\n <ItemOverflowMenu\n index={i}\n count={items.length}\n onMove={arr.move}\n onRemove={() => arr.removeAt(i)}\n />\n ) : null}\n </Row>\n {isExpanded ? (\n <div className=\"px-3 pb-3\">\n <FieldPathContext.Provider value={itemPath ?? null}>\n <ObjectItemForm\n fields={field.fields}\n value={record}\n readOnly={readOnly}\n idPrefix={`${id}-${i}`}\n onChange={(updated) => arr.setItem(i, updated)}\n />\n </FieldPathContext.Provider>\n </div>\n ) : null}\n </Card>\n )\n })\n )}\n {!readOnly ? (\n <Button variant=\"outline\" size=\"sm\" onClick={onAdd}>\n <Plus className=\"size-3\" /> {translate('cms.field.addItem')}\n </Button>\n ) : null}\n </Stack>\n </ArrayDepthContext.Provider>\n )\n}\n\n/**\n * (C) A compact editable table for a FLAT object array — columns are the scalar\n * subfields, one row per item. Kills the card-stack sprawl for the commonest case\n * (option lists, opening hours, social links). Drag-reorder + an overflow menu per\n * row; cells reuse {@link FieldControl} so each subfield keeps its native control.\n */\nfunction ObjectTableField({ field, value, onChange, readOnly, id, depth }: ObjectArrayProps) {\n const arr = useObjectArray(field, value, onChange)\n const { items, keys } = arr\n // EC-443: rows/cells stamp path anchors too (a tabular type is flat, so the\n // cell — `links/3/href` — is always the deepest possible anchor here).\n const parentPath = useFieldPath()\n const focus = useFieldFocusRequest()\n const cols = tableColumnsOf(field)\n const span = cols.length + (readOnly ? 0 : 2)\n return (\n <div className={cn('overflow-hidden rounded-md border border-border border-l-2', depthRail(depth), depthTint(depth))}>\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border/60 bg-muted/30 text-left\">\n {!readOnly ? <th className=\"w-7\" /> : null}\n {cols.map((c) => (\n <th key={c.name} className=\"px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n {fieldLabel(c)}\n {c.validation?.required ? <span className=\"text-destructive\"> *</span> : null}\n </th>\n ))}\n {!readOnly ? <th className=\"w-9\" /> : null}\n </tr>\n </thead>\n <tbody>\n {items.length === 0 ? (\n <tr>\n <td colSpan={span} className=\"px-2 py-2 text-muted-foreground\">\n <Text size=\"sm\" tone=\"subtle\">\n {translate('cms.field.noItems')}\n </Text>\n </td>\n </tr>\n ) : (\n items.map((item, i) => {\n const key = keys[i] ?? i\n const record = asRecord(item)\n const itemPath = parentPath === null ? undefined : `${parentPath}/${i}`\n return (\n <tr\n key={key}\n {...(itemPath !== undefined ? { [FIELD_PATH_ATTR]: itemPath } : {})}\n onDragOver={(e) => {\n if (arr.dragIndex === null) return\n e.preventDefault()\n if (arr.overIndex !== i) arr.setOverIndex(i)\n }}\n onDrop={() => arr.drop(i)}\n className={cn(\n 'border-b border-border/40 align-top last:border-0',\n arr.dragIndex === i ? 'opacity-50' : '',\n arr.overIndex === i && arr.dragIndex !== null && arr.dragIndex !== i\n ? 'bg-primary/5'\n : '',\n itemPath !== undefined && focus?.path === itemPath\n ? 'ring-2 ring-inset ring-primary/70'\n : '',\n )}\n >\n {!readOnly ? (\n <td className=\"px-1 py-1\">\n <span\n draggable\n onDragStart={(e) => {\n e.dataTransfer.effectAllowed = 'move'\n e.dataTransfer.setData('text/plain', String(i))\n arr.setDragIndex(i)\n }}\n onDragEnd={arr.endDrag}\n aria-label={translate('cms.field.dragToReorder')}\n className=\"inline-flex cursor-grab text-muted-foreground/50 hover:text-muted-foreground active:cursor-grabbing\"\n >\n <GripVertical className=\"size-3.5\" />\n </span>\n </td>\n ) : null}\n {cols.map((c) => {\n const cellPath = itemPath === undefined ? undefined : `${itemPath}/${c.name}`\n return (\n <td\n key={c.name}\n {...(cellPath !== undefined ? { [FIELD_PATH_ATTR]: cellPath } : {})}\n className={cn(\n 'px-2 py-1',\n cellPath !== undefined && focus?.path === cellPath\n ? 'bg-primary/5 ring-2 ring-inset ring-primary/70'\n : '',\n )}\n >\n <FieldControl\n id={`${id}-${i}-${c.name}`}\n field={c}\n value={record[c.name]}\n readOnly={isSubFieldReadOnly(readOnly, c)}\n onChange={(next) => {\n const updated = { ...record }\n if (next === undefined) delete updated[c.name]\n else updated[c.name] = next\n arr.setItem(i, updated)\n }}\n />\n </td>\n )\n })}\n {!readOnly ? (\n <td className=\"px-1 py-1\">\n <ItemOverflowMenu\n index={i}\n count={items.length}\n onMove={arr.move}\n onRemove={() => arr.removeAt(i)}\n />\n </td>\n ) : null}\n </tr>\n )\n })\n )}\n </tbody>\n </table>\n {!readOnly ? (\n <div className=\"border-t border-border/60 p-1.5\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => arr.addItem()}>\n <Plus className=\"size-3\" /> {translate('common.add')}\n </Button>\n </div>\n ) : null}\n </div>\n )\n}\n"]}
|
|
@@ -19,7 +19,7 @@ import type { PropField } from '@elytracms/core/component-registry';
|
|
|
19
19
|
* vocabulary derives from the field `type` plus the optional `form.control`
|
|
20
20
|
* presentation hint on `text` fields.
|
|
21
21
|
*/
|
|
22
|
-
export type ControlKind = 'text' | 'textarea' | 'number' | 'boolean' | 'select' | 'options' | 'json' | 'color' | 'richtext' | 'asset' | 'object' | 'relation';
|
|
22
|
+
export type ControlKind = 'text' | 'textarea' | 'number' | 'boolean' | 'select' | 'options' | 'json' | 'color' | 'richtext' | 'asset' | 'object' | 'relation' | 'date';
|
|
23
23
|
export declare function controlKind(spec: PropField): ControlKind;
|
|
24
24
|
/**
|
|
25
25
|
* The manifest `default` as the inspector's greyed HINT (EC-591, ratified 2f) — a
|
|
@@ -62,10 +62,15 @@ export interface PropValueControlProps {
|
|
|
62
62
|
* default applies, never the manifest `default` (a hint only).
|
|
63
63
|
*/
|
|
64
64
|
onClear: () => void;
|
|
65
|
+
/**
|
|
66
|
+
* The node's effective prop values (EC-582) — what a `validate` function and a
|
|
67
|
+
* `form.hidden` predicate read. Absent → judged against no siblings.
|
|
68
|
+
*/
|
|
69
|
+
siblings?: Readonly<Record<string, unknown>>;
|
|
65
70
|
}
|
|
66
71
|
/**
|
|
67
72
|
* Render + edit a single manifest prop value. Store-agnostic: emits through
|
|
68
73
|
* `onSet`/`onClear`. Shows a validation issue when the current value fails the
|
|
69
74
|
* prop's field-def validator.
|
|
70
75
|
*/
|
|
71
|
-
export declare function PropValueControl({ id, name, spec, value, onSet, onClear }: PropValueControlProps): import("react").JSX.Element;
|
|
76
|
+
export declare function PropValueControl({ id, name, spec, value, onSet, onClear, siblings }: PropValueControlProps): import("react").JSX.Element;
|