@jxsuite/studio 6.1.1 → 6.1.2
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/dist/chunks/{2020-va2wwra4.js → 2020-f2gkpy8d.js} +3 -3
- package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
- package/dist/chunks/adapter-4912g339.js +4 -0
- package/dist/chunks/cf-account-picker-wccaenh6.js +4 -0
- package/dist/chunks/cf-settings-br6105tr.js +4 -0
- package/dist/chunks/color-28ksk2qm.js +4 -0
- package/dist/chunks/color-area-0fj8a4ga.js +4 -0
- package/dist/chunks/color-field-xch8kx2g.js +4 -0
- package/dist/chunks/color-slider-jxd8v350.js +4 -0
- package/dist/chunks/combobox-p0efwjke.js +4 -0
- package/dist/chunks/components-db68vsn7.js +4 -0
- package/dist/chunks/content-source-1449qesq.js +4 -0
- package/dist/chunks/convert-to-repeater-5h457egj.js +4 -0
- package/dist/chunks/dialog-c4x05vyx.js +4 -0
- package/dist/chunks/editor-x9jn86a7.js +4 -0
- package/dist/chunks/entry-commands-may24cpt.js +4 -0
- package/dist/chunks/extension-sections-pvr14vxr.js +4 -0
- package/dist/chunks/file-ops-x9v54pcj.js +4 -0
- package/dist/chunks/files-j3knqf0s.js +4 -0
- package/dist/chunks/format-host-tyre2trb.js +4 -0
- package/dist/chunks/fs-events-64ma9htc.js +4 -0
- package/dist/chunks/git-panel-84ps5dex.js +4 -0
- package/dist/chunks/grid-view-d2wq9ezg.js +51 -0
- package/dist/chunks/icons-pnfz478q.js +4 -0
- package/dist/chunks/iframe-entry-fvbk89gm.js +5 -0
- package/dist/chunks/iframe-entry-jdcktez8.js +5 -0
- package/dist/chunks/iframe-entry-x0ygf2yr.js +5 -0
- package/dist/chunks/iframe-entry-zap785cw.js +5 -0
- package/dist/chunks/iframe-host-ck6vejt5.js +4 -0
- package/dist/chunks/index-b8xw3vy9.js +4 -0
- package/dist/chunks/{index-2veqmnhr.js → index-zpjmzqfk.js} +3 -3
- package/dist/chunks/{javascript-8nbvs12s.js → javascript-m54mnwp6.js} +3 -3
- package/dist/chunks/{jsonMode-s8kt9dsj.js → jsonMode-w15cmrcm.js} +8 -8
- package/dist/chunks/jx-validate-at3zn8wa.js +4 -0
- package/dist/chunks/layers-h4xp1pss.js +4 -0
- package/dist/chunks/layers-panel-m5hw1d7g.js +4 -0
- package/dist/chunks/listbox-e74qjyq6.js +4 -0
- package/dist/chunks/lit-html-8t8t3dnr.js +4 -0
- package/dist/chunks/media-picker-2cweexc5.js +4 -0
- package/dist/chunks/menu-n6yzswmy.js +4 -0
- package/dist/chunks/menu-ynw13y0s.js +4 -0
- package/dist/chunks/monaco-binding-7gx83x3r.js +4 -0
- package/dist/chunks/monaco-buffer-qzxn567r.js +4 -0
- package/dist/chunks/monaco-setup-gxf6656g.js +4 -0
- package/dist/chunks/notify-cj5zbrs2.js +4 -0
- package/dist/chunks/number-field-y62xq0ty.js +4 -0
- package/dist/chunks/parse-b7ddhr8m.js +4 -0
- package/dist/chunks/platform-3dfws9js.js +4 -0
- package/dist/chunks/popover-jt2gxmzs.js +4 -0
- package/dist/chunks/publish-panel-1gvxbj21.js +4 -0
- package/dist/chunks/quick-search-0dajrwqg.js +4 -0
- package/dist/chunks/references-49qgt404.js +4 -0
- package/dist/chunks/right-panel-jm1bwe53.js +4 -0
- package/dist/chunks/section-registry-6kwc4fky.js +4 -0
- package/dist/chunks/select-rzds841e.js +4 -0
- package/dist/chunks/split-n2gfpm5m.js +4 -0
- package/dist/chunks/{studio-1q1sh2ax.js → studio-0q988f9w.js} +3 -3
- package/dist/chunks/studio-0rt52vpq.js +5 -0
- package/dist/chunks/studio-18vgbhs5.js +5 -0
- package/dist/chunks/{studio-h46vtzk8.js → studio-1fxkaaea.js} +4 -4
- package/dist/chunks/studio-24mccdrj.js +5 -0
- package/dist/chunks/studio-2eh507zk.js +9 -0
- package/dist/chunks/studio-2hcbccfv.js +5 -0
- package/dist/chunks/studio-2j1cb95x.js +5 -0
- package/dist/chunks/studio-2jbs3rxv.js +5 -0
- package/dist/chunks/{studio-rv11kfwa.js → studio-485046te.js} +7 -7
- package/dist/chunks/studio-4h8k4dw9.js +5 -0
- package/dist/chunks/studio-5f6n18kx.js +5 -0
- package/dist/chunks/studio-5gthpky6.js +5 -0
- package/dist/chunks/studio-5ve6bbep.js +5 -0
- package/dist/chunks/studio-6ep3js6b.js +9 -0
- package/dist/chunks/studio-6wkmf3wz.js +9 -0
- package/dist/chunks/studio-841rf3cg.js +5 -0
- package/dist/chunks/studio-8gmwgheg.js +5 -0
- package/dist/chunks/studio-8qm0ep50.js +5 -0
- package/dist/chunks/{studio-8grwxtqk.js → studio-90pq9km1.js} +4 -4
- package/dist/chunks/studio-924p1tm1.js +6 -0
- package/dist/chunks/{studio-pre0skq6.js → studio-a3g98wjr.js} +4 -4
- package/dist/chunks/studio-a3shpz9y.js +5 -0
- package/dist/chunks/studio-amsbaaar.js +6 -0
- package/dist/chunks/studio-at5spjbc.js +7 -0
- package/dist/chunks/studio-b2xv945e.js +5 -0
- package/dist/chunks/studio-bn5nkafw.js +5 -0
- package/dist/chunks/studio-bw6q5xjf.js +9 -0
- package/dist/chunks/studio-c7q0t9x1.js +5 -0
- package/dist/chunks/studio-camnhc96.js +6 -0
- package/dist/chunks/studio-cffqvnzd.js +5 -0
- package/dist/chunks/studio-d81xfh1g.js +5 -0
- package/dist/chunks/studio-dgz8d0c1.js +5 -0
- package/dist/chunks/studio-efvfrsf8.js +5 -0
- package/dist/chunks/studio-er30bpcx.js +5 -0
- package/dist/chunks/studio-ezscgr64.js +5 -0
- package/dist/chunks/studio-ffrrncvz.js +5 -0
- package/dist/chunks/studio-fpphgn8y.js +10 -0
- package/dist/chunks/studio-j1kvhdjk.js +4 -0
- package/dist/chunks/{studio-vrmcjf9g.js → studio-j430n16g.js} +5 -5
- package/dist/chunks/studio-jjkg84nj.js +5 -0
- package/dist/chunks/studio-m0q32ars.js +4 -0
- package/dist/chunks/studio-m6bdst11.js +5 -0
- package/dist/chunks/studio-nv2cptd4.js +64 -0
- package/dist/chunks/studio-nwfrc98n.js +5 -0
- package/dist/chunks/studio-p1wgvp7r.js +5 -0
- package/dist/chunks/studio-pag2wncm.js +5 -0
- package/dist/chunks/studio-qvanvzfd.js +5 -0
- package/dist/chunks/studio-qwa64kt7.js +5 -0
- package/dist/chunks/studio-rk1zc4x3.js +928 -0
- package/dist/chunks/studio-se2r3ptc.js +5 -0
- package/dist/chunks/studio-sg2a0dh0.js +5 -0
- package/dist/chunks/studio-tjzjhe68.js +5 -0
- package/dist/chunks/{studio-wszjyh0j.js → studio-tq0rtfwj.js} +4 -4
- package/dist/chunks/{studio-kggey1jt.js → studio-v0jzqdjm.js} +4 -4
- package/dist/chunks/studio-v2w7q8r1.js +7 -0
- package/dist/chunks/studio-v5vjq1h0.js +4 -0
- package/dist/chunks/studio-v8aga3vp.js +14 -0
- package/dist/chunks/studio-vfcdrfmv.js +5 -0
- package/dist/chunks/studio-vmfkgdjf.js +5 -0
- package/dist/chunks/studio-wt1816jj.js +5 -0
- package/dist/chunks/studio-wz73q5kq.js +4 -0
- package/dist/chunks/studio-y04qtxvp.js +7 -0
- package/dist/chunks/studio-y21g8zzg.js +5 -0
- package/dist/chunks/{studio-zey7zsdw.js → studio-y64hrt8p.js} +7 -7
- package/dist/chunks/studio-ynn90f58.js +16 -0
- package/dist/chunks/studio-yxz682sx.js +5 -0
- package/dist/chunks/studio-zp7snvkq.js +5 -0
- package/dist/chunks/studio-zq4z6tm6.js +5 -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-c9fn075p.js +4 -0
- package/dist/chunks/toast-host-ke5z4ng7.js +4 -0
- package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
- package/dist/chunks/tooltip-5v8ngwj2.js +4 -0
- package/dist/chunks/tree-mdq3v5cw.js +4 -0
- package/dist/chunks/{tsMode-2frah6h1.js → tsMode-sf49ee9x.js} +7 -7
- package/dist/chunks/workspace-jtfahpee.js +4 -0
- package/dist/chunks/ws-client-nze0k6mv.js +4 -0
- package/dist/iframe-entry.js +16 -16
- package/dist/manifest.json +63 -63
- package/dist/studio.js +97 -97
- package/package.json +6 -6
- 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/library-layouts.ts +8 -5
- package/src/browse/library-model.ts +18 -6
- package/src/browse/library-pane.ts +37 -21
- package/src/browse/library-preview.ts +14 -9
- package/src/browse/library-source.ts +1 -1
- package/src/canvas/asset-refs.ts +24 -9
- package/src/canvas/asset-resolve.ts +19 -23
- package/src/canvas/canvas-helpers.ts +7 -6
- package/src/canvas/canvas-live-render.ts +44 -53
- package/src/canvas/canvas-patcher.ts +30 -30
- package/src/canvas/canvas-perf.ts +11 -5
- package/src/canvas/canvas-render.ts +62 -41
- package/src/canvas/canvas-surface.ts +5 -3
- package/src/canvas/canvas-utils.ts +90 -49
- 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 +13 -12
- package/src/canvas/iframe-editable-root.ts +29 -16
- package/src/canvas/iframe-entry.ts +80 -63
- package/src/canvas/iframe-eval.ts +73 -49
- package/src/canvas/iframe-host.ts +135 -96
- 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-overlay.ts +1 -1
- package/src/canvas/iframe-patch.ts +18 -15
- package/src/canvas/iframe-position.ts +12 -6
- package/src/canvas/iframe-protocol.ts +12 -16
- package/src/canvas/iframe-render.ts +36 -34
- package/src/canvas/iframe-slash.ts +24 -11
- package/src/canvas/iframe-subtree.ts +6 -2
- 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/serialize-scope.ts +13 -5
- package/src/canvas/stage-scrollbar.ts +2 -1
- package/src/canvas/surface-registry.ts +21 -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/budget.ts +3 -3
- package/src/commands/command-args.ts +103 -71
- package/src/commands/context.ts +22 -20
- package/src/commands/keymap.ts +47 -43
- package/src/commands/levels.ts +3 -3
- package/src/commands/live-context.ts +7 -7
- package/src/commands/reference.ts +2 -1
- package/src/commands/registry.ts +12 -10
- package/src/commands/run-reported.ts +15 -10
- package/src/component-props.ts +46 -30
- package/src/content/collection-match.ts +5 -4
- package/src/content/draft-state.ts +4 -3
- package/src/content/entry-commands.ts +3 -2
- package/src/content/entry-editor.ts +29 -17
- package/src/content/entry-fields.ts +12 -7
- package/src/content/entry-model.ts +21 -12
- 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 +11 -5
- package/src/editor/convert-to-repeater.ts +34 -22
- package/src/editor/editable-tags.ts +17 -2
- package/src/editor/file-drop-action.ts +21 -22
- package/src/editor/inline-edit-apply.ts +35 -17
- package/src/editor/inline-edit.ts +66 -50
- package/src/editor/inline-format.ts +59 -56
- package/src/editor/inline-link.ts +40 -15
- package/src/editor/insert-zone-action.ts +1 -1
- package/src/editor/merge-tags.ts +58 -19
- package/src/editor/repeater-scope.ts +39 -28
- package/src/editor/shortcuts.ts +32 -20
- package/src/editor/slash-menu.ts +1 -6
- package/src/files/asset-versions.ts +4 -4
- package/src/files/components.ts +15 -10
- package/src/files/elements.ts +5 -6
- package/src/files/file-ops.ts +77 -36
- package/src/files/files.ts +90 -95
- package/src/files/media-meta.ts +2 -1
- package/src/files/media-paths.ts +3 -0
- package/src/files/serialize-document.ts +2 -2
- 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 +76 -50
- package/src/github/github-auth-status.ts +27 -3
- package/src/github/github-auth.ts +19 -9
- package/src/github/github-publish.ts +24 -20
- 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 +20 -22
- package/src/grid/grid-layout.ts +21 -5
- package/src/grid/grid-open.ts +3 -6
- package/src/grid/grid-panel.ts +11 -4
- package/src/grid/grid-source.ts +8 -8
- package/src/grid/grid-view.ts +14 -17
- 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 +25 -24
- package/src/grid/sources/csv-file-source.ts +2 -2
- package/src/grid/tabulator-tables.d.ts +55 -34
- package/src/hosting/stage.ts +7 -7
- package/src/i18n/i18n-commands.ts +1 -2
- package/src/media/media-pane.ts +4 -1
- 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 +17 -9
- package/src/panels/ai-chat/attached-context.ts +13 -7
- 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 +46 -35
- package/src/panels/bottom-dock.ts +5 -3
- package/src/panels/canvas-dnd-bridge.ts +31 -24
- package/src/panels/data-explorer.ts +62 -25
- package/src/panels/data-grid.ts +14 -11
- package/src/panels/dnd.ts +108 -118
- package/src/panels/editors.ts +52 -21
- package/src/panels/elements-panel.ts +10 -3
- package/src/panels/events-panel.ts +84 -69
- package/src/panels/formula-workspace.ts +76 -51
- package/src/panels/frontmatter-fields.ts +24 -19
- package/src/panels/frontmatter-panel.ts +44 -34
- package/src/panels/git-diff-open.ts +4 -4
- package/src/panels/git-panel.ts +49 -61
- package/src/panels/head-panel.ts +131 -111
- package/src/panels/i18n-panel.ts +10 -3
- package/src/panels/imports-panel.ts +23 -47
- package/src/panels/jump-bar.ts +48 -29
- package/src/panels/layers-panel.ts +97 -74
- package/src/panels/left-panel.ts +3 -3
- package/src/panels/pane-context.ts +31 -22
- package/src/panels/pane-grid.ts +49 -20
- package/src/panels/panel-registry.ts +22 -37
- package/src/panels/properties-panel.ts +175 -121
- package/src/panels/quick-search.ts +53 -31
- package/src/panels/right-panel.ts +3 -3
- package/src/panels/seo-modal.ts +13 -17
- package/src/panels/settings-menu.ts +15 -15
- package/src/panels/signals-panel.ts +153 -131
- package/src/panels/statement-editor.ts +230 -140
- package/src/panels/style-panel.ts +218 -205
- package/src/panels/style-utils.ts +114 -51
- package/src/panels/stylebook-doc.ts +57 -54
- package/src/panels/stylebook-layers-panel.ts +9 -9
- package/src/panels/stylebook-panel.ts +13 -17
- package/src/panels/tab-drop.ts +27 -11
- package/src/panels/tab-strip.ts +36 -26
- package/src/platform-errors.ts +57 -43
- package/src/platform.ts +58 -30
- package/src/platforms/cloud.ts +345 -175
- package/src/platforms/default-platform.ts +10 -4
- package/src/platforms/devserver.ts +129 -117
- package/src/platforms/read-batcher.ts +16 -8
- package/src/project-list.ts +2 -1
- package/src/publish/deploy-checklist.ts +8 -2
- package/src/publish/pages-service.ts +28 -13
- package/src/publish/publish-commands.ts +5 -4
- package/src/publish/publish-panel.ts +10 -6
- 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 +58 -31
- package/src/services/cem-export.ts +149 -58
- package/src/services/clock.ts +6 -1
- package/src/services/code-services.ts +37 -31
- 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 +18 -12
- 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 +8 -7
- 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 +79 -60
- package/src/settings/css-vars-editor.ts +37 -16
- package/src/settings/defs-editor.ts +38 -35
- package/src/settings/extension-rows.ts +16 -8
- package/src/settings/extension-sections.ts +23 -13
- package/src/settings/extensions-section.ts +4 -1
- package/src/settings/general-settings.ts +11 -8
- package/src/settings/locales-section.ts +20 -12
- package/src/settings/preferences-dialog.ts +9 -6
- package/src/settings/preferences-keymap.ts +7 -5
- package/src/settings/preferences-sections.ts +11 -5
- package/src/settings/project-sections.ts +1 -1
- package/src/settings/schema-field-ui.ts +9 -0
- package/src/settings/settings-document.ts +5 -5
- package/src/shell/tree.ts +6 -5
- package/src/shell.ts +104 -81
- package/src/site-context.ts +37 -22
- package/src/state.ts +41 -49
- package/src/store.ts +54 -34
- package/src/studio.ts +25 -75
- package/src/style/live-preview.ts +1 -1
- package/src/style/project-styles.ts +6 -7
- package/src/style/token-ref.ts +5 -4
- package/src/surfaces/about.ts +18 -19
- package/src/surfaces/add-repo.ts +17 -19
- package/src/surfaces/ai-chat.ts +31 -36
- 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.ts +4 -5
- package/src/surfaces/bottom-dock.ts +9 -18
- package/src/surfaces/canvas-stage.ts +12 -11
- package/src/surfaces/cf-account-picker.ts +17 -18
- package/src/surfaces/commandbar.ts +14 -9
- 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/doc-header.ts +10 -19
- package/src/surfaces/empty-state.ts +7 -10
- package/src/surfaces/entry-editor.ts +14 -11
- 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/git-panel.ts +7 -15
- 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.ts +13 -12
- package/src/surfaces/jump-bar.ts +5 -6
- package/src/surfaces/jxsuite-update.ts +16 -22
- package/src/surfaces/library-pane.ts +19 -20
- package/src/surfaces/logic-panel.ts +17 -30
- package/src/surfaces/logic-workspace.ts +13 -15
- package/src/surfaces/media-browser.ts +11 -10
- package/src/surfaces/media-field.ts +4 -5
- package/src/surfaces/media-pane.ts +8 -7
- package/src/surfaces/menu.ts +29 -23
- package/src/surfaces/navigator-dock.ts +11 -12
- package/src/surfaces/new-project.ts +27 -26
- package/src/surfaces/pane-context.ts +20 -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.ts +5 -6
- 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.ts +11 -18
- package/src/surfaces/panel-problems.ts +5 -7
- package/src/surfaces/panel-signals.ts +20 -34
- package/src/surfaces/panel-stylebook-layers.ts +5 -8
- package/src/surfaces/preferences.ts +21 -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.ts +18 -18
- package/src/surfaces/push-plan.ts +7 -8
- package/src/surfaces/rail.ts +13 -13
- package/src/surfaces/reference-field.ts +11 -15
- package/src/surfaces/schema-builder.ts +16 -22
- package/src/surfaces/schema-form.ts +15 -25
- package/src/surfaces/secret-field.ts +9 -6
- package/src/surfaces/seo.ts +21 -15
- package/src/surfaces/settings-contexts.ts +9 -7
- package/src/surfaces/settings-contributed.ts +14 -10
- package/src/surfaces/settings-css-vars.ts +5 -12
- package/src/surfaces/settings-defs.json +2 -2
- package/src/surfaces/settings-defs.ts +17 -21
- package/src/surfaces/settings-deploy.ts +8 -15
- 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.ts +5 -6
- package/src/surfaces/settings-packages.ts +8 -7
- package/src/surfaces/settings-pane.ts +9 -18
- package/src/surfaces/settings-rawjson.ts +5 -6
- package/src/surfaces/shell.ts +1 -2
- package/src/surfaces/slash-menu.ts +19 -9
- package/src/surfaces/statements.ts +13 -18
- package/src/surfaces/statusbar.ts +17 -14
- package/src/surfaces/style-panel.ts +18 -31
- package/src/surfaces/stylebook-chrome.ts +3 -5
- package/src/surfaces/tab-strip.ts +14 -13
- package/src/surfaces/target-line.ts +6 -7
- package/src/surfaces/welcome.ts +5 -7
- 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 +52 -41
- package/src/tabs/transact.ts +98 -53
- package/src/types.ts +32 -17
- 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 +57 -48
- package/src/ui/formula-catalog.ts +239 -230
- package/src/ui/formula-chips.ts +33 -18
- package/src/ui/layers.ts +44 -31
- package/src/ui/media-picker.ts +18 -9
- package/src/ui/popover-surface.ts +20 -12
- package/src/ui/progress-modal.ts +13 -8
- package/src/ui/regions.ts +7 -6
- package/src/ui/schema-form.ts +113 -70
- 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 +3 -2
- package/src/utils/base64.ts +3 -1
- package/src/utils/edit-display.ts +73 -73
- 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/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 +10 -12
- package/src/workspace/session.ts +53 -43
- package/src/workspace/workspace.ts +40 -36
- 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/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-t6b6qe31.js +0 -5
- package/dist/chunks/studio-tdcprbqb.js +0 -5
- 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-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/workspace-zt81g1ms.js +0 -4
- package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
* text. It is one value now, and the field shows it.
|
|
40
40
|
*/
|
|
41
41
|
|
|
42
|
+
import { isFunction, isJsonObject, isNonNullObject, isString } from "@jxsuite/schema/guards";
|
|
42
43
|
import { errorMessage } from "@jxsuite/schema/parse";
|
|
43
44
|
import { getPlatform } from "../platform";
|
|
44
45
|
import { commitProjectConfig } from "../tabs/project-config";
|
|
@@ -53,7 +54,8 @@ import { paneOfContainer } from "../canvas/canvas-surface";
|
|
|
53
54
|
import { mountContributedSurface } from "../surfaces/settings-contributed";
|
|
54
55
|
|
|
55
56
|
import type { JsonSchema, SchemaFormContext } from "../ui/schema-form";
|
|
56
|
-
import type {
|
|
57
|
+
import type { JsonObject, JsonValue } from "@jxsuite/schema/types";
|
|
58
|
+
import type { ResolveContextOptions } from "../services/context-resolver";
|
|
57
59
|
import type {
|
|
58
60
|
ContributedActions,
|
|
59
61
|
ContributedSurfaceHandle,
|
|
@@ -74,7 +76,7 @@ export interface SettingsContribution {
|
|
|
74
76
|
entry?:
|
|
75
77
|
| {
|
|
76
78
|
ui?: Record<string, { control?: string; enum?: unknown }> | undefined;
|
|
77
|
-
newEntry?:
|
|
79
|
+
newEntry?: JsonObject | undefined;
|
|
78
80
|
}
|
|
79
81
|
| undefined;
|
|
80
82
|
};
|
|
@@ -139,13 +141,8 @@ export function resetContributedSectionState(): void {
|
|
|
139
141
|
* such entry, so the caller's refusal can name both sides.
|
|
140
142
|
*/
|
|
141
143
|
export function selectContributedEntry(sectionKey: string, entryKey: string): string[] | null {
|
|
142
|
-
const section =
|
|
143
|
-
|
|
144
|
-
];
|
|
145
|
-
const entries =
|
|
146
|
-
section && typeof section === "object" && !Array.isArray(section)
|
|
147
|
-
? (section as Record<string, unknown>)
|
|
148
|
-
: {};
|
|
144
|
+
const section = projectState?.projectConfig?.[sectionKey];
|
|
145
|
+
const entries = isJsonObject(section) ? section : {};
|
|
149
146
|
if (!Object.hasOwn(entries, entryKey)) {
|
|
150
147
|
return Object.keys(entries);
|
|
151
148
|
}
|
|
@@ -170,6 +167,14 @@ export function resetContributedDiagnostics(): void {
|
|
|
170
167
|
diagnostics.clear();
|
|
171
168
|
}
|
|
172
169
|
|
|
170
|
+
/** {@link routeDiagnostics}' answer: per-field messages, and the ones about the record itself. */
|
|
171
|
+
export interface RoutedDiagnostics {
|
|
172
|
+
/** The first message for each property one level under the base, keyed by property name. */
|
|
173
|
+
fields: Record<string, string>;
|
|
174
|
+
/** Messages whose pointer is the base itself, for the section line. */
|
|
175
|
+
section: string[];
|
|
176
|
+
}
|
|
177
|
+
|
|
173
178
|
/**
|
|
174
179
|
* Route `jx-validate` messages ("/search/index: must be string") to the field they are about.
|
|
175
180
|
*
|
|
@@ -182,10 +187,7 @@ export function resetContributedDiagnostics(): void {
|
|
|
182
187
|
* @param {string[]} messages
|
|
183
188
|
* @returns
|
|
184
189
|
*/
|
|
185
|
-
export function routeDiagnostics(
|
|
186
|
-
base: string,
|
|
187
|
-
messages: string[],
|
|
188
|
-
): { fields: Record<string, string>; section: string[] } {
|
|
190
|
+
export function routeDiagnostics(base: string, messages: string[]): RoutedDiagnostics {
|
|
189
191
|
const fields: Record<string, string> = {};
|
|
190
192
|
const section: string[] = [];
|
|
191
193
|
for (const message of messages) {
|
|
@@ -230,7 +232,12 @@ export function routeDiagnostics(
|
|
|
230
232
|
* @param {() => void} rerender
|
|
231
233
|
*/
|
|
232
234
|
async function saveProjectConfig(base: string, rerender: () => void) {
|
|
233
|
-
|
|
235
|
+
/* Every caller reached this through `sectionValue`, which returns null without a config, so a
|
|
236
|
+
project is open here; the guard only states that to the compiler. */
|
|
237
|
+
const config = projectState?.projectConfig;
|
|
238
|
+
if (!config) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
234
241
|
|
|
235
242
|
const commit = await commitProjectConfig();
|
|
236
243
|
if (!commit.ok) {
|
|
@@ -258,7 +265,7 @@ async function saveProjectConfig(base: string, rerender: () => void) {
|
|
|
258
265
|
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
259
266
|
|
|
260
267
|
/** Apply a schema-form patch onto a record in place; `undefined` values unset the key. */
|
|
261
|
-
function applyPatch(target: Record<string,
|
|
268
|
+
function applyPatch<V>(target: Record<string, V>, patch: Record<string, V | undefined>) {
|
|
262
269
|
for (const [key, value] of Object.entries(patch)) {
|
|
263
270
|
if (value === undefined) {
|
|
264
271
|
delete target[key];
|
|
@@ -277,30 +284,30 @@ function slugify(name: string): string {
|
|
|
277
284
|
}
|
|
278
285
|
|
|
279
286
|
/** Instantiate a newEntry template, substituting `${key}` in every string value. */
|
|
280
|
-
function instantiateNewEntry(
|
|
281
|
-
template: Record<string, unknown> | undefined,
|
|
282
|
-
key: string,
|
|
283
|
-
): Record<string, unknown> {
|
|
287
|
+
function instantiateNewEntry(template: JsonObject | undefined, key: string): JsonObject {
|
|
284
288
|
if (!template) {
|
|
285
289
|
return {};
|
|
286
290
|
}
|
|
287
|
-
const
|
|
288
|
-
|
|
291
|
+
const substituteObject = (value: JsonObject): JsonObject => {
|
|
292
|
+
const out: JsonObject = {};
|
|
293
|
+
for (const [k, v] of Object.entries(value)) {
|
|
294
|
+
out[k] = substitute(v);
|
|
295
|
+
}
|
|
296
|
+
return out;
|
|
297
|
+
};
|
|
298
|
+
const substitute = (value: JsonValue): JsonValue => {
|
|
299
|
+
if (isString(value)) {
|
|
289
300
|
return value.replaceAll("${key}", key);
|
|
290
301
|
}
|
|
291
302
|
if (Array.isArray(value)) {
|
|
292
303
|
return value.map((item) => substitute(item));
|
|
293
304
|
}
|
|
294
|
-
if (value
|
|
295
|
-
|
|
296
|
-
for (const [k, v] of Object.entries(value)) {
|
|
297
|
-
out[k] = substitute(v);
|
|
298
|
-
}
|
|
299
|
-
return out;
|
|
305
|
+
if (isJsonObject(value)) {
|
|
306
|
+
return substituteObject(value);
|
|
300
307
|
}
|
|
301
308
|
return value;
|
|
302
309
|
};
|
|
303
|
-
return
|
|
310
|
+
return substituteObject(template);
|
|
304
311
|
}
|
|
305
312
|
|
|
306
313
|
/**
|
|
@@ -314,37 +321,44 @@ function buildContext(
|
|
|
314
321
|
entryKey: string | null = null,
|
|
315
322
|
): SchemaFormContext {
|
|
316
323
|
const platform = getPlatform();
|
|
317
|
-
|
|
324
|
+
const context: SchemaFormContext = {
|
|
318
325
|
fieldKeyPrefix: `$settings.${sectionKey}`,
|
|
319
|
-
resolvePointer: (pointer, scope) =>
|
|
320
|
-
|
|
321
|
-
projectConfig:
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
: {}),
|
|
326
|
+
resolvePointer: (pointer, scope) => {
|
|
327
|
+
const resolveOpts: ResolveContextOptions = {
|
|
328
|
+
projectConfig: projectState?.projectConfig ?? {},
|
|
329
|
+
};
|
|
330
|
+
/* The scope is the form's current value record, which is section JSON; the guard is what
|
|
331
|
+
lets the compiler see that, and it also stands for the old `!== undefined` test. */
|
|
332
|
+
if (isJsonObject(scope)) {
|
|
333
|
+
resolveOpts.scope = scope;
|
|
334
|
+
}
|
|
335
|
+
if (opts.formats !== undefined) {
|
|
336
|
+
resolveOpts.formats = opts.formats;
|
|
337
|
+
}
|
|
338
|
+
return resolveContextPointer(pointer, resolveOpts);
|
|
339
|
+
},
|
|
334
340
|
};
|
|
341
|
+
if (isFunction(platform.setSecrets)) {
|
|
342
|
+
context.commitSecret = async (key: string, value: string) => {
|
|
343
|
+
const envName = deriveSecretEnvName(sectionKey, entryKey, key);
|
|
344
|
+
await platform.setSecrets!({ set: { [envName]: value } });
|
|
345
|
+
return envName;
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
return context;
|
|
335
349
|
}
|
|
336
350
|
|
|
337
351
|
/** The section's value object in the project config, created on demand. */
|
|
338
|
-
function sectionValue(key: string):
|
|
339
|
-
const config = projectState?.projectConfig
|
|
352
|
+
function sectionValue(key: string): JsonObject | null {
|
|
353
|
+
const config = projectState?.projectConfig;
|
|
340
354
|
if (!config) {
|
|
341
355
|
return null;
|
|
342
356
|
}
|
|
343
357
|
const existing = config[key];
|
|
344
|
-
if (
|
|
345
|
-
return existing
|
|
358
|
+
if (isJsonObject(existing)) {
|
|
359
|
+
return existing;
|
|
346
360
|
}
|
|
347
|
-
const fresh:
|
|
361
|
+
const fresh: JsonObject = {};
|
|
348
362
|
config[key] = fresh;
|
|
349
363
|
return fresh;
|
|
350
364
|
}
|
|
@@ -360,7 +374,8 @@ function sectionValue(key: string): Record<string, unknown> | null {
|
|
|
360
374
|
interface SectionMount {
|
|
361
375
|
/** The element the registry handed the renderer, and this record's identity. */
|
|
362
376
|
container: HTMLElement;
|
|
363
|
-
|
|
377
|
+
/** The mounted document, or `null` for the instant between creating this record and mounting. */
|
|
378
|
+
handle: ContributedSurfaceHandle | null;
|
|
364
379
|
contribution: SettingsContribution;
|
|
365
380
|
opts: ContributedSectionOptions;
|
|
366
381
|
/** Where the schema form goes, once the document has made one. */
|
|
@@ -423,8 +438,7 @@ function project(record: SectionMount): ContributedView {
|
|
|
423
438
|
const entries = sectionValue(sectionKey) ?? {};
|
|
424
439
|
const selected = selectedEntries.get(sectionKey) ?? null;
|
|
425
440
|
const value = selected === null ? undefined : entries[selected];
|
|
426
|
-
const editing =
|
|
427
|
-
selected !== null && value !== undefined && value !== null && typeof value === "object";
|
|
441
|
+
const editing = selected !== null && isNonNullObject(value);
|
|
428
442
|
return {
|
|
429
443
|
actionsState,
|
|
430
444
|
editorRegion,
|
|
@@ -499,11 +513,14 @@ function paintForm(record: SectionMount): void {
|
|
|
499
513
|
const entries = sectionValue(sectionKey) ?? {};
|
|
500
514
|
const selected = selectedEntries.get(sectionKey) ?? null;
|
|
501
515
|
const value = selected === null ? undefined : entries[selected];
|
|
502
|
-
if (selected === null || !value
|
|
516
|
+
if (selected === null || !isNonNullObject(value)) {
|
|
503
517
|
host.replaceChildren();
|
|
504
518
|
return;
|
|
505
519
|
}
|
|
506
|
-
|
|
520
|
+
/* SAFETY: a map section's entries are objects by the section schema (`additionalProperties`
|
|
521
|
+
of type object), and the check above admits only objects; an array entry is malformed config
|
|
522
|
+
the form still treats as the record it should be, reading and writing named members. */
|
|
523
|
+
const entry = value as JsonObject;
|
|
507
524
|
const base = `/${sectionKey}/${selected}`;
|
|
508
525
|
place(
|
|
509
526
|
mountSchemaForm(`section:${sectionKey}:${selected}`, contribution.entrySchema, entry, {
|
|
@@ -619,7 +636,7 @@ function actionsFor(record: SectionMount): ContributedActions {
|
|
|
619
636
|
return;
|
|
620
637
|
}
|
|
621
638
|
// Rebuild the map to preserve entry order under the new key
|
|
622
|
-
const next:
|
|
639
|
+
const next: JsonObject = {};
|
|
623
640
|
for (const [k, v] of Object.entries(target)) {
|
|
624
641
|
next[k === selected ? slug : k] = v;
|
|
625
642
|
delete target[k];
|
|
@@ -655,19 +672,20 @@ export function renderContributedSection(
|
|
|
655
672
|
record.contribution = contribution;
|
|
656
673
|
record.opts = opts;
|
|
657
674
|
}
|
|
658
|
-
|
|
659
|
-
|
|
675
|
+
let handle = record?.handle ?? null;
|
|
676
|
+
if (!record || !handle?.attached()) {
|
|
677
|
+
handle?.dispose();
|
|
660
678
|
const fresh: SectionMount = {
|
|
661
679
|
actionsHost: null,
|
|
662
680
|
container,
|
|
663
681
|
contribution,
|
|
664
682
|
echo: null,
|
|
665
683
|
formHost: null,
|
|
666
|
-
handle:
|
|
684
|
+
handle: null,
|
|
667
685
|
opts,
|
|
668
686
|
};
|
|
669
687
|
mounts.set(container, fresh);
|
|
670
|
-
|
|
688
|
+
handle = mountContributedSurface(container, actionsFor(fresh), {
|
|
671
689
|
actionsSlot: (host) => {
|
|
672
690
|
fresh.actionsHost = host;
|
|
673
691
|
paintActions(fresh);
|
|
@@ -677,9 +695,10 @@ export function renderContributedSection(
|
|
|
677
695
|
paintForm(fresh);
|
|
678
696
|
},
|
|
679
697
|
});
|
|
698
|
+
fresh.handle = handle;
|
|
680
699
|
record = fresh;
|
|
681
700
|
}
|
|
682
|
-
|
|
701
|
+
handle.update(project(record));
|
|
683
702
|
paintActions(record);
|
|
684
703
|
paintForm(record);
|
|
685
704
|
}
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
* change" true of the specimen canvas as well as the page one.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
+
import { isNumber, isString } from "@jxsuite/schema/guards";
|
|
29
30
|
import { errorMessage } from "@jxsuite/schema/parse";
|
|
30
31
|
import { notify } from "../services/notify";
|
|
31
32
|
import { projectState } from "../store";
|
|
@@ -110,7 +111,7 @@ function pending(container: HTMLElement, group: TokenGroupId): { name: string; v
|
|
|
110
111
|
|
|
111
112
|
/** The live project configuration, or an empty one before a project is open. */
|
|
112
113
|
function config(): ProjectConfig {
|
|
113
|
-
return
|
|
114
|
+
return projectState?.projectConfig || {};
|
|
114
115
|
}
|
|
115
116
|
|
|
116
117
|
/**
|
|
@@ -121,7 +122,7 @@ function config(): ProjectConfig {
|
|
|
121
122
|
* write, because there is no object here for it to have been written into.
|
|
122
123
|
*/
|
|
123
124
|
function style(): JxStyle {
|
|
124
|
-
return
|
|
125
|
+
return config().style || {};
|
|
125
126
|
}
|
|
126
127
|
|
|
127
128
|
/** Every rendering context this project declares, schemes first. */
|
|
@@ -159,10 +160,18 @@ async function persist(container: HTMLElement): Promise<void> {
|
|
|
159
160
|
// ─── Projection ──────────────────────────────────────────────────────────────
|
|
160
161
|
|
|
161
162
|
/** The colour a well is painted, and the colour the native input under it opens on. */
|
|
162
|
-
|
|
163
|
-
resolved
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
interface SwatchWell {
|
|
164
|
+
/** The resolved value as a CSS background, or `transparent` when the token resolves to nothing. */
|
|
165
|
+
swatchBg: string;
|
|
166
|
+
/**
|
|
167
|
+
* What the native colour input opens on: the background when it is a hex colour, else the
|
|
168
|
+
* fallback.
|
|
169
|
+
*/
|
|
170
|
+
swatchInput: string;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** Paint one well from what the token resolves to. */
|
|
174
|
+
function well(resolved: string | number | undefined, fallback: string): SwatchWell {
|
|
166
175
|
const swatchBg = resolved === undefined ? "transparent" : String(resolved);
|
|
167
176
|
return { swatchBg, swatchInput: swatchBg.startsWith("#") ? swatchBg : fallback };
|
|
168
177
|
}
|
|
@@ -344,13 +353,25 @@ function addOverride(container: HTMLElement, token: string, ctx: string): void {
|
|
|
344
353
|
return;
|
|
345
354
|
}
|
|
346
355
|
const base = rootStyle[token];
|
|
347
|
-
if (
|
|
356
|
+
if (!isString(base) && !isNumber(base)) {
|
|
348
357
|
return;
|
|
349
358
|
}
|
|
350
359
|
writeTokenOverride(rootStyle, context, token, String(base));
|
|
351
360
|
commit(container);
|
|
352
361
|
}
|
|
353
362
|
|
|
363
|
+
/** Switch Settings to the Contexts section, saying so when the section registry will not load. */
|
|
364
|
+
async function openContextsSection(): Promise<void> {
|
|
365
|
+
try {
|
|
366
|
+
const { setSettingsSection } = await import("./section-registry");
|
|
367
|
+
setSettingsSection("contexts");
|
|
368
|
+
} catch (error) {
|
|
369
|
+
notify.error(`Could not open Settings › Contexts — ${errorMessage(error)}`, {
|
|
370
|
+
source: "Settings",
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
354
375
|
/**
|
|
355
376
|
* What the reader may do, bound to one container.
|
|
356
377
|
*
|
|
@@ -378,13 +399,7 @@ function actions(container: HTMLElement): CssVarsActions {
|
|
|
378
399
|
* breaks the css-vars-editor ↔ section-registry cycle.
|
|
379
400
|
*/
|
|
380
401
|
manageContexts: () => {
|
|
381
|
-
void
|
|
382
|
-
.then(({ setSettingsSection }) => setSettingsSection("contexts"))
|
|
383
|
-
.catch((error: unknown) => {
|
|
384
|
-
notify.error(`Could not open Settings › Contexts — ${errorMessage(error)}`, {
|
|
385
|
-
source: "Settings",
|
|
386
|
-
});
|
|
387
|
-
});
|
|
402
|
+
void openContextsSection();
|
|
388
403
|
},
|
|
389
404
|
removeToken: (name: string) => {
|
|
390
405
|
delete style()[name];
|
|
@@ -399,10 +414,16 @@ function actions(container: HTMLElement): CssVarsActions {
|
|
|
399
414
|
* predecessor's `ref()` into the DOM could never do.
|
|
400
415
|
*/
|
|
401
416
|
setAddName: (groupId: string, value: string) => {
|
|
402
|
-
|
|
417
|
+
const group = groupOf(groupId);
|
|
418
|
+
if (group) {
|
|
419
|
+
pending(container, group.id).name = value;
|
|
420
|
+
}
|
|
403
421
|
},
|
|
404
422
|
setAddValue: (groupId: string, value: string) => {
|
|
405
|
-
|
|
423
|
+
const group = groupOf(groupId);
|
|
424
|
+
if (group) {
|
|
425
|
+
pending(container, group.id).value = value;
|
|
426
|
+
}
|
|
406
427
|
},
|
|
407
428
|
setOverride: (token: string, ctx: string, value: string) => {
|
|
408
429
|
const context = contexts().find((c) => c.name === ctx);
|
|
@@ -40,10 +40,12 @@
|
|
|
40
40
|
* @docs studio/projects/settings
|
|
41
41
|
*/
|
|
42
42
|
|
|
43
|
+
import { isBoolean, isJsonObject, isString } from "@jxsuite/schema/guards";
|
|
43
44
|
import { projectState } from "../store";
|
|
44
45
|
import { commitProjectConfig } from "../tabs/project-config";
|
|
45
46
|
import { camelToLabel } from "../utils/studio-utils";
|
|
46
47
|
import {
|
|
48
|
+
BLANK_FIELD,
|
|
47
49
|
FIELD_TYPES,
|
|
48
50
|
FORMAT_OPTIONS,
|
|
49
51
|
detectFieldFormat,
|
|
@@ -52,39 +54,30 @@ import {
|
|
|
52
54
|
} from "./schema-field-ui";
|
|
53
55
|
import { mountDefsSurface } from "../surfaces/settings-defs";
|
|
54
56
|
|
|
55
|
-
import type { SchemaProperty } from "./schema-field-ui";
|
|
57
|
+
import type { NestedFieldDraft, SchemaProperty } from "./schema-field-ui";
|
|
56
58
|
import type {
|
|
57
59
|
DefsActions,
|
|
58
|
-
DefsChoice,
|
|
59
60
|
DefsFieldView,
|
|
60
61
|
DefsSurfaceHandle,
|
|
61
62
|
DefsView,
|
|
62
63
|
NestedFieldView,
|
|
63
64
|
} from "../surfaces/settings-defs";
|
|
64
|
-
import type { ContentTypeSchema
|
|
65
|
+
import type { ContentTypeSchema } from "@jxsuite/schema/types";
|
|
66
|
+
import type { SurfaceOption } from "../ui/surface";
|
|
65
67
|
|
|
66
68
|
// ─── The pickers ──────────────────────────────────────────────────────────────
|
|
67
69
|
|
|
68
70
|
/** The field types, as picker rows. One array, made once: an equal write re-runs no binding. */
|
|
69
|
-
const TYPE_ROWS:
|
|
71
|
+
const TYPE_ROWS: SurfaceOption[] = FIELD_TYPES.map((type) => ({ label: type, value: type }));
|
|
70
72
|
|
|
71
73
|
/** The formats, with the empty one named: a blank row says nothing about what choosing it does. */
|
|
72
|
-
const FORMAT_ROWS:
|
|
74
|
+
const FORMAT_ROWS: SurfaceOption[] = FORMAT_OPTIONS.map((format) => ({
|
|
73
75
|
label: format || "(none)",
|
|
74
76
|
value: format,
|
|
75
77
|
}));
|
|
76
78
|
|
|
77
|
-
/** What a new field starts as. */
|
|
78
|
-
const BLANK_FIELD = { format: "", name: "", required: false, type: "string" };
|
|
79
|
-
|
|
80
79
|
// ─── Per-container state ──────────────────────────────────────────────────────
|
|
81
80
|
|
|
82
|
-
/** One object field's unsubmitted nested field. */
|
|
83
|
-
interface Draft {
|
|
84
|
-
name: string;
|
|
85
|
-
type: string;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
81
|
/**
|
|
89
82
|
* What the reader is part-way through, per rendered container.
|
|
90
83
|
*
|
|
@@ -100,7 +93,7 @@ interface DefsUi {
|
|
|
100
93
|
addOpen: boolean;
|
|
101
94
|
add: { format: string; name: string; required: boolean; type: string };
|
|
102
95
|
/** Each object field's nested add row, by the field's name on disk. */
|
|
103
|
-
drafts: Map<string,
|
|
96
|
+
drafts: Map<string, NestedFieldDraft>;
|
|
104
97
|
/**
|
|
105
98
|
* The ONE control whose value has parted from what is on disk, and what it holds.
|
|
106
99
|
*
|
|
@@ -166,9 +159,19 @@ function hush(container: HTMLElement): void {
|
|
|
166
159
|
uiFor(container).echo = null;
|
|
167
160
|
}
|
|
168
161
|
|
|
169
|
-
/**
|
|
170
|
-
|
|
171
|
-
|
|
162
|
+
/**
|
|
163
|
+
* What a text control shows: what it was last told it holds, or what is on disk.
|
|
164
|
+
*
|
|
165
|
+
* The echo's value is a string whenever its id is a {@link nameId}, because only the rename setters
|
|
166
|
+
* echo under one; the check states that rather than assuming it.
|
|
167
|
+
*/
|
|
168
|
+
function shownText(ui: DefsUi, id: string, disk: string): string {
|
|
169
|
+
return ui.echo?.id === id && isString(ui.echo.value) ? ui.echo.value : disk;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** What a checkbox shows: what it was last told it holds, or what is on disk. */
|
|
173
|
+
function shownFlag(ui: DefsUi, id: string, disk: boolean): boolean {
|
|
174
|
+
return ui.echo?.id === id && isBoolean(ui.echo.value) ? ui.echo.value : disk;
|
|
172
175
|
}
|
|
173
176
|
|
|
174
177
|
// ─── Persistence ──────────────────────────────────────────────────────────────
|
|
@@ -200,6 +203,9 @@ function persist(): void {
|
|
|
200
203
|
* outlive a projection, which makes reading through to the store the thing that keeps them honest.
|
|
201
204
|
*/
|
|
202
205
|
function currentDefs(): Record<string, ContentTypeSchema> | undefined {
|
|
206
|
+
/* SAFETY: project `$defs` holds JSON Schema type definitions (project-schema.json, "Global type
|
|
207
|
+
definitions") and this editor is their writer; ContentTypeSchema is that schema object's view,
|
|
208
|
+
every member optional, and each read below falls back (`?? {}`, `?? []`) when one is absent. */
|
|
203
209
|
return projectState?.projectConfig?.$defs as Record<string, ContentTypeSchema> | undefined;
|
|
204
210
|
}
|
|
205
211
|
|
|
@@ -213,19 +219,16 @@ function selectedDef(ui: DefsUi): ContentTypeSchema | undefined {
|
|
|
213
219
|
* resolves through `#/$context/content`, read here without a schema-form context to go through.
|
|
214
220
|
*/
|
|
215
221
|
function contentTypeNames(): string[] {
|
|
216
|
-
const content =
|
|
217
|
-
|
|
218
|
-
return content && typeof content === "object" && !Array.isArray(content)
|
|
219
|
-
? Object.keys(content)
|
|
220
|
-
: [];
|
|
222
|
+
const content = projectState?.projectConfig?.content;
|
|
223
|
+
return isJsonObject(content) ? Object.keys(content) : [];
|
|
221
224
|
}
|
|
222
225
|
|
|
223
226
|
/** The last target list, so an unchanged one is the same array and re-runs no binding. */
|
|
224
|
-
let targetRows:
|
|
227
|
+
let targetRows: SurfaceOption[] = [];
|
|
225
228
|
let targetNames = " ";
|
|
226
229
|
|
|
227
230
|
/** The reference targets, as picker rows. */
|
|
228
|
-
function targets():
|
|
231
|
+
function targets(): SurfaceOption[] {
|
|
229
232
|
const names = contentTypeNames();
|
|
230
233
|
const id = names.join(" ");
|
|
231
234
|
if (id !== targetNames) {
|
|
@@ -256,9 +259,9 @@ function nestedView(
|
|
|
256
259
|
format: detectFieldFormat(schema),
|
|
257
260
|
hasFormat: takesFormat(type),
|
|
258
261
|
key,
|
|
259
|
-
name:
|
|
262
|
+
name: shownText(ui, nameId(id), key),
|
|
260
263
|
parent,
|
|
261
|
-
required:
|
|
264
|
+
required: shownFlag(ui, requiredId(id), required),
|
|
262
265
|
type,
|
|
263
266
|
};
|
|
264
267
|
}
|
|
@@ -290,9 +293,9 @@ function fieldView(
|
|
|
290
293
|
hasFormat: takesFormat(type),
|
|
291
294
|
key,
|
|
292
295
|
label: camelToLabel(key),
|
|
293
|
-
name:
|
|
296
|
+
name: shownText(ui, nameId(key), key),
|
|
294
297
|
refTarget: schema.$ref ? schema.$ref.replace(/^#\/[^/]+\//, "") : "",
|
|
295
|
-
required:
|
|
298
|
+
required: shownFlag(ui, requiredId(key), required),
|
|
296
299
|
type,
|
|
297
300
|
};
|
|
298
301
|
}
|
|
@@ -312,15 +315,15 @@ function project(container: HTMLElement): DefsView {
|
|
|
312
315
|
addRequired: ui.add.required,
|
|
313
316
|
addState: ui.addOpen && def ? "open" : "closed",
|
|
314
317
|
addType: ui.add.type,
|
|
318
|
+
defs: Object.keys(defs).map((name) => ({ name, selected: name === ui.selected })),
|
|
315
319
|
editorState: def ? "editing" : "empty",
|
|
316
320
|
fields: Object.entries(properties).map(([key, schema]) =>
|
|
317
|
-
fieldView(ui, key, schema
|
|
321
|
+
fieldView(ui, key, schema, required.includes(key), rows.length > 0),
|
|
318
322
|
),
|
|
319
323
|
formatOptions: FORMAT_ROWS,
|
|
320
324
|
newName: ui.newName,
|
|
321
325
|
newState: ui.newOpen ? "open" : "closed",
|
|
322
326
|
selected: def && ui.selected !== null ? ui.selected : "",
|
|
323
|
-
shapes: Object.keys(defs).map((name) => ({ name, selected: name === ui.selected })),
|
|
324
327
|
targets: rows,
|
|
325
328
|
typeOptions: TYPE_ROWS,
|
|
326
329
|
};
|
|
@@ -338,10 +341,10 @@ function actionsFor(container: HTMLElement): DefsActions {
|
|
|
338
341
|
|
|
339
342
|
/** The parent object a nested edit is about, or `undefined` when it has gone underneath. */
|
|
340
343
|
const parentOf = (parent: string): SchemaProperty | undefined =>
|
|
341
|
-
selectedDef(ui)?.properties?.[parent]
|
|
344
|
+
selectedDef(ui)?.properties?.[parent];
|
|
342
345
|
|
|
343
346
|
/** One object field's add-row draft, made on first use. */
|
|
344
|
-
const draftOf = (parent: string):
|
|
347
|
+
const draftOf = (parent: string): NestedFieldDraft => {
|
|
345
348
|
let draft = ui.drafts.get(parent);
|
|
346
349
|
if (!draft) {
|
|
347
350
|
draft = { name: "", type: "string" };
|
|
@@ -513,7 +516,7 @@ function actionsFor(container: HTMLElement): DefsActions {
|
|
|
513
516
|
}
|
|
514
517
|
done();
|
|
515
518
|
},
|
|
516
|
-
|
|
519
|
+
removeSelected() {
|
|
517
520
|
const defs = currentDefs();
|
|
518
521
|
if (ui.selected === null || !defs?.[ui.selected]) {
|
|
519
522
|
return;
|
|
@@ -613,7 +616,7 @@ function actionsFor(container: HTMLElement): DefsActions {
|
|
|
613
616
|
}
|
|
614
617
|
/* The pointer form is `#/content/<type>` — the same one `ui/form-controls.ts` writes, so a
|
|
615
618
|
reference authored here and one authored in the content-types builder are the same value. */
|
|
616
|
-
def.properties[key] = { $ref: `#/content/${value}` }
|
|
619
|
+
def.properties[key] = { $ref: `#/content/${value}` };
|
|
617
620
|
done();
|
|
618
621
|
},
|
|
619
622
|
setType(key, value) {
|
|
@@ -42,7 +42,7 @@ export interface ExtensionRow {
|
|
|
42
42
|
|
|
43
43
|
/** The live project configuration, or an empty one before a project is open. */
|
|
44
44
|
export function projectConfig(): ProjectConfig {
|
|
45
|
-
return
|
|
45
|
+
return projectState?.projectConfig ?? {};
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/** The specifiers `project.json` currently enables. */
|
|
@@ -71,7 +71,7 @@ export function buildRows(packages: PackageInfo[] | null = null): ExtensionRow[]
|
|
|
71
71
|
const here = entry.installed ?? installed.has(entry.name);
|
|
72
72
|
const bundled = entry.bundled ?? false;
|
|
73
73
|
const info = resolved.get(entry.name);
|
|
74
|
-
|
|
74
|
+
const row: ExtensionRow = {
|
|
75
75
|
broken: enabled.has(specifier) && !here && !bundled,
|
|
76
76
|
bundled,
|
|
77
77
|
enabled: enabled.has(specifier),
|
|
@@ -83,9 +83,14 @@ export function buildRows(packages: PackageInfo[] | null = null): ExtensionRow[]
|
|
|
83
83
|
: entry.sections.map((s) => s.key),
|
|
84
84
|
specifier,
|
|
85
85
|
title: entry.title ?? entry.name,
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
};
|
|
87
|
+
if (entry.description !== undefined) {
|
|
88
|
+
row.description = entry.description;
|
|
89
|
+
}
|
|
90
|
+
if (entry.problem !== undefined) {
|
|
91
|
+
row.unavailable = entry.problem;
|
|
92
|
+
}
|
|
93
|
+
rows.push(row);
|
|
89
94
|
}
|
|
90
95
|
|
|
91
96
|
// Anything project.json names that the backend did not describe. It can still be turned OFF,
|
|
@@ -95,7 +100,7 @@ export function buildRows(packages: PackageInfo[] | null = null): ExtensionRow[]
|
|
|
95
100
|
continue;
|
|
96
101
|
}
|
|
97
102
|
const info = resolved.get(specifier);
|
|
98
|
-
|
|
103
|
+
const row: ExtensionRow = {
|
|
99
104
|
broken: !installed.has(specifier) && info === undefined,
|
|
100
105
|
bundled: false,
|
|
101
106
|
enabled: true,
|
|
@@ -105,8 +110,11 @@ export function buildRows(packages: PackageInfo[] | null = null): ExtensionRow[]
|
|
|
105
110
|
sections: info ? info.contributions.map((c) => c.project.key) : [],
|
|
106
111
|
specifier,
|
|
107
112
|
title: info?.title ?? specifier,
|
|
108
|
-
|
|
109
|
-
|
|
113
|
+
};
|
|
114
|
+
if (info?.description !== undefined) {
|
|
115
|
+
row.description = info.description;
|
|
116
|
+
}
|
|
117
|
+
rows.push(row);
|
|
110
118
|
}
|
|
111
119
|
|
|
112
120
|
return rows;
|