@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
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
* **This flow fails, and until now it failed silently.** `https://github.com/login/device/code`
|
|
16
16
|
* sends no `Access-Control-Allow-Origin`, so a browser cannot call it: in Studio-in-a-browser the
|
|
17
17
|
* very first request rejects with a bare `TypeError`. That rejection used to become a thrown
|
|
18
|
-
* `Error` out of {@link authenticateGithub}, into `void createGithubRepository(…)` in
|
|
19
|
-
*
|
|
18
|
+
* `Error` out of {@link authenticateGithub}, into `void createGithubRepository(…)` in the Source
|
|
19
|
+
* Control panel of the time, and from there into an unhandled promise rejection — the user clicked
|
|
20
20
|
* "Create GitHub repository" and the app did nothing at all, forever, with no message anywhere.
|
|
21
21
|
*
|
|
22
22
|
* Three failures now reach a surface, each as the kind of record §16 says it is:
|
|
@@ -59,8 +59,14 @@ import { errorMessage } from "@jxsuite/schema/parse";
|
|
|
59
59
|
import { notify } from "../services/notify";
|
|
60
60
|
import { layerHost } from "../ui/layers";
|
|
61
61
|
import { openGithubAuthSurface } from "../surfaces/github-auth";
|
|
62
|
-
import
|
|
63
|
-
|
|
62
|
+
import {
|
|
63
|
+
getGithubToken,
|
|
64
|
+
GITHUB_OAUTH_CLIENT_ID,
|
|
65
|
+
nativeAuth,
|
|
66
|
+
setNativeToken,
|
|
67
|
+
STORAGE_KEY,
|
|
68
|
+
} from "./github-auth-status";
|
|
69
|
+
import type { DialogLayerHandle } from "../ui/surface";
|
|
64
70
|
|
|
65
71
|
// Every other caller in Studio still reaches these through this module.
|
|
66
72
|
export {
|
|
@@ -71,8 +77,6 @@ export {
|
|
|
71
77
|
hydrateGithubToken,
|
|
72
78
|
} from "./github-auth-status";
|
|
73
79
|
|
|
74
|
-
const CLIENT_ID = "Ov23liYVlMFpgjOEPXJH";
|
|
75
|
-
|
|
76
80
|
/** One key for the whole sign-in, so a second attempt REPLACES the first report. */
|
|
77
81
|
const NOTIFY_KEY = "github.auth";
|
|
78
82
|
|
|
@@ -108,10 +112,10 @@ interface TokenResponse {
|
|
|
108
112
|
}
|
|
109
113
|
|
|
110
114
|
/** The request never completed — a Problem, with the one sentence that covers both causes. */
|
|
111
|
-
function reportUnreachable(
|
|
115
|
+
function reportUnreachable(cause: unknown): void {
|
|
112
116
|
notify.error("Could not reach GitHub to sign in.", {
|
|
113
117
|
action: RETRY,
|
|
114
|
-
detail: `${UNREACHABLE_DETAIL}\n\n${errorMessage(
|
|
118
|
+
detail: `${UNREACHABLE_DETAIL}\n\n${errorMessage(cause)}`,
|
|
115
119
|
key: NOTIFY_KEY,
|
|
116
120
|
source: SOURCE,
|
|
117
121
|
});
|
|
@@ -132,7 +136,7 @@ async function requestDeviceCode(): Promise<DeviceCodeResponse | null> {
|
|
|
132
136
|
let codeRes: Response;
|
|
133
137
|
try {
|
|
134
138
|
codeRes = await fetch("https://github.com/login/device/code", {
|
|
135
|
-
body: JSON.stringify({ client_id:
|
|
139
|
+
body: JSON.stringify({ client_id: GITHUB_OAUTH_CLIENT_ID, scope: "repo" }),
|
|
136
140
|
headers: {
|
|
137
141
|
Accept: "application/json",
|
|
138
142
|
"Content-Type": "application/json",
|
|
@@ -151,6 +155,9 @@ async function requestDeviceCode(): Promise<DeviceCodeResponse | null> {
|
|
|
151
155
|
);
|
|
152
156
|
return null;
|
|
153
157
|
}
|
|
158
|
+
/* SAFETY: a 2xx from GitHub's device-code endpoint (checked just above) is the JSON object
|
|
159
|
+
RFC 8628 §3.2 defines — `device_code`, `user_code`, `verification_uri` and an optional
|
|
160
|
+
`interval` — which is exactly what `DeviceCodeResponse` declares. */
|
|
154
161
|
return (await codeRes.json()) as DeviceCodeResponse;
|
|
155
162
|
}
|
|
156
163
|
|
|
@@ -247,7 +254,7 @@ export async function authenticateGithub() {
|
|
|
247
254
|
try {
|
|
248
255
|
const tokenRes = await fetch("https://github.com/login/oauth/access_token", {
|
|
249
256
|
body: JSON.stringify({
|
|
250
|
-
client_id:
|
|
257
|
+
client_id: GITHUB_OAUTH_CLIENT_ID,
|
|
251
258
|
device_code,
|
|
252
259
|
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
253
260
|
}),
|
|
@@ -257,6 +264,9 @@ export async function authenticateGithub() {
|
|
|
257
264
|
},
|
|
258
265
|
method: "POST",
|
|
259
266
|
});
|
|
267
|
+
/* SAFETY: GitHub's token endpoint answers every poll with a JSON object carrying either an
|
|
268
|
+
`access_token` (RFC 6749 §5.1) or an `error` code (RFC 8628 §3.5); `TokenResponse` makes
|
|
269
|
+
Both optional, and every branch below reads them as possibly absent. */
|
|
260
270
|
const tokenData = (await tokenRes.json()) as TokenResponse;
|
|
261
271
|
failures = 0;
|
|
262
272
|
|
|
@@ -303,7 +313,7 @@ export async function authenticateGithub() {
|
|
|
303
313
|
* the surface existed would find a binding that is not initialised yet — which a zero-second
|
|
304
314
|
* device interval makes reachable rather than theoretical.
|
|
305
315
|
*/
|
|
306
|
-
const handle:
|
|
316
|
+
const handle: DialogLayerHandle = openGithubAuthSurface({
|
|
307
317
|
layer: layerHost("dialog"),
|
|
308
318
|
onCancel: () => {
|
|
309
319
|
takeDown();
|
|
@@ -31,7 +31,8 @@ import { authenticateGithub } from "./github-auth";
|
|
|
31
31
|
import { beginActivity } from "../panels/activity-panel";
|
|
32
32
|
import { getPlatform } from "../platform";
|
|
33
33
|
import { notify } from "../services/notify";
|
|
34
|
-
import type {
|
|
34
|
+
import type { RepoOptions } from "../surfaces/github-publish";
|
|
35
|
+
import type { DialogLayerHandle } from "../ui/surface";
|
|
35
36
|
|
|
36
37
|
interface GithubErrorResponse {
|
|
37
38
|
errors?: { message?: string }[];
|
|
@@ -77,7 +78,7 @@ function askForRepoOptions(projectName: string): Promise<RepoOptions | null> {
|
|
|
77
78
|
answered = true;
|
|
78
79
|
resolve(value);
|
|
79
80
|
};
|
|
80
|
-
const handle:
|
|
81
|
+
const handle: DialogLayerHandle = openGithubPublishSurface({
|
|
81
82
|
layer: layerHost("dialog"),
|
|
82
83
|
name: projectName,
|
|
83
84
|
onCancel: () => {
|
|
@@ -125,25 +126,24 @@ export async function createGithubRepository({ projectName }: { projectName: str
|
|
|
125
126
|
});
|
|
126
127
|
|
|
127
128
|
activity.step(REPO_STEPS[0]);
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
129
|
+
let createRes: Response;
|
|
130
|
+
try {
|
|
131
|
+
createRes = await fetch("https://api.github.com/user/repos", {
|
|
132
|
+
body: JSON.stringify({
|
|
133
|
+
auto_init: false,
|
|
134
|
+
description: repoOpts.description,
|
|
135
|
+
name: repoOpts.name,
|
|
136
|
+
private: repoOpts.isPrivate,
|
|
137
|
+
}),
|
|
138
|
+
headers: {
|
|
139
|
+
Accept: "application/vnd.github+json",
|
|
140
|
+
Authorization: `Bearer ${token}`,
|
|
141
|
+
"Content-Type": "application/json",
|
|
142
|
+
},
|
|
143
|
+
method: "POST",
|
|
144
|
+
});
|
|
145
|
+
} catch (error) {
|
|
142
146
|
activity.log(errorMessage(error));
|
|
143
|
-
return null;
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
if (!createRes) {
|
|
147
147
|
activity.fail("Could not reach GitHub to create the repository.", {
|
|
148
148
|
action: "git.createGithubRepository",
|
|
149
149
|
});
|
|
@@ -151,6 +151,8 @@ export async function createGithubRepository({ projectName }: { projectName: str
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
if (!createRes.ok) {
|
|
154
|
+
/* SAFETY: GitHub's REST API answers a failed request with a JSON body carrying `message` and,
|
|
155
|
+
For a validation failure, an `errors` array; both are optional here and read with fallbacks. */
|
|
154
156
|
const err = (await createRes.json()) as GithubErrorResponse;
|
|
155
157
|
activity.log(err.errors?.[0]?.message || err.message || `GitHub answered ${createRes.status}.`);
|
|
156
158
|
activity.fail("Could not create the GitHub repository.", {
|
|
@@ -159,6 +161,8 @@ export async function createGithubRepository({ projectName }: { projectName: str
|
|
|
159
161
|
return false;
|
|
160
162
|
}
|
|
161
163
|
|
|
164
|
+
/* SAFETY: `createRes.ok` was checked above, and a successful `POST /user/repos` answers with the
|
|
165
|
+
Full repository object, of which `clone_url` and `html_url` are required members. */
|
|
162
166
|
const repo = (await createRes.json()) as GithubRepoResponse;
|
|
163
167
|
activity.log(`Created ${repo.html_url}`);
|
|
164
168
|
const platform = getPlatform();
|
|
@@ -171,7 +175,8 @@ export async function createGithubRepository({ projectName }: { projectName: str
|
|
|
171
175
|
// Surfaced as a push failure describing the push.
|
|
172
176
|
activity.log(errorMessage(error));
|
|
173
177
|
activity.fail("The repository was created, but the remote could not be added.", {
|
|
174
|
-
action: "
|
|
178
|
+
action: "view.setWorkspace",
|
|
179
|
+
actionArgs: { workspace: "publish" },
|
|
175
180
|
});
|
|
176
181
|
return false;
|
|
177
182
|
}
|
|
@@ -187,8 +192,8 @@ export async function createGithubRepository({ projectName }: { projectName: str
|
|
|
187
192
|
return false;
|
|
188
193
|
}
|
|
189
194
|
|
|
190
|
-
// Lazy import breaks the github-publish ↔
|
|
191
|
-
const { refreshGitStatus } = await import("../
|
|
195
|
+
// Lazy import breaks the github-publish ↔ source-control module cycle
|
|
196
|
+
const { refreshGitStatus } = await import("../publish/source-control");
|
|
192
197
|
await refreshGitStatus();
|
|
193
198
|
activity.done(repo.html_url);
|
|
194
199
|
notify.success(`Repository created: ${repo.html_url}`, { key: "github.repo" });
|
package/src/grid/cell-editors.ts
CHANGED
|
@@ -58,15 +58,18 @@ import { live } from "lit-html/directives/live.js";
|
|
|
58
58
|
import { cellToText, coerceCellInput } from "./schema-columns";
|
|
59
59
|
import type { GridCellValue, GridColumn } from "./grid-source";
|
|
60
60
|
|
|
61
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* The subset of Tabulator's CellComponent the editors/formatters touch. A cell's value is a
|
|
63
|
+
* {@link GridCellValue}: the grid's row data is the grid source's rows, which hold nothing else.
|
|
64
|
+
*/
|
|
62
65
|
export interface CellLike {
|
|
63
|
-
getValue: () =>
|
|
66
|
+
getValue: () => GridCellValue;
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
export type CellEditorFn = (
|
|
67
70
|
cell: CellLike,
|
|
68
71
|
onRendered: (fn: () => void) => void,
|
|
69
|
-
success: (value:
|
|
72
|
+
success: (value: GridCellValue) => void,
|
|
70
73
|
cancel: () => void,
|
|
71
74
|
) => HTMLElement;
|
|
72
75
|
|
|
@@ -75,6 +78,17 @@ export type CellFormatterFn = (cell: CellLike) => HTMLElement;
|
|
|
75
78
|
/** Detached-host factory — grid-view owns the one sanctioned document.createElement. */
|
|
76
79
|
export type HostFactory = (className: string) => HTMLElement;
|
|
77
80
|
|
|
81
|
+
/**
|
|
82
|
+
* The `<input>` a listener in this file is bound on.
|
|
83
|
+
*
|
|
84
|
+
* Every input listener here sits on the `<input>` its own template renders, and an input has no
|
|
85
|
+
* children, so a keydown, change or blur it hears was dispatched at the input itself.
|
|
86
|
+
*/
|
|
87
|
+
function inputOf(e: Event): HTMLInputElement {
|
|
88
|
+
// SAFETY: the listener is bound on an `<input>` (above), and a void element is its events' target.
|
|
89
|
+
return e.target as HTMLInputElement;
|
|
90
|
+
}
|
|
91
|
+
|
|
78
92
|
/** Commit/cancel wiring shared by every text-ish editor. */
|
|
79
93
|
function inputEditor(makeHost: HostFactory, column: GridColumn, inputType: string): CellEditorFn {
|
|
80
94
|
return (cell, onRendered, success, cancel) => {
|
|
@@ -94,8 +108,8 @@ function inputEditor(makeHost: HostFactory, column: GridColumn, inputType: strin
|
|
|
94
108
|
};
|
|
95
109
|
const initial =
|
|
96
110
|
column.kind === "date"
|
|
97
|
-
? cellToText(cell.getValue()
|
|
98
|
-
: cellToText(cell.getValue()
|
|
111
|
+
? cellToText(cell.getValue()).slice(0, 10)
|
|
112
|
+
: cellToText(cell.getValue());
|
|
99
113
|
render(
|
|
100
114
|
html`<input
|
|
101
115
|
class="jx-grid-input"
|
|
@@ -103,12 +117,12 @@ function inputEditor(makeHost: HostFactory, column: GridColumn, inputType: strin
|
|
|
103
117
|
.value=${live(initial)}
|
|
104
118
|
@keydown=${(e: KeyboardEvent) => {
|
|
105
119
|
if (e.key === "Enter") {
|
|
106
|
-
commit((e
|
|
120
|
+
commit(inputOf(e).value);
|
|
107
121
|
} else if (e.key === "Escape") {
|
|
108
122
|
abort();
|
|
109
123
|
}
|
|
110
124
|
}}
|
|
111
|
-
@blur=${(e: Event) => commit((e
|
|
125
|
+
@blur=${(e: Event) => commit(inputOf(e).value)}
|
|
112
126
|
/>`,
|
|
113
127
|
host,
|
|
114
128
|
);
|
|
@@ -133,7 +147,7 @@ function checkboxEditor(makeHost: HostFactory): CellEditorFn {
|
|
|
133
147
|
@change=${(e: Event) => {
|
|
134
148
|
if (!done) {
|
|
135
149
|
done = true;
|
|
136
|
-
success((e
|
|
150
|
+
success(inputOf(e).checked);
|
|
137
151
|
}
|
|
138
152
|
}}
|
|
139
153
|
@keydown=${(e: KeyboardEvent) => {
|
|
@@ -142,13 +156,13 @@ function checkboxEditor(makeHost: HostFactory): CellEditorFn {
|
|
|
142
156
|
cancel();
|
|
143
157
|
} else if (e.key === "Enter" && !done) {
|
|
144
158
|
done = true;
|
|
145
|
-
success((e
|
|
159
|
+
success(inputOf(e).checked);
|
|
146
160
|
}
|
|
147
161
|
}}
|
|
148
162
|
@blur=${(e: Event) => {
|
|
149
163
|
if (!done) {
|
|
150
164
|
done = true;
|
|
151
|
-
success((e
|
|
165
|
+
success(inputOf(e).checked);
|
|
152
166
|
}
|
|
153
167
|
}}
|
|
154
168
|
/>`,
|
|
@@ -160,19 +174,19 @@ function checkboxEditor(makeHost: HostFactory): CellEditorFn {
|
|
|
160
174
|
}
|
|
161
175
|
|
|
162
176
|
function selectEditor(makeHost: HostFactory, column: GridColumn): CellEditorFn {
|
|
163
|
-
const options = Array.isArray(column.schema?.enum)
|
|
164
|
-
? (column.schema.enum as unknown[]).map(String)
|
|
165
|
-
: [];
|
|
177
|
+
const options = Array.isArray(column.schema?.enum) ? column.schema.enum.map(String) : [];
|
|
166
178
|
return (cell, onRendered, success, cancel) => {
|
|
167
179
|
const host = makeHost("jx-grid-editor");
|
|
168
180
|
let done = false;
|
|
169
|
-
const current = cellToText(cell.getValue()
|
|
181
|
+
const current = cellToText(cell.getValue());
|
|
170
182
|
render(
|
|
171
183
|
html`<select
|
|
172
184
|
class="jx-grid-select"
|
|
173
185
|
@change=${(e: Event) => {
|
|
174
186
|
if (!done) {
|
|
175
187
|
done = true;
|
|
188
|
+
// SAFETY: this listener is bound on the `<select>` rendered here, and `change` is
|
|
189
|
+
// Dispatched at the select itself, never at one of its options.
|
|
176
190
|
const { value } = e.target as HTMLSelectElement;
|
|
177
191
|
success(value === "" ? null : value);
|
|
178
192
|
}
|
|
@@ -235,26 +249,27 @@ function pillEditor(makeHost: HostFactory, column: GridColumn): CellEditorFn {
|
|
|
235
249
|
render(
|
|
236
250
|
html`<span class="jx-grid-pills">
|
|
237
251
|
${chips.map(
|
|
238
|
-
(chip, i) =>
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
+
(chip, i) =>
|
|
253
|
+
html`<span class="jx-grid-chip"
|
|
254
|
+
>${chip}<button
|
|
255
|
+
class="jx-grid-chip-x"
|
|
256
|
+
title="Remove"
|
|
257
|
+
@mousedown=${(e: Event) => e.preventDefault()}
|
|
258
|
+
@click=${() => {
|
|
259
|
+
chips.splice(i, 1);
|
|
260
|
+
doRender();
|
|
261
|
+
inputEl()?.focus();
|
|
262
|
+
}}
|
|
263
|
+
>
|
|
264
|
+
×
|
|
265
|
+
</button></span
|
|
266
|
+
>`,
|
|
252
267
|
)}
|
|
253
268
|
<input
|
|
254
269
|
class="jx-grid-pill-input"
|
|
255
270
|
placeholder=${chips.length === 0 ? "add…" : ""}
|
|
256
271
|
@keydown=${(e: KeyboardEvent) => {
|
|
257
|
-
const input = e
|
|
272
|
+
const input = inputOf(e);
|
|
258
273
|
if (e.key === "Enter" || e.key === ",") {
|
|
259
274
|
e.preventDefault();
|
|
260
275
|
if (addFromInput(input)) {
|
|
@@ -272,7 +287,7 @@ function pillEditor(makeHost: HostFactory, column: GridColumn): CellEditorFn {
|
|
|
272
287
|
}
|
|
273
288
|
}}
|
|
274
289
|
@blur=${(e: Event) => {
|
|
275
|
-
addFromInput(e
|
|
290
|
+
addFromInput(inputOf(e));
|
|
276
291
|
finish([...chips]);
|
|
277
292
|
}}
|
|
278
293
|
/>
|
|
@@ -317,7 +332,7 @@ export function editorForColumn(
|
|
|
317
332
|
/** Formatter factory — plain-text projection rendered as a real element (innerHTML-safe). */
|
|
318
333
|
export function formatterForColumn(column: GridColumn, makeHost: HostFactory): CellFormatterFn {
|
|
319
334
|
return (cell) => {
|
|
320
|
-
const value = cell.getValue()
|
|
335
|
+
const value = cell.getValue();
|
|
321
336
|
const host = makeHost(`jx-grid-cell-content jx-grid-kind-${column.kind}`);
|
|
322
337
|
if (column.kind === "boolean") {
|
|
323
338
|
render(html`${value === true ? "✓" : ""}`, host);
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* through the panel's island seam (specs/studio-ui-guidelines.md §9.4) — the box is drawn by one
|
|
13
13
|
* document and filled by another, and nothing in this file renders anything.
|
|
14
14
|
*/
|
|
15
|
+
import { isString } from "@jxsuite/schema/guards";
|
|
15
16
|
import { openGridCellSurface } from "../surfaces/grid-cell";
|
|
16
17
|
import { mountMediaPicker } from "../ui/media-picker";
|
|
17
18
|
import { listCollectionEntryIds } from "./sources/content-source";
|
|
@@ -25,8 +26,9 @@ export function hasPopoverEditor(column: GridColumn): boolean {
|
|
|
25
26
|
|
|
26
27
|
/** Target content-type name of a relationship column (`#/content/<name>` on the schema). */
|
|
27
28
|
export function referenceTargetType(column: GridColumn): string | null {
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
// The schema is the project's own JSON, so `$ref` is checked rather than trusted to be a string.
|
|
30
|
+
const ref = column.schema?.$ref;
|
|
31
|
+
if (!isString(ref) || !ref.startsWith("#/content/")) {
|
|
30
32
|
return null;
|
|
31
33
|
}
|
|
32
34
|
return ref.slice("#/content/".length);
|
|
@@ -47,7 +49,7 @@ export interface CellPopoverArgs {
|
|
|
47
49
|
* The clamp is the panel's own width and a floor for its height, because a cell near the right edge
|
|
48
50
|
* of a wide grid is exactly where a relationship column tends to be.
|
|
49
51
|
*/
|
|
50
|
-
function placement(anchor: CellPopoverArgs["anchor"])
|
|
52
|
+
function placement(anchor: CellPopoverArgs["anchor"]) {
|
|
51
53
|
return {
|
|
52
54
|
x: Math.max(4, Math.min(anchor.left, window.innerWidth - 340)),
|
|
53
55
|
y: Math.max(4, Math.min(anchor.bottom + 2, window.innerHeight - 200)),
|
package/src/grid/edit-buffer.ts
CHANGED
|
@@ -92,15 +92,16 @@ export function createEditBuffer(opts: EditBufferOptions): EditBuffer {
|
|
|
92
92
|
const coalesceMs = opts.coalesceMs ?? 800;
|
|
93
93
|
const now = opts.now ?? (() => Date.now());
|
|
94
94
|
|
|
95
|
-
const
|
|
96
|
-
deletes: new Set
|
|
97
|
-
errors: new Map
|
|
98
|
-
inserts: new Map
|
|
99
|
-
pending: new Map
|
|
100
|
-
redoStack: []
|
|
101
|
-
stale: new Set
|
|
102
|
-
undoStack: []
|
|
103
|
-
}
|
|
95
|
+
const initial: EditBufferState = {
|
|
96
|
+
deletes: new Set(),
|
|
97
|
+
errors: new Map(),
|
|
98
|
+
inserts: new Map(),
|
|
99
|
+
pending: new Map(),
|
|
100
|
+
redoStack: [],
|
|
101
|
+
stale: new Set(),
|
|
102
|
+
undoStack: [],
|
|
103
|
+
};
|
|
104
|
+
const state: EditBufferState = reactive(initial);
|
|
104
105
|
|
|
105
106
|
let groupOps: BufferOp[] | null = null;
|
|
106
107
|
|
|
@@ -19,6 +19,7 @@ import { isRecentLocal } from "../files/fs-events";
|
|
|
19
19
|
import { showConfirmDialog } from "../ui/layers";
|
|
20
20
|
import { showProgressModal } from "../ui/progress-modal";
|
|
21
21
|
import { errorMessage } from "@jxsuite/schema/parse";
|
|
22
|
+
import { isNonNullObject, isNumber, isString } from "@jxsuite/schema/guards";
|
|
22
23
|
import { createEditBuffer } from "./edit-buffer";
|
|
23
24
|
import { cellToText } from "./schema-columns";
|
|
24
25
|
import type { EditBuffer } from "./edit-buffer";
|
|
@@ -111,25 +112,26 @@ export interface GridController {
|
|
|
111
112
|
/** Row-object key carrying the grid row identity through the engine. */
|
|
112
113
|
export const ROW_KEY_FIELD = "__key";
|
|
113
114
|
|
|
114
|
-
const _controllers = new WeakMap<
|
|
115
|
+
const _controllers = new WeakMap<Tab, GridController>();
|
|
115
116
|
|
|
116
117
|
/** The grid controller for a tab, if it is a grid tab. */
|
|
117
118
|
export function getGridController(tab: Tab | null): GridController | null {
|
|
118
|
-
return tab ? (_controllers.get(toRaw(tab
|
|
119
|
+
return tab ? (_controllers.get(toRaw(tab)) ?? null) : null;
|
|
119
120
|
}
|
|
120
121
|
|
|
121
122
|
/** Create and register the controller for a grid tab. One per tab; lives in the tab's scope. */
|
|
122
123
|
export function createGridController(tab: Tab, source: GridSource): GridController {
|
|
123
|
-
const
|
|
124
|
-
columns: []
|
|
125
|
-
error: null
|
|
126
|
-
grouping: null
|
|
124
|
+
const initial: GridControllerState = {
|
|
125
|
+
columns: [],
|
|
126
|
+
error: null,
|
|
127
|
+
grouping: null,
|
|
127
128
|
loading: false,
|
|
128
|
-
query: {}
|
|
129
|
-
rows: []
|
|
129
|
+
query: {},
|
|
130
|
+
rows: [],
|
|
130
131
|
saving: false,
|
|
131
132
|
total: 0,
|
|
132
|
-
}
|
|
133
|
+
};
|
|
134
|
+
const state: GridControllerState = reactive(initial);
|
|
133
135
|
|
|
134
136
|
let rowByKey = new Map<string, GridRow>();
|
|
135
137
|
const indexRows = (rows: GridRow[]) => {
|
|
@@ -142,9 +144,13 @@ export function createGridController(tab: Tab, source: GridSource): GridControll
|
|
|
142
144
|
|
|
143
145
|
const reloadRows = async () => {
|
|
144
146
|
const result = await source.rows(state.query);
|
|
147
|
+
/* Index BEFORE the rows are published. The index is not reactive, and assigning `state.rows`
|
|
148
|
+
runs the effects that read it at once: a record's entry form (`content/record-entry.ts`)
|
|
149
|
+
resolves its row key from the new rows and reads that row's cells through the baseline,
|
|
150
|
+
which with the index still empty drew every field blank until something else re-ran it. */
|
|
151
|
+
indexRows(result.rows);
|
|
145
152
|
state.rows = result.rows;
|
|
146
153
|
state.total = result.total;
|
|
147
|
-
indexRows(result.rows);
|
|
148
154
|
};
|
|
149
155
|
|
|
150
156
|
/** Missing required cells block the save (marked as row/cell errors, like a failed commit). */
|
|
@@ -181,7 +187,7 @@ export function createGridController(tab: Tab, source: GridSource): GridControll
|
|
|
181
187
|
|
|
182
188
|
const compareCells = (a: GridCellValue, b: GridCellValue, kind: GridColumnKind | undefined) => {
|
|
183
189
|
if (kind === "number") {
|
|
184
|
-
return (
|
|
190
|
+
return (isNumber(a) ? a : 0) - (isNumber(b) ? b : 0);
|
|
185
191
|
}
|
|
186
192
|
if (kind === "boolean") {
|
|
187
193
|
return (a === true ? 1 : 0) - (b === true ? 1 : 0);
|
|
@@ -280,7 +286,7 @@ export function createGridController(tab: Tab, source: GridSource): GridControll
|
|
|
280
286
|
}
|
|
281
287
|
for (const column of textColumns) {
|
|
282
288
|
const value = buffer.effectiveValue(rowKey, column.field);
|
|
283
|
-
if (
|
|
289
|
+
if (isString(value) && value.includes(find)) {
|
|
284
290
|
buffer.setCell(rowKey, column.field, value.replaceAll(find, replace));
|
|
285
291
|
changed += 1;
|
|
286
292
|
}
|
|
@@ -296,17 +302,13 @@ export function createGridController(tab: Tab, source: GridSource): GridControll
|
|
|
296
302
|
effectiveRows() {
|
|
297
303
|
// Detach values from reactive proxies — the grid engine must never hold live proxies.
|
|
298
304
|
const plain = (value: GridCellValue): GridCellValue =>
|
|
299
|
-
Array.isArray(value)
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
? { $ref: value.$ref }
|
|
303
|
-
: value;
|
|
304
|
-
const rowObject = (key: string) => {
|
|
305
|
-
const cells: Record<string, GridCellValue> = { [ROW_KEY_FIELD]: key };
|
|
305
|
+
Array.isArray(value) ? [...value] : isNonNullObject(value) ? { $ref: value.$ref } : value;
|
|
306
|
+
const rowObject = (key: string): Record<string, GridCellValue> => {
|
|
307
|
+
const cells: [field: string, value: GridCellValue][] = [[ROW_KEY_FIELD, key]];
|
|
306
308
|
for (const column of state.columns) {
|
|
307
|
-
cells[column.field
|
|
309
|
+
cells.push([column.field, plain(buffer.effectiveValue(key, column.field))]);
|
|
308
310
|
}
|
|
309
|
-
return cells;
|
|
311
|
+
return Object.fromEntries(cells);
|
|
310
312
|
};
|
|
311
313
|
const rows = orderedKeys().map((key) => rowObject(key));
|
|
312
314
|
for (const [tempKey] of buffer.state.inserts) {
|
|
@@ -547,11 +549,11 @@ export function createGridController(tab: Tab, source: GridSource): GridControll
|
|
|
547
549
|
|
|
548
550
|
onScopeDispose(() => {
|
|
549
551
|
setHistoryDelegate(tab, null);
|
|
550
|
-
_controllers.delete(toRaw(tab
|
|
552
|
+
_controllers.delete(toRaw(tab));
|
|
551
553
|
source.dispose?.();
|
|
552
554
|
});
|
|
553
555
|
});
|
|
554
556
|
|
|
555
|
-
_controllers.set(toRaw(tab
|
|
557
|
+
_controllers.set(toRaw(tab), controller);
|
|
556
558
|
return controller;
|
|
557
559
|
}
|
package/src/grid/grid-layout.ts
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
* layout keep their relative position at the end; saved fields that no longer exist are ignored —
|
|
24
24
|
* schemas drift).
|
|
25
25
|
*/
|
|
26
|
+
import { isNonNullObject, isString } from "@jxsuite/schema/guards";
|
|
26
27
|
|
|
27
28
|
/** One sort, as a saved view records it. The grid is single-key sorted; a second key is not saved. */
|
|
28
29
|
export interface GridSortSpec {
|
|
@@ -70,7 +71,7 @@ const STORAGE_PREFIX = "jx-grid-layout:";
|
|
|
70
71
|
|
|
71
72
|
function storage(): Storage | null {
|
|
72
73
|
try {
|
|
73
|
-
return
|
|
74
|
+
return typeof localStorage === "undefined" ? null : localStorage;
|
|
74
75
|
} catch {
|
|
75
76
|
return null; // Storage disabled (privacy mode) — layouts just don't persist.
|
|
76
77
|
}
|
|
@@ -83,8 +84,11 @@ function readRecord(gridId: string): GridLayoutRecord | null {
|
|
|
83
84
|
return null;
|
|
84
85
|
}
|
|
85
86
|
try {
|
|
86
|
-
const parsed = JSON.parse(raw)
|
|
87
|
-
|
|
87
|
+
const parsed: unknown = JSON.parse(raw);
|
|
88
|
+
/* SAFETY: this key is written only by `writeRecord`, which stores a serialized
|
|
89
|
+
GridLayoutRecord, and every reader treats each field as possibly absent (`?.`, `??`, and
|
|
90
|
+
`listSavedViews` drops any entry that is not a named view). A non-object is refused here. */
|
|
91
|
+
return isNonNullObject(parsed) ? (parsed as GridLayoutRecord) : null;
|
|
88
92
|
} catch {
|
|
89
93
|
return null;
|
|
90
94
|
}
|
|
@@ -153,7 +157,11 @@ export function resetGridLayout(gridId: string): void {
|
|
|
153
157
|
if (!record) {
|
|
154
158
|
return;
|
|
155
159
|
}
|
|
156
|
-
|
|
160
|
+
const next: GridLayoutRecord = { active: null };
|
|
161
|
+
if (record.views) {
|
|
162
|
+
next.views = record.views;
|
|
163
|
+
}
|
|
164
|
+
writeRecord(gridId, next);
|
|
157
165
|
}
|
|
158
166
|
|
|
159
167
|
// ─── Named views ──────────────────────────────────────────────────────────────
|
|
@@ -161,7 +169,15 @@ export function resetGridLayout(gridId: string): void {
|
|
|
161
169
|
/** The named views for a grid id, in save order. */
|
|
162
170
|
export function listSavedViews(gridId: string): SavedGridView[] {
|
|
163
171
|
const views = readRecord(gridId)?.views;
|
|
164
|
-
return Array.isArray(views) ? views.filter((view) =>
|
|
172
|
+
return Array.isArray(views) ? views.filter((view) => isSavedGridView(view)) : [];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Whether a stored `views` entry is a named view. Storage outlives the code that wrote it, so an
|
|
177
|
+
* entry without a string `name` (null, a primitive, an older shape) is skipped rather than shown.
|
|
178
|
+
*/
|
|
179
|
+
function isSavedGridView(view: unknown): view is SavedGridView {
|
|
180
|
+
return isNonNullObject(view) && "name" in view && isString(view.name);
|
|
165
181
|
}
|
|
166
182
|
|
|
167
183
|
/** The name of the view last applied to this grid, or null when the layout is unnamed. */
|
package/src/grid/grid-open.ts
CHANGED
|
@@ -19,17 +19,13 @@ import {
|
|
|
19
19
|
createPagesSource,
|
|
20
20
|
} from "./sources/content-source";
|
|
21
21
|
import { createConnectorSource } from "./sources/connector-source";
|
|
22
|
-
import { makeGridTabId, parseGridTabId } from "./grid-source";
|
|
23
|
-
import { libraryTabId } from "../browse/library-source";
|
|
22
|
+
import { GRID_STUB_DOCUMENT, makeGridTabId, parseGridTabId } from "./grid-source";
|
|
24
23
|
import { argsSchema, optionalStringArg, stringArg, stringProperty } from "../commands/command-args";
|
|
25
24
|
import type { GridSource } from "./grid-source";
|
|
26
25
|
import type { GridOpenSurfaceHandle, GridSourceGroup } from "../surfaces/grid-open";
|
|
27
26
|
import type { Tab } from "../tabs/tab";
|
|
28
27
|
import type { AnyCommand, CommandRegistry } from "../commands/registry";
|
|
29
28
|
|
|
30
|
-
/** Placeholder document for grid tabs — the grid never reads it; save routes to the controller. */
|
|
31
|
-
const GRID_STUB_DOCUMENT = { children: [], tagName: "div" };
|
|
32
|
-
|
|
33
29
|
/**
|
|
34
30
|
* Open (or activate) a `.csv` file as a grid tab.
|
|
35
31
|
*
|
|
@@ -102,32 +98,6 @@ export function openCollectionGrid(typeName: string): Tab {
|
|
|
102
98
|
return openVirtualGridTab(createCollectionSource(typeName));
|
|
103
99
|
}
|
|
104
100
|
|
|
105
|
-
/**
|
|
106
|
-
* Open (or activate) the Library.
|
|
107
|
-
*
|
|
108
|
-
* A real tab, in the primary pane, with `manage` as its only mode — `commands/context.ts` maps that
|
|
109
|
-
* to the `library` editor kind, so the status bar and the pane context bar can name what is on
|
|
110
|
-
* screen. It is opened here rather than in `browse/` because this is the module that knows how a
|
|
111
|
-
* virtual tab is made; the pane itself resolves its own source and its own view state.
|
|
112
|
-
*
|
|
113
|
-
* Idempotent by construction, which is what lets a shot say "the Library is open" without caring
|
|
114
|
-
* whether an earlier step opened it.
|
|
115
|
-
*/
|
|
116
|
-
export function openLibraryTab(): Tab {
|
|
117
|
-
const id = libraryTabId();
|
|
118
|
-
const existing = workspace.tabs.get(id);
|
|
119
|
-
if (existing) {
|
|
120
|
-
activateTab(id);
|
|
121
|
-
return existing;
|
|
122
|
-
}
|
|
123
|
-
return openTab({
|
|
124
|
-
capabilities: { modes: ["manage"] },
|
|
125
|
-
document: structuredClone(GRID_STUB_DOCUMENT),
|
|
126
|
-
documentPath: null,
|
|
127
|
-
id,
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
|
|
131
101
|
/** Open (or activate) the pages metadata grid. */
|
|
132
102
|
export function openPagesGrid(): Tab {
|
|
133
103
|
const id = makeGridTabId({ kind: "pages" });
|
|
@@ -187,14 +157,14 @@ function sourceGroups(
|
|
|
187
157
|
state: "listed",
|
|
188
158
|
title: "Project",
|
|
189
159
|
},
|
|
190
|
-
...connections.map((conn) => ({
|
|
160
|
+
...connections.map((conn): GridSourceGroup => ({
|
|
191
161
|
emptyMessage: "No tables — push a schema first.",
|
|
192
162
|
key: `data:${conn.name}`,
|
|
193
163
|
rows: conn.tables.map((table) => ({
|
|
194
164
|
id: makeGridTabId({ connection: conn.name, kind: "data", table }),
|
|
195
165
|
label: table,
|
|
196
166
|
})),
|
|
197
|
-
state:
|
|
167
|
+
state: conn.tables.length === 0 ? "empty" : "listed",
|
|
198
168
|
title: `Data · ${conn.name}`,
|
|
199
169
|
})),
|
|
200
170
|
];
|