@jxsuite/studio 6.1.1 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/chunks/2020-5wtzce5g.js +4 -0
- package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
- package/dist/chunks/adapter-5tphg7xe.js +4 -0
- package/dist/chunks/add-new-flow-psym14sn.js +4 -0
- package/dist/chunks/cf-account-picker-haqazq5r.js +4 -0
- package/dist/chunks/cf-settings-h2wrh6hq.js +4 -0
- package/dist/chunks/color-area-6rbra5dy.js +4 -0
- package/dist/chunks/color-field-gy56c94g.js +4 -0
- package/dist/chunks/color-m7r1vk54.js +4 -0
- package/dist/chunks/color-slider-sqqdyf6c.js +4 -0
- package/dist/chunks/combobox-72h32ejk.js +4 -0
- package/dist/chunks/components-r22xca09.js +4 -0
- package/dist/chunks/content-source-mmppmcyg.js +4 -0
- package/dist/chunks/convert-to-repeater-he70fc2b.js +4 -0
- package/dist/chunks/dialog-c4x05vyx.js +4 -0
- package/dist/chunks/editor-ccd9jwsa.js +4 -0
- package/dist/chunks/entry-commands-6qxz9e8p.js +4 -0
- package/dist/chunks/extension-sections-0egb88dm.js +4 -0
- package/dist/chunks/file-ops-qnab36ek.js +4 -0
- package/dist/chunks/files-rcn56qvm.js +4 -0
- package/dist/chunks/format-host-yxz0kjjs.js +4 -0
- package/dist/chunks/fs-events-d1qxq4z4.js +4 -0
- package/dist/chunks/grid-open-4z1g062t.js +4 -0
- package/dist/chunks/grid-view-qg1b5eqx.js +51 -0
- package/dist/chunks/icons-63bjtbs7.js +4 -0
- package/dist/chunks/iframe-entry-2zggzajv.js +5 -0
- package/dist/chunks/iframe-entry-76j8vwwx.js +5 -0
- package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
- package/dist/chunks/iframe-entry-pkgmcgp0.js +5 -0
- package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
- package/dist/chunks/{index-2veqmnhr.js → index-32eqzv1k.js} +3 -3
- package/dist/chunks/index-f0jn7nnp.js +4 -0
- package/dist/chunks/{javascript-8nbvs12s.js → javascript-pjp734q4.js} +3 -3
- package/dist/chunks/jsonMode-njkvsa02.js +13 -0
- package/dist/chunks/jx-validate-ttasrbh7.js +4 -0
- package/dist/chunks/layers-bgyr11tr.js +4 -0
- package/dist/chunks/layers-panel-7ez66zeq.js +4 -0
- package/dist/chunks/listbox-c421cf8c.js +4 -0
- package/dist/chunks/lit-html-v9gh687x.js +4 -0
- package/dist/chunks/media-library-sq468wts.js +4 -0
- package/dist/chunks/media-picker-shfe59pt.js +4 -0
- package/dist/chunks/menu-bdpzbfvs.js +4 -0
- package/dist/chunks/monaco-binding-vq1hgnn0.js +4 -0
- package/dist/chunks/monaco-buffer-3afgwvbp.js +4 -0
- package/dist/chunks/monaco-setup-xrd2cbkp.js +4 -0
- package/dist/chunks/notify-kzrjr3fv.js +4 -0
- package/dist/chunks/number-field-y62xq0ty.js +4 -0
- package/dist/chunks/parse-v77xtwv7.js +4 -0
- package/dist/chunks/platform-7v4rtd7m.js +4 -0
- package/dist/chunks/popover-b89sfej7.js +4 -0
- package/dist/chunks/publish-panel-2z9gw8ee.js +4 -0
- package/dist/chunks/publish-quick-qx2455cj.js +4 -0
- package/dist/chunks/publish-workspace-wrc1dgwx.js +4 -0
- package/dist/chunks/quick-search-n0t0eqxb.js +4 -0
- package/dist/chunks/references-9547rg5s.js +4 -0
- package/dist/chunks/right-panel-wsgnr9pn.js +4 -0
- package/dist/chunks/select-rzds841e.js +4 -0
- package/dist/chunks/source-control-kwktr9y6.js +4 -0
- package/dist/chunks/split-c9zfdgxf.js +4 -0
- package/dist/chunks/studio-03ct6yfv.js +9 -0
- package/dist/chunks/studio-07rcfje3.js +5 -0
- package/dist/chunks/studio-3e54qh39.js +7 -0
- package/dist/chunks/studio-3exxhz5g.js +5 -0
- package/dist/chunks/studio-3q40e3rj.js +5 -0
- package/dist/chunks/studio-3qeh9t0h.js +6 -0
- package/dist/chunks/studio-3qqjeep5.js +6 -0
- package/dist/chunks/studio-43sd2mam.js +4 -0
- package/dist/chunks/studio-4hp8pkyt.js +5 -0
- package/dist/chunks/studio-58xg6j2q.js +9 -0
- package/dist/chunks/studio-5g0rprdt.js +7 -0
- package/dist/chunks/studio-6m380wp7.js +5 -0
- package/dist/chunks/studio-80jyh1xh.js +4 -0
- package/dist/chunks/studio-83mk4bgg.js +9 -0
- package/dist/chunks/{studio-kggey1jt.js → studio-881z1xrx.js} +4 -4
- package/dist/chunks/studio-8m0y2qe7.js +5 -0
- package/dist/chunks/studio-8tr6cfrc.js +5 -0
- package/dist/chunks/studio-8vcvfs7r.js +6 -0
- package/dist/chunks/studio-9tmebf0s.js +5 -0
- package/dist/chunks/studio-a2bvaptz.js +5 -0
- package/dist/chunks/studio-b7y5mr30.js +5 -0
- package/dist/chunks/studio-bavb31r0.js +5 -0
- package/dist/chunks/studio-bbe4c90a.js +5 -0
- package/dist/chunks/studio-c05wdnt3.js +5 -0
- package/dist/chunks/studio-ccv2svc6.js +5 -0
- package/dist/chunks/studio-d5grtb9e.js +16 -0
- package/dist/chunks/studio-df0baea9.js +5 -0
- package/dist/chunks/studio-dgk4dqtx.js +7 -0
- package/dist/chunks/studio-e1g64q43.js +5 -0
- package/dist/chunks/studio-ed1hp6zf.js +6 -0
- package/dist/chunks/studio-ed3xx40h.js +7 -0
- package/dist/chunks/studio-f14e1zdj.js +5 -0
- package/dist/chunks/studio-fbhxxc5f.js +5 -0
- package/dist/chunks/studio-fyh0jc96.js +5 -0
- package/dist/chunks/studio-gcxk20n7.js +5 -0
- package/dist/chunks/studio-jaaz8ce9.js +5 -0
- package/dist/chunks/{studio-8grwxtqk.js → studio-jcnsdaep.js} +4 -4
- package/dist/chunks/studio-jsgf2q5k.js +7 -0
- package/dist/chunks/{studio-1q1sh2ax.js → studio-k3xxbagr.js} +3 -3
- package/dist/chunks/studio-k7evxqh4.js +5 -0
- package/dist/chunks/studio-kt3pjkwd.js +5 -0
- package/dist/chunks/studio-m8g16bgz.js +5 -0
- package/dist/chunks/studio-mn0476ag.js +5 -0
- package/dist/chunks/studio-mx1smyq0.js +5 -0
- package/dist/chunks/studio-n0c5h6mf.js +5 -0
- package/dist/chunks/{studio-rv11kfwa.js → studio-nh6d342n.js} +7 -7
- package/dist/chunks/studio-nqxqf8p2.js +4 -0
- package/dist/chunks/studio-p4nrkvqr.js +5 -0
- package/dist/chunks/{studio-h46vtzk8.js → studio-pbxa5fpc.js} +4 -4
- package/dist/chunks/studio-pgmvdv7z.js +7 -0
- package/dist/chunks/studio-ph84avkf.js +5 -0
- package/dist/chunks/{studio-wszjyh0j.js → studio-q0mvbaq6.js} +4 -4
- package/dist/chunks/studio-q0tccd43.js +5 -0
- package/dist/chunks/studio-q7rtx6zq.js +14 -0
- package/dist/chunks/{studio-pre0skq6.js → studio-qgh13jtz.js} +4 -4
- package/dist/chunks/studio-qmn1xc24.js +5 -0
- package/dist/chunks/studio-qwdqwkj0.js +5 -0
- package/dist/chunks/{studio-t6b6qe31.js → studio-r5qy30vx.js} +4 -4
- package/dist/chunks/studio-rj9eamf8.js +5 -0
- package/dist/chunks/studio-rptgsk96.js +5 -0
- package/dist/chunks/studio-rthyg42z.js +928 -0
- package/dist/chunks/studio-s19tp1xr.js +5 -0
- package/dist/chunks/studio-s32578pn.js +5 -0
- package/dist/chunks/studio-svb7yyve.js +5 -0
- package/dist/chunks/studio-syreb644.js +5 -0
- package/dist/chunks/studio-tf9jryb1.js +10 -0
- package/dist/chunks/studio-tfkznv39.js +5 -0
- package/dist/chunks/studio-tft6r105.js +5 -0
- package/dist/chunks/studio-txf2kysx.js +5 -0
- package/dist/chunks/studio-v8867ddv.js +12 -0
- package/dist/chunks/studio-vxq7fcvv.js +5 -0
- package/dist/chunks/studio-w4rz9hdk.js +5 -0
- package/dist/chunks/studio-wbcjbhy1.js +9 -0
- package/dist/chunks/studio-wc649wss.js +5 -0
- package/dist/chunks/studio-wys23mxz.js +5 -0
- package/dist/chunks/studio-x1x167jh.js +5 -0
- package/dist/chunks/studio-x9hsze61.js +5 -0
- package/dist/chunks/studio-y0n7yxea.js +9 -0
- package/dist/chunks/studio-y3ahhdpx.js +5 -0
- package/dist/chunks/studio-z97c48fk.js +5 -0
- package/dist/chunks/studio-zat62m0c.js +5 -0
- package/dist/chunks/studio-zcd2e7yz.js +5 -0
- package/dist/chunks/studio-zz9qe3rw.js +64 -0
- package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
- package/dist/chunks/tabs-f5cw3tgp.js +4 -0
- package/dist/chunks/textfield-wewc8rq2.js +4 -0
- package/dist/chunks/toast-1gv0h53h.js +4 -0
- package/dist/chunks/toast-host-1yg5ar8d.js +4 -0
- package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
- package/dist/chunks/tooltip-yypz28gq.js +4 -0
- package/dist/chunks/tree-9xa4hm7n.js +4 -0
- package/dist/chunks/tsMode-epyfz1hv.js +14 -0
- package/dist/chunks/workspace-dz7nxfhv.js +4 -0
- package/dist/chunks/workspace-home-xsd7hkjw.js +4 -0
- package/dist/chunks/ws-client-bv552sfx.js +4 -0
- package/dist/iframe-entry.js +20 -16
- package/dist/manifest.json +77 -63
- package/dist/studio.js +106 -107
- package/dist/workers/ts.worker.js +3 -3
- package/package.json +17 -16
- package/src/about/about-modal.ts +4 -3
- package/src/account/action-flow.ts +45 -38
- package/src/account-status.ts +7 -2
- package/src/browse/component-examples.ts +272 -0
- package/src/browse/library-commands.ts +64 -104
- package/src/browse/library-layouts.ts +270 -53
- package/src/browse/library-model.ts +194 -134
- package/src/browse/library-pane.ts +748 -440
- package/src/browse/library-preview.ts +161 -26
- package/src/browse/library-source.ts +308 -41
- package/src/browse/preview-root.ts +78 -0
- package/src/browse/preview-style.ts +155 -0
- package/src/canvas/asset-refs.ts +40 -10
- package/src/canvas/asset-resolve.ts +19 -23
- package/src/canvas/canvas-helpers.ts +7 -6
- package/src/canvas/canvas-live-render.ts +260 -77
- package/src/canvas/canvas-origin.ts +37 -12
- package/src/canvas/canvas-page-context.ts +112 -0
- package/src/canvas/canvas-patcher.ts +30 -30
- package/src/canvas/canvas-perf.ts +11 -5
- package/src/canvas/canvas-render.ts +175 -148
- package/src/canvas/canvas-surface.ts +5 -3
- package/src/canvas/canvas-utils.ts +147 -61
- package/src/canvas/dialog-path.ts +9 -4
- package/src/canvas/dialog-state.ts +1 -2
- package/src/canvas/diff-marks.ts +9 -16
- package/src/canvas/diff-toolbar.ts +8 -7
- package/src/canvas/edit-width-drag.ts +4 -1
- package/src/canvas/edit-width.ts +1 -3
- package/src/canvas/iframe-channel.ts +27 -13
- package/src/canvas/iframe-drop.ts +120 -12
- package/src/canvas/iframe-editable-root.ts +29 -16
- package/src/canvas/iframe-entry.ts +104 -75
- package/src/canvas/iframe-eval.ts +73 -49
- package/src/canvas/iframe-host.ts +269 -158
- package/src/canvas/iframe-inline-edit.ts +49 -30
- package/src/canvas/iframe-insert.ts +5 -4
- package/src/canvas/iframe-interaction.ts +30 -25
- package/src/canvas/iframe-keys.ts +11 -0
- package/src/canvas/iframe-overlay.ts +1 -1
- package/src/canvas/iframe-patch.ts +25 -21
- package/src/canvas/iframe-position.ts +12 -6
- package/src/canvas/iframe-protocol.ts +36 -21
- package/src/canvas/iframe-render.ts +84 -35
- package/src/canvas/iframe-slash.ts +24 -11
- package/src/canvas/iframe-subtree.ts +10 -3
- package/src/canvas/npm-modules.ts +22 -0
- package/src/canvas/path-mapping.ts +19 -12
- package/src/canvas/popover-path.ts +7 -3
- package/src/canvas/popover-state.ts +1 -2
- package/src/canvas/preview-navigate.ts +16 -0
- package/src/canvas/repeater-sources.ts +200 -0
- package/src/canvas/serialize-scope.ts +13 -5
- package/src/canvas/stage-scrollbar.ts +7 -2
- package/src/canvas/surface-registry.ts +27 -3
- package/src/collab/collab-commands.ts +7 -2
- package/src/collab/collab-session.ts +84 -45
- package/src/collab/collab-state.ts +4 -3
- package/src/collab/monaco-binding.ts +16 -13
- package/src/collab/monaco-cursors.ts +5 -2
- package/src/commands/app-commands.ts +16 -6
- package/src/commands/budget.ts +13 -11
- package/src/commands/command-args.ts +103 -71
- package/src/commands/context.ts +55 -28
- package/src/commands/defaults.ts +69 -45
- package/src/commands/keymap.ts +56 -43
- package/src/commands/levels.ts +14 -8
- package/src/commands/live-context.ts +9 -7
- package/src/commands/reference.ts +2 -1
- package/src/commands/registry.ts +22 -11
- package/src/commands/run-reported.ts +15 -10
- package/src/component-props.ts +46 -30
- package/src/content/collection-match.ts +11 -9
- package/src/content/collection-pages.ts +412 -0
- package/src/content/content-collections.ts +270 -0
- package/src/content/draft-state.ts +4 -3
- package/src/content/entry-commands.ts +54 -62
- package/src/content/entry-editor.ts +137 -32
- package/src/content/entry-fields.ts +25 -8
- package/src/content/entry-inspector.ts +225 -0
- package/src/content/entry-model.ts +38 -15
- package/src/content/entry-open.ts +80 -0
- package/src/content/entry-summaries.ts +440 -0
- package/src/content/file-record-ids.ts +80 -0
- package/src/content/file-records.ts +125 -0
- package/src/content/page-summaries.ts +129 -0
- package/src/content/record-entry.ts +201 -0
- package/src/content/writing-banner.ts +177 -0
- package/src/create/add-new-commands.ts +185 -0
- package/src/create/add-new-flow.ts +1116 -0
- package/src/create/add-new.ts +1014 -0
- package/src/create/element-name.ts +121 -0
- package/src/editor/canvas-context-menu.ts +1 -2
- package/src/editor/canvas-slash-bridge.ts +3 -6
- package/src/editor/content-slice.ts +16 -14
- package/src/editor/context-menu.ts +35 -22
- package/src/editor/convert-targets.ts +30 -35
- package/src/editor/convert-to-component.ts +78 -48
- package/src/editor/convert-to-repeater.ts +34 -22
- package/src/editor/editable-tags.ts +17 -2
- package/src/editor/file-drop-action.ts +29 -22
- package/src/editor/inline-edit-apply.ts +79 -17
- package/src/editor/inline-edit.ts +76 -50
- package/src/editor/inline-format.ts +59 -56
- package/src/editor/inline-link.ts +40 -15
- package/src/editor/insert-component.ts +91 -0
- package/src/editor/insert-zone-action.ts +14 -5
- package/src/editor/merge-tags.ts +58 -19
- package/src/editor/repeater-scope.ts +39 -28
- package/src/editor/shortcuts.ts +76 -42
- package/src/editor/slash-menu.ts +52 -14
- package/src/files/asset-versions.ts +4 -4
- package/src/files/components.ts +89 -20
- package/src/files/elements.ts +5 -6
- package/src/files/file-ops.ts +92 -41
- package/src/files/files.ts +248 -239
- package/src/files/fs-events.ts +18 -7
- package/src/files/media-meta.ts +97 -2
- package/src/files/media-paths.ts +3 -0
- package/src/files/media-types.ts +55 -0
- package/src/files/media-upload.ts +209 -52
- package/src/files/new-file-name.ts +156 -0
- package/src/files/serialize-document.ts +15 -5
- package/src/format/constraints.ts +1 -1
- package/src/format/convert-file.ts +27 -13
- package/src/format/format-choices.ts +2 -1
- package/src/format/format-host.ts +91 -50
- package/src/github/github-auth-status.ts +27 -3
- package/src/github/github-auth.ts +21 -11
- package/src/github/github-publish.ts +28 -23
- package/src/grid/cell-editors.ts +46 -31
- package/src/grid/cell-popovers.ts +5 -3
- package/src/grid/edit-buffer.ts +10 -9
- package/src/grid/grid-controller.ts +25 -23
- package/src/grid/grid-layout.ts +21 -5
- package/src/grid/grid-open.ts +3 -33
- package/src/grid/grid-panel.ts +65 -6
- package/src/grid/grid-reveal.ts +34 -0
- package/src/grid/grid-source.ts +9 -31
- package/src/grid/grid-view.ts +45 -23
- package/src/grid/redirects-grid.ts +14 -5
- package/src/grid/redirects.ts +16 -14
- package/src/grid/schema-columns.ts +25 -19
- package/src/grid/sources/connector-source.ts +47 -20
- package/src/grid/sources/content-source.ts +100 -31
- package/src/grid/sources/csv-file-source.ts +2 -2
- package/src/grid/tabulator-tables.d.ts +61 -34
- package/src/hosting/document.ts +2 -2
- package/src/hosting/stage.ts +7 -7
- package/src/i18n/i18n-commands.ts +3 -3
- package/src/media/media-commands.ts +181 -0
- package/src/media/media-library-model.ts +232 -0
- package/src/media/media-library.ts +1283 -0
- package/src/media/media-pane.ts +51 -20
- package/src/new-project/add-repo-modal.ts +20 -19
- package/src/new-project/import-tab.ts +10 -14
- package/src/new-project/location-fields.ts +2 -1
- package/src/new-project/new-project-modal.ts +12 -9
- package/src/packages/jxsuite-update.ts +4 -3
- package/src/packages/pull-package-sync.ts +26 -25
- package/src/page-params.ts +97 -68
- package/src/panels/activity-panel.ts +38 -14
- package/src/panels/ai-chat/attached-context.ts +13 -7
- package/src/panels/ai-chat/chat-markdown.ts +8 -8
- package/src/panels/ai-chat/chat-view.ts +80 -73
- package/src/panels/ai-chat/composer.ts +30 -33
- package/src/panels/ai-chat/sessions-view.ts +1 -2
- package/src/panels/ai-panel.ts +23 -20
- package/src/panels/block-action-bar.ts +57 -46
- package/src/panels/bottom-dock.ts +5 -3
- package/src/panels/canvas-dnd-bridge.ts +36 -26
- package/src/panels/chat-panel.ts +6 -6
- package/src/panels/collections-panel.ts +306 -0
- package/src/panels/component-preview.ts +35 -13
- package/src/panels/data-explorer.ts +63 -26
- package/src/panels/data-grid.ts +18 -11
- package/src/panels/dnd.ts +115 -138
- package/src/panels/editors.ts +52 -21
- package/src/panels/elements-panel.ts +19 -5
- package/src/panels/empty-state.ts +2 -2
- package/src/panels/events-panel.ts +84 -69
- package/src/panels/formula-workspace.ts +78 -54
- package/src/panels/frontmatter-fields.ts +33 -28
- package/src/panels/git-diff-open.ts +10 -6
- package/src/panels/head-panel.ts +488 -202
- package/src/panels/i18n-panel.ts +20 -12
- package/src/panels/imports-panel.ts +25 -47
- package/src/panels/jump-bar.ts +75 -31
- package/src/panels/layers-panel.ts +130 -101
- package/src/panels/left-panel.ts +25 -11
- package/src/panels/navigator-panels.ts +23 -11
- package/src/panels/pane-context.ts +140 -49
- package/src/panels/pane-grid.ts +55 -26
- package/src/panels/panel-registry.ts +36 -46
- package/src/panels/properties-panel.ts +182 -124
- package/src/panels/quick-search.ts +53 -31
- package/src/panels/right-panel.ts +201 -45
- package/src/panels/seo-modal.ts +54 -125
- package/src/panels/settings-menu.ts +63 -61
- package/src/panels/settings-pane.ts +268 -162
- package/src/panels/signals-panel.ts +156 -135
- package/src/panels/site-model.ts +367 -0
- package/src/panels/site-panel.ts +638 -0
- package/src/panels/statement-editor.ts +230 -140
- package/src/panels/style-panel.ts +253 -206
- package/src/panels/style-utils.ts +114 -51
- package/src/panels/stylebook-doc.ts +195 -60
- package/src/panels/stylebook-layers-panel.ts +48 -89
- package/src/panels/stylebook-panel.ts +60 -27
- package/src/panels/styles-panel.ts +327 -0
- package/src/panels/tab-drop.ts +27 -11
- package/src/panels/tab-strip.ts +143 -49
- package/src/platform-errors.ts +57 -43
- package/src/platform.ts +59 -31
- package/src/platforms/cloud.ts +373 -176
- package/src/platforms/default-platform.ts +14 -8
- package/src/platforms/devserver.ts +180 -142
- package/src/platforms/read-batcher.ts +16 -8
- package/src/project-list.ts +2 -1
- package/src/publish/deploy-checklist.ts +20 -9
- package/src/publish/pages-service.ts +66 -27
- package/src/publish/publish-changes.ts +491 -0
- package/src/publish/publish-commands.ts +88 -22
- package/src/publish/publish-ids.ts +49 -0
- package/src/publish/publish-panel.ts +10 -6
- package/src/publish/publish-quick.ts +148 -0
- package/src/publish/publish-workspace.ts +926 -0
- package/src/publish/source-control.ts +907 -0
- package/src/recent-projects.ts +15 -8
- package/src/resize-edges.ts +26 -36
- package/src/services/a11y-report.ts +26 -19
- package/src/services/agent-seed.ts +23 -11
- package/src/services/ai-ask.ts +9 -12
- package/src/services/ai-command-tools.ts +68 -62
- package/src/services/ai-import-tools.ts +80 -67
- package/src/services/ai-models.ts +17 -13
- package/src/services/ai-project-tools.ts +68 -32
- package/src/services/ai-session-store.ts +19 -10
- package/src/services/ai-system-prompt.ts +46 -20
- package/src/services/ai-tools.ts +71 -27
- package/src/services/ai-write-report.ts +20 -12
- package/src/services/ai-writes.ts +4 -4
- package/src/services/automation.ts +74 -51
- package/src/services/cem-export.ts +149 -58
- package/src/services/cf-settings.ts +4 -4
- package/src/services/clock.ts +6 -1
- package/src/services/code-services.ts +37 -31
- package/src/services/connection.ts +2 -2
- package/src/services/context-manager.ts +14 -10
- package/src/services/context-resolver.ts +20 -8
- package/src/services/data-service.ts +19 -15
- package/src/services/directory-picker.ts +20 -14
- package/src/services/document-assistant.ts +39 -19
- package/src/services/gated-registry.ts +10 -6
- package/src/services/harness/chat-reducer.ts +23 -1
- package/src/services/import-client.ts +91 -38
- package/src/services/import-seed.ts +8 -2
- package/src/services/jx-validate.ts +28 -31
- package/src/services/live-preview.ts +0 -0
- package/src/services/live-surfaces.ts +6 -3
- package/src/services/model-uri.ts +10 -2
- package/src/services/module-preloads.ts +12 -8
- package/src/services/monaco-buffer.ts +43 -24
- package/src/services/monaco-lazy.ts +7 -8
- package/src/services/monaco-setup.ts +23 -16
- package/src/services/notify.ts +44 -17
- package/src/services/popover-report.ts +25 -10
- package/src/services/preview-eval.ts +20 -8
- package/src/services/profile.ts +13 -6
- package/src/services/project-path.ts +13 -10
- package/src/services/references.ts +0 -0
- package/src/services/render-critic.ts +29 -9
- package/src/services/settings/definitions.ts +25 -14
- package/src/services/settings/kernel.ts +13 -4
- package/src/services/settings/write-queue.ts +9 -9
- package/src/services/token-lint.ts +12 -10
- package/src/services/tool-executor.ts +17 -5
- package/src/services/tool-outcomes.ts +44 -24
- package/src/services/trusted-types.ts +24 -7
- package/src/settings/contexts-section.ts +11 -8
- package/src/settings/contributed-section.ts +128 -70
- package/src/settings/css-vars-editor.ts +119 -32
- package/src/settings/defs-editor.ts +38 -35
- package/src/settings/developer-panels.ts +43 -0
- package/src/settings/extension-rows.ts +16 -8
- package/src/settings/extension-sections.ts +42 -14
- package/src/settings/extensions-section.ts +4 -1
- package/src/settings/general-settings.ts +101 -28
- package/src/settings/locales-section.ts +20 -12
- package/src/settings/preferences-dialog.ts +17 -7
- package/src/settings/preferences-keymap.ts +7 -5
- package/src/settings/preferences-sections.ts +11 -5
- package/src/settings/project-sections.ts +28 -11
- package/src/settings/schema-field-ui.ts +12 -1
- package/src/settings/section-registry.ts +116 -11
- package/src/settings/settings-dialog.ts +192 -0
- package/src/settings/settings-document.ts +186 -166
- package/src/shell/tree.ts +6 -5
- package/src/shell.ts +536 -477
- package/src/site-context.ts +101 -32
- package/src/state.ts +68 -57
- package/src/store.ts +54 -34
- package/src/studio.ts +219 -116
- package/src/style/live-preview.ts +1 -1
- package/src/style/project-styles.ts +40 -7
- package/src/style/stylebook-specimens.ts +89 -0
- package/src/style/stylebook-target.ts +26 -0
- package/src/style/tag-inheritance.ts +105 -0
- package/src/style/token-ref.ts +5 -4
- package/src/style/variables-focus.ts +61 -0
- package/src/style/variables-view.ts +235 -0
- package/src/surfaces/about.ts +18 -19
- package/src/surfaces/add-new.json +1482 -0
- package/src/surfaces/add-new.ts +325 -0
- package/src/surfaces/add-repo.ts +17 -19
- package/src/surfaces/ai-chat.ts +33 -38
- package/src/surfaces/ai-credentials-form.ts +6 -16
- package/src/surfaces/ai-managed-connect.ts +3 -4
- package/src/surfaces/ai-model-picker.ts +3 -5
- package/src/surfaces/block-action-bar.ts +22 -11
- package/src/surfaces/boot-failure.json +4 -3
- package/src/surfaces/boot-failure.ts +4 -5
- package/src/surfaces/bottom-dock.json +1 -1
- package/src/surfaces/bottom-dock.ts +9 -18
- package/src/surfaces/canvas-stage.json +30 -19
- package/src/surfaces/canvas-stage.ts +17 -16
- package/src/surfaces/cf-account-picker.ts +17 -18
- package/src/surfaces/collections-panel.json +615 -0
- package/src/surfaces/collections-panel.ts +168 -0
- package/src/surfaces/commandbar.json +241 -96
- package/src/surfaces/commandbar.ts +145 -105
- package/src/surfaces/convert-repeater.ts +17 -19
- package/src/surfaces/data-actions.ts +9 -7
- package/src/surfaces/dialog.ts +26 -28
- package/src/surfaces/diff-toolbar.ts +9 -7
- package/src/surfaces/empty-state.json +1 -1
- package/src/surfaces/empty-state.ts +7 -10
- package/src/surfaces/entry-editor.json +136 -0
- package/src/surfaces/entry-editor.ts +35 -11
- package/src/surfaces/entry-inspector.json +371 -0
- package/src/surfaces/entry-inspector.ts +143 -0
- package/src/surfaces/expression-editor.ts +11 -25
- package/src/surfaces/files-panel.ts +27 -14
- package/src/surfaces/formula-palette.ts +4 -5
- package/src/surfaces/github-auth.ts +16 -20
- package/src/surfaces/github-publish.ts +17 -22
- package/src/surfaces/grid-cell.ts +30 -31
- package/src/surfaces/grid-open.ts +10 -14
- package/src/surfaces/grid-panel.ts +13 -9
- package/src/surfaces/grid-replace.ts +13 -13
- package/src/surfaces/grid-views.ts +15 -18
- package/src/surfaces/inspector-dock.json +162 -14
- package/src/surfaces/inspector-dock.ts +59 -31
- package/src/surfaces/jump-bar.ts +5 -6
- package/src/surfaces/jxsuite-update.ts +16 -22
- package/src/surfaces/library-pane.json +670 -437
- package/src/surfaces/library-pane.ts +111 -77
- package/src/surfaces/logic-panel.ts +17 -30
- package/src/surfaces/logic-workspace.ts +13 -15
- package/src/surfaces/media-browser.json +62 -6
- package/src/surfaces/media-browser.ts +26 -11
- package/src/surfaces/media-field.json +1 -1
- package/src/surfaces/media-field.ts +4 -5
- package/src/surfaces/media-library.json +1586 -0
- package/src/surfaces/media-library.ts +282 -0
- package/src/surfaces/media-pane.ts +8 -7
- package/src/surfaces/media-pick-dialog.json +71 -0
- package/src/surfaces/media-pick-dialog.ts +132 -0
- package/src/surfaces/menu.ts +47 -23
- package/src/surfaces/navigator-dock.ts +11 -12
- package/src/surfaces/new-project.ts +27 -26
- package/src/surfaces/pane-context.json +144 -77
- package/src/surfaces/pane-context.ts +44 -25
- package/src/surfaces/pane-grid.ts +15 -10
- package/src/surfaces/panel-activity.ts +5 -6
- package/src/surfaces/panel-data.ts +3 -4
- package/src/surfaces/panel-deploy-checklist.json +12 -6
- package/src/surfaces/panel-deploy-checklist.ts +8 -7
- package/src/surfaces/panel-elements.ts +5 -7
- package/src/surfaces/panel-i18n.ts +5 -7
- package/src/surfaces/panel-imports.ts +6 -13
- package/src/surfaces/panel-outline.ts +25 -19
- package/src/surfaces/panel-page.json +72 -2
- package/src/surfaces/panel-page.ts +49 -25
- package/src/surfaces/panel-problems.ts +5 -7
- package/src/surfaces/panel-signals.json +1 -1
- package/src/surfaces/panel-signals.ts +25 -39
- package/src/surfaces/panel-stylebook-layers.json +71 -204
- package/src/surfaces/panel-stylebook-layers.ts +5 -29
- package/src/surfaces/preferences.json +120 -48
- package/src/surfaces/preferences.ts +29 -11
- package/src/surfaces/progress-modal.ts +15 -9
- package/src/surfaces/properties-panel.json +1 -1
- package/src/surfaces/properties-panel.ts +20 -42
- package/src/surfaces/publish-quick.json +428 -0
- package/src/surfaces/publish-quick.ts +165 -0
- package/src/surfaces/publish-workspace.json +2892 -0
- package/src/surfaces/publish-workspace.ts +391 -0
- package/src/surfaces/publish.ts +18 -18
- package/src/surfaces/push-plan.ts +7 -8
- package/src/surfaces/rail.json +1 -159
- package/src/surfaces/rail.ts +22 -79
- package/src/surfaces/reference-field.ts +11 -15
- package/src/surfaces/schema-builder.ts +16 -22
- package/src/surfaces/schema-form.json +10 -2
- package/src/surfaces/schema-form.ts +17 -25
- package/src/surfaces/secret-field.ts +9 -6
- package/src/surfaces/seo.json +1 -1
- package/src/surfaces/seo.ts +21 -15
- package/src/surfaces/settings-contexts.ts +9 -7
- package/src/surfaces/settings-contributed.json +5 -5
- package/src/surfaces/settings-contributed.ts +32 -12
- package/src/surfaces/settings-css-vars.json +44 -36
- package/src/surfaces/settings-css-vars.ts +82 -16
- package/src/surfaces/settings-defs.json +2 -2
- package/src/surfaces/settings-defs.ts +17 -21
- package/src/surfaces/settings-deploy.json +2 -15
- package/src/surfaces/settings-deploy.ts +9 -16
- package/src/surfaces/settings-dialog.json +51 -0
- package/src/surfaces/settings-dialog.ts +169 -0
- package/src/surfaces/settings-extensions.ts +5 -6
- package/src/surfaces/settings-head.ts +33 -39
- package/src/surfaces/settings-locales.ts +8 -20
- package/src/surfaces/settings-overview.json +3 -3
- package/src/surfaces/settings-overview.ts +14 -8
- package/src/surfaces/settings-packages.ts +8 -7
- package/src/surfaces/settings-pane.json +269 -46
- package/src/surfaces/settings-pane.ts +88 -36
- package/src/surfaces/settings-rawjson.ts +5 -6
- package/src/surfaces/shell.json +2 -1
- package/src/surfaces/shell.ts +1 -2
- package/src/surfaces/site-panel.json +1029 -0
- package/src/surfaces/site-panel.ts +233 -0
- package/src/surfaces/slash-menu.json +63 -21
- package/src/surfaces/slash-menu.ts +42 -9
- package/src/surfaces/statements.ts +13 -18
- package/src/surfaces/statusbar.ts +56 -29
- package/src/surfaces/style-panel.ts +18 -31
- package/src/surfaces/stylebook-chrome.ts +3 -5
- package/src/surfaces/styles-panel.json +735 -0
- package/src/surfaces/styles-panel.ts +195 -0
- package/src/surfaces/styles-variables.json +149 -0
- package/src/surfaces/styles-variables.ts +145 -0
- package/src/surfaces/tab-strip.json +4 -4
- package/src/surfaces/tab-strip.ts +14 -13
- package/src/surfaces/target-line.ts +6 -7
- package/src/surfaces/welcome.ts +6 -8
- package/src/surfaces/writing-banner.json +94 -0
- package/src/surfaces/writing-banner.ts +80 -0
- package/src/tabs/bare-repeaters.ts +101 -0
- package/src/tabs/patch-ops.ts +4 -3
- package/src/tabs/project-config.ts +32 -21
- package/src/tabs/selection.ts +36 -8
- package/src/tabs/tab.ts +99 -48
- package/src/tabs/transact.ts +98 -53
- package/src/types.ts +53 -43
- package/src/ui/ai-credentials-form.ts +10 -13
- package/src/ui/ai-model-picker.ts +3 -3
- package/src/ui/cf-account-picker.ts +7 -9
- package/src/ui/color-selector.ts +9 -5
- package/src/ui/dynamic-slot.ts +7 -8
- package/src/ui/expression-editor.ts +112 -105
- package/src/ui/form-controls.ts +104 -56
- package/src/ui/formula-catalog.ts +239 -230
- package/src/ui/formula-chips.ts +33 -18
- package/src/ui/layers.ts +57 -31
- package/src/ui/media-picker.ts +300 -47
- package/src/ui/popover-surface.ts +20 -12
- package/src/ui/progress-modal.ts +13 -8
- package/src/ui/regions.ts +14 -12
- package/src/ui/schema-form.ts +372 -97
- package/src/ui/surface.ts +71 -8
- package/src/ui/timing.ts +9 -0
- package/src/ui/value-source.ts +44 -31
- package/src/ui/virtual-window.ts +29 -3
- package/src/utils/base64.ts +6 -4
- package/src/utils/edit-display.ts +366 -111
- package/src/utils/element-selectors.ts +3 -2
- package/src/utils/google-fonts.ts +15 -14
- package/src/utils/inherited-style.ts +18 -20
- package/src/utils/link-target.ts +1 -1
- package/src/utils/local-day.ts +18 -0
- package/src/utils/preview-format.ts +25 -3
- package/src/utils/strip-events.ts +49 -22
- package/src/utils/studio-utils.ts +29 -14
- package/src/view.ts +2 -3
- package/src/workspace/pane-derive.ts +14 -16
- package/src/workspace/session.ts +81 -50
- package/src/workspace/tab-workspace.ts +137 -0
- package/src/workspace/workspace-back.ts +189 -0
- package/src/workspace/workspace-home.ts +133 -0
- package/src/workspace/workspace-ids.ts +129 -0
- package/src/workspace/workspace-switch.ts +372 -0
- package/src/workspace/workspace.ts +165 -47
- package/styles/shell-frame.css +30 -7
- package/styles/shell-frame.json +15 -3
- package/dist/chunks/2020-va2wwra4.js +0 -4
- package/dist/chunks/adapter-f93pafd7.js +0 -4
- package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
- package/dist/chunks/cf-settings-125tdm0w.js +0 -4
- package/dist/chunks/color-area-jqhna8zy.js +0 -4
- package/dist/chunks/color-field-embq5ctg.js +0 -4
- package/dist/chunks/color-fpezvnkt.js +0 -4
- package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
- package/dist/chunks/combobox-773hdzyj.js +0 -4
- package/dist/chunks/components-ax2f1fnn.js +0 -4
- package/dist/chunks/content-source-108aqtk1.js +0 -4
- package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
- package/dist/chunks/dialog-mtm9fq5t.js +0 -4
- package/dist/chunks/editor-pfgdmkb0.js +0 -4
- package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
- package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
- package/dist/chunks/file-ops-meej5mqf.js +0 -4
- package/dist/chunks/files-44vp8a2s.js +0 -4
- package/dist/chunks/format-host-7q1petb9.js +0 -4
- package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
- package/dist/chunks/git-panel-zngbymvd.js +0 -4
- package/dist/chunks/grid-view-sx9vynsp.js +0 -51
- package/dist/chunks/icons-p44xhjf0.js +0 -4
- package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
- package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
- package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
- package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
- package/dist/chunks/index-wkyfjeqz.js +0 -4
- package/dist/chunks/jsonMode-s8kt9dsj.js +0 -13
- package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
- package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
- package/dist/chunks/layers-xd92fg8d.js +0 -4
- package/dist/chunks/listbox-s8fkmnq8.js +0 -4
- package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
- package/dist/chunks/media-picker-0svzkdyb.js +0 -4
- package/dist/chunks/menu-37d07z9m.js +0 -4
- package/dist/chunks/menu-5c55ea3d.js +0 -4
- package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
- package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
- package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
- package/dist/chunks/notify-0xgtn8q1.js +0 -4
- package/dist/chunks/number-field-gw7sq8rn.js +0 -4
- package/dist/chunks/parse-897fvqah.js +0 -4
- package/dist/chunks/platform-v1qctbe6.js +0 -4
- package/dist/chunks/popover-8htra4er.js +0 -4
- package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
- package/dist/chunks/quick-search-a54e6t5n.js +0 -4
- package/dist/chunks/references-gmqp82fs.js +0 -4
- package/dist/chunks/right-panel-v7t9awbk.js +0 -4
- package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
- package/dist/chunks/select-n3v7gwas.js +0 -4
- package/dist/chunks/split-pff8f3ze.js +0 -4
- package/dist/chunks/studio-0bhx5hz6.js +0 -5
- package/dist/chunks/studio-0k1ddnyy.js +0 -6
- package/dist/chunks/studio-1b04pd0j.js +0 -64
- package/dist/chunks/studio-4dwbj6gb.js +0 -5
- package/dist/chunks/studio-4tanh828.js +0 -5
- package/dist/chunks/studio-55h4mstj.js +0 -4
- package/dist/chunks/studio-5tnvjkz4.js +0 -5
- package/dist/chunks/studio-60dqgb0c.js +0 -5
- package/dist/chunks/studio-61dp09qg.js +0 -9
- package/dist/chunks/studio-63epcrj2.js +0 -5
- package/dist/chunks/studio-74k29dy9.js +0 -5
- package/dist/chunks/studio-7vg6jcd3.js +0 -5
- package/dist/chunks/studio-7zx31knw.js +0 -9
- package/dist/chunks/studio-8bxk97km.js +0 -5
- package/dist/chunks/studio-933e30n4.js +0 -5
- package/dist/chunks/studio-98wnwhbg.js +0 -5
- package/dist/chunks/studio-9mccjwjh.js +0 -14
- package/dist/chunks/studio-a2ke1e4t.js +0 -5
- package/dist/chunks/studio-e3a2a6v3.js +0 -4
- package/dist/chunks/studio-e81q1vb9.js +0 -5
- package/dist/chunks/studio-epgrmqqm.js +0 -5
- package/dist/chunks/studio-ery42sqr.js +0 -4
- package/dist/chunks/studio-g1shz58g.js +0 -5
- package/dist/chunks/studio-gf0fz03c.js +0 -5
- package/dist/chunks/studio-gjtpe62q.js +0 -6
- package/dist/chunks/studio-gkskhg7m.js +0 -5
- package/dist/chunks/studio-gx4dnjzd.js +0 -5
- package/dist/chunks/studio-j03zga3y.js +0 -9
- package/dist/chunks/studio-jhpxeckz.js +0 -5
- package/dist/chunks/studio-k01r7ykp.js +0 -5
- package/dist/chunks/studio-kk7h30ne.js +0 -7
- package/dist/chunks/studio-kt1zqney.js +0 -5
- package/dist/chunks/studio-m3cwhvye.js +0 -5
- package/dist/chunks/studio-mcayt6hz.js +0 -5
- package/dist/chunks/studio-myjcghv3.js +0 -5
- package/dist/chunks/studio-n8bxwc3y.js +0 -4
- package/dist/chunks/studio-ngm8gvpb.js +0 -5
- package/dist/chunks/studio-nj5a01jy.js +0 -928
- package/dist/chunks/studio-pcgz8heb.js +0 -5
- package/dist/chunks/studio-qcsq0t15.js +0 -5
- package/dist/chunks/studio-qkstvve9.js +0 -5
- package/dist/chunks/studio-qv1pwd3c.js +0 -5
- package/dist/chunks/studio-rc6dvxjb.js +0 -7
- package/dist/chunks/studio-s8dmmz66.js +0 -5
- package/dist/chunks/studio-sp5xzbj4.js +0 -6
- package/dist/chunks/studio-szsjbj0g.js +0 -5
- package/dist/chunks/studio-t1xzawhr.js +0 -16
- package/dist/chunks/studio-tdcprbqb.js +0 -5
- package/dist/chunks/studio-vrmcjf9g.js +0 -7
- package/dist/chunks/studio-vyc0b4he.js +0 -10
- package/dist/chunks/studio-w0cgf6jg.js +0 -5
- package/dist/chunks/studio-w3hskzqk.js +0 -5
- package/dist/chunks/studio-xgrgcdyh.js +0 -9
- package/dist/chunks/studio-xz2yxfcb.js +0 -5
- package/dist/chunks/studio-y6n42tgs.js +0 -5
- package/dist/chunks/studio-yb560vxr.js +0 -5
- package/dist/chunks/studio-yn9f8vtx.js +0 -5
- package/dist/chunks/studio-yw05w8f0.js +0 -7
- package/dist/chunks/studio-z16sgavc.js +0 -5
- package/dist/chunks/studio-zey7zsdw.js +0 -12
- package/dist/chunks/studio-zyqn40w4.js +0 -5
- package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
- package/dist/chunks/tabs-jwthg40w.js +0 -4
- package/dist/chunks/textfield-spy3hc77.js +0 -4
- package/dist/chunks/toast-4d35zd64.js +0 -4
- package/dist/chunks/toast-host-8sjmfed3.js +0 -4
- package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
- package/dist/chunks/tree-h19v1jfz.js +0 -4
- package/dist/chunks/tsMode-2frah6h1.js +0 -14
- package/dist/chunks/workspace-zt81g1ms.js +0 -4
- package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
- package/src/panels/frontmatter-panel.ts +0 -701
- package/src/panels/git-panel.ts +0 -1120
- package/src/surfaces/doc-header.json +0 -776
- package/src/surfaces/doc-header.ts +0 -231
- package/src/surfaces/git-panel.json +0 -1880
- package/src/surfaces/git-panel.ts +0 -272
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
* The **Entry editor** (site-architecture.md §7.4): a content entry's fields, as a form, in a pane.
|
|
4
4
|
*
|
|
5
5
|
* Until now a markdown entry could be edited two ways and neither was its schema: the canvas edited
|
|
6
|
-
* its BODY, and the Document Header card drew a field list from
|
|
7
|
-
* own type→widget ladder, which is a second implementation of
|
|
8
|
-
* branch, no validation and no value-source ladder. A JSON
|
|
9
|
-
* editor at all — it opened as a component tree, so `bio`
|
|
10
|
-
* child array.
|
|
6
|
+
* its BODY, and the Document Header card (since removed) drew a field list from
|
|
7
|
+
* `panels/frontmatter-fields.ts`'s own type→widget ladder, which is a second implementation of
|
|
8
|
+
* `ui/schema-form.ts` with no reference branch, no validation and no value-source ladder. A JSON
|
|
9
|
+
* entry (`authors/ada.json`) had no field editor at all — it opened as a component tree, so `bio`
|
|
10
|
+
* was a node's property and `links` was a child array.
|
|
11
11
|
*
|
|
12
12
|
* This is one editor over the schema form, so every improvement to the engine reaches content
|
|
13
13
|
* entries, settings and the inspector at once — and the `reference` control in particular arrives
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* it unshifts its mode onto the tab the file already has, so ⌘S, the dirty flag, the transaction
|
|
26
26
|
* log and undo are the ordinary document verbs. Every field commits through
|
|
27
27
|
* {@link mutateEntryField}, so an edit made here is undone by ⌘Z and replayed by a collaborator
|
|
28
|
-
* exactly as one made in the
|
|
28
|
+
* exactly as one made in the Inspector's Page tab.
|
|
29
29
|
*
|
|
30
30
|
* **One editor, two storage shapes.** A markdown entry keeps its fields in frontmatter; a JSON
|
|
31
31
|
* entry IS its fields. `content/entry-fields.ts` owns that single question, and this file never
|
|
@@ -50,17 +50,23 @@ import { mountEntryEditorSurface } from "../surfaces/entry-editor";
|
|
|
50
50
|
import { paneRegion } from "../ui/regions";
|
|
51
51
|
import { activateTab, workspace } from "../workspace/workspace";
|
|
52
52
|
import { commitEntryFields, entryFields, mutateEntryField } from "./entry-fields";
|
|
53
|
+
import type { EntryFields } from "./entry-fields";
|
|
53
54
|
import { DRAFT_FIELD, DRAFT_MEANING, hasDraftAxis, isDraftEntry } from "./draft-state";
|
|
54
|
-
import { collectionOfPath, missingRequired } from "./entry-model";
|
|
55
|
+
import { collectionOfPath, missingRequired, recordCollectionOfPath } from "./entry-model";
|
|
56
|
+
import { ENTRY_MODE, isRecordTab, recordPlace, showRecord } from "./record-entry";
|
|
57
|
+
import { requestGridReveal } from "../grid/grid-reveal";
|
|
58
|
+
import { titleFieldOf } from "./entry-summaries";
|
|
55
59
|
import type { EntryCollection } from "./entry-model";
|
|
56
60
|
import type { EntryEditorSurfaceHandle, EntryEditorView } from "../surfaces/entry-editor";
|
|
57
61
|
import type { JsonSchema, SchemaFormContext } from "../ui/schema-form";
|
|
58
62
|
import type { Tab } from "../tabs/tab";
|
|
59
63
|
import type { CanvasSurface } from "../canvas/canvas-surface";
|
|
60
|
-
import type {
|
|
64
|
+
import type { ContentTypeSchema, JsonObject } from "@jxsuite/schema/types";
|
|
65
|
+
import { isString } from "@jxsuite/schema/guards";
|
|
66
|
+
import { fieldTitle } from "../browse/library-source";
|
|
61
67
|
|
|
62
|
-
/** The `canvasMode` the entry form draws under. */
|
|
63
|
-
export
|
|
68
|
+
/** The `canvasMode` the entry form draws under (defined with the record a form may be over). */
|
|
69
|
+
export { ENTRY_MODE } from "./record-entry";
|
|
64
70
|
|
|
65
71
|
/** What an entry tab's mode list becomes when the Entry editor opens it: the form leads. */
|
|
66
72
|
const ENTRY_TAB_MODES = [ENTRY_MODE];
|
|
@@ -120,7 +126,7 @@ export function detachEntryPane(paneId: string): void {
|
|
|
120
126
|
* has explicitly published something should be able to see that they did.
|
|
121
127
|
*/
|
|
122
128
|
export function setEntryDraft(tab: Tab, draft: boolean): void {
|
|
123
|
-
transactDoc(tab, (t) => mutateEntryField(t, DRAFT_FIELD, draft
|
|
129
|
+
transactDoc(tab, (t) => mutateEntryField(t, DRAFT_FIELD, draft));
|
|
124
130
|
}
|
|
125
131
|
|
|
126
132
|
/** What the tab chip's draft pill says. A value, drawn by `surfaces/tab-strip.json`. */
|
|
@@ -148,7 +154,7 @@ export interface DraftPill {
|
|
|
148
154
|
* chip's `status` slot, and `.entry-pill`'s rules in `styles/overlays.css` are dead with it.
|
|
149
155
|
*/
|
|
150
156
|
export function entryDraftPill(tab: Tab): DraftPill | null {
|
|
151
|
-
const collection =
|
|
157
|
+
const collection = entryCollectionOf(tab);
|
|
152
158
|
const fields = entryFields(tab);
|
|
153
159
|
if (!collection || !hasDraftAxis(collection.schema, fields)) {
|
|
154
160
|
return null;
|
|
@@ -163,13 +169,29 @@ export function entryDraftPill(tab: Tab): DraftPill | null {
|
|
|
163
169
|
|
|
164
170
|
// ─── The form ────────────────────────────────────────────────────────────────
|
|
165
171
|
|
|
172
|
+
/**
|
|
173
|
+
* The words each field's row is titled with: the schema's own `title` where it states one, else the
|
|
174
|
+
* key in words (`publishedAt` → "Published at"), the spelling the Content home's columns use. A raw
|
|
175
|
+
* key is a storage name, and an author reads "Cover", not `cover`.
|
|
176
|
+
*/
|
|
177
|
+
export function fieldLabels(
|
|
178
|
+
schema: ContentTypeSchema | null | undefined,
|
|
179
|
+
): Record<string, { label: string }> {
|
|
180
|
+
return Object.fromEntries(
|
|
181
|
+
Object.entries(schema?.properties ?? {}).map(([name, field]) => [
|
|
182
|
+
name,
|
|
183
|
+
{ label: isString(field.title) && field.title !== "" ? field.title : fieldTitle(name) },
|
|
184
|
+
]),
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
166
188
|
/** The form's host context: enum pointers resolve against this project's configuration. */
|
|
167
|
-
function formContext(tab: Tab): SchemaFormContext {
|
|
189
|
+
export function formContext(tab: Tab): SchemaFormContext {
|
|
168
190
|
return {
|
|
169
191
|
fieldKeyPrefix: `entry:${tab.id}`,
|
|
170
192
|
resolvePointer: (pointer, scope) =>
|
|
171
193
|
resolveContextPointer(pointer, {
|
|
172
|
-
projectConfig:
|
|
194
|
+
projectConfig: projectState?.projectConfig ?? {},
|
|
173
195
|
scope,
|
|
174
196
|
}),
|
|
175
197
|
};
|
|
@@ -183,15 +205,42 @@ function formContext(tab: Tab): SchemaFormContext {
|
|
|
183
205
|
* missing from the file is a fact about the document, and saying so is the whole reason the form
|
|
184
206
|
* knows the schema.
|
|
185
207
|
*/
|
|
186
|
-
function absentRequiredErrors(
|
|
208
|
+
export function absentRequiredErrors(
|
|
187
209
|
collection: EntryCollection,
|
|
188
|
-
fields:
|
|
210
|
+
fields: EntryFields,
|
|
189
211
|
): Record<string, string> {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
212
|
+
return Object.fromEntries(
|
|
213
|
+
missingRequired(collection.schema, fields).map((field) => [
|
|
214
|
+
field,
|
|
215
|
+
"Required — this entry does not have one.",
|
|
216
|
+
]),
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** The collection an entry tab's form is typed by: its file's, or for a record its file's records'. */
|
|
221
|
+
function entryCollectionOf(tab: Tab): EntryCollection | null {
|
|
222
|
+
return isRecordTab(tab)
|
|
223
|
+
? recordCollectionOfPath(tab.documentPath)
|
|
224
|
+
: collectionOfPath(tab.documentPath);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* The schema with the entry's title field moved to the top: what an entry is called is the first
|
|
229
|
+
* thing an author looks for, and a schema imported from a CMS lists its properties alphabetically,
|
|
230
|
+
* which put `title` after forty other fields.
|
|
231
|
+
*/
|
|
232
|
+
export function titleFirst(
|
|
233
|
+
form: JsonSchema,
|
|
234
|
+
schema: ContentTypeSchema | null,
|
|
235
|
+
fields: EntryFields,
|
|
236
|
+
): JsonSchema {
|
|
237
|
+
const title = titleFieldOf(schema, fields);
|
|
238
|
+
const properties = form.properties ?? {};
|
|
239
|
+
const held = title === null ? undefined : properties[title];
|
|
240
|
+
if (title === null || held === undefined) {
|
|
241
|
+
return form;
|
|
193
242
|
}
|
|
194
|
-
return
|
|
243
|
+
return { ...form, properties: { [title]: held, ...properties } };
|
|
195
244
|
}
|
|
196
245
|
|
|
197
246
|
/** What the document says when the file belongs to no collection: the reason, then the fix. */
|
|
@@ -212,14 +261,20 @@ function entryView(paneId: string, tab: Tab, collection: EntryCollection | null)
|
|
|
212
261
|
emptyLine: emptyLine(tab),
|
|
213
262
|
fieldsRegion,
|
|
214
263
|
name: "",
|
|
264
|
+
nextDisabled: true,
|
|
215
265
|
note: "",
|
|
216
266
|
noteState: "hidden",
|
|
267
|
+
place: "",
|
|
268
|
+
previousDisabled: true,
|
|
269
|
+
recordNav: "hidden",
|
|
217
270
|
region,
|
|
218
271
|
stage: "empty",
|
|
219
272
|
};
|
|
220
273
|
}
|
|
221
274
|
const fields = entryFields(tab);
|
|
222
275
|
const draft = isDraftEntry(fields);
|
|
276
|
+
const record = isRecordTab(tab);
|
|
277
|
+
const place = recordPlace(tab);
|
|
223
278
|
return {
|
|
224
279
|
collection: collection.name,
|
|
225
280
|
draft,
|
|
@@ -227,14 +282,31 @@ function entryView(paneId: string, tab: Tab, collection: EntryCollection | null)
|
|
|
227
282
|
draftHint: DRAFT_MEANING,
|
|
228
283
|
emptyLine: "",
|
|
229
284
|
fieldsRegion,
|
|
230
|
-
|
|
285
|
+
// A record is called what the Content home calls it: its title field, else its row.
|
|
286
|
+
name: record
|
|
287
|
+
? recordName(collection, fields, place.index)
|
|
288
|
+
: (tab.documentPath?.split("/").pop() ?? "Untitled"),
|
|
289
|
+
nextDisabled: place.next === null,
|
|
231
290
|
note: DRAFT_MEANING,
|
|
232
291
|
noteState: draft ? "shown" : "hidden",
|
|
292
|
+
place: place.index === -1 ? "" : `${place.index + 1} of ${place.total}`,
|
|
293
|
+
previousDisabled: place.previous === null,
|
|
294
|
+
recordNav: record ? "shown" : "hidden",
|
|
233
295
|
region,
|
|
234
296
|
stage: "entry",
|
|
235
297
|
};
|
|
236
298
|
}
|
|
237
299
|
|
|
300
|
+
/** A record's heading: its title field's text, else its first text, else "Row n". */
|
|
301
|
+
function recordName(collection: EntryCollection, fields: EntryFields, index: number): string {
|
|
302
|
+
const field = titleFieldOf(collection.schema, fields);
|
|
303
|
+
const named = field === null ? undefined : fields[field];
|
|
304
|
+
if (isString(named) && named.trim() !== "") {
|
|
305
|
+
return named.trim();
|
|
306
|
+
}
|
|
307
|
+
return index === -1 ? "Record" : `Row ${index + 1}`;
|
|
308
|
+
}
|
|
309
|
+
|
|
238
310
|
/**
|
|
239
311
|
* Mount the entry form into the pane.
|
|
240
312
|
*
|
|
@@ -280,19 +352,30 @@ export function renderEntryMode(surface: CanvasSurface, tab: Tab): void {
|
|
|
280
352
|
return;
|
|
281
353
|
}
|
|
282
354
|
const fields = entryFields(tab);
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
355
|
+
/* SAFETY: `collection` comes from `collectionOfPath`, which matches only a content type that
|
|
356
|
+
declares a `schema` (`findContentTypeSchema` refuses one without), and that schema is the
|
|
357
|
+
collection's JSON Schema — the shape `JsonSchema` names for the form. `fields` is a
|
|
358
|
+
frontmatter block or a JSON entry's own root (entry-fields.ts), both parsed from YAML or
|
|
359
|
+
JSON text, so every value is JSON; a key an editor cleared reads as absent either way. */
|
|
360
|
+
const form = mountSchemaForm(
|
|
361
|
+
`entry:${paneId}`,
|
|
362
|
+
titleFirst(collection.schema as JsonSchema, collection.schema, fields),
|
|
363
|
+
fields as JsonObject,
|
|
364
|
+
{
|
|
365
|
+
context: formContext(tab),
|
|
366
|
+
errors: absentRequiredErrors(collection, fields),
|
|
367
|
+
onChange: (patch) => commitEntryFields(tab, patch),
|
|
368
|
+
rerender: redraw,
|
|
369
|
+
ui: fieldLabels(collection.schema),
|
|
370
|
+
},
|
|
371
|
+
);
|
|
289
372
|
if (form.parentNode !== formHost) {
|
|
290
373
|
formHost.replaceChildren(form);
|
|
291
374
|
}
|
|
292
375
|
};
|
|
293
376
|
|
|
294
377
|
const draw = () => {
|
|
295
|
-
const collection =
|
|
378
|
+
const collection = entryCollectionOf(tab);
|
|
296
379
|
if (!collection) {
|
|
297
380
|
/* The `fields` node goes with the case that held it, so the handle is dropped here rather
|
|
298
381
|
than left pointing at a node the reconciler is about to remove. */
|
|
@@ -305,17 +388,37 @@ export function renderEntryMode(surface: CanvasSurface, tab: Tab): void {
|
|
|
305
388
|
const scope = effectScope();
|
|
306
389
|
const mounted = mountEntryEditorSurface(
|
|
307
390
|
canvasWrap,
|
|
308
|
-
entryView(paneId, tab,
|
|
391
|
+
entryView(paneId, tab, entryCollectionOf(tab)),
|
|
309
392
|
{
|
|
310
393
|
openContentTypes: () => {
|
|
311
394
|
void activeRegistry()?.run("settings.open", { section: "content" });
|
|
312
395
|
},
|
|
396
|
+
openGrid: () => {
|
|
397
|
+
// The grid lands on the row this form was showing (`grid/grid-reveal.ts`).
|
|
398
|
+
const { index } = recordPlace(tab);
|
|
399
|
+
if (index !== -1 && tab.documentPath) {
|
|
400
|
+
requestGridReveal(tab.documentPath, index);
|
|
401
|
+
}
|
|
402
|
+
tab.session.ui.canvasMode = "grid";
|
|
403
|
+
},
|
|
313
404
|
setDraft: (draft) => setEntryDraft(tab, draft),
|
|
405
|
+
showNext: () => {
|
|
406
|
+
const { next } = recordPlace(tab);
|
|
407
|
+
if (next !== null) {
|
|
408
|
+
showRecord(tab, next);
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
showPrevious: () => {
|
|
412
|
+
const { previous } = recordPlace(tab);
|
|
413
|
+
if (previous !== null) {
|
|
414
|
+
showRecord(tab, previous);
|
|
415
|
+
}
|
|
416
|
+
},
|
|
314
417
|
},
|
|
315
418
|
{
|
|
316
419
|
fieldsSlot: (host) => {
|
|
317
420
|
formHost = host;
|
|
318
|
-
paintForm(
|
|
421
|
+
paintForm(entryCollectionOf(tab));
|
|
319
422
|
},
|
|
320
423
|
},
|
|
321
424
|
);
|
|
@@ -332,8 +435,10 @@ export function renderEntryMode(surface: CanvasSurface, tab: Tab): void {
|
|
|
332
435
|
// Never this effect's guess. `tab.doc.document` is also the reference every transaction
|
|
333
436
|
// Replaces, so it is how an undo reaches the form whichever store the edit was in.
|
|
334
437
|
void tab.doc.document;
|
|
335
|
-
void tab.doc.content
|
|
438
|
+
void tab.doc.content.frontmatter;
|
|
336
439
|
void projectState?.projectConfig?.content;
|
|
440
|
+
// A record's fields are its grid's rows and pending cells, read through `entryFields`, which
|
|
441
|
+
// Tracks them. Which record is shown is tracked by `recordOf` the same way.
|
|
337
442
|
draw();
|
|
338
443
|
});
|
|
339
444
|
});
|
|
@@ -365,7 +470,7 @@ export async function openEntryEditor(path: string): Promise<Tab | null> {
|
|
|
365
470
|
tab.session.ui.canvasMode = ENTRY_MODE;
|
|
366
471
|
tab.session.ui.preview = false;
|
|
367
472
|
activateTab(id);
|
|
368
|
-
return tab
|
|
473
|
+
return tab;
|
|
369
474
|
}
|
|
370
475
|
return null;
|
|
371
476
|
}
|
|
@@ -32,9 +32,17 @@ import { cloneValue } from "@jxsuite/schema/doc-ops";
|
|
|
32
32
|
import { notePreviewOverlayEdit } from "../preview/preview-overlay";
|
|
33
33
|
import { recordDocOp } from "../tabs/patch-ops";
|
|
34
34
|
import { mutateUpdateFrontmatter, transactDoc } from "../tabs/transact";
|
|
35
|
+
import { commitRecordFields, isRecordTab, recordFields } from "./record-entry";
|
|
36
|
+
import type { JxDocumentValue } from "@jxsuite/schema/types";
|
|
35
37
|
import type { Tab } from "../tabs/tab";
|
|
36
38
|
import type { JsonValue } from "../types";
|
|
37
39
|
|
|
40
|
+
/**
|
|
41
|
+
* An entry's fields, whichever record holds them: a frontmatter block's keys, or a JSON entry's own
|
|
42
|
+
* document keys. `undefined` is a key an editor has cleared.
|
|
43
|
+
*/
|
|
44
|
+
export type EntryFields = Record<string, JxDocumentValue | undefined>;
|
|
45
|
+
|
|
38
46
|
/**
|
|
39
47
|
* Whether this tab's entry fields are the document itself rather than a frontmatter block.
|
|
40
48
|
*
|
|
@@ -56,10 +64,12 @@ function fieldsAreDocument(tab: Tab): boolean {
|
|
|
56
64
|
* reactive tab, and a copy would break that. It is also the identity a caller can compare against
|
|
57
65
|
* `tab.doc.document` to see which store answered.
|
|
58
66
|
*/
|
|
59
|
-
export function entryFields(tab: Tab):
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
67
|
+
export function entryFields(tab: Tab): EntryFields {
|
|
68
|
+
// A record of a file-backed collection keeps its fields in a row of its file's grid.
|
|
69
|
+
if (isRecordTab(tab)) {
|
|
70
|
+
return recordFields(tab);
|
|
71
|
+
}
|
|
72
|
+
return fieldsAreDocument(tab) ? tab.doc.document : tab.doc.content.frontmatter;
|
|
63
73
|
}
|
|
64
74
|
|
|
65
75
|
/**
|
|
@@ -72,7 +82,7 @@ export function entryFields(tab: Tab): Record<string, unknown> {
|
|
|
72
82
|
* is already the "not surgically patchable, fall back" signal `transactDoc` reads.
|
|
73
83
|
*/
|
|
74
84
|
function mutateDocumentField(tab: Tab, field: string, value?: JsonValue): void {
|
|
75
|
-
const doc = tab.doc.document
|
|
85
|
+
const doc = tab.doc.document;
|
|
76
86
|
const before = Object.hasOwn(doc, field) ? cloneValue(doc[field]) : undefined;
|
|
77
87
|
const deletes = value === undefined || value === null || value === "";
|
|
78
88
|
if (deletes) {
|
|
@@ -100,7 +110,9 @@ function mutateDocumentField(tab: Tab, field: string, value?: JsonValue): void {
|
|
|
100
110
|
* step.
|
|
101
111
|
*/
|
|
102
112
|
export function mutateEntryField(tab: Tab, field: string, value?: JsonValue): void {
|
|
103
|
-
if (
|
|
113
|
+
if (isRecordTab(tab)) {
|
|
114
|
+
commitRecordFields(tab, { [field]: value });
|
|
115
|
+
} else if (fieldsAreDocument(tab)) {
|
|
104
116
|
mutateDocumentField(tab, field, value);
|
|
105
117
|
} else {
|
|
106
118
|
mutateUpdateFrontmatter(tab, field, value);
|
|
@@ -113,10 +125,15 @@ export function mutateEntryField(tab: Tab, field: string, value?: JsonValue): vo
|
|
|
113
125
|
* `renderForm` emits single-key patches today, but committing per key would put a multi-key patch
|
|
114
126
|
* on the undo stack as several steps — and an author who changed one thing expects one ⌘Z.
|
|
115
127
|
*/
|
|
116
|
-
export function commitEntryFields(tab: Tab, patch: Record<string,
|
|
128
|
+
export function commitEntryFields(tab: Tab, patch: Record<string, JsonValue | undefined>): void {
|
|
129
|
+
// A record's edit is the grid buffer's, whose own undo group is the one ⌘Z reverts.
|
|
130
|
+
if (isRecordTab(tab)) {
|
|
131
|
+
commitRecordFields(tab, patch);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
117
134
|
transactDoc(tab, (t) => {
|
|
118
135
|
for (const [field, value] of Object.entries(patch)) {
|
|
119
|
-
mutateEntryField(t, field, value
|
|
136
|
+
mutateEntryField(t, field, value);
|
|
120
137
|
}
|
|
121
138
|
});
|
|
122
139
|
}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
2
|
+
/**
|
|
3
|
+
* The Inspector's Entry tab: what the Page tab draws while a collection entry is the focused
|
|
4
|
+
* document (`specs/studio.md` §6, §22.5; the Content-Entry board's sidebar).
|
|
5
|
+
*
|
|
6
|
+
* Four things, in the board's order: the entry's **status** (its draft flag, when the collection
|
|
7
|
+
* has a draft workflow, `content/draft-state.ts`), its **fields** as the collection's schema types
|
|
8
|
+
* them (`ui/schema-form.ts` over `content/entry-fields.ts`, the same form and the same transacted
|
|
9
|
+
* commits as the form-only editor, so ⌘Z undoes a field here exactly as it does there), the **URL**
|
|
10
|
+
* its collection page publishes it at (`content/collection-pages.ts`), and the **file** it is
|
|
11
|
+
* stored in, with what that file holds.
|
|
12
|
+
*
|
|
13
|
+
* The body is written on the canvas beside it; this tab is the entry's frontmatter (or, for a JSON
|
|
14
|
+
* entry opened on the canvas by hand, its root). The form-only `entry` editor stays for the entries
|
|
15
|
+
* the canvas cannot write.
|
|
16
|
+
*
|
|
17
|
+
* @docs studio/projects/content-types
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { effect, effectScope } from "../reactivity";
|
|
21
|
+
import { projectState } from "../store";
|
|
22
|
+
import { runActiveReported } from "../commands/run-reported";
|
|
23
|
+
import { mountSchemaForm } from "../ui/schema-form";
|
|
24
|
+
import { collectionForFile } from "./collection-match";
|
|
25
|
+
import { capitalise, contentCollection } from "./content-collections";
|
|
26
|
+
import {
|
|
27
|
+
entryLocale,
|
|
28
|
+
entryUrl,
|
|
29
|
+
onCollectionPagesRead,
|
|
30
|
+
peekCollectionPage,
|
|
31
|
+
} from "./collection-pages";
|
|
32
|
+
import { commitEntryFields, entryFields } from "./entry-fields";
|
|
33
|
+
import { DRAFT_MEANING, hasDraftAxis, isDraftEntry } from "./draft-state";
|
|
34
|
+
import { entryCollection } from "./entry-model";
|
|
35
|
+
import {
|
|
36
|
+
absentRequiredErrors,
|
|
37
|
+
fieldLabels,
|
|
38
|
+
formContext,
|
|
39
|
+
setEntryDraft,
|
|
40
|
+
titleFirst,
|
|
41
|
+
} from "./entry-editor";
|
|
42
|
+
import { mountEntryInspectorSurface } from "../surfaces/entry-inspector";
|
|
43
|
+
import type { EntryInspectorHandle, EntryInspectorView } from "../surfaces/entry-inspector";
|
|
44
|
+
import type { JsonSchema } from "../ui/schema-form";
|
|
45
|
+
import type { JsonObject } from "@jxsuite/schema/types";
|
|
46
|
+
import type { EffectScope } from "@vue/reactivity";
|
|
47
|
+
import type { Tab } from "../tabs/tab";
|
|
48
|
+
|
|
49
|
+
/** The region the tab's root carries. */
|
|
50
|
+
export const ENTRY_INSPECTOR_REGION = "inspector/entry";
|
|
51
|
+
|
|
52
|
+
/** A word with its first letter in capitals. */
|
|
53
|
+
|
|
54
|
+
/** Whether a tab's document is a collection entry: what titles the Page tab "Entry" (§6). */
|
|
55
|
+
export function isEntryTab(tab: Tab | null): boolean {
|
|
56
|
+
const match = collectionForFile(tab?.documentPath);
|
|
57
|
+
return match !== null && !match.fileBacked;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** What the tab draws for an entry. */
|
|
61
|
+
export function entryInspectorView(tab: Tab): EntryInspectorView {
|
|
62
|
+
const path = tab.documentPath ?? "";
|
|
63
|
+
const match = collectionForFile(path);
|
|
64
|
+
const name = match?.name ?? "";
|
|
65
|
+
const collection = entryCollection(name);
|
|
66
|
+
const fields = entryFields(tab);
|
|
67
|
+
const draftAxis = hasDraftAxis(collection?.schema, fields);
|
|
68
|
+
const draft = isDraftEntry(fields);
|
|
69
|
+
const page = name === "" ? null : peekCollectionPage(name, entryLocale(path));
|
|
70
|
+
const url = page ? entryUrl(page, path, fields) : null;
|
|
71
|
+
const isJson = path.endsWith(".json");
|
|
72
|
+
return {
|
|
73
|
+
draft,
|
|
74
|
+
draftAxis: draftAxis ? "shown" : "hidden",
|
|
75
|
+
draftHint: DRAFT_MEANING,
|
|
76
|
+
fieldsState: collection?.schema ? "form" : "none",
|
|
77
|
+
kind: capitalise(contentCollection(name)?.item ?? "entry"),
|
|
78
|
+
path,
|
|
79
|
+
region: ENTRY_INSPECTOR_REGION,
|
|
80
|
+
status: draftAxis ? (draft ? "Draft" : "Published") : "",
|
|
81
|
+
storage: isJson
|
|
82
|
+
? ". Its fields are the file itself."
|
|
83
|
+
: ". Fields are its frontmatter, and the body is its Markdown.",
|
|
84
|
+
url: url ?? "",
|
|
85
|
+
urlState: page === undefined ? "loading" : url ? "shown" : page ? "unlisted" : "none",
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ─── Mounting ────────────────────────────────────────────────────────────────
|
|
90
|
+
|
|
91
|
+
interface StandingInspector {
|
|
92
|
+
host: HTMLElement;
|
|
93
|
+
tabId: string;
|
|
94
|
+
handle: EntryInspectorHandle;
|
|
95
|
+
scope: EffectScope;
|
|
96
|
+
formHost: HTMLElement | null;
|
|
97
|
+
/**
|
|
98
|
+
* Repaint this tab, if it is still the one standing: the form's, the pages index's and the
|
|
99
|
+
* effect's.
|
|
100
|
+
*/
|
|
101
|
+
redraw: () => void;
|
|
102
|
+
unlisten: () => void;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
let _standing: StandingInspector | null = null;
|
|
106
|
+
|
|
107
|
+
/** Put the field form into the node the document made for it, or bring it up to date. */
|
|
108
|
+
function paintForm(standing: StandingInspector, tab: Tab): void {
|
|
109
|
+
const collection = entryCollection(collectionForFile(tab.documentPath)?.name ?? "");
|
|
110
|
+
if (!standing.formHost || !collection?.schema) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const fields = entryFields(tab);
|
|
114
|
+
/* SAFETY: `collection.schema` is the collection's JSON Schema, the shape `JsonSchema` names for
|
|
115
|
+
the form; `fields` is a frontmatter block or a JSON entry's root, both parsed from YAML or JSON
|
|
116
|
+
text, so every value is JSON. The same reading `entry-editor.ts` makes. */
|
|
117
|
+
const form = mountSchemaForm(
|
|
118
|
+
"entry-inspector",
|
|
119
|
+
titleFirst(collection.schema as JsonSchema, collection.schema, fields),
|
|
120
|
+
fields as JsonObject,
|
|
121
|
+
{
|
|
122
|
+
context: formContext(tab),
|
|
123
|
+
errors: absentRequiredErrors(collection, fields),
|
|
124
|
+
onChange: (patch) => commitEntryFields(tab, patch),
|
|
125
|
+
rerender: standing.redraw,
|
|
126
|
+
ui: fieldLabels(collection.schema),
|
|
127
|
+
},
|
|
128
|
+
);
|
|
129
|
+
if (form.parentNode !== standing.formHost) {
|
|
130
|
+
standing.formHost.replaceChildren(form);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Repaint the tab and its form. */
|
|
135
|
+
function draw(standing: StandingInspector, tab: Tab): void {
|
|
136
|
+
const view = entryInspectorView(tab);
|
|
137
|
+
if (view.fieldsState === "none") {
|
|
138
|
+
standing.formHost = null;
|
|
139
|
+
}
|
|
140
|
+
standing.handle.update(view);
|
|
141
|
+
paintForm(standing, tab);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Take the tab down. Idempotent. */
|
|
145
|
+
export function unmountEntryInspector(host?: HTMLElement): void {
|
|
146
|
+
if (!_standing || (host !== undefined && _standing.host !== host)) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
_standing.unlisten();
|
|
150
|
+
_standing.scope.stop();
|
|
151
|
+
_standing.handle.dispose();
|
|
152
|
+
_standing = null;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Draw the Entry tab for `tab` into `host`, or bring the one already there up to date.
|
|
157
|
+
*
|
|
158
|
+
* Owns its own effect over the entry's fields, like the form-only editor, so a field commit
|
|
159
|
+
* repaints the tab and nothing else.
|
|
160
|
+
*/
|
|
161
|
+
export function renderEntryInspector(host: HTMLElement, tab: Tab): void {
|
|
162
|
+
if (
|
|
163
|
+
_standing &&
|
|
164
|
+
_standing.host === host &&
|
|
165
|
+
_standing.tabId === tab.id &&
|
|
166
|
+
_standing.handle.attached()
|
|
167
|
+
) {
|
|
168
|
+
draw(_standing, tab);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
unmountEntryInspector();
|
|
172
|
+
const scope = effectScope();
|
|
173
|
+
const redraw = (): void => {
|
|
174
|
+
if (_standing === standing) {
|
|
175
|
+
draw(standing, tab);
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
const standing: StandingInspector = {
|
|
179
|
+
formHost: null,
|
|
180
|
+
handle: mountEntryInspectorSurface(
|
|
181
|
+
host,
|
|
182
|
+
entryInspectorView(tab),
|
|
183
|
+
{
|
|
184
|
+
openFields: () => {
|
|
185
|
+
const name = collectionForFile(tab.documentPath)?.name;
|
|
186
|
+
void runActiveReported(
|
|
187
|
+
"settings.open",
|
|
188
|
+
name ? { entry: name, section: "content" } : { section: "content" },
|
|
189
|
+
"Entry",
|
|
190
|
+
);
|
|
191
|
+
},
|
|
192
|
+
/* The command, not a local open(): Search appearance has one definition site, and an
|
|
193
|
+
entry's search title, description and image are frontmatter it commits into. */
|
|
194
|
+
openSeo: () => {
|
|
195
|
+
void runActiveReported("document.openSeo", undefined, "Entry");
|
|
196
|
+
},
|
|
197
|
+
setDraft: (draft) => setEntryDraft(tab, draft),
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
fieldsSlot: (element) => {
|
|
201
|
+
if (_standing === standing) {
|
|
202
|
+
standing.formHost = element;
|
|
203
|
+
paintForm(standing, tab);
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
),
|
|
208
|
+
host,
|
|
209
|
+
redraw,
|
|
210
|
+
scope,
|
|
211
|
+
tabId: tab.id,
|
|
212
|
+
unlisten: onCollectionPagesRead(redraw),
|
|
213
|
+
};
|
|
214
|
+
_standing = standing;
|
|
215
|
+
scope.run(() => {
|
|
216
|
+
effect(() => {
|
|
217
|
+
// Both stores, for the reason `entry-editor.ts` gives: which one holds the fields is
|
|
218
|
+
// `entry-fields.ts`'s answer, and the document is the reference every transaction replaces.
|
|
219
|
+
void tab.doc.document;
|
|
220
|
+
void tab.doc.content.frontmatter;
|
|
221
|
+
void projectState?.projectConfig?.content;
|
|
222
|
+
redraw();
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
}
|