@elytracms/studio 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +3 -0
- package/convex/assets.ts +107 -0
- package/convex/auth.config.ts +15 -0
- package/convex/auth.ts +50 -0
- package/convex/cliTokens.ts +63 -0
- package/convex/cms.ts +174 -0
- package/convex/content.ts +316 -0
- package/convex/delivery.ts +266 -0
- package/convex/functions.ts +35 -0
- package/convex/graphs.ts +51 -0
- package/convex/guard.ts +67 -0
- package/convex/http.ts +30 -0
- package/convex/members.ts +83 -0
- package/convex/publishing.ts +102 -0
- package/convex/references.ts +168 -0
- package/convex/schema.ts +173 -0
- package/convex/sync.ts +322 -0
- package/convex/tsconfig.json +12 -0
- package/convex/users.ts +23 -0
- package/convex/webhooks.ts +85 -0
- package/dist/components/assets/asset-library.d.ts +14 -0
- package/dist/components/assets/asset-library.js +191 -0
- package/dist/components/assets/asset-library.js.map +1 -0
- package/dist/components/assets/asset-metadata.d.ts +34 -0
- package/dist/components/assets/asset-metadata.js +40 -0
- package/dist/components/assets/asset-metadata.js.map +1 -0
- package/dist/components/assets/asset-search.d.ts +7 -0
- package/dist/components/assets/asset-search.js +12 -0
- package/dist/components/assets/asset-search.js.map +1 -0
- package/dist/components/assets/asset-selection.d.ts +17 -0
- package/dist/components/assets/asset-selection.js +33 -0
- package/dist/components/assets/asset-selection.js.map +1 -0
- package/dist/components/assets/assets-store.d.ts +51 -0
- package/dist/components/assets/assets-store.js +153 -0
- package/dist/components/assets/assets-store.js.map +1 -0
- package/dist/components/auth-context.d.ts +38 -0
- package/dist/components/auth-context.js +88 -0
- package/dist/components/auth-context.js.map +1 -0
- package/dist/components/backend-gate.d.ts +19 -0
- package/dist/components/backend-gate.js +63 -0
- package/dist/components/backend-gate.js.map +1 -0
- package/dist/components/breadcrumb-context.d.ts +39 -0
- package/dist/components/breadcrumb-context.js +38 -0
- package/dist/components/breadcrumb-context.js.map +1 -0
- package/dist/components/builder/blocks-model.d.ts +80 -0
- package/dist/components/builder/blocks-model.js +181 -0
- package/dist/components/builder/blocks-model.js.map +1 -0
- package/dist/components/builder/blocks-panel.d.ts +44 -0
- package/dist/components/builder/blocks-panel.js +147 -0
- package/dist/components/builder/blocks-panel.js.map +1 -0
- package/dist/components/builder/builder-store.d.ts +69 -0
- package/dist/components/builder/builder-store.js +294 -0
- package/dist/components/builder/builder-store.js.map +1 -0
- package/dist/components/builder/canvas-stylesheet.d.ts +4 -0
- package/dist/components/builder/canvas-stylesheet.js +24 -0
- package/dist/components/builder/canvas-stylesheet.js.map +1 -0
- package/dist/components/builder/canvas.d.ts +8 -0
- package/dist/components/builder/canvas.js +723 -0
- package/dist/components/builder/canvas.js.map +1 -0
- package/dist/components/builder/clipboard-actions.d.ts +93 -0
- package/dist/components/builder/clipboard-actions.js +246 -0
- package/dist/components/builder/clipboard-actions.js.map +1 -0
- package/dist/components/builder/composition-field-editor.d.ts +11 -0
- package/dist/components/builder/composition-field-editor.js +150 -0
- package/dist/components/builder/composition-field-editor.js.map +1 -0
- package/dist/components/builder/composition-scope.d.ts +16 -0
- package/dist/components/builder/composition-scope.js +7 -0
- package/dist/components/builder/composition-scope.js.map +1 -0
- package/dist/components/builder/drag-session.d.ts +41 -0
- package/dist/components/builder/drag-session.js +51 -0
- package/dist/components/builder/drag-session.js.map +1 -0
- package/dist/components/builder/fixture-thumbnail.d.ts +18 -0
- package/dist/components/builder/fixture-thumbnail.js +97 -0
- package/dist/components/builder/fixture-thumbnail.js.map +1 -0
- package/dist/components/builder/inline-edit.d.ts +142 -0
- package/dist/components/builder/inline-edit.js +136 -0
- package/dist/components/builder/inline-edit.js.map +1 -0
- package/dist/components/builder/insert-context.d.ts +14 -0
- package/dist/components/builder/insert-context.js +65 -0
- package/dist/components/builder/insert-context.js.map +1 -0
- package/dist/components/builder/insert-menu.d.ts +9 -0
- package/dist/components/builder/insert-menu.js +9 -0
- package/dist/components/builder/insert-menu.js.map +1 -0
- package/dist/components/builder/layout-inspector.d.ts +14 -0
- package/dist/components/builder/layout-inspector.js +84 -0
- package/dist/components/builder/layout-inspector.js.map +1 -0
- package/dist/components/builder/node-factory.d.ts +17 -0
- package/dist/components/builder/node-factory.js +90 -0
- package/dist/components/builder/node-factory.js.map +1 -0
- package/dist/components/builder/page-tree.d.ts +3 -0
- package/dist/components/builder/page-tree.js +207 -0
- package/dist/components/builder/page-tree.js.map +1 -0
- package/dist/components/builder/property-inspector.d.ts +1 -0
- package/dist/components/builder/property-inspector.js +233 -0
- package/dist/components/builder/property-inspector.js.map +1 -0
- package/dist/components/builder/rich-text-toolbar.d.ts +4 -0
- package/dist/components/builder/rich-text-toolbar.js +104 -0
- package/dist/components/builder/rich-text-toolbar.js.map +1 -0
- package/dist/components/builder/spacing-handles.d.ts +22 -0
- package/dist/components/builder/spacing-handles.js +213 -0
- package/dist/components/builder/spacing-handles.js.map +1 -0
- package/dist/components/cms/asset-picker.d.ts +12 -0
- package/dist/components/cms/asset-picker.js +60 -0
- package/dist/components/cms/asset-picker.js.map +1 -0
- package/dist/components/cms/bulk-actions.d.ts +60 -0
- package/dist/components/cms/bulk-actions.js +95 -0
- package/dist/components/cms/bulk-actions.js.map +1 -0
- package/dist/components/cms/bulk-bar.d.ts +23 -0
- package/dist/components/cms/bulk-bar.js +26 -0
- package/dist/components/cms/bulk-bar.js.map +1 -0
- package/dist/components/cms/cell-edit.d.ts +91 -0
- package/dist/components/cms/cell-edit.js +144 -0
- package/dist/components/cms/cell-edit.js.map +1 -0
- package/dist/components/cms/cell.d.ts +29 -0
- package/dist/components/cms/cell.js +127 -0
- package/dist/components/cms/cell.js.map +1 -0
- package/dist/components/cms/cms-index.d.ts +8 -0
- package/dist/components/cms/cms-index.js +23 -0
- package/dist/components/cms/cms-index.js.map +1 -0
- package/dist/components/cms/cms-store.d.ts +188 -0
- package/dist/components/cms/cms-store.js +702 -0
- package/dist/components/cms/cms-store.js.map +1 -0
- package/dist/components/cms/collection-table.d.ts +6 -0
- package/dist/components/cms/collection-table.js +250 -0
- package/dist/components/cms/collection-table.js.map +1 -0
- package/dist/components/cms/collections-sidebar.d.ts +9 -0
- package/dist/components/cms/collections-sidebar.js +25 -0
- package/dist/components/cms/collections-sidebar.js.map +1 -0
- package/dist/components/cms/detail-editor.d.ts +7 -0
- package/dist/components/cms/detail-editor.js +386 -0
- package/dist/components/cms/detail-editor.js.map +1 -0
- package/dist/components/cms/doc-state.d.ts +13 -0
- package/dist/components/cms/doc-state.js +18 -0
- package/dist/components/cms/doc-state.js.map +1 -0
- package/dist/components/cms/document-editor-context.d.ts +48 -0
- package/dist/components/cms/document-editor-context.js +23 -0
- package/dist/components/cms/document-editor-context.js.map +1 -0
- package/dist/components/cms/editable-cell.d.ts +22 -0
- package/dist/components/cms/editable-cell.js +176 -0
- package/dist/components/cms/editable-cell.js.map +1 -0
- package/dist/components/cms/field-control.d.ts +8 -0
- package/dist/components/cms/field-control.js +149 -0
- package/dist/components/cms/field-control.js.map +1 -0
- package/dist/components/cms/filter-builder.d.ts +12 -0
- package/dist/components/cms/filter-builder.js +84 -0
- package/dist/components/cms/filter-builder.js.map +1 -0
- package/dist/components/cms/import-export.d.ts +6 -0
- package/dist/components/cms/import-export.js +33 -0
- package/dist/components/cms/import-export.js.map +1 -0
- package/dist/components/cms/new-page-dialog.d.ts +22 -0
- package/dist/components/cms/new-page-dialog.js +42 -0
- package/dist/components/cms/new-page-dialog.js.map +1 -0
- package/dist/components/cms/reference-confirm.d.ts +25 -0
- package/dist/components/cms/reference-confirm.js +124 -0
- package/dist/components/cms/reference-confirm.js.map +1 -0
- package/dist/components/cms/relation-picker.d.ts +16 -0
- package/dist/components/cms/relation-picker.js +47 -0
- package/dist/components/cms/relation-picker.js.map +1 -0
- package/dist/components/cms/use-cell-edit.d.ts +33 -0
- package/dist/components/cms/use-cell-edit.js +125 -0
- package/dist/components/cms/use-cell-edit.js.map +1 -0
- package/dist/components/cms/versions-model.d.ts +15 -0
- package/dist/components/cms/versions-model.js +23 -0
- package/dist/components/cms/versions-model.js.map +1 -0
- package/dist/components/cms/versions-pane.d.ts +14 -0
- package/dist/components/cms/versions-pane.js +86 -0
- package/dist/components/cms/versions-pane.js.map +1 -0
- package/dist/components/cms/view-bar.d.ts +11 -0
- package/dist/components/cms/view-bar.js +80 -0
- package/dist/components/cms/view-bar.js.map +1 -0
- package/dist/components/collab/collab-context.d.ts +34 -0
- package/dist/components/collab/collab-context.js +52 -0
- package/dist/components/collab/collab-context.js.map +1 -0
- package/dist/components/collab/collab-seed.d.ts +27 -0
- package/dist/components/collab/collab-seed.js +42 -0
- package/dist/components/collab/collab-seed.js.map +1 -0
- package/dist/components/components/component-detail.d.ts +9 -0
- package/dist/components/components/component-detail.js +30 -0
- package/dist/components/components/component-detail.js.map +1 -0
- package/dist/components/components/component-status.d.ts +10 -0
- package/dist/components/components/component-status.js +30 -0
- package/dist/components/components/component-status.js.map +1 -0
- package/dist/components/components/components-index.d.ts +8 -0
- package/dist/components/components/components-index.js +42 -0
- package/dist/components/components/components-index.js.map +1 -0
- package/dist/components/components/field-inspector.d.ts +9 -0
- package/dist/components/components/field-inspector.js +38 -0
- package/dist/components/components/field-inspector.js.map +1 -0
- package/dist/components/components/fixture-runner.d.ts +10 -0
- package/dist/components/components/fixture-runner.js +24 -0
- package/dist/components/components/fixture-runner.js.map +1 -0
- package/dist/components/components/registry-browser.d.ts +4 -0
- package/dist/components/components/registry-browser.js +64 -0
- package/dist/components/components/registry-browser.js.map +1 -0
- package/dist/components/current-user-menu.d.ts +13 -0
- package/dist/components/current-user-menu.js +31 -0
- package/dist/components/current-user-menu.js.map +1 -0
- package/dist/components/dev-login-badge.d.ts +9 -0
- package/dist/components/dev-login-badge.js +18 -0
- package/dist/components/dev-login-badge.js.map +1 -0
- package/dist/components/extensions/extensions-view.d.ts +7 -0
- package/dist/components/extensions/extensions-view.js +126 -0
- package/dist/components/extensions/extensions-view.js.map +1 -0
- package/dist/components/guards.d.ts +27 -0
- package/dist/components/guards.js +46 -0
- package/dist/components/guards.js.map +1 -0
- package/dist/components/inspector/inspector-sidebar.d.ts +26 -0
- package/dist/components/inspector/inspector-sidebar.js +17 -0
- package/dist/components/inspector/inspector-sidebar.js.map +1 -0
- package/dist/components/operation-error.d.ts +17 -0
- package/dist/components/operation-error.js +54 -0
- package/dist/components/operation-error.js.map +1 -0
- package/dist/components/playground-badge.d.ts +10 -0
- package/dist/components/playground-badge.js +19 -0
- package/dist/components/playground-badge.js.map +1 -0
- package/dist/components/project-list.d.ts +15 -0
- package/dist/components/project-list.js +52 -0
- package/dist/components/project-list.js.map +1 -0
- package/dist/components/project-session.d.ts +46 -0
- package/dist/components/project-session.js +107 -0
- package/dist/components/project-session.js.map +1 -0
- package/dist/components/project-switcher.d.ts +11 -0
- package/dist/components/project-switcher.js +44 -0
- package/dist/components/project-switcher.js.map +1 -0
- package/dist/components/references/builder-deep-link.d.ts +12 -0
- package/dist/components/references/builder-deep-link.js +53 -0
- package/dist/components/references/builder-deep-link.js.map +1 -0
- package/dist/components/references/references-panel.d.ts +17 -0
- package/dist/components/references/references-panel.js +66 -0
- package/dist/components/references/references-panel.js.map +1 -0
- package/dist/components/routes/redirect-chain.d.ts +9 -0
- package/dist/components/routes/redirect-chain.js +16 -0
- package/dist/components/routes/redirect-chain.js.map +1 -0
- package/dist/components/routes/redirect-manager.d.ts +13 -0
- package/dist/components/routes/redirect-manager.js +24 -0
- package/dist/components/routes/redirect-manager.js.map +1 -0
- package/dist/components/routes/route-list.d.ts +35 -0
- package/dist/components/routes/route-list.js +69 -0
- package/dist/components/routes/route-list.js.map +1 -0
- package/dist/components/routes/routes-shell.d.ts +14 -0
- package/dist/components/routes/routes-shell.js +68 -0
- package/dist/components/routes/routes-shell.js.map +1 -0
- package/dist/components/section-nav.d.ts +17 -0
- package/dist/components/section-nav.js +33 -0
- package/dist/components/section-nav.js.map +1 -0
- package/dist/components/section-state.d.ts +24 -0
- package/dist/components/section-state.js +78 -0
- package/dist/components/section-state.js.map +1 -0
- package/dist/components/section-surface.d.ts +31 -0
- package/dist/components/section-surface.js +46 -0
- package/dist/components/section-surface.js.map +1 -0
- package/dist/components/sections.d.ts +38 -0
- package/dist/components/sections.js +72 -0
- package/dist/components/sections.js.map +1 -0
- package/dist/components/settings-form.d.ts +10 -0
- package/dist/components/settings-form.js +17 -0
- package/dist/components/settings-form.js.map +1 -0
- package/dist/components/studio-context.d.ts +22 -0
- package/dist/components/studio-context.js +48 -0
- package/dist/components/studio-context.js.map +1 -0
- package/dist/components/studio-project-screen.d.ts +19 -0
- package/dist/components/studio-project-screen.js +195 -0
- package/dist/components/studio-project-screen.js.map +1 -0
- package/dist/components/studio-shell.d.ts +18 -0
- package/dist/components/studio-shell.js +64 -0
- package/dist/components/studio-shell.js.map +1 -0
- package/dist/components/theme-context.d.ts +17 -0
- package/dist/components/theme-context.js +26 -0
- package/dist/components/theme-context.js.map +1 -0
- package/dist/components/workspace-gate.d.ts +12 -0
- package/dist/components/workspace-gate.js +27 -0
- package/dist/components/workspace-gate.js.map +1 -0
- package/dist/components/workspace-projects.d.ts +13 -0
- package/dist/components/workspace-projects.js +18 -0
- package/dist/components/workspace-projects.js.map +1 -0
- package/dist/lib/assets/delete-asset.d.ts +34 -0
- package/dist/lib/assets/delete-asset.js +34 -0
- package/dist/lib/assets/delete-asset.js.map +1 -0
- package/dist/lib/assets/image-dimensions.d.ts +18 -0
- package/dist/lib/assets/image-dimensions.js +26 -0
- package/dist/lib/assets/image-dimensions.js.map +1 -0
- package/dist/lib/assets/index.d.ts +9 -0
- package/dist/lib/assets/index.js +10 -0
- package/dist/lib/assets/index.js.map +1 -0
- package/dist/lib/assets/upload-state.d.ts +53 -0
- package/dist/lib/assets/upload-state.js +59 -0
- package/dist/lib/assets/upload-state.js.map +1 -0
- package/dist/lib/assets/upload.d.ts +56 -0
- package/dist/lib/assets/upload.js +125 -0
- package/dist/lib/assets/upload.js.map +1 -0
- package/dist/lib/auth/auth-adapter.d.ts +57 -0
- package/dist/lib/auth/auth-adapter.js +13 -0
- package/dist/lib/auth/auth-adapter.js.map +1 -0
- package/dist/lib/auth/convex-auth-adapter.d.ts +39 -0
- package/dist/lib/auth/convex-auth-adapter.js +171 -0
- package/dist/lib/auth/convex-auth-adapter.js.map +1 -0
- package/dist/lib/auth/dev-auto-login-adapter.d.ts +25 -0
- package/dist/lib/auth/dev-auto-login-adapter.js +40 -0
- package/dist/lib/auth/dev-auto-login-adapter.js.map +1 -0
- package/dist/lib/auth/index.d.ts +28 -0
- package/dist/lib/auth/index.js +61 -0
- package/dist/lib/auth/index.js.map +1 -0
- package/dist/lib/auth/local-auth-adapter.d.ts +57 -0
- package/dist/lib/auth/local-auth-adapter.js +78 -0
- package/dist/lib/auth/local-auth-adapter.js.map +1 -0
- package/dist/lib/auth/route-guard.d.ts +33 -0
- package/dist/lib/auth/route-guard.js +51 -0
- package/dist/lib/auth/route-guard.js.map +1 -0
- package/dist/lib/auth-errors.d.ts +42 -0
- package/dist/lib/auth-errors.js +74 -0
- package/dist/lib/auth-errors.js.map +1 -0
- package/dist/lib/bindings/section-bindings.d.ts +24 -0
- package/dist/lib/bindings/section-bindings.js +9 -0
- package/dist/lib/bindings/section-bindings.js.map +1 -0
- package/dist/lib/clipboard/index.d.ts +7 -0
- package/dist/lib/clipboard/index.js +8 -0
- package/dist/lib/clipboard/index.js.map +1 -0
- package/dist/lib/clipboard/os-clipboard.d.ts +46 -0
- package/dist/lib/clipboard/os-clipboard.js +105 -0
- package/dist/lib/clipboard/os-clipboard.js.map +1 -0
- package/dist/lib/clipboard/paste-issues.d.ts +34 -0
- package/dist/lib/clipboard/paste-issues.js +67 -0
- package/dist/lib/clipboard/paste-issues.js.map +1 -0
- package/dist/lib/clipboard/paste-target.d.ts +20 -0
- package/dist/lib/clipboard/paste-target.js +28 -0
- package/dist/lib/clipboard/paste-target.js.map +1 -0
- package/dist/lib/cms/published-documents.d.ts +30 -0
- package/dist/lib/cms/published-documents.js +75 -0
- package/dist/lib/cms/published-documents.js.map +1 -0
- package/dist/lib/cms-views/index.d.ts +9 -0
- package/dist/lib/cms-views/index.js +10 -0
- package/dist/lib/cms-views/index.js.map +1 -0
- package/dist/lib/cms-views/selection.d.ts +29 -0
- package/dist/lib/cms-views/selection.js +46 -0
- package/dist/lib/cms-views/selection.js.map +1 -0
- package/dist/lib/cms-views/view-model.d.ts +192 -0
- package/dist/lib/cms-views/view-model.js +353 -0
- package/dist/lib/cms-views/view-model.js.map +1 -0
- package/dist/lib/cms-views/views-store.d.ts +70 -0
- package/dist/lib/cms-views/views-store.js +129 -0
- package/dist/lib/cms-views/views-store.js.map +1 -0
- package/dist/lib/data/collection-content.d.ts +105 -0
- package/dist/lib/data/collection-content.js +196 -0
- package/dist/lib/data/collection-content.js.map +1 -0
- package/dist/lib/data/data-store.d.ts +97 -0
- package/dist/lib/data/data-store.js +205 -0
- package/dist/lib/data/data-store.js.map +1 -0
- package/dist/lib/data/index.d.ts +4 -0
- package/dist/lib/data/index.js +8 -0
- package/dist/lib/data/index.js.map +1 -0
- package/dist/lib/data/providers.d.ts +143 -0
- package/dist/lib/data/providers.js +255 -0
- package/dist/lib/data/providers.js.map +1 -0
- package/dist/lib/data/sample-capture.d.ts +30 -0
- package/dist/lib/data/sample-capture.js +70 -0
- package/dist/lib/data/sample-capture.js.map +1 -0
- package/dist/lib/data/sources-store.d.ts +42 -0
- package/dist/lib/data/sources-store.js +120 -0
- package/dist/lib/data/sources-store.js.map +1 -0
- package/dist/lib/dnd/drop-rules.d.ts +219 -0
- package/dist/lib/dnd/drop-rules.js +257 -0
- package/dist/lib/dnd/drop-rules.js.map +1 -0
- package/dist/lib/dnd/gap-drag.d.ts +66 -0
- package/dist/lib/dnd/gap-drag.js +95 -0
- package/dist/lib/dnd/gap-drag.js.map +1 -0
- package/dist/lib/locale/binding-fallback.d.ts +28 -0
- package/dist/lib/locale/binding-fallback.js +66 -0
- package/dist/lib/locale/binding-fallback.js.map +1 -0
- package/dist/lib/locale/fallback.d.ts +43 -0
- package/dist/lib/locale/fallback.js +52 -0
- package/dist/lib/locale/fallback.js.map +1 -0
- package/dist/lib/locale/index.d.ts +6 -0
- package/dist/lib/locale/index.js +7 -0
- package/dist/lib/locale/index.js.map +1 -0
- package/dist/lib/locale/locale-store.d.ts +40 -0
- package/dist/lib/locale/locale-store.js +61 -0
- package/dist/lib/locale/locale-store.js.map +1 -0
- package/dist/lib/locale/locale-switcher.d.ts +10 -0
- package/dist/lib/locale/locale-switcher.js +24 -0
- package/dist/lib/locale/locale-switcher.js.map +1 -0
- package/dist/lib/locale/route-variant.d.ts +14 -0
- package/dist/lib/locale/route-variant.js +11 -0
- package/dist/lib/locale/route-variant.js.map +1 -0
- package/dist/lib/locale/use-studio-locale.d.ts +10 -0
- package/dist/lib/locale/use-studio-locale.js +8 -0
- package/dist/lib/locale/use-studio-locale.js.map +1 -0
- package/dist/lib/operations/asset-repository.d.ts +15 -0
- package/dist/lib/operations/asset-repository.js +56 -0
- package/dist/lib/operations/asset-repository.js.map +1 -0
- package/dist/lib/operations/cms-persistence.d.ts +35 -0
- package/dist/lib/operations/cms-persistence.js +75 -0
- package/dist/lib/operations/cms-persistence.js.map +1 -0
- package/dist/lib/operations/graph-commands.d.ts +140 -0
- package/dist/lib/operations/graph-commands.js +86 -0
- package/dist/lib/operations/graph-commands.js.map +1 -0
- package/dist/lib/operations/graph-persistence.d.ts +27 -0
- package/dist/lib/operations/graph-persistence.js +35 -0
- package/dist/lib/operations/graph-persistence.js.map +1 -0
- package/dist/lib/operations/index.d.ts +13 -0
- package/dist/lib/operations/index.js +14 -0
- package/dist/lib/operations/index.js.map +1 -0
- package/dist/lib/operations/operations-package.d.ts +6 -0
- package/dist/lib/operations/operations-package.js +7 -0
- package/dist/lib/operations/operations-package.js.map +1 -0
- package/dist/lib/operations/persist-queue.d.ts +16 -0
- package/dist/lib/operations/persist-queue.js +18 -0
- package/dist/lib/operations/persist-queue.js.map +1 -0
- package/dist/lib/operations/session-hydration.d.ts +84 -0
- package/dist/lib/operations/session-hydration.js +112 -0
- package/dist/lib/operations/session-hydration.js.map +1 -0
- package/dist/lib/operations/studio-operations.d.ts +59 -0
- package/dist/lib/operations/studio-operations.js +92 -0
- package/dist/lib/operations/studio-operations.js.map +1 -0
- package/dist/lib/persistence/backend-mode.d.ts +69 -0
- package/dist/lib/persistence/backend-mode.js +120 -0
- package/dist/lib/persistence/backend-mode.js.map +1 -0
- package/dist/lib/persistence/convex-adapter.d.ts +34 -0
- package/dist/lib/persistence/convex-adapter.js +681 -0
- package/dist/lib/persistence/convex-adapter.js.map +1 -0
- package/dist/lib/persistence/convex-blob-storage.d.ts +57 -0
- package/dist/lib/persistence/convex-blob-storage.js +97 -0
- package/dist/lib/persistence/convex-blob-storage.js.map +1 -0
- package/dist/lib/persistence/convex-client.d.ts +19 -0
- package/dist/lib/persistence/convex-client.js +40 -0
- package/dist/lib/persistence/convex-client.js.map +1 -0
- package/dist/lib/persistence/index.d.ts +30 -0
- package/dist/lib/persistence/index.js +60 -0
- package/dist/lib/persistence/index.js.map +1 -0
- package/dist/lib/persona/labels.d.ts +23 -0
- package/dist/lib/persona/labels.js +122 -0
- package/dist/lib/persona/labels.js.map +1 -0
- package/dist/lib/rail.d.ts +11 -0
- package/dist/lib/rail.js +26 -0
- package/dist/lib/rail.js.map +1 -0
- package/dist/lib/references/impact.d.ts +64 -0
- package/dist/lib/references/impact.js +62 -0
- package/dist/lib/references/impact.js.map +1 -0
- package/dist/lib/references/index.d.ts +7 -0
- package/dist/lib/references/index.js +8 -0
- package/dist/lib/references/index.js.map +1 -0
- package/dist/lib/references/reference-model.d.ts +125 -0
- package/dist/lib/references/reference-model.js +242 -0
- package/dist/lib/references/reference-model.js.map +1 -0
- package/dist/lib/references/references-store.d.ts +65 -0
- package/dist/lib/references/references-store.js +221 -0
- package/dist/lib/references/references-store.js.map +1 -0
- package/dist/lib/registry/index.d.ts +65 -0
- package/dist/lib/registry/index.js +114 -0
- package/dist/lib/registry/index.js.map +1 -0
- package/dist/lib/registry/preview.d.ts +15 -0
- package/dist/lib/registry/preview.js +110 -0
- package/dist/lib/registry/preview.js.map +1 -0
- package/dist/lib/registry/project-components.d.ts +16 -0
- package/dist/lib/registry/project-components.js +152 -0
- package/dist/lib/registry/project-components.js.map +1 -0
- package/dist/lib/routing/index.d.ts +10 -0
- package/dist/lib/routing/index.js +11 -0
- package/dist/lib/routing/index.js.map +1 -0
- package/dist/lib/routing/routing-analysis.d.ts +26 -0
- package/dist/lib/routing/routing-analysis.js +37 -0
- package/dist/lib/routing/routing-analysis.js.map +1 -0
- package/dist/lib/routing/routing-store.d.ts +50 -0
- package/dist/lib/routing/routing-store.js +72 -0
- package/dist/lib/routing/routing-store.js.map +1 -0
- package/dist/lib/starters/kit-session.d.ts +5 -0
- package/dist/lib/starters/kit-session.js +17 -0
- package/dist/lib/starters/kit-session.js.map +1 -0
- package/dist/lib/theme.d.ts +21 -0
- package/dist/lib/theme.js +32 -0
- package/dist/lib/theme.js.map +1 -0
- package/dist/lib/utils.d.ts +11 -0
- package/dist/lib/utils.js +28 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/lib/webhooks/config.d.ts +15 -0
- package/dist/lib/webhooks/config.js +64 -0
- package/dist/lib/webhooks/config.js.map +1 -0
- package/dist/lib/webhooks/dispatcher.d.ts +67 -0
- package/dist/lib/webhooks/dispatcher.js +61 -0
- package/dist/lib/webhooks/dispatcher.js.map +1 -0
- package/dist/lib/webhooks/index.d.ts +11 -0
- package/dist/lib/webhooks/index.js +10 -0
- package/dist/lib/webhooks/index.js.map +1 -0
- package/dist/lib/webhooks/signing.d.ts +15 -0
- package/dist/lib/webhooks/signing.js +24 -0
- package/dist/lib/webhooks/signing.js.map +1 -0
- package/dist/lib/webhooks/tags.d.ts +25 -0
- package/dist/lib/webhooks/tags.js +173 -0
- package/dist/lib/webhooks/tags.js.map +1 -0
- package/dist/lib/working-graph.d.ts +82 -0
- package/dist/lib/working-graph.js +113 -0
- package/dist/lib/working-graph.js.map +1 -0
- package/dist/lib/workspace/index.d.ts +109 -0
- package/dist/lib/workspace/index.js +206 -0
- package/dist/lib/workspace/index.js.map +1 -0
- package/dist/lib/workspace/switcher-source.d.ts +39 -0
- package/dist/lib/workspace/switcher-source.js +23 -0
- package/dist/lib/workspace/switcher-source.js.map +1 -0
- package/dist/lib/workspace/workspace-source.d.ts +47 -0
- package/dist/lib/workspace/workspace-source.js +67 -0
- package/dist/lib/workspace/workspace-source.js.map +1 -0
- package/dist/router/index.d.ts +32 -0
- package/dist/router/index.js +32 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/match.d.ts +75 -0
- package/dist/router/match.js +87 -0
- package/dist/router/match.js.map +1 -0
- package/dist/router/search.d.ts +22 -0
- package/dist/router/search.js +16 -0
- package/dist/router/search.js.map +1 -0
- package/dist/ui/avatar.d.ts +17 -0
- package/dist/ui/avatar.js +38 -0
- package/dist/ui/avatar.js.map +1 -0
- package/dist/ui/badge.d.ts +9 -0
- package/dist/ui/badge.js +23 -0
- package/dist/ui/badge.js.map +1 -0
- package/dist/ui/button.d.ts +11 -0
- package/dist/ui/button.js +30 -0
- package/dist/ui/button.js.map +1 -0
- package/dist/ui/card.d.ts +11 -0
- package/dist/ui/card.js +23 -0
- package/dist/ui/card.js.map +1 -0
- package/dist/ui/dialog.d.ts +12 -0
- package/dist/ui/dialog.js +27 -0
- package/dist/ui/dialog.js.map +1 -0
- package/dist/ui/dropdown-menu.d.ts +15 -0
- package/dist/ui/dropdown-menu.js +24 -0
- package/dist/ui/dropdown-menu.js.map +1 -0
- package/dist/ui/field.d.ts +15 -0
- package/dist/ui/field.js +14 -0
- package/dist/ui/field.js.map +1 -0
- package/dist/ui/index.d.ts +14 -0
- package/dist/ui/index.js +15 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/input.d.ts +3 -0
- package/dist/ui/input.js +7 -0
- package/dist/ui/input.js.map +1 -0
- package/dist/ui/inspector.d.ts +18 -0
- package/dist/ui/inspector.js +14 -0
- package/dist/ui/inspector.js.map +1 -0
- package/dist/ui/layout.d.ts +45 -0
- package/dist/ui/layout.js +48 -0
- package/dist/ui/layout.js.map +1 -0
- package/dist/ui/panel.d.ts +12 -0
- package/dist/ui/panel.js +20 -0
- package/dist/ui/panel.js.map +1 -0
- package/dist/ui/separator.d.ts +6 -0
- package/dist/ui/separator.js +7 -0
- package/dist/ui/separator.js.map +1 -0
- package/dist/ui/toolbar.d.ts +9 -0
- package/dist/ui/toolbar.js +16 -0
- package/dist/ui/toolbar.js.map +1 -0
- package/dist/ui/typography.d.ts +50 -0
- package/dist/ui/typography.js +43 -0
- package/dist/ui/typography.js.map +1 -0
- package/package.json +149 -0
- package/src/styles/studio.css +101 -0
- package/src/styles/tokens.css +63 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { STUDIO_PROJECT_ROUTE, studioPath, useNavigate } from '@elytracms/studio/router';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { Button, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Field, Input, Stack, } from '@elytracms/studio/ui';
|
|
5
|
+
import { useCms } from './cms-store';
|
|
6
|
+
/**
|
|
7
|
+
* Create a page in ONE action (EC-192). Pages are documents in the `page`
|
|
8
|
+
* collection (EC-187): this dialog mints the page document (stable slug id,
|
|
9
|
+
* `cms.createPage`) and opens the new page's editor.
|
|
10
|
+
*
|
|
11
|
+
* EC-207 ("routes as code"): creating a page no longer persists an addressing
|
|
12
|
+
* route to the backend — routes are authored in `elytra.config.ts` and read
|
|
13
|
+
* from the resolved config, never written to or read from the DB. The page's
|
|
14
|
+
* URL is bound by a route in the consuming repo's `cms/routes.ts`, so this
|
|
15
|
+
* dialog only creates the page document.
|
|
16
|
+
*/
|
|
17
|
+
export function NewPageDialog({ projectId, open, onOpenChange, }) {
|
|
18
|
+
const cms = useCms();
|
|
19
|
+
const navigate = useNavigate();
|
|
20
|
+
const [name, setName] = useState('');
|
|
21
|
+
function reset() {
|
|
22
|
+
setName('');
|
|
23
|
+
}
|
|
24
|
+
function handleOpenChange(next) {
|
|
25
|
+
if (!next)
|
|
26
|
+
reset();
|
|
27
|
+
onOpenChange(next);
|
|
28
|
+
}
|
|
29
|
+
function submit(event) {
|
|
30
|
+
event.preventDefault();
|
|
31
|
+
if (name.trim() === '')
|
|
32
|
+
return;
|
|
33
|
+
const ref = cms.createPage({ name: name.trim() });
|
|
34
|
+
handleOpenChange(false);
|
|
35
|
+
void navigate({
|
|
36
|
+
to: STUDIO_PROJECT_ROUTE,
|
|
37
|
+
params: { projectId, _splat: studioPath.cmsDocument('page', ref.id) },
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return (_jsx(Dialog, { open: open, onOpenChange: handleOpenChange, children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "New page" }), _jsx(DialogDescription, { children: "Give the page a name. You can design it next; its address is set in elytra.config.ts." })] }), _jsxs("form", { onSubmit: submit, children: [_jsx(Stack, { gap: "3", children: _jsx(Field, { label: "Name", htmlFor: "new-page-name", required: true, children: _jsx(Input, { id: "new-page-name", value: name, onChange: (event) => setName(event.target.value), placeholder: "About us", autoFocus: true, required: true }) }) }), _jsxs(DialogFooter, { className: "mt-4", children: [_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => handleOpenChange(false), children: "Cancel" }), _jsx(Button, { type: "submit", size: "sm", disabled: name.trim() === '', "data-testid": "create-page", children: "Create page" })] })] })] }) }));
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=new-page-dialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"new-page-dialog.js","sourceRoot":"","sources":["../../../src/components/cms/new-page-dialog.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACxF,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEhC,OAAO,EACL,MAAM,EACN,MAAM,EACN,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,KAAK,EACL,KAAK,EACL,KAAK,GACN,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,SAAS,EACT,IAAI,EACJ,YAAY,GAWb;IACC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAA;IACpB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAEpC,SAAS,KAAK;QACZ,OAAO,CAAC,EAAE,CAAC,CAAA;IACb,CAAC;IAED,SAAS,gBAAgB,CAAC,IAAa;QACrC,IAAI,CAAC,IAAI;YAAE,KAAK,EAAE,CAAA;QAClB,YAAY,CAAC,IAAI,CAAC,CAAA;IACpB,CAAC;IAED,SAAS,MAAM,CAAC,KAAgB;QAC9B,KAAK,CAAC,cAAc,EAAE,CAAA;QACtB,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,OAAM;QAC9B,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QACjD,gBAAgB,CAAC,KAAK,CAAC,CAAA;QACvB,KAAK,QAAQ,CAAC;YACZ,EAAE,EAAE,oBAAoB;YACxB,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE;SACtE,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,CACL,KAAC,MAAM,IAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,gBAAgB,YAChD,MAAC,aAAa,eACZ,MAAC,YAAY,eACX,KAAC,WAAW,2BAAuB,EACnC,KAAC,iBAAiB,wGAEE,IACP,EACf,gBAAM,QAAQ,EAAE,MAAM,aACpB,KAAC,KAAK,IAAC,GAAG,EAAC,GAAG,YACZ,KAAC,KAAK,IAAC,KAAK,EAAC,MAAM,EAAC,OAAO,EAAC,eAAe,EAAC,QAAQ,kBAClD,KAAC,KAAK,IACJ,EAAE,EAAC,eAAe,EAClB,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAChD,WAAW,EAAC,UAAU,EACtB,SAAS,QACT,QAAQ,SACR,GACI,GACF,EACR,MAAC,YAAY,IAAC,SAAS,EAAC,MAAM,aAC5B,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAC,OAAO,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,uBAE7E,EACT,KAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,IAAI,EACT,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,iBAChB,aAAa,4BAGlB,IACI,IACV,IACO,GACT,CACV,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DocumentRef } from '@elytracms/cms-core';
|
|
2
|
+
import type { ReferenceAction, ReferenceEntryView } from '@elytracms/studio/lib/references';
|
|
3
|
+
export declare function ReferenceConfirmDialog({ projectId, action, targets, open, busy, onOpenChange, onConfirm, }: {
|
|
4
|
+
projectId: string;
|
|
5
|
+
action: ReferenceAction;
|
|
6
|
+
/** The documents being acted on (a stable snapshot taken when opening). */
|
|
7
|
+
targets: readonly DocumentRef[];
|
|
8
|
+
open: boolean;
|
|
9
|
+
busy?: boolean;
|
|
10
|
+
onOpenChange: (open: boolean) => void;
|
|
11
|
+
onConfirm: () => void;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
13
|
+
/**
|
|
14
|
+
* The shared EC-173 impact rows: one deep-linked row per broken inbound
|
|
15
|
+
* reference, strict-blocking ones flagged. Rendered by the document
|
|
16
|
+
* confirmation dialog (above) and the asset-delete dialog (EC-202) alike — both
|
|
17
|
+
* reduce to "these places reference the thing you're removing", so both lean on
|
|
18
|
+
* the same row + deep-link rendering (which already handles asset link kinds).
|
|
19
|
+
*/
|
|
20
|
+
export declare function ReferenceImpactRows({ projectId, broken, blocking, onNavigate, }: {
|
|
21
|
+
projectId: string;
|
|
22
|
+
broken: readonly ReferenceEntryView[];
|
|
23
|
+
blocking?: readonly ReferenceEntryView[];
|
|
24
|
+
onNavigate: () => void;
|
|
25
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { jsxs as _jsxs, Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Link, STUDIO_PROJECT_ROUTE, studioPath } from '@elytracms/studio/router';
|
|
3
|
+
import { AlertTriangle, ShieldAlert } from 'lucide-react';
|
|
4
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
5
|
+
import { documentKey } from '@elytracms/cms-core';
|
|
6
|
+
import { buildReferenceImpact, loadInboundReferenceViews } from '@elytracms/studio/lib/references';
|
|
7
|
+
import { Badge, Button, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Row, Stack, Text, } from '@elytracms/studio/ui';
|
|
8
|
+
import { useCms } from './cms-store';
|
|
9
|
+
const ACTION_LABELS = {
|
|
10
|
+
unpublish: 'Unpublish',
|
|
11
|
+
delete: 'Delete',
|
|
12
|
+
};
|
|
13
|
+
export function ReferenceConfirmDialog({ projectId, action, targets, open, busy = false, onOpenChange, onConfirm, }) {
|
|
14
|
+
const cms = useCms();
|
|
15
|
+
const [status, setStatus] = useState('loading');
|
|
16
|
+
const [impact, setImpact] = useState(null);
|
|
17
|
+
// A stable identity for the acted-on set, so the effect re-runs exactly
|
|
18
|
+
// when the selection (not the array instance) changes.
|
|
19
|
+
const targetsKey = targets.map((ref) => documentKey(ref)).join('\n');
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (!open || targets.length === 0)
|
|
22
|
+
return;
|
|
23
|
+
let cancelled = false;
|
|
24
|
+
setStatus('loading');
|
|
25
|
+
setImpact(null);
|
|
26
|
+
void (async () => {
|
|
27
|
+
try {
|
|
28
|
+
// Queued session mutations (and the persisted baseline) must land
|
|
29
|
+
// before the pre-flight query — the index is maintained on write.
|
|
30
|
+
await cms.ensurePersistedBaseline();
|
|
31
|
+
await cms.flushPersistence();
|
|
32
|
+
const views = await loadInboundReferenceViews(projectId, targets);
|
|
33
|
+
if (cancelled)
|
|
34
|
+
return;
|
|
35
|
+
setImpact(buildReferenceImpact(cms.collections, action, views));
|
|
36
|
+
setStatus('ready');
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// The index being unreachable must not trap the editor: degrade to a
|
|
40
|
+
// plain confirm with an explicit "could not check" warning.
|
|
41
|
+
if (!cancelled)
|
|
42
|
+
setStatus('unavailable');
|
|
43
|
+
}
|
|
44
|
+
})();
|
|
45
|
+
return () => {
|
|
46
|
+
cancelled = true;
|
|
47
|
+
};
|
|
48
|
+
// `targetsKey` stands in for `targets` (stable identity for the acted-on set).
|
|
49
|
+
}, [open, action, targetsKey, projectId]);
|
|
50
|
+
const actionLabel = ACTION_LABELS[action];
|
|
51
|
+
const subject = useMemo(() => {
|
|
52
|
+
if (targets.length === 1) {
|
|
53
|
+
const ref = targets[0];
|
|
54
|
+
return `“${cms.titleOf(ref)}”`;
|
|
55
|
+
}
|
|
56
|
+
return `${targets.length} documents`;
|
|
57
|
+
}, [targets, cms]);
|
|
58
|
+
const blocked = status === 'ready' && (impact?.totalBlocking ?? 0) > 0;
|
|
59
|
+
const totalBroken = impact?.totalBroken ?? 0;
|
|
60
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { "data-testid": "reference-confirm", className: "max-h-[80vh] overflow-y-auto", children: [_jsxs(DialogHeader, { children: [_jsxs(DialogTitle, { children: [actionLabel, " ", subject, "?"] }), _jsx(DialogDescription, { "data-testid": "reference-confirm-summary", children: status === 'loading' ? ('Checking inbound references…') : status === 'unavailable' ? ('Inbound references could not be checked — the reference index is unreachable.') : blocked ? (_jsxs(_Fragment, { children: ["Blocked: ", impact.totalBlocking, ' ', impact.totalBlocking === 1 ? 'strict reference prevents' : 'strict references prevent', ' ', "this. Remove the references below first."] })) : totalBroken === 0 ? (_jsxs(_Fragment, { children: ["Not referenced anywhere.", action === 'delete'
|
|
61
|
+
? ` This permanently deletes ${targets.length === 1 ? 'the document' : `the ${targets.length} selected documents`}.`
|
|
62
|
+
: ''] })) : (_jsxs(_Fragment, { children: ["You can ", action, " \u2014 ", impactSummary(targets.length, totalBroken), " will show a fallback until fixed. Each one becomes a visible validation issue."] })) })] }), status === 'ready' && impact !== null && totalBroken > 0 ? (_jsx(ImpactList, { projectId: projectId, impact: impact, onNavigate: () => onOpenChange(false) })) : null, status === 'unavailable' ? (_jsxs(Row, { gap: "2", "data-testid": "reference-confirm-unavailable", children: [_jsx(AlertTriangle, { className: "size-4 shrink-0 text-warning" }), _jsx(Text, { size: "xs", tone: "muted", children: "Proceeding is allowed, but affected places cannot be listed right now." })] })) : null, _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", "data-testid": "reference-confirm-cancel", onClick: () => onOpenChange(false), children: "Cancel" }), _jsx(Button, { variant: action === 'delete' ? 'destructive' : 'default', disabled: status === 'loading' || blocked || busy, "data-testid": "reference-confirm-proceed", onClick: onConfirm, children: totalBroken > 0 && !blocked ? `${actionLabel} anyway` : actionLabel })] })] }) }));
|
|
63
|
+
}
|
|
64
|
+
function impactSummary(targetCount, totalBroken) {
|
|
65
|
+
const places = `${totalBroken} ${totalBroken === 1 ? 'place' : 'places'}`;
|
|
66
|
+
// The bulk aggregate: "N documents, M inbound references will break."
|
|
67
|
+
return targetCount > 1 ? `${targetCount} documents are affected; ${places}` : places;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The enumerated impact: flat for a single target, grouped per target for
|
|
71
|
+
* bulk selections (per-item detail, EC-169 honesty rules).
|
|
72
|
+
*/
|
|
73
|
+
function ImpactList({ projectId, impact, onNavigate, }) {
|
|
74
|
+
const affected = impact.documents.filter((doc) => doc.broken.length > 0);
|
|
75
|
+
return (_jsx(Stack, { gap: "3", "data-testid": "reference-confirm-impact", children: affected.map((doc) => (_jsx(ImpactGroup, { projectId: projectId, doc: doc, grouped: impact.documents.length > 1, onNavigate: onNavigate }, documentKey(doc.ref)))) }));
|
|
76
|
+
}
|
|
77
|
+
function ImpactGroup({ projectId, doc, grouped, onNavigate, }) {
|
|
78
|
+
const cms = useCms();
|
|
79
|
+
const blockingKeys = new Set(doc.blocking.map((entry) => entry.key));
|
|
80
|
+
return (_jsxs(Stack, { gap: "2", "data-testid": `reference-confirm-doc-${doc.ref.id}`, children: [grouped ? (_jsxs(Row, { gap: "2", children: [_jsx(Text, { size: "xs", weight: "semibold", tone: "muted", className: "uppercase tracking-wide", children: cms.titleOf(doc.ref) }), _jsx(Badge, { variant: "outline", children: doc.broken.length })] })) : null, doc.broken.map((entry) => (_jsx(ImpactEntryRow, { projectId: projectId, entry: entry, blocking: blockingKeys.has(entry.key), onNavigate: onNavigate }, entry.key)))] }));
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The shared EC-173 impact rows: one deep-linked row per broken inbound
|
|
84
|
+
* reference, strict-blocking ones flagged. Rendered by the document
|
|
85
|
+
* confirmation dialog (above) and the asset-delete dialog (EC-202) alike — both
|
|
86
|
+
* reduce to "these places reference the thing you're removing", so both lean on
|
|
87
|
+
* the same row + deep-link rendering (which already handles asset link kinds).
|
|
88
|
+
*/
|
|
89
|
+
export function ReferenceImpactRows({ projectId, broken, blocking = [], onNavigate, }) {
|
|
90
|
+
const blockingKeys = new Set(blocking.map((entry) => entry.key));
|
|
91
|
+
return (_jsx(Stack, { gap: "2", "data-testid": "reference-impact-rows", children: broken.map((entry) => (_jsx(ImpactEntryRow, { projectId: projectId, entry: entry, blocking: blockingKeys.has(entry.key), onNavigate: onNavigate }, entry.key))) }));
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* One affected place: the EC-172 labels with a working deep link to the exact
|
|
95
|
+
* field/node, the entry kind, draft/published visibility — and a strict
|
|
96
|
+
* marker when this entry is what blocks the action.
|
|
97
|
+
*/
|
|
98
|
+
function ImpactEntryRow({ projectId, entry, blocking, onNavigate, }) {
|
|
99
|
+
return (_jsxs(Row, { gap: "2", className: blocking
|
|
100
|
+
? 'rounded-md border border-destructive/50 bg-destructive/5 px-2.5 py-2'
|
|
101
|
+
: 'rounded-md border border-border/70 bg-background/40 px-2.5 py-2', "data-testid": "reference-confirm-entry", children: [_jsxs(Stack, { gap: "1", className: "min-w-0 flex-1", children: [_jsx(ImpactDeepLink, { projectId: projectId, link: entry.sourceLink, label: entry.sourceLabel, primary: true, onNavigate: onNavigate }), _jsxs(Row, { gap: "1", className: "min-w-0", children: [_jsx(Text, { size: "xs", tone: "muted", className: "shrink-0", children: "at" }), _jsx(ImpactDeepLink, { projectId: projectId, link: entry.sourceLink, label: entry.locationLabel, onNavigate: onNavigate })] })] }), blocking ? (_jsxs(Badge, { variant: "error", "data-testid": "reference-confirm-strict", children: [_jsx(ShieldAlert, { className: "size-3" }), " strict"] })) : null, _jsx(Badge, { variant: "outline", className: "shrink-0", children: entry.kindLabel }), _jsxs(Row, { gap: "1", className: "shrink-0", children: [entry.draft ? _jsx(Badge, { variant: "warning", children: "draft" }) : null, entry.published ? _jsx(Badge, { variant: "success", children: "published" }) : null] })] }));
|
|
102
|
+
}
|
|
103
|
+
/** A deep link to the exact source location; closes the dialog on navigate. */
|
|
104
|
+
function ImpactDeepLink({ projectId, link, label, primary = false, onNavigate, }) {
|
|
105
|
+
const className = primary
|
|
106
|
+
? 'min-w-0 truncate text-sm font-medium text-foreground hover:text-primary hover:underline'
|
|
107
|
+
: 'min-w-0 truncate text-xs text-muted-foreground hover:text-primary hover:underline';
|
|
108
|
+
if (link === null) {
|
|
109
|
+
return primary ? (_jsx(Text, { size: "sm", weight: "medium", className: "min-w-0 truncate", children: label })) : (_jsx(Text, { size: "xs", tone: "muted", className: "min-w-0 truncate", children: label }));
|
|
110
|
+
}
|
|
111
|
+
switch (link.kind) {
|
|
112
|
+
case 'cms-field':
|
|
113
|
+
return (_jsx(Link, { to: STUDIO_PROJECT_ROUTE, params: { projectId, _splat: studioPath.cmsDocument(link.collectionId, link.documentId) }, search: link.fieldPath !== undefined ? { field: link.fieldPath } : {}, className: className, "data-testid": "reference-confirm-link", onClick: onNavigate, children: label }));
|
|
114
|
+
case 'builder-node':
|
|
115
|
+
// The builder redirect (EC-187) only reads `?page=`; the page-graph-only
|
|
116
|
+
// `node` has no home in the document editor and is dropped.
|
|
117
|
+
return (_jsx(Link, { to: STUDIO_PROJECT_ROUTE, params: { projectId, _splat: studioPath.builder() }, search: link.pageId !== undefined ? { page: link.pageId } : {}, className: className, "data-testid": "reference-confirm-link", onClick: onNavigate, children: label }));
|
|
118
|
+
case 'component':
|
|
119
|
+
return (_jsx(Link, { to: STUDIO_PROJECT_ROUTE, params: { projectId, _splat: studioPath.component(link.componentId) }, className: className, "data-testid": "reference-confirm-link", onClick: onNavigate, children: label }));
|
|
120
|
+
case 'asset':
|
|
121
|
+
return (_jsx(Link, { to: STUDIO_PROJECT_ROUTE, params: { projectId, _splat: studioPath.assets() }, search: { asset: link.assetId }, className: className, "data-testid": "reference-confirm-link", onClick: onNavigate, children: label }));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=reference-confirm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference-confirm.js","sourceRoot":"","sources":["../../../src/components/cms/reference-confirm.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { DocumentRef } from '@elytracms/cms-core';
|
|
2
|
+
/** Pick related document(s) from a target collection (brief §8.4, EC-074). */
|
|
3
|
+
export declare function RelationPicker({ targetCollection, cardinality, value, open, onOpenChange, onChange, excludeIds, }: {
|
|
4
|
+
targetCollection: string;
|
|
5
|
+
cardinality: 'one' | 'many';
|
|
6
|
+
value: DocumentRef[];
|
|
7
|
+
open: boolean;
|
|
8
|
+
onOpenChange: (open: boolean) => void;
|
|
9
|
+
onChange: (refs: DocumentRef[]) => void;
|
|
10
|
+
/**
|
|
11
|
+
* Document ids to omit from the candidate list (EC-218): a `parent` self-relation
|
|
12
|
+
* passes the editing document plus its descendants, so a page can never be set
|
|
13
|
+
* as its own ancestor (which would form a cycle).
|
|
14
|
+
*/
|
|
15
|
+
excludeIds?: ReadonlySet<string>;
|
|
16
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Check, Search } from 'lucide-react';
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
import { Badge, Button, Code, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Input, Row, Spacer, Text, } from '@elytracms/studio/ui';
|
|
5
|
+
import { cn } from '@elytracms/studio/lib/utils';
|
|
6
|
+
import { useCms } from './cms-store';
|
|
7
|
+
/** Pick related document(s) from a target collection (brief §8.4, EC-074). */
|
|
8
|
+
export function RelationPicker({ targetCollection, cardinality, value, open, onOpenChange, onChange, excludeIds, }) {
|
|
9
|
+
const cms = useCms();
|
|
10
|
+
const [query, setQuery] = useState('');
|
|
11
|
+
const [selected, setSelected] = useState(value);
|
|
12
|
+
// Seed selection only on open transitions — `value` is a fresh array each
|
|
13
|
+
// parent render, so depending on it would reset in-progress multi-selection.
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (open) {
|
|
16
|
+
setSelected(value);
|
|
17
|
+
setQuery('');
|
|
18
|
+
}
|
|
19
|
+
}, [open]);
|
|
20
|
+
const candidates = cms.documentsOf(targetCollection).filter((d) => {
|
|
21
|
+
if (excludeIds?.has(d.id))
|
|
22
|
+
return false;
|
|
23
|
+
if (!query.trim())
|
|
24
|
+
return true;
|
|
25
|
+
return cms.titleOf({ collection: targetCollection, id: d.id }).toLowerCase().includes(query.toLowerCase());
|
|
26
|
+
});
|
|
27
|
+
const isSelected = (id) => selected.some((r) => r.id === id);
|
|
28
|
+
function toggle(id) {
|
|
29
|
+
const ref = { collection: targetCollection, id };
|
|
30
|
+
if (cardinality === 'one') {
|
|
31
|
+
setSelected([ref]);
|
|
32
|
+
onChange([ref]);
|
|
33
|
+
onOpenChange(false);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
setSelected((prev) => (isSelected(id) ? prev.filter((r) => r.id !== id) : [...prev, ref]));
|
|
37
|
+
}
|
|
38
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "max-w-md", children: [_jsxs(DialogHeader, { children: [_jsxs(DialogTitle, { children: ["Pick ", cardinality === 'many' ? 'related' : 'a related', " document"] }), _jsxs(DialogDescription, { children: ["From ", _jsx(Code, { tone: "muted", children: targetCollection }), cardinality === 'many' ? ' · select multiple' : ''] })] }), _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "pointer-events-none absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { autoFocus: true, value: query, onChange: (e) => setQuery(e.target.value), placeholder: "Search\u2026", className: "pl-8" })] }), _jsx("div", { className: "max-h-72 overflow-auto", children: candidates.length === 0 ? (_jsxs(Text, { size: "sm", tone: "muted", className: "p-3", children: ["No documents in ", targetCollection, "."] })) : (candidates.map((doc) => {
|
|
39
|
+
const title = cms.titleOf({ collection: targetCollection, id: doc.id });
|
|
40
|
+
const sel = isSelected(doc.id);
|
|
41
|
+
return (_jsxs("button", { type: "button", onClick: () => toggle(doc.id), className: cn('flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors hover:bg-muted', sel && 'bg-accent text-accent-foreground'), children: [_jsx("span", { className: "min-w-0 flex-1 truncate font-medium", children: title }), _jsx(Code, { tone: "muted", children: doc.id }), sel ? _jsx(Check, { className: "size-4 text-primary" }) : null] }, doc.id));
|
|
42
|
+
})) }), cardinality === 'many' ? (_jsx(DialogFooter, { children: _jsxs(Row, { gap: "2", className: "w-full", children: [_jsxs(Badge, { variant: "outline", children: [selected.length, " selected"] }), _jsx(Spacer, {}), _jsx(Button, { variant: "ghost", onClick: () => onOpenChange(false), children: "Cancel" }), _jsx(Button, { onClick: () => {
|
|
43
|
+
onChange(selected);
|
|
44
|
+
onOpenChange(false);
|
|
45
|
+
}, children: "Apply" })] }) })) : null] }) }));
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=relation-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation-picker.js","sourceRoot":"","sources":["../../../src/components/cms/relation-picker.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { RefObject } from 'react';
|
|
2
|
+
import type { CmsDocument, CollectionDef } from '@elytracms/cms-core';
|
|
3
|
+
import type { AdvanceDirection, CellCoord } from './cell-edit';
|
|
4
|
+
/**
|
|
5
|
+
* Table-level cell-edit controller (EC-168). Owns the state machine the cells
|
|
6
|
+
* render from:
|
|
7
|
+
*
|
|
8
|
+
* idle → editing (click/Enter) → committing (Enter/Tab/blur) → idle
|
|
9
|
+
* ↘ cancelled (Esc, no operation) ↘ rejected (rollback + cell error)
|
|
10
|
+
*
|
|
11
|
+
* Exactly one cell edits at a time; commits go through
|
|
12
|
+
* `cms.commitFieldEdit` (one operations command each); rejections park a
|
|
13
|
+
* per-cell error that the cell renders inline until the cell is edited again.
|
|
14
|
+
*/
|
|
15
|
+
export interface CellEditController {
|
|
16
|
+
/** Ref for the table container (focus restoration after commits/cancels). */
|
|
17
|
+
containerRef: RefObject<HTMLDivElement | null>;
|
|
18
|
+
/** Key of the cell currently editing, or null. */
|
|
19
|
+
activeKey: string | null;
|
|
20
|
+
/** Key of the cell with a commit in flight, or null. */
|
|
21
|
+
busyKey: string | null;
|
|
22
|
+
errorOf(key: string): string | null;
|
|
23
|
+
start(coord: CellCoord): void;
|
|
24
|
+
cancel(coord: CellCoord): void;
|
|
25
|
+
commit(coord: CellCoord, value: unknown, advance: AdvanceDirection | null): void;
|
|
26
|
+
}
|
|
27
|
+
export declare function useCellEdit({ collection, docs, editableFields, }: {
|
|
28
|
+
collection: CollectionDef;
|
|
29
|
+
/** Documents in rendered (sorted) row order. */
|
|
30
|
+
docs: readonly CmsDocument[];
|
|
31
|
+
/** Editable column field names in rendered order. */
|
|
32
|
+
editableFields: readonly string[];
|
|
33
|
+
}): CellEditController;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { useCallback, useRef, useState } from 'react';
|
|
2
|
+
import { resolveField } from '@elytracms/cms-core';
|
|
3
|
+
import { cellErrorMessage, cellKey, nextEditableCell } from './cell-edit';
|
|
4
|
+
import { useCms } from './cms-store';
|
|
5
|
+
export function useCellEdit({ collection, docs, editableFields, }) {
|
|
6
|
+
const cms = useCms();
|
|
7
|
+
const [activeKey, setActiveKey] = useState(null);
|
|
8
|
+
const [busyKey, setBusyKey] = useState(null);
|
|
9
|
+
const [errors, setErrors] = useState({});
|
|
10
|
+
const containerRef = useRef(null);
|
|
11
|
+
// Snapshots for async commit completion (row order may re-sort mid-flight).
|
|
12
|
+
const activeRef = useRef(activeKey);
|
|
13
|
+
activeRef.current = activeKey;
|
|
14
|
+
const docsRef = useRef(docs);
|
|
15
|
+
docsRef.current = docs;
|
|
16
|
+
const fieldsRef = useRef(editableFields);
|
|
17
|
+
fieldsRef.current = editableFields;
|
|
18
|
+
const clearError = useCallback((key) => {
|
|
19
|
+
setErrors((prev) => {
|
|
20
|
+
if (!(key in prev))
|
|
21
|
+
return prev;
|
|
22
|
+
const next = { ...prev };
|
|
23
|
+
delete next[key];
|
|
24
|
+
return next;
|
|
25
|
+
});
|
|
26
|
+
}, []);
|
|
27
|
+
const focusCell = useCallback((key) => {
|
|
28
|
+
// After state settles: return focus to the cell so Enter re-edits and the
|
|
29
|
+
// keyboard flow continues where the user left off.
|
|
30
|
+
requestAnimationFrame(() => {
|
|
31
|
+
containerRef.current
|
|
32
|
+
?.querySelector(`[data-cell-key="${CSS.escape(key)}"]`)
|
|
33
|
+
?.focus();
|
|
34
|
+
});
|
|
35
|
+
}, []);
|
|
36
|
+
const start = useCallback((coord) => {
|
|
37
|
+
const key = cellKey(coord);
|
|
38
|
+
clearError(key);
|
|
39
|
+
setActiveKey(key);
|
|
40
|
+
}, [clearError]);
|
|
41
|
+
const cancel = useCallback((coord) => {
|
|
42
|
+
const key = cellKey(coord);
|
|
43
|
+
if (activeRef.current !== key)
|
|
44
|
+
return;
|
|
45
|
+
setActiveKey(null);
|
|
46
|
+
focusCell(key);
|
|
47
|
+
}, [focusCell]);
|
|
48
|
+
/** Close the editor and move on (commit settled or value unchanged). */
|
|
49
|
+
const settle = useCallback((coord, next) => {
|
|
50
|
+
const key = cellKey(coord);
|
|
51
|
+
// The user may have clicked into another cell while the commit ran —
|
|
52
|
+
// never clobber their new edit session.
|
|
53
|
+
if (activeRef.current !== key)
|
|
54
|
+
return;
|
|
55
|
+
if (next) {
|
|
56
|
+
clearError(cellKey(next));
|
|
57
|
+
setActiveKey(cellKey(next));
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
setActiveKey(null);
|
|
61
|
+
focusCell(key);
|
|
62
|
+
}
|
|
63
|
+
}, [clearError, focusCell]);
|
|
64
|
+
const commit = useCallback((coord, value, advance) => {
|
|
65
|
+
const key = cellKey(coord);
|
|
66
|
+
const doc = docsRef.current.find((d) => d.id === coord.docId);
|
|
67
|
+
const field = collection.fields.find((f) => f.name === coord.field);
|
|
68
|
+
if (!doc || !field) {
|
|
69
|
+
settle(coord, null);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
// The advance target is computed against the row order at commit time —
|
|
73
|
+
// a re-sort caused by the edit must not teleport the cursor.
|
|
74
|
+
const next = advance
|
|
75
|
+
? nextEditableCell(docsRef.current.map((d) => d.id), fieldsRef.current, coord, advance)
|
|
76
|
+
: null;
|
|
77
|
+
// Same value as displayed → close (and advance) without any operation.
|
|
78
|
+
// Notably: re-committing an unchanged fallback-shown value dispatches
|
|
79
|
+
// nothing — a localized variant is only created by an actual edit.
|
|
80
|
+
const locale = cms.activeLocale;
|
|
81
|
+
const original = resolveField(collection, doc, field.name, locale, cms.localeConfig).value;
|
|
82
|
+
if (sameCellValue(value, original)) {
|
|
83
|
+
settle(coord, next);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
setBusyKey(key);
|
|
87
|
+
void cms
|
|
88
|
+
.commitFieldEdit({ collection, doc, field, locale, value })
|
|
89
|
+
.then((outcome) => {
|
|
90
|
+
if (outcome.ok) {
|
|
91
|
+
clearError(key);
|
|
92
|
+
settle(coord, next);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
// Rejected: the session already rolled back — park the error on the
|
|
96
|
+
// cell (never a toast) and return focus there.
|
|
97
|
+
setErrors((prev) => ({ ...prev, [key]: cellErrorMessage(outcome.error) }));
|
|
98
|
+
settle(coord, null);
|
|
99
|
+
})
|
|
100
|
+
.finally(() => {
|
|
101
|
+
setBusyKey((prev) => (prev === key ? null : prev));
|
|
102
|
+
});
|
|
103
|
+
}, [cms, collection, clearError, settle]);
|
|
104
|
+
return {
|
|
105
|
+
containerRef,
|
|
106
|
+
activeKey,
|
|
107
|
+
busyKey,
|
|
108
|
+
errorOf: (key) => errors[key] ?? null,
|
|
109
|
+
start,
|
|
110
|
+
cancel,
|
|
111
|
+
commit,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/** Structural equality good enough for cell values (scalars, refs, id arrays). */
|
|
115
|
+
function sameCellValue(a, b) {
|
|
116
|
+
if (a === undefined && b === undefined)
|
|
117
|
+
return true;
|
|
118
|
+
try {
|
|
119
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=use-cell-edit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-cell-edit.js","sourceRoot":"","sources":["../../../src/components/cms/use-cell-edit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CmsDocument } from '@elytracms/cms-core';
|
|
2
|
+
/**
|
|
3
|
+
* Does a recorded snapshot equal the working draft, by VALUE (EC-224)? Decides
|
|
4
|
+
* whether the Versions pane shows "unpublished changes".
|
|
5
|
+
*
|
|
6
|
+
* The compare MUST be canonical (key-order-insensitive): a recorded snapshot is
|
|
7
|
+
* round-tripped through `documentSchema` on save (which reorders object keys to
|
|
8
|
+
* the schema's declaration order), while the live draft is assembled by the
|
|
9
|
+
* editor's spread-mutations (keys in mutation order). A plain `JSON.stringify`
|
|
10
|
+
* equality is order-sensitive, so it would report a just-published, byte-equal
|
|
11
|
+
* document as still having changes — pinning the Publish affordance on forever.
|
|
12
|
+
*/
|
|
13
|
+
export declare function snapshotMatchesDraft(snapshot: CmsDocument, draft: CmsDocument): boolean;
|
|
14
|
+
/** Format a version's stored timestamp; fall back to the raw value if unparseable. */
|
|
15
|
+
export declare function formatVersionTimestamp(value: string): string;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { stableStringify } from '@elytracms/content';
|
|
2
|
+
/**
|
|
3
|
+
* Does a recorded snapshot equal the working draft, by VALUE (EC-224)? Decides
|
|
4
|
+
* whether the Versions pane shows "unpublished changes".
|
|
5
|
+
*
|
|
6
|
+
* The compare MUST be canonical (key-order-insensitive): a recorded snapshot is
|
|
7
|
+
* round-tripped through `documentSchema` on save (which reorders object keys to
|
|
8
|
+
* the schema's declaration order), while the live draft is assembled by the
|
|
9
|
+
* editor's spread-mutations (keys in mutation order). A plain `JSON.stringify`
|
|
10
|
+
* equality is order-sensitive, so it would report a just-published, byte-equal
|
|
11
|
+
* document as still having changes — pinning the Publish affordance on forever.
|
|
12
|
+
*/
|
|
13
|
+
export function snapshotMatchesDraft(snapshot, draft) {
|
|
14
|
+
return stableStringify(snapshot) === stableStringify(draft);
|
|
15
|
+
}
|
|
16
|
+
/** Format a version's stored timestamp; fall back to the raw value if unparseable. */
|
|
17
|
+
export function formatVersionTimestamp(value) {
|
|
18
|
+
const ms = Date.parse(value);
|
|
19
|
+
if (Number.isNaN(ms))
|
|
20
|
+
return value;
|
|
21
|
+
return new Date(ms).toLocaleString();
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=versions-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"versions-model.js","sourceRoot":"","sources":["../../../src/components/cms/versions-model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAGpD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAqB,EAAE,KAAkB;IAC5E,OAAO,eAAe,CAAC,QAAQ,CAAC,KAAK,eAAe,CAAC,KAAK,CAAC,CAAA;AAC7D,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,sBAAsB,CAAC,KAAa;IAClD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAC5B,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAAE,OAAO,KAAK,CAAA;IAClC,OAAO,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,cAAc,EAAE,CAAA;AACtC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EC-224 — the document-level **Versions** inspector pane. Re-homes the EC-180
|
|
3
|
+
* VersionsPanel at the document level (the Sanity model): the continuous draft
|
|
4
|
+
* on top with **Publish**, then the recorded version history (the live pin
|
|
5
|
+
* badged), each older version **restorable** into the draft.
|
|
6
|
+
*
|
|
7
|
+
* Publish routes through the same pointer op as the header control
|
|
8
|
+
* (`cms.publishDocument`); restore loads a recorded snapshot as the new working
|
|
9
|
+
* draft (the operation snapshots the current draft first, so a rollback is
|
|
10
|
+
* itself undoable) and the open editor adopts it via `replaceDraft`. Unpublish
|
|
11
|
+
* deliberately stays in the header — it routes through the EC-173
|
|
12
|
+
* reference-aware confirmation, which this pane does not duplicate.
|
|
13
|
+
*/
|
|
14
|
+
export declare function VersionsPane(): import("react").JSX.Element;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
3
|
+
import { Eye, RotateCcw } from 'lucide-react';
|
|
4
|
+
import { Badge, Button, Code, Row, Spacer, Stack, Text } from '@elytracms/studio/ui';
|
|
5
|
+
import { useCms } from './cms-store';
|
|
6
|
+
import { useDocumentEditor } from './document-editor-context';
|
|
7
|
+
import { formatVersionTimestamp, snapshotMatchesDraft } from './versions-model';
|
|
8
|
+
/**
|
|
9
|
+
* EC-224 — the document-level **Versions** inspector pane. Re-homes the EC-180
|
|
10
|
+
* VersionsPanel at the document level (the Sanity model): the continuous draft
|
|
11
|
+
* on top with **Publish**, then the recorded version history (the live pin
|
|
12
|
+
* badged), each older version **restorable** into the draft.
|
|
13
|
+
*
|
|
14
|
+
* Publish routes through the same pointer op as the header control
|
|
15
|
+
* (`cms.publishDocument`); restore loads a recorded snapshot as the new working
|
|
16
|
+
* draft (the operation snapshots the current draft first, so a rollback is
|
|
17
|
+
* itself undoable) and the open editor adopts it via `replaceDraft`. Unpublish
|
|
18
|
+
* deliberately stays in the header — it routes through the EC-173
|
|
19
|
+
* reference-aware confirmation, which this pane does not duplicate.
|
|
20
|
+
*/
|
|
21
|
+
export function VersionsPane() {
|
|
22
|
+
const cms = useCms();
|
|
23
|
+
const { docRef, draft, dirty, hasErrors, viewReadOnly, save, replaceDraft } = useDocumentEditor();
|
|
24
|
+
const [view, setView] = useState(null);
|
|
25
|
+
const [busy, setBusy] = useState(false);
|
|
26
|
+
const published = cms.isPublished(docRef);
|
|
27
|
+
const reload = useCallback(async () => {
|
|
28
|
+
// Flush any queued publish/save so the listed history is authoritative
|
|
29
|
+
// regardless of which surface (header or pane) triggered the change.
|
|
30
|
+
await cms.flushPersistence();
|
|
31
|
+
setView(await cms.loadDocumentVersions(docRef));
|
|
32
|
+
}, [cms, docRef]);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
void reload();
|
|
35
|
+
// Re-load when publish-ness flips from anywhere (e.g. the header control).
|
|
36
|
+
}, [reload, published]);
|
|
37
|
+
const liveSnapshot = view?.publishedVersion !== undefined
|
|
38
|
+
? view.versions.find((v) => v.version === view.publishedVersion)?.snapshot
|
|
39
|
+
: undefined;
|
|
40
|
+
// Value-equality (key-order-insensitive) so a just-published, unchanged doc
|
|
41
|
+
// doesn't read as "unpublished changes" — see snapshotMatchesDraft.
|
|
42
|
+
const liveMatchesDraft = liveSnapshot !== undefined && snapshotMatchesDraft(liveSnapshot, draft);
|
|
43
|
+
const canPublish = !liveMatchesDraft;
|
|
44
|
+
const handlePublish = useCallback(async () => {
|
|
45
|
+
setBusy(true);
|
|
46
|
+
try {
|
|
47
|
+
// Publish snapshots the SAVED draft — capture any unsaved edits first so
|
|
48
|
+
// the published version is exactly what the editor shows. Await the
|
|
49
|
+
// publish (it flushes + reconciles the pin, EC-225) before re-reading the
|
|
50
|
+
// version list so the new version shows.
|
|
51
|
+
if (dirty)
|
|
52
|
+
save();
|
|
53
|
+
await cms.publishDocument(docRef);
|
|
54
|
+
await reload();
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
setBusy(false);
|
|
58
|
+
}
|
|
59
|
+
}, [cms, docRef, dirty, save, reload]);
|
|
60
|
+
const handleRestore = useCallback(async (version) => {
|
|
61
|
+
setBusy(true);
|
|
62
|
+
try {
|
|
63
|
+
// Capture any unsaved buffer edits FIRST so the operation's pre-restore
|
|
64
|
+
// snapshot records them — otherwise they'd be lost and the rollback
|
|
65
|
+
// wouldn't be undoable (restore snapshots the persisted draft).
|
|
66
|
+
if (dirty)
|
|
67
|
+
save();
|
|
68
|
+
const restored = await cms.restoreDocumentVersion(docRef, version);
|
|
69
|
+
if (restored)
|
|
70
|
+
replaceDraft(restored);
|
|
71
|
+
await reload();
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
setBusy(false);
|
|
75
|
+
}
|
|
76
|
+
}, [cms, docRef, dirty, save, replaceDraft, reload]);
|
|
77
|
+
return (_jsxs(Stack, { gap: "3", className: "p-3", children: [canPublish ? (_jsxs(Row, { gap: "2", align: "center", className: "rounded-md border border-primary/40 bg-primary/5 px-2.5 py-2", children: [_jsxs(Stack, { gap: "none", className: "min-w-0", children: [_jsx(Text, { size: "sm", weight: "medium", children: "Draft" }), _jsx(Text, { size: "xs", tone: "muted", children: published ? 'Unpublished changes' : 'Not published yet' })] }), _jsx(Spacer, {}), _jsxs(Button, { size: "sm", onClick: handlePublish, disabled: busy || hasErrors || viewReadOnly, title: viewReadOnly
|
|
78
|
+
? 'Switch to Draft to publish'
|
|
79
|
+
: hasErrors
|
|
80
|
+
? 'Fix the document’s validation issues to publish'
|
|
81
|
+
: undefined, children: [_jsx(Eye, {}), " Publish"] })] })) : (_jsx(Text, { size: "xs", tone: "muted", className: "px-0.5", children: "The live version is up to date \u2014 nothing to publish." })), _jsx(Stack, { gap: "1", children: view === null ? (_jsx(Text, { size: "xs", tone: "muted", className: "px-0.5", children: "Loading\u2026" })) : view.versions.length === 0 ? (_jsx(Text, { size: "xs", tone: "muted", className: "px-0.5", children: "No published versions yet." })) : (view.versions.map((entry) => {
|
|
82
|
+
const isLive = entry.version === view.publishedVersion;
|
|
83
|
+
return (_jsxs(Row, { gap: "2", align: "center", className: "rounded-md border border-border/60 px-2.5 py-1.5", children: [_jsxs(Code, { tone: isLive ? 'primary' : 'muted', children: ["v", entry.version] }), isLive ? _jsx(Badge, { variant: "success", children: "Published" }) : null, _jsx(Text, { size: "xs", tone: "subtle", mono: true, className: "truncate", children: formatVersionTimestamp(entry.createdAt) }), _jsx(Spacer, {}), isLive ? null : (_jsxs(Button, { size: "sm", variant: "outline", onClick: () => void handleRestore(entry.version), disabled: busy || viewReadOnly, title: viewReadOnly ? 'Switch to Draft to restore' : undefined, children: [_jsx(RotateCcw, {}), " Restore"] }))] }, entry.version));
|
|
84
|
+
})) })] }));
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=versions-pane.js.map
|