@jxsuite/studio 6.1.2 → 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/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-0fj8a4ga.js → color-area-6rbra5dy.js} +2 -2
- package/dist/chunks/{color-field-xch8kx2g.js → color-field-gy56c94g.js} +3 -3
- package/dist/chunks/color-m7r1vk54.js +4 -0
- package/dist/chunks/{color-slider-jxd8v350.js → color-slider-sqqdyf6c.js} +2 -2
- package/dist/chunks/{combobox-p0efwjke.js → combobox-72h32ejk.js} +3 -3
- 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/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-d2wq9ezg.js → grid-view-qg1b5eqx.js} +25 -25
- package/dist/chunks/{icons-pnfz478q.js → icons-63bjtbs7.js} +2 -2
- package/dist/chunks/{iframe-entry-jdcktez8.js → iframe-entry-2zggzajv.js} +4 -4
- package/dist/chunks/{iframe-entry-zap785cw.js → iframe-entry-76j8vwwx.js} +4 -4
- package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
- package/dist/chunks/{iframe-entry-x0ygf2yr.js → iframe-entry-pkgmcgp0.js} +4 -4
- package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
- package/dist/chunks/{index-zpjmzqfk.js → index-32eqzv1k.js} +3 -3
- package/dist/chunks/index-f0jn7nnp.js +4 -0
- package/dist/chunks/{javascript-m54mnwp6.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-e74qjyq6.js → listbox-c421cf8c.js} +2 -2
- 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-n6yzswmy.js → menu-bdpzbfvs.js} +2 -2
- package/dist/chunks/{monaco-binding-7gx83x3r.js → monaco-binding-vq1hgnn0.js} +3 -3
- 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/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/source-control-kwktr9y6.js +4 -0
- package/dist/chunks/{split-n2gfpm5m.js → split-c9zfdgxf.js} +2 -2
- 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-2j1cb95x.js → studio-6m380wp7.js} +4 -4
- package/dist/chunks/studio-80jyh1xh.js +4 -0
- package/dist/chunks/studio-83mk4bgg.js +9 -0
- package/dist/chunks/{studio-v0jzqdjm.js → studio-881z1xrx.js} +4 -4
- package/dist/chunks/studio-8m0y2qe7.js +5 -0
- package/dist/chunks/{studio-d81xfh1g.js → studio-8tr6cfrc.js} +4 -4
- 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-dgz8d0c1.js → studio-bbe4c90a.js} +4 -4
- 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-90pq9km1.js → studio-jcnsdaep.js} +4 -4
- package/dist/chunks/studio-jsgf2q5k.js +7 -0
- package/dist/chunks/{studio-0q988f9w.js → studio-k3xxbagr.js} +3 -3
- package/dist/chunks/{studio-5ve6bbep.js → studio-k7evxqh4.js} +4 -4
- 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-485046te.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-1fxkaaea.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-tq0rtfwj.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-a3g98wjr.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-r5qy30vx.js +5 -0
- 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/toast-1gv0h53h.js +4 -0
- package/dist/chunks/{toast-host-ke5z4ng7.js → toast-host-1yg5ar8d.js} +3 -3
- package/dist/chunks/{tooltip-5v8ngwj2.js → tooltip-yypz28gq.js} +3 -3
- package/dist/chunks/{tree-mdq3v5cw.js → tree-9xa4hm7n.js} +2 -2
- 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-nze0k6mv.js → ws-client-bv552sfx.js} +3 -3
- package/dist/iframe-entry.js +20 -16
- package/dist/manifest.json +77 -63
- package/dist/studio.js +103 -104
- package/dist/workers/ts.worker.js +3 -3
- package/package.json +12 -11
- package/src/browse/component-examples.ts +272 -0
- package/src/browse/library-commands.ts +64 -104
- package/src/browse/library-layouts.ts +263 -49
- package/src/browse/library-model.ts +181 -133
- package/src/browse/library-pane.ts +738 -446
- package/src/browse/library-preview.ts +149 -19
- 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 +16 -1
- package/src/canvas/canvas-live-render.ts +222 -30
- package/src/canvas/canvas-origin.ts +37 -12
- package/src/canvas/canvas-page-context.ts +112 -0
- package/src/canvas/canvas-render.ts +113 -107
- package/src/canvas/canvas-utils.ts +57 -12
- package/src/canvas/iframe-drop.ts +107 -0
- package/src/canvas/iframe-entry.ts +24 -12
- package/src/canvas/iframe-host.ts +134 -62
- package/src/canvas/iframe-keys.ts +11 -0
- package/src/canvas/iframe-patch.ts +8 -7
- package/src/canvas/iframe-protocol.ts +24 -5
- package/src/canvas/iframe-render.ts +48 -1
- package/src/canvas/iframe-subtree.ts +5 -2
- package/src/canvas/npm-modules.ts +22 -0
- package/src/canvas/preview-navigate.ts +16 -0
- package/src/canvas/repeater-sources.ts +200 -0
- package/src/canvas/stage-scrollbar.ts +5 -1
- package/src/canvas/surface-registry.ts +6 -0
- package/src/commands/app-commands.ts +16 -6
- package/src/commands/budget.ts +10 -8
- package/src/commands/context.ts +35 -10
- package/src/commands/defaults.ts +69 -45
- package/src/commands/keymap.ts +9 -0
- package/src/commands/levels.ts +11 -5
- package/src/commands/live-context.ts +2 -0
- package/src/commands/registry.ts +10 -1
- package/src/content/collection-match.ts +6 -5
- package/src/content/collection-pages.ts +412 -0
- package/src/content/content-collections.ts +270 -0
- package/src/content/entry-commands.ts +51 -60
- package/src/content/entry-editor.ts +111 -18
- package/src/content/entry-fields.ts +13 -1
- package/src/content/entry-inspector.ts +225 -0
- package/src/content/entry-model.ts +17 -3
- 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/convert-to-component.ts +67 -43
- package/src/editor/file-drop-action.ts +9 -1
- package/src/editor/inline-edit-apply.ts +44 -0
- package/src/editor/inline-edit.ts +10 -0
- package/src/editor/insert-component.ts +91 -0
- package/src/editor/insert-zone-action.ts +13 -4
- package/src/editor/shortcuts.ts +44 -22
- package/src/editor/slash-menu.ts +51 -8
- package/src/files/components.ts +74 -10
- package/src/files/file-ops.ts +15 -5
- package/src/files/files.ts +164 -150
- package/src/files/fs-events.ts +18 -7
- package/src/files/media-meta.ts +95 -1
- 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 +13 -3
- package/src/format/format-host.ts +15 -0
- package/src/github/github-auth.ts +2 -2
- package/src/github/github-publish.ts +4 -3
- package/src/grid/grid-controller.ts +5 -1
- package/src/grid/grid-open.ts +0 -27
- package/src/grid/grid-panel.ts +54 -2
- package/src/grid/grid-reveal.ts +34 -0
- package/src/grid/grid-source.ts +3 -25
- package/src/grid/grid-view.ts +31 -6
- package/src/grid/sources/content-source.ts +75 -7
- package/src/grid/tabulator-tables.d.ts +6 -0
- package/src/hosting/document.ts +2 -2
- package/src/i18n/i18n-commands.ts +2 -1
- 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 +47 -19
- package/src/packages/pull-package-sync.ts +1 -1
- package/src/panels/activity-panel.ts +21 -5
- package/src/panels/ai-chat/chat-markdown.ts +8 -8
- package/src/panels/block-action-bar.ts +11 -11
- package/src/panels/canvas-dnd-bridge.ts +5 -2
- 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 +1 -1
- package/src/panels/data-grid.ts +4 -0
- package/src/panels/dnd.ts +17 -30
- package/src/panels/elements-panel.ts +9 -2
- package/src/panels/empty-state.ts +2 -2
- package/src/panels/formula-workspace.ts +2 -3
- package/src/panels/frontmatter-fields.ts +9 -9
- package/src/panels/git-diff-open.ts +9 -5
- package/src/panels/head-panel.ts +369 -103
- package/src/panels/i18n-panel.ts +11 -10
- package/src/panels/imports-panel.ts +2 -0
- package/src/panels/jump-bar.ts +27 -2
- package/src/panels/layers-panel.ts +36 -30
- package/src/panels/left-panel.ts +22 -8
- package/src/panels/navigator-panels.ts +23 -11
- package/src/panels/pane-context.ts +111 -29
- package/src/panels/pane-grid.ts +6 -6
- package/src/panels/panel-registry.ts +14 -9
- package/src/panels/properties-panel.ts +7 -3
- package/src/panels/right-panel.ts +199 -43
- package/src/panels/seo-modal.ts +41 -108
- package/src/panels/settings-menu.ts +52 -50
- package/src/panels/settings-pane.ts +268 -162
- package/src/panels/signals-panel.ts +3 -4
- package/src/panels/site-model.ts +367 -0
- package/src/panels/site-panel.ts +638 -0
- package/src/panels/style-panel.ts +37 -3
- package/src/panels/stylebook-doc.ts +142 -10
- package/src/panels/stylebook-layers-panel.ts +39 -80
- package/src/panels/stylebook-panel.ts +47 -10
- package/src/panels/styles-panel.ts +327 -0
- package/src/panels/tab-strip.ts +109 -25
- package/src/platform.ts +1 -1
- package/src/platforms/cloud.ts +28 -1
- package/src/platforms/default-platform.ts +4 -4
- package/src/platforms/devserver.ts +51 -25
- package/src/publish/deploy-checklist.ts +12 -7
- package/src/publish/pages-service.ts +38 -14
- package/src/publish/publish-changes.ts +491 -0
- package/src/publish/publish-commands.ts +83 -18
- package/src/publish/publish-ids.ts +49 -0
- 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/services/automation.ts +16 -20
- package/src/services/cf-settings.ts +4 -4
- package/src/services/connection.ts +2 -2
- package/src/services/directory-picker.ts +2 -2
- package/src/services/references.ts +0 -0
- package/src/services/render-critic.ts +21 -2
- package/src/services/settings/definitions.ts +25 -14
- package/src/settings/contributed-section.ts +49 -10
- package/src/settings/css-vars-editor.ts +93 -27
- package/src/settings/developer-panels.ts +43 -0
- package/src/settings/extension-sections.ts +20 -2
- package/src/settings/general-settings.ts +91 -21
- package/src/settings/preferences-dialog.ts +8 -1
- package/src/settings/project-sections.ts +27 -10
- package/src/settings/schema-field-ui.ts +3 -1
- package/src/settings/section-registry.ts +116 -11
- package/src/settings/settings-dialog.ts +192 -0
- package/src/settings/settings-document.ts +182 -162
- package/src/shell.ts +467 -431
- package/src/site-context.ts +64 -10
- package/src/state.ts +28 -9
- package/src/studio.ts +194 -41
- package/src/style/project-styles.ts +34 -0
- 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/variables-focus.ts +61 -0
- package/src/style/variables-view.ts +235 -0
- package/src/surfaces/add-new.json +1482 -0
- package/src/surfaces/add-new.ts +325 -0
- package/src/surfaces/ai-chat.ts +2 -2
- package/src/surfaces/boot-failure.json +4 -3
- package/src/surfaces/bottom-dock.json +1 -1
- package/src/surfaces/canvas-stage.json +30 -19
- package/src/surfaces/canvas-stage.ts +5 -5
- 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 +134 -99
- package/src/surfaces/empty-state.json +1 -1
- package/src/surfaces/entry-editor.json +136 -0
- package/src/surfaces/entry-editor.ts +21 -0
- package/src/surfaces/entry-inspector.json +371 -0
- package/src/surfaces/entry-inspector.ts +143 -0
- package/src/surfaces/inspector-dock.json +162 -14
- package/src/surfaces/inspector-dock.ts +46 -19
- package/src/surfaces/library-pane.json +670 -437
- package/src/surfaces/library-pane.ts +94 -59
- package/src/surfaces/media-browser.json +62 -6
- package/src/surfaces/media-browser.ts +15 -1
- package/src/surfaces/media-field.json +1 -1
- package/src/surfaces/media-library.json +1586 -0
- package/src/surfaces/media-library.ts +282 -0
- package/src/surfaces/media-pick-dialog.json +71 -0
- package/src/surfaces/media-pick-dialog.ts +132 -0
- package/src/surfaces/menu.ts +18 -0
- package/src/surfaces/pane-context.json +144 -77
- package/src/surfaces/pane-context.ts +24 -0
- package/src/surfaces/panel-deploy-checklist.json +12 -6
- package/src/surfaces/panel-deploy-checklist.ts +3 -1
- package/src/surfaces/panel-page.json +72 -2
- package/src/surfaces/panel-page.ts +38 -7
- package/src/surfaces/panel-signals.json +1 -1
- package/src/surfaces/panel-signals.ts +5 -5
- package/src/surfaces/panel-stylebook-layers.json +71 -204
- package/src/surfaces/panel-stylebook-layers.ts +0 -21
- package/src/surfaces/preferences.json +120 -48
- package/src/surfaces/preferences.ts +8 -0
- 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/rail.json +1 -159
- package/src/surfaces/rail.ts +18 -75
- package/src/surfaces/schema-form.json +10 -2
- package/src/surfaces/schema-form.ts +2 -0
- package/src/surfaces/seo.json +1 -1
- package/src/surfaces/settings-contributed.json +5 -5
- package/src/surfaces/settings-contributed.ts +18 -2
- package/src/surfaces/settings-css-vars.json +44 -36
- package/src/surfaces/settings-css-vars.ts +77 -4
- package/src/surfaces/settings-deploy.json +2 -15
- package/src/surfaces/settings-deploy.ts +1 -1
- package/src/surfaces/settings-dialog.json +51 -0
- package/src/surfaces/settings-dialog.ts +169 -0
- package/src/surfaces/settings-overview.json +3 -3
- package/src/surfaces/settings-overview.ts +9 -2
- package/src/surfaces/settings-pane.json +269 -46
- package/src/surfaces/settings-pane.ts +85 -24
- package/src/surfaces/shell.json +2 -1
- 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 +23 -0
- package/src/surfaces/statusbar.ts +39 -15
- 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/welcome.ts +1 -1
- 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/tab.ts +47 -7
- package/src/types.ts +21 -26
- package/src/ui/form-controls.ts +47 -8
- package/src/ui/layers.ts +13 -0
- package/src/ui/media-picker.ts +284 -40
- package/src/ui/regions.ts +7 -6
- package/src/ui/schema-form.ts +259 -27
- package/src/ui/virtual-window.ts +26 -1
- package/src/utils/base64.ts +3 -3
- package/src/utils/edit-display.ts +322 -67
- package/src/utils/local-day.ts +18 -0
- package/src/workspace/pane-derive.ts +4 -4
- package/src/workspace/session.ts +28 -7
- 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 +125 -11
- package/styles/shell-frame.css +30 -7
- package/styles/shell-frame.json +15 -3
- package/dist/chunks/2020-f2gkpy8d.js +0 -4
- package/dist/chunks/adapter-4912g339.js +0 -4
- package/dist/chunks/cf-account-picker-wccaenh6.js +0 -4
- package/dist/chunks/cf-settings-br6105tr.js +0 -4
- package/dist/chunks/color-28ksk2qm.js +0 -4
- package/dist/chunks/components-db68vsn7.js +0 -4
- package/dist/chunks/content-source-1449qesq.js +0 -4
- package/dist/chunks/convert-to-repeater-5h457egj.js +0 -4
- package/dist/chunks/editor-x9jn86a7.js +0 -4
- package/dist/chunks/entry-commands-may24cpt.js +0 -4
- package/dist/chunks/extension-sections-pvr14vxr.js +0 -4
- package/dist/chunks/file-ops-x9v54pcj.js +0 -4
- package/dist/chunks/files-j3knqf0s.js +0 -4
- package/dist/chunks/format-host-tyre2trb.js +0 -4
- package/dist/chunks/fs-events-64ma9htc.js +0 -4
- package/dist/chunks/git-panel-84ps5dex.js +0 -4
- package/dist/chunks/iframe-entry-fvbk89gm.js +0 -5
- package/dist/chunks/iframe-host-ck6vejt5.js +0 -4
- package/dist/chunks/index-b8xw3vy9.js +0 -4
- package/dist/chunks/jsonMode-w15cmrcm.js +0 -13
- package/dist/chunks/jx-validate-at3zn8wa.js +0 -4
- package/dist/chunks/layers-h4xp1pss.js +0 -4
- package/dist/chunks/layers-panel-m5hw1d7g.js +0 -4
- package/dist/chunks/lit-html-8t8t3dnr.js +0 -4
- package/dist/chunks/media-picker-2cweexc5.js +0 -4
- package/dist/chunks/menu-ynw13y0s.js +0 -4
- package/dist/chunks/monaco-buffer-qzxn567r.js +0 -4
- package/dist/chunks/monaco-setup-gxf6656g.js +0 -4
- package/dist/chunks/notify-cj5zbrs2.js +0 -4
- package/dist/chunks/parse-b7ddhr8m.js +0 -4
- package/dist/chunks/platform-3dfws9js.js +0 -4
- package/dist/chunks/popover-jt2gxmzs.js +0 -4
- package/dist/chunks/publish-panel-1gvxbj21.js +0 -4
- package/dist/chunks/quick-search-0dajrwqg.js +0 -4
- package/dist/chunks/references-49qgt404.js +0 -4
- package/dist/chunks/right-panel-jm1bwe53.js +0 -4
- package/dist/chunks/section-registry-6kwc4fky.js +0 -4
- package/dist/chunks/studio-0rt52vpq.js +0 -5
- package/dist/chunks/studio-18vgbhs5.js +0 -5
- package/dist/chunks/studio-24mccdrj.js +0 -5
- package/dist/chunks/studio-2eh507zk.js +0 -9
- package/dist/chunks/studio-2hcbccfv.js +0 -5
- package/dist/chunks/studio-2jbs3rxv.js +0 -5
- package/dist/chunks/studio-4h8k4dw9.js +0 -5
- package/dist/chunks/studio-5f6n18kx.js +0 -5
- package/dist/chunks/studio-5gthpky6.js +0 -5
- package/dist/chunks/studio-6ep3js6b.js +0 -9
- package/dist/chunks/studio-6wkmf3wz.js +0 -9
- package/dist/chunks/studio-841rf3cg.js +0 -5
- package/dist/chunks/studio-8gmwgheg.js +0 -5
- package/dist/chunks/studio-8qm0ep50.js +0 -5
- package/dist/chunks/studio-924p1tm1.js +0 -6
- package/dist/chunks/studio-a3shpz9y.js +0 -5
- package/dist/chunks/studio-amsbaaar.js +0 -6
- package/dist/chunks/studio-at5spjbc.js +0 -7
- package/dist/chunks/studio-b2xv945e.js +0 -5
- package/dist/chunks/studio-bn5nkafw.js +0 -5
- package/dist/chunks/studio-bw6q5xjf.js +0 -9
- package/dist/chunks/studio-c7q0t9x1.js +0 -5
- package/dist/chunks/studio-camnhc96.js +0 -6
- package/dist/chunks/studio-cffqvnzd.js +0 -5
- package/dist/chunks/studio-efvfrsf8.js +0 -5
- package/dist/chunks/studio-er30bpcx.js +0 -5
- package/dist/chunks/studio-ezscgr64.js +0 -5
- package/dist/chunks/studio-ffrrncvz.js +0 -5
- package/dist/chunks/studio-fpphgn8y.js +0 -10
- package/dist/chunks/studio-j1kvhdjk.js +0 -4
- package/dist/chunks/studio-j430n16g.js +0 -7
- package/dist/chunks/studio-jjkg84nj.js +0 -5
- package/dist/chunks/studio-m0q32ars.js +0 -4
- package/dist/chunks/studio-m6bdst11.js +0 -5
- package/dist/chunks/studio-nv2cptd4.js +0 -64
- package/dist/chunks/studio-nwfrc98n.js +0 -5
- package/dist/chunks/studio-p1wgvp7r.js +0 -5
- package/dist/chunks/studio-pag2wncm.js +0 -5
- package/dist/chunks/studio-qvanvzfd.js +0 -5
- package/dist/chunks/studio-qwa64kt7.js +0 -5
- package/dist/chunks/studio-rk1zc4x3.js +0 -928
- package/dist/chunks/studio-se2r3ptc.js +0 -5
- package/dist/chunks/studio-sg2a0dh0.js +0 -5
- package/dist/chunks/studio-tjzjhe68.js +0 -5
- package/dist/chunks/studio-v2w7q8r1.js +0 -7
- package/dist/chunks/studio-v5vjq1h0.js +0 -4
- package/dist/chunks/studio-v8aga3vp.js +0 -14
- package/dist/chunks/studio-vfcdrfmv.js +0 -5
- package/dist/chunks/studio-vmfkgdjf.js +0 -5
- package/dist/chunks/studio-wt1816jj.js +0 -5
- package/dist/chunks/studio-wz73q5kq.js +0 -4
- package/dist/chunks/studio-y04qtxvp.js +0 -7
- package/dist/chunks/studio-y21g8zzg.js +0 -5
- package/dist/chunks/studio-y64hrt8p.js +0 -12
- package/dist/chunks/studio-ynn90f58.js +0 -16
- package/dist/chunks/studio-yxz682sx.js +0 -5
- package/dist/chunks/studio-zp7snvkq.js +0 -5
- package/dist/chunks/studio-zq4z6tm6.js +0 -5
- package/dist/chunks/toast-c9fn075p.js +0 -4
- package/dist/chunks/tsMode-sf49ee9x.js +0 -14
- package/dist/chunks/workspace-jtfahpee.js +0 -4
- package/src/panels/frontmatter-panel.ts +0 -711
- package/src/panels/git-panel.ts +0 -1108
- package/src/surfaces/doc-header.json +0 -776
- package/src/surfaces/doc-header.ts +0 -222
- package/src/surfaces/git-panel.json +0 -1880
- package/src/surfaces/git-panel.ts +0 -264
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The content-entry verbs:
|
|
3
|
-
* drafts are listed at all
|
|
2
|
+
* The content-entry verbs: open one where it is written, mark one a draft, and choose whether
|
|
3
|
+
* drafts are listed at all — and {@link createEntry}, the New File tree's route into a collection
|
|
4
|
+
* folder.
|
|
5
|
+
*
|
|
6
|
+
* Creating an entry from anywhere else is Add new's (`file.new { kind: "entry", collection }`,
|
|
7
|
+
* `create/add-new-flow.ts`), which seeds through {@link entryFormatName} and `entryBody` exactly as
|
|
8
|
+
* {@link createEntry} does, so both routes write the same bytes.
|
|
4
9
|
*
|
|
5
10
|
* Each is a record in its owning module, so the palette row, the assistant's tool, the automation
|
|
6
11
|
* step and (for the two that declare one) the context-menu item are renderings of the same
|
|
@@ -14,8 +19,6 @@ import {
|
|
|
14
19
|
argsSchema,
|
|
15
20
|
booleanArg,
|
|
16
21
|
booleanProperty,
|
|
17
|
-
derivedEnumProperty,
|
|
18
|
-
enumArg,
|
|
19
22
|
stringArg,
|
|
20
23
|
stringProperty,
|
|
21
24
|
} from "../commands/command-args";
|
|
@@ -32,48 +35,61 @@ import { serializeJson } from "@jxsuite/schema/json-layout";
|
|
|
32
35
|
import { invalidateReferenceEntries } from "../ui/form-controls";
|
|
33
36
|
import { reloadDraftAwareGrids } from "../grid/sources/content-source";
|
|
34
37
|
import { setIncludeDrafts } from "./draft-state";
|
|
35
|
-
import { collectionOfPath, entryCollection
|
|
38
|
+
import { collectionOfPath, entryCollection } from "./entry-model";
|
|
39
|
+
import { entryBody } from "../create/add-new";
|
|
36
40
|
import { collectionForDirectory } from "./collection-match";
|
|
37
41
|
import { LOCALE_PLACEHOLDER } from "../canvas/asset-resolve";
|
|
38
|
-
import {
|
|
42
|
+
import { setEntryDraft } from "./entry-editor";
|
|
43
|
+
import { openEntry } from "./entry-open";
|
|
39
44
|
import { errorMessage } from "@jxsuite/schema/parse";
|
|
40
45
|
import type { EntryCollection } from "./entry-model";
|
|
41
46
|
import type { AnyCommand, CommandRegistry } from "../commands/registry";
|
|
42
47
|
import type { Tab } from "../tabs/tab";
|
|
48
|
+
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
43
49
|
|
|
44
|
-
/**
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
/**
|
|
51
|
+
* The format class that writes a collection's entries, or `null` for native JSON.
|
|
52
|
+
*
|
|
53
|
+
* `collectionInfo` derives `.json` exactly when no format class claimed the collection — the
|
|
54
|
+
* extension and the serializer name come off the same three lookups in the same order — so "the
|
|
55
|
+
* extension is .json" and "no format can write this" are one condition. Writing JSON into a `.md`
|
|
56
|
+
* file is therefore not a state a seed can reach.
|
|
57
|
+
*/
|
|
58
|
+
export function entryFormatName(collection: Pick<EntryCollection, "def" | "ext">): string | null {
|
|
59
|
+
if (collection.ext === ".json") {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return (
|
|
63
|
+
(collection.def.format ? formatByName(collection.def.format)?.name : undefined) ??
|
|
64
|
+
formatForPath(`untitled${collection.ext}`)?.name ??
|
|
65
|
+
defaultContentFormat()?.name ??
|
|
66
|
+
null
|
|
67
|
+
);
|
|
47
68
|
}
|
|
48
69
|
|
|
49
70
|
/**
|
|
50
|
-
* The source text a new entry starts as.
|
|
71
|
+
* The source text a new entry starts as: `create/add-new.ts`'s `entryBody`, serialized.
|
|
51
72
|
*
|
|
52
73
|
* A `json` collection is serialized here rather than through the format registry, because JSON is
|
|
53
74
|
* the one native collection shape (site-architecture.md §6.2) and has no format class to ask.
|
|
54
|
-
*
|
|
55
|
-
* `collectionInfo` derives `.json` exactly when no format class claimed the collection — the
|
|
56
|
-
* extension and the serializer name come off the same three lookups in the same order — so "the
|
|
57
|
-
* extension is .json" and "no format can write this" are one condition, and the second is not a
|
|
58
|
-
* separate failure to report. Writing JSON into a `.md` file is therefore not a state this can
|
|
59
|
-
* reach.
|
|
60
75
|
*/
|
|
61
76
|
async function seedText(collection: EntryCollection): Promise<string> {
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (
|
|
77
|
+
const body = entryBody({
|
|
78
|
+
ext: collection.ext,
|
|
79
|
+
formatName: entryFormatName(collection),
|
|
80
|
+
schema: collection.schema,
|
|
81
|
+
});
|
|
82
|
+
if (body.format === null) {
|
|
68
83
|
// The save serializer with no layout (`@jxsuite/schema/json-layout`): a seed has no source text, and
|
|
69
84
|
// This is what the formatter makes of one, newline included.
|
|
70
|
-
return serializeJson(
|
|
85
|
+
return serializeJson(body.doc, null);
|
|
71
86
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
87
|
+
/* SAFETY: an entry body is `{ ...seed, children: [] }`, an element-shaped object, which is the
|
|
88
|
+
document a format's serializer reads. */
|
|
89
|
+
return formatSerialize(body.format, body.doc as JxMutableNode, {
|
|
90
|
+
frontmatter: body.frontmatter ?? false,
|
|
91
|
+
mode: "roundtrip",
|
|
92
|
+
});
|
|
77
93
|
}
|
|
78
94
|
|
|
79
95
|
/**
|
|
@@ -127,8 +143,8 @@ export async function createEntry(
|
|
|
127
143
|
* Where the entry lands.
|
|
128
144
|
*
|
|
129
145
|
* A localized collection's `dir` is `content/exhibitions/{locale}` — a path nobody has. Creating
|
|
130
|
-
* there makes a directory literally named `{locale}`, which is what
|
|
131
|
-
*
|
|
146
|
+
* there makes a directory literally named `{locale}`, which is what the palette's New Entry and
|
|
147
|
+
* the `new_content_entry` tool used to do. There is no default locale to pick on
|
|
132
148
|
* the author's behalf (choosing one silently files the entry under a language), so this refuses
|
|
133
149
|
* and names the gesture that works.
|
|
134
150
|
*/
|
|
@@ -162,7 +178,7 @@ export async function createEntry(
|
|
|
162
178
|
}
|
|
163
179
|
// The picker's choices just changed; a cached list would keep offering the old set.
|
|
164
180
|
invalidateReferenceEntries(collection.name);
|
|
165
|
-
await
|
|
181
|
+
await openEntry(created);
|
|
166
182
|
return created;
|
|
167
183
|
}
|
|
168
184
|
|
|
@@ -175,32 +191,6 @@ function activeEntryTab(): Tab | null {
|
|
|
175
191
|
/** The content-entry command records. */
|
|
176
192
|
export function contentCommands(): AnyCommand[] {
|
|
177
193
|
return [
|
|
178
|
-
{
|
|
179
|
-
args: argsSchema({
|
|
180
|
-
collection: derivedEnumProperty(
|
|
181
|
-
creatableCollections,
|
|
182
|
-
"The content collection the entry is created in.",
|
|
183
|
-
),
|
|
184
|
-
}),
|
|
185
|
-
category: "File",
|
|
186
|
-
id: "content.newEntry",
|
|
187
|
-
level: "project",
|
|
188
|
-
menus: ["palette"],
|
|
189
|
-
group: "1_file",
|
|
190
|
-
requires: "a project with a directory-backed content collection",
|
|
191
|
-
when: (ctx) => ctx.project.open,
|
|
192
|
-
enablement: () => creatableCollections().length > 0,
|
|
193
|
-
undo: "project",
|
|
194
|
-
/* No `aiTool`, by studio-ui-guidelines.md §12.4's second deletion rule: `createEntry` awaits
|
|
195
|
-
`createFileIn`, which awaits the New File prompt for the name; a cancel resolves with
|
|
196
|
-
nothing thrown. An optional `name` argument that skips the prompt is the way back in, and
|
|
197
|
-
is a UX call (issue 273). */
|
|
198
|
-
run: async (_ctx, args) => {
|
|
199
|
-
const names = creatableCollections();
|
|
200
|
-
await createEntry(enumArg("content.newEntry", args, "collection", names));
|
|
201
|
-
},
|
|
202
|
-
title: "New Entry",
|
|
203
|
-
},
|
|
204
194
|
{
|
|
205
195
|
args: argsSchema({
|
|
206
196
|
path: stringProperty("Project-relative path of the entry file to open."),
|
|
@@ -213,11 +203,12 @@ export function contentCommands(): AnyCommand[] {
|
|
|
213
203
|
requires: "an open project",
|
|
214
204
|
when: (ctx) => ctx.project.open,
|
|
215
205
|
/* No `aiTool`, by studio-ui-guidelines.md §12.4's first deletion rule: this opens a surface;
|
|
216
|
-
the model has `open_document`.
|
|
206
|
+
the model has `open_document`. An entry with a body opens on the canvas in its writing
|
|
207
|
+
editor, inside its template's layout; a JSON entry opens in the form (§22.5). */
|
|
217
208
|
run: async (_ctx, args) => {
|
|
218
|
-
await
|
|
209
|
+
await openEntry(stringArg("content.openEntry", args, "path"));
|
|
219
210
|
},
|
|
220
|
-
title: "Open Entry
|
|
211
|
+
title: "Open Entry",
|
|
221
212
|
},
|
|
222
213
|
{
|
|
223
214
|
args: argsSchema({
|
|
@@ -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
|
|
@@ -52,16 +52,21 @@ import { activateTab, workspace } from "../workspace/workspace";
|
|
|
52
52
|
import { commitEntryFields, entryFields, mutateEntryField } from "./entry-fields";
|
|
53
53
|
import type { EntryFields } from "./entry-fields";
|
|
54
54
|
import { DRAFT_FIELD, DRAFT_MEANING, hasDraftAxis, isDraftEntry } from "./draft-state";
|
|
55
|
-
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";
|
|
56
59
|
import type { EntryCollection } from "./entry-model";
|
|
57
60
|
import type { EntryEditorSurfaceHandle, EntryEditorView } from "../surfaces/entry-editor";
|
|
58
61
|
import type { JsonSchema, SchemaFormContext } from "../ui/schema-form";
|
|
59
62
|
import type { Tab } from "../tabs/tab";
|
|
60
63
|
import type { CanvasSurface } from "../canvas/canvas-surface";
|
|
61
|
-
import type { JsonObject } from "@jxsuite/schema/types";
|
|
64
|
+
import type { ContentTypeSchema, JsonObject } from "@jxsuite/schema/types";
|
|
65
|
+
import { isString } from "@jxsuite/schema/guards";
|
|
66
|
+
import { fieldTitle } from "../browse/library-source";
|
|
62
67
|
|
|
63
|
-
/** The `canvasMode` the entry form draws under. */
|
|
64
|
-
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";
|
|
65
70
|
|
|
66
71
|
/** What an entry tab's mode list becomes when the Entry editor opens it: the form leads. */
|
|
67
72
|
const ENTRY_TAB_MODES = [ENTRY_MODE];
|
|
@@ -149,7 +154,7 @@ export interface DraftPill {
|
|
|
149
154
|
* chip's `status` slot, and `.entry-pill`'s rules in `styles/overlays.css` are dead with it.
|
|
150
155
|
*/
|
|
151
156
|
export function entryDraftPill(tab: Tab): DraftPill | null {
|
|
152
|
-
const collection =
|
|
157
|
+
const collection = entryCollectionOf(tab);
|
|
153
158
|
const fields = entryFields(tab);
|
|
154
159
|
if (!collection || !hasDraftAxis(collection.schema, fields)) {
|
|
155
160
|
return null;
|
|
@@ -164,8 +169,24 @@ export function entryDraftPill(tab: Tab): DraftPill | null {
|
|
|
164
169
|
|
|
165
170
|
// ─── The form ────────────────────────────────────────────────────────────────
|
|
166
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
|
+
|
|
167
188
|
/** The form's host context: enum pointers resolve against this project's configuration. */
|
|
168
|
-
function formContext(tab: Tab): SchemaFormContext {
|
|
189
|
+
export function formContext(tab: Tab): SchemaFormContext {
|
|
169
190
|
return {
|
|
170
191
|
fieldKeyPrefix: `entry:${tab.id}`,
|
|
171
192
|
resolvePointer: (pointer, scope) =>
|
|
@@ -184,7 +205,7 @@ function formContext(tab: Tab): SchemaFormContext {
|
|
|
184
205
|
* missing from the file is a fact about the document, and saying so is the whole reason the form
|
|
185
206
|
* knows the schema.
|
|
186
207
|
*/
|
|
187
|
-
function absentRequiredErrors(
|
|
208
|
+
export function absentRequiredErrors(
|
|
188
209
|
collection: EntryCollection,
|
|
189
210
|
fields: EntryFields,
|
|
190
211
|
): Record<string, string> {
|
|
@@ -196,6 +217,32 @@ function absentRequiredErrors(
|
|
|
196
217
|
);
|
|
197
218
|
}
|
|
198
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;
|
|
242
|
+
}
|
|
243
|
+
return { ...form, properties: { [title]: held, ...properties } };
|
|
244
|
+
}
|
|
245
|
+
|
|
199
246
|
/** What the document says when the file belongs to no collection: the reason, then the fix. */
|
|
200
247
|
function emptyLine(tab: Tab): string {
|
|
201
248
|
return `${tab.documentPath ?? "This document"} is not an entry of any content collection, so there is no schema to draw a form from.`;
|
|
@@ -214,14 +261,20 @@ function entryView(paneId: string, tab: Tab, collection: EntryCollection | null)
|
|
|
214
261
|
emptyLine: emptyLine(tab),
|
|
215
262
|
fieldsRegion,
|
|
216
263
|
name: "",
|
|
264
|
+
nextDisabled: true,
|
|
217
265
|
note: "",
|
|
218
266
|
noteState: "hidden",
|
|
267
|
+
place: "",
|
|
268
|
+
previousDisabled: true,
|
|
269
|
+
recordNav: "hidden",
|
|
219
270
|
region,
|
|
220
271
|
stage: "empty",
|
|
221
272
|
};
|
|
222
273
|
}
|
|
223
274
|
const fields = entryFields(tab);
|
|
224
275
|
const draft = isDraftEntry(fields);
|
|
276
|
+
const record = isRecordTab(tab);
|
|
277
|
+
const place = recordPlace(tab);
|
|
225
278
|
return {
|
|
226
279
|
collection: collection.name,
|
|
227
280
|
draft,
|
|
@@ -229,14 +282,31 @@ function entryView(paneId: string, tab: Tab, collection: EntryCollection | null)
|
|
|
229
282
|
draftHint: DRAFT_MEANING,
|
|
230
283
|
emptyLine: "",
|
|
231
284
|
fieldsRegion,
|
|
232
|
-
|
|
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,
|
|
233
290
|
note: DRAFT_MEANING,
|
|
234
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",
|
|
235
295
|
region,
|
|
236
296
|
stage: "entry",
|
|
237
297
|
};
|
|
238
298
|
}
|
|
239
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
|
+
|
|
240
310
|
/**
|
|
241
311
|
* Mount the entry form into the pane.
|
|
242
312
|
*
|
|
@@ -289,13 +359,14 @@ export function renderEntryMode(surface: CanvasSurface, tab: Tab): void {
|
|
|
289
359
|
JSON text, so every value is JSON; a key an editor cleared reads as absent either way. */
|
|
290
360
|
const form = mountSchemaForm(
|
|
291
361
|
`entry:${paneId}`,
|
|
292
|
-
collection.schema as JsonSchema,
|
|
362
|
+
titleFirst(collection.schema as JsonSchema, collection.schema, fields),
|
|
293
363
|
fields as JsonObject,
|
|
294
364
|
{
|
|
295
365
|
context: formContext(tab),
|
|
296
366
|
errors: absentRequiredErrors(collection, fields),
|
|
297
367
|
onChange: (patch) => commitEntryFields(tab, patch),
|
|
298
368
|
rerender: redraw,
|
|
369
|
+
ui: fieldLabels(collection.schema),
|
|
299
370
|
},
|
|
300
371
|
);
|
|
301
372
|
if (form.parentNode !== formHost) {
|
|
@@ -304,7 +375,7 @@ export function renderEntryMode(surface: CanvasSurface, tab: Tab): void {
|
|
|
304
375
|
};
|
|
305
376
|
|
|
306
377
|
const draw = () => {
|
|
307
|
-
const collection =
|
|
378
|
+
const collection = entryCollectionOf(tab);
|
|
308
379
|
if (!collection) {
|
|
309
380
|
/* The `fields` node goes with the case that held it, so the handle is dropped here rather
|
|
310
381
|
than left pointing at a node the reconciler is about to remove. */
|
|
@@ -317,17 +388,37 @@ export function renderEntryMode(surface: CanvasSurface, tab: Tab): void {
|
|
|
317
388
|
const scope = effectScope();
|
|
318
389
|
const mounted = mountEntryEditorSurface(
|
|
319
390
|
canvasWrap,
|
|
320
|
-
entryView(paneId, tab,
|
|
391
|
+
entryView(paneId, tab, entryCollectionOf(tab)),
|
|
321
392
|
{
|
|
322
393
|
openContentTypes: () => {
|
|
323
394
|
void activeRegistry()?.run("settings.open", { section: "content" });
|
|
324
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
|
+
},
|
|
325
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
|
+
},
|
|
326
417
|
},
|
|
327
418
|
{
|
|
328
419
|
fieldsSlot: (host) => {
|
|
329
420
|
formHost = host;
|
|
330
|
-
paintForm(
|
|
421
|
+
paintForm(entryCollectionOf(tab));
|
|
331
422
|
},
|
|
332
423
|
},
|
|
333
424
|
);
|
|
@@ -346,6 +437,8 @@ export function renderEntryMode(surface: CanvasSurface, tab: Tab): void {
|
|
|
346
437
|
void tab.doc.document;
|
|
347
438
|
void tab.doc.content.frontmatter;
|
|
348
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.
|
|
349
442
|
draw();
|
|
350
443
|
});
|
|
351
444
|
});
|
|
@@ -32,6 +32,7 @@ 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";
|
|
35
36
|
import type { JxDocumentValue } from "@jxsuite/schema/types";
|
|
36
37
|
import type { Tab } from "../tabs/tab";
|
|
37
38
|
import type { JsonValue } from "../types";
|
|
@@ -64,6 +65,10 @@ function fieldsAreDocument(tab: Tab): boolean {
|
|
|
64
65
|
* `tab.doc.document` to see which store answered.
|
|
65
66
|
*/
|
|
66
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
|
+
}
|
|
67
72
|
return fieldsAreDocument(tab) ? tab.doc.document : tab.doc.content.frontmatter;
|
|
68
73
|
}
|
|
69
74
|
|
|
@@ -105,7 +110,9 @@ function mutateDocumentField(tab: Tab, field: string, value?: JsonValue): void {
|
|
|
105
110
|
* step.
|
|
106
111
|
*/
|
|
107
112
|
export function mutateEntryField(tab: Tab, field: string, value?: JsonValue): void {
|
|
108
|
-
if (
|
|
113
|
+
if (isRecordTab(tab)) {
|
|
114
|
+
commitRecordFields(tab, { [field]: value });
|
|
115
|
+
} else if (fieldsAreDocument(tab)) {
|
|
109
116
|
mutateDocumentField(tab, field, value);
|
|
110
117
|
} else {
|
|
111
118
|
mutateUpdateFrontmatter(tab, field, value);
|
|
@@ -119,6 +126,11 @@ export function mutateEntryField(tab: Tab, field: string, value?: JsonValue): vo
|
|
|
119
126
|
* on the undo stack as several steps — and an author who changed one thing expects one ⌘Z.
|
|
120
127
|
*/
|
|
121
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
|
+
}
|
|
122
134
|
transactDoc(tab, (t) => {
|
|
123
135
|
for (const [field, value] of Object.entries(patch)) {
|
|
124
136
|
mutateEntryField(t, field, value);
|