@marimo-team/frontend 0.16.1 → 0.16.3
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/assets/{ConnectedDataExplorerComponent-2wVcyvDj.js → ConnectedDataExplorerComponent-Brtw1DxF.js} +1 -1
- package/dist/assets/{ImageComparisonComponent-D2j6i0hv.js → ImageComparisonComponent-Dxl-PbZX.js} +1 -1
- package/dist/assets/{VegaLite-BckFaf2D.js → VegaLite-BXQF0Cx_.js} +1 -1
- package/dist/assets/_baseEach-BjSm9ht3.js +1 -0
- package/dist/assets/_baseMap-CV4Ezmtf.js +1 -0
- package/dist/assets/_baseUniq-Ci9yZGxz.js +1 -0
- package/dist/assets/{_createAggregator-C5CVY-0t.js → _createAggregator-VFK9K2d9.js} +1 -1
- package/dist/assets/{agent-panel-RGLNjkYe.js → agent-panel-BoscVLCT.js} +7 -7
- package/dist/assets/{any-language-editor-DjuXwGCA.js → any-language-editor-ChaY_VUU.js} +1 -1
- package/dist/assets/{architectureDiagram-W76B3OCA-Dyj4ds_R.js → architectureDiagram-W76B3OCA-CueUUFYd.js} +1 -1
- package/dist/assets/{between-horizontal-start-Dt2aKpPf.js → between-horizontal-start-DAHqmLYT.js} +1 -1
- package/dist/assets/{blockDiagram-QIGZ2CNN-o-i7DDvN.js → blockDiagram-QIGZ2CNN-BYYygyWn.js} +1 -1
- package/dist/assets/{c4Diagram-FPNF74CW-DGHEwWrx.js → c4Diagram-FPNF74CW-DAz3xEh1.js} +1 -1
- package/dist/assets/channel-6SqQ2U_X.js +1 -0
- package/dist/assets/chat-panel-DJkOLrw9.js +3 -0
- package/dist/assets/{chunk-4BX2VUAB-BJecb-Ri.js → chunk-4BX2VUAB-8g-RyHdt.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-CAATkc4w.js → chunk-55IACEB6-iWZZ8Mt6.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-DPuNbQ-f.js → chunk-FMBD7UC4-knjss4wk.js} +1 -1
- package/dist/assets/{chunk-K7UQS3LO-C8TWVLiH.js → chunk-K7UQS3LO-DVIwPBgZ.js} +1 -1
- package/dist/assets/{chunk-QN33PNHL-DiZZ09q4.js → chunk-QN33PNHL-CBU8pN6I.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-BIUM7usu.js → chunk-QZHKN3VN-5ljElUF4.js} +1 -1
- package/dist/assets/{chunk-TVAH2DTR-vGTArPBG.js → chunk-TVAH2DTR-DkIdGINc.js} +1 -1
- package/dist/assets/{chunk-TZMSLE5B-D2KRqp_x.js → chunk-TZMSLE5B-CIFOSTqh.js} +1 -1
- package/dist/assets/{circle-play-cjeNez0N.js → circle-play-BOdsbq5u.js} +1 -1
- package/dist/assets/classDiagram-KNZD7YFC-DVqXcTYf.js +1 -0
- package/dist/assets/classDiagram-v2-RKCZMP56-DVqXcTYf.js +1 -0
- package/dist/assets/{clear-button-C97JtAez.js → clear-button-GAjXl0CQ.js} +1 -1
- package/dist/assets/clone-DSDb0xen.js +1 -0
- package/dist/assets/command-palette-BUXkqoLh.js +1 -0
- package/dist/assets/{common-Du9rSOwD.js → common-DahoYqdi.js} +1 -1
- package/dist/assets/{compile-CZXqyOxa.js → compile-Bg8uJ7vm.js} +1 -1
- package/dist/assets/{cose-bilkent-S5V4N54A-CqUN5Y9b.js → cose-bilkent-S5V4N54A-z_0gqD9K.js} +1 -1
- package/dist/assets/{dagre-5GWH7T2D-RJqTI9DM.js → dagre-5GWH7T2D-BMt7CNXL.js} +1 -1
- package/dist/assets/{data-grid-overlay-editor-DZN0q1LV.js → data-grid-overlay-editor-Ctn4XtXx.js} +1 -1
- package/dist/assets/datasources-panel-C7sqRIHs.js +1 -0
- package/dist/assets/{dependency-graph-panel-CEog_O7V.js → dependency-graph-panel-DNajptzv.js} +4 -4
- package/dist/assets/{diagram-N5W7TBWH-D-l4zZ9d.js → diagram-N5W7TBWH-BzwvLvAy.js} +1 -1
- package/dist/assets/{diagram-QEK2KX5R-CCOmBUt-.js → diagram-QEK2KX5R-DRLJ56FS.js} +1 -1
- package/dist/assets/{diagram-S2PKOQOG-C_I_9jnZ.js → diagram-S2PKOQOG-Bf8x4KTU.js} +1 -1
- package/dist/assets/{documentation-panel-C1BtMZ3M.js → documentation-panel-Dm6Ozl67.js} +1 -1
- package/dist/assets/{edit-page-B-oevUZ9.js → edit-page-CGc9EjuG.js} +53 -42
- package/dist/assets/{ellipsis-vertical-BEb-J8z6.js → ellipsis-vertical-Bj1YXvZe.js} +1 -1
- package/dist/assets/{empty-state-C99UyDE3.js → empty-state-CYev-D31.js} +1 -1
- package/dist/assets/{erDiagram-AWTI2OKA-BePOLi5M.js → erDiagram-AWTI2OKA-DmgzgN_I.js} +1 -1
- package/dist/assets/{error-panel-Bs34jXFh.js → error-panel-BYG4twCa.js} +1 -1
- package/dist/assets/{file-explorer-panel-Ck6UL861.js → file-explorer-panel-BSMiOApi.js} +1 -1
- package/dist/assets/{flowDiagram-PVAE7QVJ-BgjFu5l7.js → flowDiagram-PVAE7QVJ-BdRKkajr.js} +1 -1
- package/dist/assets/{ganttDiagram-OWAHRB6G-YOPb3XSV.js → ganttDiagram-OWAHRB6G-lfRAMnq_.js} +5 -5
- package/dist/assets/{gitGraphDiagram-NY62KEGX-CGhqaDTy.js → gitGraphDiagram-NY62KEGX-CQVTIrHF.js} +1 -1
- package/dist/assets/{glide-data-editor-9QUH6iso.js → glide-data-editor-D5A4pou7.js} +4 -4
- package/dist/assets/{graph-DQQFGrho.js → graph-CBNo279v.js} +1 -1
- package/dist/assets/{home-page-DRKpPCrF.js → home-page-CmdznBJR.js} +2 -2
- package/dist/assets/{index-SGLNXrGP.js → index-0dfGh-Gj.js} +1 -1
- package/dist/assets/{index-aE43R74q.js → index-BDYVSSzB.js} +1 -1
- package/dist/assets/{index-BJNCMUmG.js → index-B_KyDZ94.js} +1 -1
- package/dist/assets/{index-BjgnbONl.js → index-Bfy-I_lW.js} +1 -1
- package/dist/assets/{index-CUFv_thQ.js → index-Bh98Tp-z.js} +1 -1
- package/dist/assets/{index-C2MD0vgD.js → index-BhroIwBL.js} +1 -1
- package/dist/assets/{index-DdnKZNxM.js → index-BtQtesaI.js} +1 -1
- package/dist/assets/index-C0iXCvyY.css +1 -0
- package/dist/assets/index-C1SHFMCp.js +581 -0
- package/dist/assets/{index-C_tkBKNO.js → index-C6DWtSls.js} +1 -1
- package/dist/assets/{index-Aeo6WiK7.js → index-C71cdkH-.js} +1 -1
- package/dist/assets/{index-G5QZppK2.js → index-CT_FTqvK.js} +1 -1
- package/dist/assets/{index-B8jXZ12t.js → index-CU5rRr66.js} +1 -1
- package/dist/assets/{index-BAbIIxHU.js → index-Cb6duXQm.js} +1 -1
- package/dist/assets/{index-BW3k9Gss.js → index-D23e9zQj.js} +1 -1
- package/dist/assets/index-DUGecC2Z.js +68 -0
- package/dist/assets/{index-CFKO7WXI.js → index-DcGIOAQi.js} +1 -1
- package/dist/assets/{index-ClzeQrN7.js → index-PJfa9qXY.js} +1 -1
- package/dist/assets/{index-C1ez98sk.js → index-SPslPC2B.js} +1 -1
- package/dist/assets/{index-BprjMYH5.js → index-VPQlo4Uz.js} +1 -1
- package/dist/assets/{index-CfaDbEdi.js → index-qbTLKWyG.js} +1 -1
- package/dist/assets/infoDiagram-STP46IZ2-DBu8p9gd.js +2 -0
- package/dist/assets/{isEmpty-D-4c7sMv.js → isEmpty-CnOLuQIv.js} +1 -1
- package/dist/assets/{journeyDiagram-BIP6EPQ6-C94u3Mv3.js → journeyDiagram-BIP6EPQ6-6U_vHJBH.js} +1 -1
- package/dist/assets/{kanban-definition-6OIFK2YF-BEXYFzz7.js → kanban-definition-6OIFK2YF-DgnR14ys.js} +1 -1
- package/dist/assets/{layout-Bz2BJ2ru.js → layout-RHmq4fP9.js} +1 -1
- package/dist/assets/{linear-D8s7K76e.js → linear-CLdOVPGV.js} +1 -1
- package/dist/assets/links-Dd1icsEk.js +7 -0
- package/dist/assets/{logs-panel-DC7wpmPz.js → logs-panel-CjbuhBLx.js} +1 -1
- package/dist/assets/{markdown-renderer-DRdSWR9X.js → markdown-renderer-X5YJvAZq.js} +3 -3
- package/dist/assets/{mermaid-Y3x4hmD0.js → mermaid-Bl2T5oEC.js} +1 -1
- package/dist/assets/{mermaid.core-DzthE35Y.js → mermaid.core-CfukBvGI.js} +4 -4
- package/dist/assets/min-BXIes1Za.js +1 -0
- package/dist/assets/{mindmap-definition-Q6HEUPPD-DktvuLe1.js → mindmap-definition-Q6HEUPPD-BXCjP4Lu.js} +1 -1
- package/dist/assets/{number-overlay-editor-BEfwI1IT.js → number-overlay-editor-BUyqkSes.js} +1 -1
- package/dist/assets/{outline-panel-CdsnAy2w.js → outline-panel-BvGcPKdd.js} +1 -1
- package/dist/assets/{packages-panel-DiTA-d_D.js → packages-panel-BichDQWG.js} +1 -1
- package/dist/assets/{pieDiagram-ADFJNKIX-DQDNQ-de.js → pieDiagram-ADFJNKIX-CMzJFIJM.js} +1 -1
- package/dist/assets/{quadrantDiagram-LMRXKWRM-0kgIXc2-.js → quadrantDiagram-LMRXKWRM-CfGssUlO.js} +1 -1
- package/dist/assets/{react-plotly-DJqqfM7c.js → react-plotly-DR3hV0HW.js} +1 -1
- package/dist/assets/{requirementDiagram-4UW4RH46-B5rb0ypd.js → requirementDiagram-4UW4RH46-CfrFolth.js} +1 -1
- package/dist/assets/{run-page-CFmLrv1R.js → run-page-Bqd_4ePD.js} +1 -1
- package/dist/assets/{sankeyDiagram-GR3RE2ED-Dom7IlnF.js → sankeyDiagram-GR3RE2ED-D_UttKU0.js} +1 -1
- package/dist/assets/{scratchpad-panel-CuHWpHO8.js → scratchpad-panel-D5N15ji1.js} +1 -1
- package/dist/assets/secrets-panel-BpbnAO4R.js +1 -0
- package/dist/assets/{sequenceDiagram-C3RYC4MD-PNJWXQbw.js → sequenceDiagram-C3RYC4MD-MdfQQApP.js} +1 -1
- package/dist/assets/{slides-component-CJgaTRZ0.js → slides-component-C0z7rXmk.js} +1 -1
- package/dist/assets/{snippets-panel-B2EC1txM.js → snippets-panel-wlpZ_Wzx.js} +1 -1
- package/dist/assets/sortBy-BW_zNHP6.js +1 -0
- package/dist/assets/{state-CWict9RU.js → state-CDooX-dk.js} +1 -1
- package/dist/assets/{stateDiagram-KXAO66HF-BE58aJnr.js → stateDiagram-KXAO66HF-H7kfw3ot.js} +1 -1
- package/dist/assets/stateDiagram-v2-UMBNRL4Z-YMeb9qMR.js +1 -0
- package/dist/assets/{storage-DRaR04wR.js → storage-b1QCapTq.js} +6 -6
- package/dist/assets/{terminal-BX3Su5q7.js → terminal-CPV44BXz.js} +1 -1
- package/dist/assets/{time-hUzZfpNE.js → time-DDy3xv5Y.js} +1 -1
- package/dist/assets/{timeline-definition-XQNQX7LJ-CqQP9t51.js → timeline-definition-XQNQX7LJ-J-cPRT2_.js} +1 -1
- package/dist/assets/{tracing-B10Q1n-L.js → tracing-3eHHRUiJ.js} +2 -2
- package/dist/assets/{tracing-panel-Du8WCnno.js → tracing-panel-BMgy3D7d.js} +2 -2
- package/dist/assets/{trash-B81GTiv6.js → trash--tonOuDe.js} +1 -1
- package/dist/assets/{tree-6vW2ogkh.js → tree-ouIGEsVg.js} +1 -1
- package/dist/assets/{treemap-75Q7IDZK-CdwDwwsz.js → treemap-75Q7IDZK-CzJTJ_3R.js} +20 -20
- package/dist/assets/{variable-panel-D5qgJI7k.js → variable-panel-sFTn4Oih.js} +1 -1
- package/dist/assets/{vega-component-DJaJWMJM.js → vega-component-BkPkzX9r.js} +1 -1
- package/dist/assets/{xychartDiagram-6GGTOJPD-WFtXqaM9.js → xychartDiagram-6GGTOJPD-BZ8WOb_8.js} +1 -1
- package/dist/index.html +10 -3
- package/package.json +8 -8
- package/src/__mocks__/common.ts +5 -3
- package/src/__mocks__/notebook.ts +2 -2
- package/src/__mocks__/requests.ts +1 -0
- package/src/__tests__/main.test.tsx +2 -2
- package/src/components/ai/ai-provider-icon.tsx +2 -0
- package/src/components/app-config/ai-config.tsx +32 -1
- package/src/components/app-config/common.tsx +2 -2
- package/src/components/app-config/user-config-form.tsx +26 -0
- package/src/components/audio/audio-recorder.tsx +0 -1
- package/src/components/chat/acp/blocks.tsx +2 -2
- package/src/components/chat/acp/thread.tsx +3 -5
- package/src/components/chat/acp/utils.ts +5 -5
- package/src/components/chat/chat-panel.tsx +1 -1
- package/src/components/data-table/__tests__/columns.test.tsx +38 -0
- package/src/components/data-table/__tests__/data-table.test.tsx +2 -2
- package/src/components/data-table/cell-hover-template/feature.ts +1 -1
- package/src/components/data-table/cell-hover-template/types.ts +1 -1
- package/src/components/data-table/charts/__tests__/altair-generator.test.ts +1 -1
- package/src/components/data-table/charts/chart-spec/tooltips.ts +3 -3
- package/src/components/data-table/charts/components/chart-items.tsx +1 -1
- package/src/components/data-table/charts/components/form-fields.tsx +2 -2
- package/src/components/data-table/charts/constants.ts +1 -1
- package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
- package/src/components/data-table/column-summary/chart-spec-model.tsx +2 -2
- package/src/components/data-table/columns.tsx +22 -3
- package/src/components/data-table/data-table.tsx +35 -3
- package/src/components/data-table/date-popover.tsx +1 -1
- package/src/components/data-table/download-actions.tsx +1 -1
- package/src/components/data-table/range-focus/__tests__/utils.test.ts +5 -5
- package/src/components/data-table/renderers.tsx +22 -13
- package/src/components/data-table/row-viewer-panel/row-viewer.tsx +1 -1
- package/src/components/data-table/schemas.ts +16 -0
- package/src/components/data-table/types.ts +4 -3
- package/src/components/datasources/column-preview.tsx +9 -6
- package/src/components/debugger/debugger-code.tsx +1 -1
- package/src/components/dependency-graph/custom-node.tsx +15 -6
- package/src/components/dependency-graph/dependency-graph-minimap.tsx +2 -2
- package/src/components/dependency-graph/dependency-graph-tree.tsx +2 -2
- package/src/components/dependency-graph/dependency-graph.tsx +1 -1
- package/src/components/dependency-graph/elements.ts +7 -7
- package/src/components/dependency-graph/utils/changes.ts +4 -4
- package/src/components/editor/Cell.tsx +7 -1
- package/src/components/editor/ai/transport/chat-transport.tsx +1 -1
- package/src/components/editor/chrome/panels/outline/useActiveOutline.tsx +1 -1
- package/src/components/editor/chrome/panels/packages-panel.tsx +1 -1
- package/src/components/editor/columns/storage.ts +1 -1
- package/src/components/editor/database/__tests__/__snapshots__/as-code.test.ts.snap +36 -0
- package/src/components/editor/database/__tests__/as-code.test.ts +30 -7
- package/src/components/editor/database/add-database-form.tsx +11 -0
- package/src/components/editor/database/as-code.ts +104 -5
- package/src/components/editor/database/schemas.ts +36 -18
- package/src/components/editor/errors/auto-fix.tsx +12 -2
- package/src/components/editor/errors/sql-validation-errors.tsx +40 -0
- package/src/components/editor/navigation/clipboard.ts +2 -2
- package/src/components/editor/output/ConsoleOutput.tsx +14 -2
- package/src/components/editor/output/JsonOutput.tsx +1 -1
- package/src/components/editor/output/MarimoErrorOutput.tsx +60 -1
- package/src/components/editor/output/MarimoTracebackOutput.tsx +17 -2
- package/src/components/editor/renderers/grid-layout/types.ts +2 -2
- package/src/components/editor/renderers/plugins.ts +1 -1
- package/src/components/editor/renderers/types.ts +1 -1
- package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +7 -7
- package/src/components/forms/form.tsx +5 -5
- package/src/components/ui/links.tsx +1 -0
- package/src/core/ai/__tests__/model-registry.test.ts +0 -10
- package/src/core/ai/context/providers/cell-output.ts +1 -18
- package/src/core/ai/context/providers/error.ts +2 -2
- package/src/core/ai/ids/ids.ts +1 -0
- package/src/core/ai/model-registry.ts +2 -1
- package/src/core/cells/cells.ts +5 -5
- package/src/core/cells/logs.ts +1 -1
- package/src/core/cells/types.ts +1 -1
- package/src/core/codemirror/__tests__/format.test.ts +6 -0
- package/src/core/codemirror/cells/traceback-decorations.ts +1 -1
- package/src/core/codemirror/editing/commands.ts +2 -2
- package/src/core/codemirror/find-replace/navigate.ts +1 -1
- package/src/core/codemirror/language/__tests__/extension.test.ts +24 -0
- package/src/core/codemirror/language/__tests__/sql-validation.test.ts +133 -0
- package/src/core/codemirror/language/__tests__/sql.test.ts +764 -79
- package/src/core/codemirror/language/languages/markdown.ts +4 -1
- package/src/core/codemirror/language/languages/sql/banner-validation-errors.ts +85 -0
- package/src/core/codemirror/language/languages/sql/completion-builder.ts +160 -0
- package/src/core/codemirror/language/languages/sql/completion-sources.tsx +9 -3
- package/src/core/codemirror/language/languages/sql/completion-store.ts +46 -50
- package/src/core/codemirror/language/languages/sql/renderers.tsx +485 -0
- package/src/core/codemirror/language/languages/sql/sql-mode.ts +20 -0
- package/src/core/codemirror/language/languages/sql/sql.ts +218 -4
- package/src/core/codemirror/language/languages/sql/utils.ts +4 -1
- package/src/core/codemirror/language/panel/panel.tsx +8 -2
- package/src/core/codemirror/language/panel/sql.tsx +86 -4
- package/src/core/codemirror/language/utils/ast.ts +3 -3
- package/src/core/codemirror/lsp/federated-lsp.ts +4 -4
- package/src/core/codemirror/lsp/lens.ts +4 -4
- package/src/core/codemirror/lsp/notebook-lsp.ts +1 -1
- package/src/core/codemirror/lsp/types.ts +1 -1
- package/src/core/codemirror/markdown/completions.ts +1 -1
- package/src/core/codemirror/reactive-references/analyzer.ts +2 -2
- package/src/core/codemirror/rtc/loro/awareness.ts +1 -1
- package/src/core/config/config-schema.ts +1 -0
- package/src/core/config/feature-flag.tsx +6 -2
- package/src/core/datasets/request-registry.ts +24 -1
- package/src/core/dom/events.ts +1 -1
- package/src/core/dom/outline.ts +2 -2
- package/src/core/dom/uiregistry.ts +2 -8
- package/src/core/errors/__tests__/errors.test.ts +22 -4
- package/src/core/errors/errors.ts +29 -1
- package/src/core/errors/state.ts +1 -1
- package/src/core/islands/bridge.ts +1 -0
- package/src/core/islands/main.ts +3 -2
- package/src/core/islands/parse.ts +1 -3
- package/src/core/kernel/messages.ts +2 -1
- package/src/core/network/CachingRequestRegistry.ts +74 -0
- package/src/core/network/DeferredRequestRegistry.ts +3 -1
- package/src/core/network/__tests__/CachingRequestRegistry.test.ts +73 -0
- package/src/core/network/requests-network.ts +7 -0
- package/src/core/network/requests-static.ts +1 -0
- package/src/core/network/requests-toasting.ts +1 -0
- package/src/core/network/types.ts +3 -1
- package/src/core/variables/state.ts +2 -2
- package/src/core/wasm/__tests__/state.test.ts +1 -1
- package/src/core/wasm/bridge.ts +5 -0
- package/src/core/websocket/useMarimoWebSocket.tsx +9 -2
- package/src/custom.d.ts +1 -1
- package/src/hooks/useCellRenderCount.ts +1 -0
- package/src/hooks/useResizeHandle.ts +4 -1
- package/src/plugins/core/RenderHTML.tsx +1 -2
- package/src/plugins/core/registerReactComponent.tsx +23 -19
- package/src/plugins/impl/DataTablePlugin.tsx +18 -6
- package/src/plugins/impl/FileUploadPlugin.tsx +1 -1
- package/src/plugins/impl/RefreshPlugin.tsx +1 -1
- package/src/plugins/impl/SliderPlugin.tsx +4 -0
- package/src/plugins/impl/anywidget/AnyWidgetPlugin.tsx +27 -9
- package/src/plugins/impl/anywidget/__tests__/AnyWidgetPlugin.test.tsx +58 -2
- package/src/plugins/impl/anywidget/__tests__/model.test.ts +3 -4
- package/src/plugins/impl/anywidget/model.ts +2 -3
- package/src/plugins/impl/data-editor/types.ts +1 -1
- package/src/plugins/impl/data-explorer/components/query-form.tsx +1 -1
- package/src/plugins/impl/data-frames/DataFramePlugin.tsx +17 -5
- package/src/plugins/impl/data-frames/types.ts +1 -1
- package/src/plugins/impl/panel/PanelPlugin.tsx +2 -2
- package/src/plugins/impl/plotly/PlotlyPlugin.tsx +3 -3
- package/src/plugins/impl/vega/__tests__/loader.test.ts +2 -2
- package/src/plugins/impl/vega/loader.ts +1 -1
- package/src/plugins/impl/vega/vega-component.tsx +1 -1
- package/src/plugins/impl/vega/vega-loader.ts +2 -2
- package/src/plugins/layout/NavigationMenuPlugin.tsx +1 -1
- package/src/plugins/layout/RoutesPlugin.tsx +1 -2
- package/src/plugins/plugins.ts +2 -2
- package/src/stories/dataframe.stories.tsx +2 -0
- package/src/utils/Logger.ts +1 -1
- package/src/utils/__tests__/data-views.test.ts +30 -68
- package/src/utils/__tests__/dom.test.ts +167 -0
- package/src/utils/__tests__/id-tree.test.ts +49 -1
- package/src/utils/__tests__/storage.test.ts +1 -1
- package/src/utils/__tests__/traceback.test.ts +13 -2
- package/src/utils/arrays.ts +1 -1
- package/src/utils/createReducer.ts +1 -5
- package/src/utils/data-views.ts +6 -19
- package/src/utils/dom.ts +55 -0
- package/src/utils/edit-distance.ts +1 -1
- package/src/utils/fileToBase64.ts +1 -1
- package/src/utils/id-tree.tsx +20 -18
- package/src/utils/json/base64.ts +13 -0
- package/src/utils/json/json-parser.ts +2 -2
- package/src/utils/lru.ts +4 -0
- package/src/utils/mergeRefs.ts +1 -1
- package/src/utils/objects.ts +3 -3
- package/src/utils/pluralize.ts +1 -1
- package/src/utils/routes.ts +2 -2
- package/src/utils/sets.ts +1 -1
- package/src/utils/traceback.ts +45 -15
- package/src/utils/tracer.ts +11 -9
- package/dist/assets/_baseEach-CvTX9w0Y.js +0 -1
- package/dist/assets/_baseMap-CtlwA90f.js +0 -1
- package/dist/assets/_baseUniq-BKktIGQ1.js +0 -1
- package/dist/assets/channel-Co6iMgWq.js +0 -1
- package/dist/assets/chat-panel-9alr8FS4.js +0 -3
- package/dist/assets/classDiagram-KNZD7YFC-BbJ0rY3y.js +0 -1
- package/dist/assets/classDiagram-v2-RKCZMP56-BbJ0rY3y.js +0 -1
- package/dist/assets/clone-BMP0PsTa.js +0 -1
- package/dist/assets/command-palette-B93Pjcky.js +0 -1
- package/dist/assets/datasources-panel-v7H3cR0p.js +0 -1
- package/dist/assets/index-2252nrk6.js +0 -68
- package/dist/assets/index-C7CoaNFb.js +0 -578
- package/dist/assets/index-DadI618h.css +0 -1
- package/dist/assets/infoDiagram-STP46IZ2-CJLOpSAf.js +0 -2
- package/dist/assets/links-BpXlz1GG.js +0 -7
- package/dist/assets/min-BBO3-1Hg.js +0 -1
- package/dist/assets/secrets-panel-CfHc5YD0.js +0 -1
- package/dist/assets/sortBy-DZnlX29-.js +0 -1
- package/dist/assets/stateDiagram-v2-UMBNRL4Z-CdThjimL.js +0 -1
- package/src/__tests__/lru.test.ts +0 -74
|
@@ -29,7 +29,7 @@ interface GetTooltipParams {
|
|
|
29
29
|
|
|
30
30
|
export function getTooltips(
|
|
31
31
|
params: GetTooltipParams,
|
|
32
|
-
):
|
|
32
|
+
): StringFieldDef<string>[] | undefined {
|
|
33
33
|
const { formValues, xEncoding, yEncoding, colorByEncoding } = params;
|
|
34
34
|
|
|
35
35
|
if (!formValues.tooltips) {
|
|
@@ -73,7 +73,7 @@ export function getTooltips(
|
|
|
73
73
|
|
|
74
74
|
// If autoTooltips is enabled, we manually add the x, y, and color columns to the tooltips
|
|
75
75
|
if (formValues.tooltips.auto) {
|
|
76
|
-
const tooltips:
|
|
76
|
+
const tooltips: StringFieldDef<string>[] = [];
|
|
77
77
|
const xTooltip = addTooltip(
|
|
78
78
|
xEncoding,
|
|
79
79
|
formValues.general?.xColumn?.type || "string",
|
|
@@ -105,7 +105,7 @@ export function getTooltips(
|
|
|
105
105
|
|
|
106
106
|
// Selected tooltips from the form.
|
|
107
107
|
const selectedTooltips = formValues.tooltips.fields ?? [];
|
|
108
|
-
const tooltips:
|
|
108
|
+
const tooltips: StringFieldDef<string>[] = [];
|
|
109
109
|
|
|
110
110
|
// We need to find the matching columns for the selected tooltips if they exist
|
|
111
111
|
// Otherwise, we can add them without other parameters
|
|
@@ -103,7 +103,7 @@ const ColumnSelectorWithAggregation: React.FC<{
|
|
|
103
103
|
selectedDataType?: SelectedDataType;
|
|
104
104
|
};
|
|
105
105
|
defaultAggregation?: AggregationFn;
|
|
106
|
-
columns:
|
|
106
|
+
columns: { name: string; type: DataType }[];
|
|
107
107
|
binFieldName: FieldName;
|
|
108
108
|
}> = ({
|
|
109
109
|
columnFieldName,
|
|
@@ -86,7 +86,7 @@ export const ColumnSelector = ({
|
|
|
86
86
|
includeCountField = true,
|
|
87
87
|
}: {
|
|
88
88
|
fieldName: FieldName;
|
|
89
|
-
columns:
|
|
89
|
+
columns: { name: string; type: DataType }[];
|
|
90
90
|
onValueChange?: (fieldName: string, type: DataType | undefined) => void;
|
|
91
91
|
includeCountField?: boolean;
|
|
92
92
|
}) => {
|
|
@@ -197,7 +197,7 @@ export const SelectField = ({
|
|
|
197
197
|
}: {
|
|
198
198
|
fieldName: FieldName;
|
|
199
199
|
label: string;
|
|
200
|
-
options:
|
|
200
|
+
options: { display: React.ReactNode; value: string }[];
|
|
201
201
|
defaultValue: string;
|
|
202
202
|
}) => {
|
|
203
203
|
const form = useFormContext();
|
|
@@ -79,7 +79,7 @@ export const AGGREGATION_TYPE_DESCRIPTIONS: Record<AggregationFn, string> = {
|
|
|
79
79
|
bin: "Group values into bins",
|
|
80
80
|
};
|
|
81
81
|
|
|
82
|
-
export const COLOR_SCHEMES:
|
|
82
|
+
export const COLOR_SCHEMES: (ColorScheme | typeof DEFAULT_COLOR_SCHEME)[] = [
|
|
83
83
|
DEFAULT_COLOR_SCHEME,
|
|
84
84
|
// Categorical schemes
|
|
85
85
|
"accent",
|
|
@@ -211,7 +211,7 @@ const ColumnPreview = ({
|
|
|
211
211
|
refetchPreview,
|
|
212
212
|
});
|
|
213
213
|
|
|
214
|
-
const previewStats = stats && renderStats(stats, dataType, locale);
|
|
214
|
+
const previewStats = stats && renderStats({ stats, dataType, locale });
|
|
215
215
|
|
|
216
216
|
const chart = chart_spec && renderChart(chart_spec, theme);
|
|
217
217
|
|
|
@@ -778,14 +778,14 @@ export class ColumnChartSpecModel<T> {
|
|
|
778
778
|
const yField = "value";
|
|
779
779
|
|
|
780
780
|
// Calculate xStart and xEnd for each value count
|
|
781
|
-
const newValueCounts:
|
|
781
|
+
const newValueCounts: {
|
|
782
782
|
count: number;
|
|
783
783
|
value: string;
|
|
784
784
|
xStart: number;
|
|
785
785
|
xEnd: number;
|
|
786
786
|
xMid: number;
|
|
787
787
|
proportion: number;
|
|
788
|
-
}
|
|
788
|
+
}[] = [];
|
|
789
789
|
let xStart = 0;
|
|
790
790
|
for (const valueCount of valueCounts) {
|
|
791
791
|
const xEnd = xStart + valueCount.count;
|
|
@@ -17,6 +17,7 @@ import { JsonOutput } from "../editor/output/JsonOutput";
|
|
|
17
17
|
import { Button } from "../ui/button";
|
|
18
18
|
import { Checkbox } from "../ui/checkbox";
|
|
19
19
|
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
|
|
20
|
+
import { Tooltip } from "../ui/tooltip";
|
|
20
21
|
import { DataTableColumnHeader } from "./column-header";
|
|
21
22
|
import type { ColumnChartSpecModel } from "./column-summary/chart-spec-model";
|
|
22
23
|
import { TableColumnSummary } from "./column-summary/column-summary";
|
|
@@ -103,6 +104,7 @@ export function generateColumns<T>({
|
|
|
103
104
|
chartSpecModel,
|
|
104
105
|
textJustifyColumns,
|
|
105
106
|
wrappedColumns,
|
|
107
|
+
headerTooltip,
|
|
106
108
|
showDataTypes,
|
|
107
109
|
calculateTopKRows,
|
|
108
110
|
}: {
|
|
@@ -112,9 +114,10 @@ export function generateColumns<T>({
|
|
|
112
114
|
chartSpecModel?: ColumnChartSpecModel<unknown>;
|
|
113
115
|
textJustifyColumns?: Record<string, "left" | "center" | "right">;
|
|
114
116
|
wrappedColumns?: string[];
|
|
117
|
+
headerTooltip?: Record<string, string>;
|
|
115
118
|
showDataTypes?: boolean;
|
|
116
119
|
calculateTopKRows?: CalculateTopKRows;
|
|
117
|
-
}):
|
|
120
|
+
}): ColumnDef<T>[] {
|
|
118
121
|
// Row-headers are typically index columns
|
|
119
122
|
const rowHeadersSet = new Set(rowHeaders.map(([columnName]) => columnName));
|
|
120
123
|
|
|
@@ -165,6 +168,7 @@ export function generateColumns<T>({
|
|
|
165
168
|
header: ({ column }) => {
|
|
166
169
|
const stats = chartSpecModel?.getColumnStats(key);
|
|
167
170
|
const dtype = column.columnDef.meta?.dtype;
|
|
171
|
+
const headerTitle = headerTooltip?.[key];
|
|
168
172
|
const dtypeHeader =
|
|
169
173
|
showDataTypes && dtype ? (
|
|
170
174
|
<div className="flex flex-row gap-1">
|
|
@@ -179,14 +183,29 @@ export function generateColumns<T>({
|
|
|
179
183
|
|
|
180
184
|
const headerWithType = (
|
|
181
185
|
<div className="flex flex-col">
|
|
182
|
-
<span
|
|
186
|
+
<span
|
|
187
|
+
className={cn(
|
|
188
|
+
"font-bold",
|
|
189
|
+
headerTitle && "underline decoration-dotted",
|
|
190
|
+
)}
|
|
191
|
+
>
|
|
192
|
+
{key === "" ? " " : key}
|
|
193
|
+
</span>
|
|
183
194
|
{dtypeHeader}
|
|
184
195
|
</div>
|
|
185
196
|
);
|
|
186
197
|
|
|
198
|
+
const headerWithTooltip = headerTitle ? (
|
|
199
|
+
<Tooltip content={headerTitle} delayDuration={300}>
|
|
200
|
+
{headerWithType}
|
|
201
|
+
</Tooltip>
|
|
202
|
+
) : (
|
|
203
|
+
headerWithType
|
|
204
|
+
);
|
|
205
|
+
|
|
187
206
|
const dataTableColumnHeader = (
|
|
188
207
|
<DataTableColumnHeader
|
|
189
|
-
header={
|
|
208
|
+
header={headerWithTooltip}
|
|
190
209
|
column={column}
|
|
191
210
|
calculateTopKRows={calculateTopKRows}
|
|
192
211
|
/>
|
|
@@ -47,7 +47,8 @@ import { getStableRowId } from "./utils";
|
|
|
47
47
|
interface DataTableProps<TData> extends Partial<DownloadActionProps> {
|
|
48
48
|
wrapperClassName?: string;
|
|
49
49
|
className?: string;
|
|
50
|
-
|
|
50
|
+
maxHeight?: number;
|
|
51
|
+
columns: ColumnDef<TData>[];
|
|
51
52
|
data: TData[];
|
|
52
53
|
// Sorting
|
|
53
54
|
manualSorting?: boolean; // server-side sorting
|
|
@@ -95,6 +96,7 @@ interface DataTableProps<TData> extends Partial<DownloadActionProps> {
|
|
|
95
96
|
const DataTableInternal = <TData,>({
|
|
96
97
|
wrapperClassName,
|
|
97
98
|
className,
|
|
99
|
+
maxHeight,
|
|
98
100
|
columns,
|
|
99
101
|
data,
|
|
100
102
|
selection,
|
|
@@ -250,6 +252,36 @@ const DataTableInternal = <TData,>({
|
|
|
250
252
|
|
|
251
253
|
const rowViewerPanelOpen = isPanelOpen?.("row-viewer") ?? false;
|
|
252
254
|
|
|
255
|
+
const tableRef = React.useRef<HTMLTableElement | null>(null);
|
|
256
|
+
|
|
257
|
+
// Why use a ref to set max-height on the wrapper?
|
|
258
|
+
// - position: sticky only works when the sticky element's nearest scrollable
|
|
259
|
+
// ancestor is its immediate container. If max-height/overflow are applied
|
|
260
|
+
// on a grandparent, sticky table headers (th) will not stick.
|
|
261
|
+
// - We keep the scroll wrapper colocated with the base Table component, but
|
|
262
|
+
// derive the scroll boundary from maxHeight here to avoid coupling UI base
|
|
263
|
+
// components to data-table specifics or expanding their API surface.
|
|
264
|
+
// - Setting styles on the table's direct wrapper ensures the header sticks
|
|
265
|
+
// reliably across browsers without changing upstream components.
|
|
266
|
+
React.useEffect(() => {
|
|
267
|
+
if (!tableRef.current) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
const wrapper = tableRef.current.parentElement as HTMLDivElement | null;
|
|
271
|
+
if (!wrapper) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
if (maxHeight) {
|
|
275
|
+
wrapper.style.maxHeight = `${maxHeight}px`;
|
|
276
|
+
// Ensure wrapper scrolls
|
|
277
|
+
if (!wrapper.style.overflow) {
|
|
278
|
+
wrapper.style.overflow = "auto";
|
|
279
|
+
}
|
|
280
|
+
} else {
|
|
281
|
+
wrapper.style.removeProperty("max-height");
|
|
282
|
+
}
|
|
283
|
+
}, [maxHeight]);
|
|
284
|
+
|
|
253
285
|
return (
|
|
254
286
|
<div className={cn(wrapperClassName, "flex flex-col space-y-1")}>
|
|
255
287
|
<FilterPills filters={filters} table={table} />
|
|
@@ -263,11 +295,11 @@ const DataTableInternal = <TData,>({
|
|
|
263
295
|
reloading={reloading}
|
|
264
296
|
/>
|
|
265
297
|
)}
|
|
266
|
-
<Table className="relative">
|
|
298
|
+
<Table className="relative" ref={tableRef}>
|
|
267
299
|
{showLoadingBar && (
|
|
268
300
|
<div className="absolute top-0 left-0 h-[3px] w-1/2 bg-primary animate-slide" />
|
|
269
301
|
)}
|
|
270
|
-
{renderTableHeader(table)}
|
|
302
|
+
{renderTableHeader(table, Boolean(maxHeight))}
|
|
271
303
|
<CellSelectionProvider>
|
|
272
304
|
<DataTableBody
|
|
273
305
|
table={table}
|
|
@@ -124,7 +124,7 @@ const RelativeTime = ({ date }: { date: Date }) => {
|
|
|
124
124
|
const differenceInSeconds = (currentTime.getTime() - date.getTime()) / 1000;
|
|
125
125
|
|
|
126
126
|
// Define time units with their thresholds and conversion factors
|
|
127
|
-
const timeUnits:
|
|
127
|
+
const timeUnits: [number, number, string][] = [
|
|
128
128
|
[60, 1, "second"], // Less than 60 seconds
|
|
129
129
|
[60, 60, "minute"], // Less than 60 minutes
|
|
130
130
|
[24, 3600, "hour"], // Less than 24 hours
|
|
@@ -167,7 +167,7 @@ export const DownloadAs: React.FC<DownloadActionProps> = (props) => {
|
|
|
167
167
|
);
|
|
168
168
|
};
|
|
169
169
|
|
|
170
|
-
function fetchJson(url: string): Promise<
|
|
170
|
+
function fetchJson(url: string): Promise<Record<string, unknown>[]> {
|
|
171
171
|
return fetch(url).then((res) => {
|
|
172
172
|
if (!res.ok) {
|
|
173
173
|
throw new Error(res.statusText);
|
|
@@ -20,17 +20,17 @@ function createMockCell(id: string, value: unknown): Cell<unknown, unknown> {
|
|
|
20
20
|
function createMockColumn(id: string): Column<unknown> {
|
|
21
21
|
return {
|
|
22
22
|
id: id,
|
|
23
|
-
getIndex: () => Number.parseInt(id),
|
|
23
|
+
getIndex: () => Number.parseInt(id, 10),
|
|
24
24
|
} as unknown as Column<unknown>;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
function createMockRow(
|
|
28
28
|
id: string,
|
|
29
|
-
cells:
|
|
29
|
+
cells: Cell<unknown, unknown>[],
|
|
30
30
|
): Row<unknown> {
|
|
31
31
|
return {
|
|
32
32
|
id,
|
|
33
|
-
index: Number.parseInt(id),
|
|
33
|
+
index: Number.parseInt(id, 10),
|
|
34
34
|
getAllCells: () => cells,
|
|
35
35
|
original: {},
|
|
36
36
|
depth: 0,
|
|
@@ -43,8 +43,8 @@ function createMockRow(
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
function createMockTable(
|
|
46
|
-
rows:
|
|
47
|
-
columns:
|
|
46
|
+
rows: Row<unknown>[],
|
|
47
|
+
columns: Column<unknown>[],
|
|
48
48
|
): Table<unknown> {
|
|
49
49
|
return {
|
|
50
50
|
getRow: (id: string) => rows.find((row) => row.id === id),
|
|
@@ -26,12 +26,13 @@ import { useScrollIntoViewOnFocus } from "./range-focus/use-scroll-into-view";
|
|
|
26
26
|
|
|
27
27
|
export function renderTableHeader<TData>(
|
|
28
28
|
table: Table<TData>,
|
|
29
|
+
isSticky?: boolean,
|
|
29
30
|
): JSX.Element | null {
|
|
30
31
|
if (!table.getRowModel().rows?.length) {
|
|
31
32
|
return null;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
const renderHeaderGroup = (headerGroups:
|
|
35
|
+
const renderHeaderGroup = (headerGroups: HeaderGroup<TData>[]) => {
|
|
35
36
|
return headerGroups.map((headerGroup) =>
|
|
36
37
|
headerGroup.headers.map((header) => {
|
|
37
38
|
const { className, style } = getPinningStyles(header.column);
|
|
@@ -57,7 +58,7 @@ export function renderTableHeader<TData>(
|
|
|
57
58
|
};
|
|
58
59
|
|
|
59
60
|
return (
|
|
60
|
-
<TableHeader>
|
|
61
|
+
<TableHeader className={cn(isSticky && "sticky top-0 z-10")}>
|
|
61
62
|
<TableRow>
|
|
62
63
|
{renderHeaderGroup(table.getLeftHeaderGroups())}
|
|
63
64
|
{renderHeaderGroup(table.getCenterHeaderGroups())}
|
|
@@ -69,7 +70,7 @@ export function renderTableHeader<TData>(
|
|
|
69
70
|
|
|
70
71
|
interface DataTableBodyProps<TData> {
|
|
71
72
|
table: Table<TData>;
|
|
72
|
-
columns:
|
|
73
|
+
columns: ColumnDef<TData>[];
|
|
73
74
|
rowViewerPanelOpen: boolean;
|
|
74
75
|
getRowIndex?: (row: TData, idx: number) => number;
|
|
75
76
|
viewedRowIdx?: number;
|
|
@@ -95,7 +96,7 @@ export const DataTableBody = <TData,>({
|
|
|
95
96
|
|
|
96
97
|
function applyHoverTemplate(
|
|
97
98
|
template: string,
|
|
98
|
-
cells:
|
|
99
|
+
cells: Cell<TData, unknown>[],
|
|
99
100
|
): string {
|
|
100
101
|
const variableRegex = /{{(\w+)}}/g;
|
|
101
102
|
// Map column id -> stringified value
|
|
@@ -106,13 +107,13 @@ export const DataTableBody = <TData,>({
|
|
|
106
107
|
const s = renderUnknownValue({ value: v, nullAsEmptyString: true });
|
|
107
108
|
idToValue.set(c.column.id, s);
|
|
108
109
|
}
|
|
109
|
-
return template.
|
|
110
|
+
return template.replaceAll(variableRegex, (_substr, varName: string) => {
|
|
110
111
|
const val = idToValue.get(varName);
|
|
111
|
-
return val
|
|
112
|
+
return val === undefined ? `{{${varName}}}` : val;
|
|
112
113
|
});
|
|
113
114
|
}
|
|
114
115
|
|
|
115
|
-
const renderCells = (cells:
|
|
116
|
+
const renderCells = (cells: Cell<TData, unknown>[]) => {
|
|
116
117
|
return cells.map((cell) => {
|
|
117
118
|
const { className, style: pinningstyle } = getPinningStyles(cell.column);
|
|
118
119
|
const style = Object.assign(
|
|
@@ -154,6 +155,8 @@ export const DataTableBody = <TData,>({
|
|
|
154
155
|
}
|
|
155
156
|
};
|
|
156
157
|
|
|
158
|
+
const hoverTemplate = table.getState().cellHoverTemplate || null;
|
|
159
|
+
|
|
157
160
|
return (
|
|
158
161
|
<TableBody onKeyDown={handleCellsKeyDown} ref={tableRef}>
|
|
159
162
|
{table.getRowModel().rows?.length ? (
|
|
@@ -165,12 +168,18 @@ export const DataTableBody = <TData,>({
|
|
|
165
168
|
const isRowViewedInPanel =
|
|
166
169
|
rowViewerPanelOpen && viewedRowIdx === rowIndex;
|
|
167
170
|
|
|
168
|
-
// Compute hover title once per row using
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
171
|
+
// Compute hover title once per row using all visible cells
|
|
172
|
+
let rowTitle: string | undefined;
|
|
173
|
+
if (hoverTemplate) {
|
|
174
|
+
const visibleCells = row.getVisibleCells?.() ?? [
|
|
175
|
+
...row.getLeftVisibleCells(),
|
|
176
|
+
...row.getCenterVisibleCells(),
|
|
177
|
+
...row.getRightVisibleCells(),
|
|
178
|
+
];
|
|
179
|
+
rowTitle = hoverTemplate
|
|
180
|
+
? applyHoverTemplate(hoverTemplate, visibleCells)
|
|
181
|
+
: undefined;
|
|
182
|
+
}
|
|
174
183
|
|
|
175
184
|
return (
|
|
176
185
|
<TableRow
|
|
@@ -188,7 +188,7 @@ export const RowViewerPanel: React.FC<RowViewerPanelProps> = ({
|
|
|
188
188
|
</TableRow>
|
|
189
189
|
</TableHeader>
|
|
190
190
|
<TableBody>
|
|
191
|
-
{fieldTypes?.map(([columnName, [dataType,
|
|
191
|
+
{fieldTypes?.map(([columnName, [dataType, _externalType]]) => {
|
|
192
192
|
const columnValue = rowValues[columnName];
|
|
193
193
|
|
|
194
194
|
if (!inSearchQuery({ columnName, columnValue, searchQuery })) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/* Copyright 2024 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import z from "zod";
|
|
4
|
+
import { rpc } from "@/plugins/core/rpc";
|
|
5
|
+
|
|
6
|
+
export type DownloadAsArgs = (req: {
|
|
7
|
+
format: "csv" | "json" | "parquet";
|
|
8
|
+
}) => Promise<string>;
|
|
9
|
+
|
|
10
|
+
export const DownloadAsSchema = rpc
|
|
11
|
+
.input(
|
|
12
|
+
z.object({
|
|
13
|
+
format: z.enum(["csv", "json", "parquet"]),
|
|
14
|
+
}),
|
|
15
|
+
)
|
|
16
|
+
.output(z.string());
|
|
@@ -27,9 +27,10 @@ export type ColumnHeaderStats = Record<
|
|
|
27
27
|
number | string | null
|
|
28
28
|
>;
|
|
29
29
|
|
|
30
|
-
export type FieldTypesWithExternalType =
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
export type FieldTypesWithExternalType = [
|
|
31
|
+
columnName: string,
|
|
32
|
+
[dataType: DataType, externalType: string],
|
|
33
|
+
][];
|
|
33
34
|
export type FieldTypes = Record<string, DataType>;
|
|
34
35
|
|
|
35
36
|
export function toFieldTypes(
|
|
@@ -110,7 +110,8 @@ export const DatasetColumnPreview: React.FC<{
|
|
|
110
110
|
});
|
|
111
111
|
|
|
112
112
|
const stats =
|
|
113
|
-
preview.stats &&
|
|
113
|
+
preview.stats &&
|
|
114
|
+
renderStats({ stats: preview.stats, dataType: column.type, locale });
|
|
114
115
|
|
|
115
116
|
const chart = preview.chart_spec && renderChart(preview.chart_spec, theme);
|
|
116
117
|
|
|
@@ -175,11 +176,13 @@ export function renderPreviewError({
|
|
|
175
176
|
);
|
|
176
177
|
}
|
|
177
178
|
|
|
178
|
-
|
|
179
|
-
stats: Partial<Record<ColumnHeaderStatsKey, unknown
|
|
180
|
-
dataType: DataType
|
|
181
|
-
locale: string
|
|
182
|
-
|
|
179
|
+
interface RenderStatsProps {
|
|
180
|
+
stats: Partial<Record<ColumnHeaderStatsKey, unknown>>;
|
|
181
|
+
dataType: DataType;
|
|
182
|
+
locale: string;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function renderStats({ stats, dataType, locale }: RenderStatsProps) {
|
|
183
186
|
return (
|
|
184
187
|
<div className="gap-x-16 gap-y-1 grid grid-cols-2-fit border rounded p-2 empty:hidden">
|
|
185
188
|
{Object.entries(stats).map(([key, value]) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* Copyright 2024 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
3
|
import { useAtomValue } from "jotai";
|
|
4
|
-
import React, { memo, use } from "react";
|
|
4
|
+
import React, { memo, use, useId } from "react";
|
|
5
5
|
import { Handle, Position, useStore } from "reactflow";
|
|
6
6
|
import { TinyCode } from "@/components/editor/cell/TinyCode";
|
|
7
7
|
import { useCellIds } from "@/core/cells/cells";
|
|
@@ -23,7 +23,7 @@ const EQUALITY_CHECK = (
|
|
|
23
23
|
prevProps: CustomNodeProps,
|
|
24
24
|
nextProps: CustomNodeProps,
|
|
25
25
|
) => {
|
|
26
|
-
const keys:
|
|
26
|
+
const keys: (keyof CustomNodeProps)[] = ["data", "selected", "id"];
|
|
27
27
|
return keys.every((key) => prevProps[key] === nextProps[key]);
|
|
28
28
|
};
|
|
29
29
|
|
|
@@ -37,18 +37,25 @@ export const CustomNode = memo((props: CustomNodeProps) => {
|
|
|
37
37
|
const reactFlowWidth = useStore(({ width }) => width);
|
|
38
38
|
const edgeMarkers = use(EdgeMarkerContext);
|
|
39
39
|
|
|
40
|
+
const inputOneId = useId();
|
|
41
|
+
const inputTwoId = useId();
|
|
42
|
+
const outputOneId = useId();
|
|
43
|
+
const outputTwoId = useId();
|
|
44
|
+
|
|
40
45
|
const linesOfCode = cell.code.split("\n").length;
|
|
41
46
|
return (
|
|
42
47
|
<div>
|
|
43
48
|
<Handle
|
|
44
49
|
type="target"
|
|
45
|
-
id=
|
|
50
|
+
id={inputOneId}
|
|
51
|
+
data-testid="input-one"
|
|
46
52
|
position={edgeMarkers === "LR" ? Position.Left : Position.Top}
|
|
47
53
|
style={{ background: color }}
|
|
48
54
|
/>
|
|
49
55
|
<Handle
|
|
50
56
|
type="source"
|
|
51
|
-
id=
|
|
57
|
+
id={inputTwoId}
|
|
58
|
+
data-testid="input-two"
|
|
52
59
|
position={edgeMarkers === "LR" ? Position.Left : Position.Top}
|
|
53
60
|
style={{ background: color }}
|
|
54
61
|
/>
|
|
@@ -69,13 +76,15 @@ export const CustomNode = memo((props: CustomNodeProps) => {
|
|
|
69
76
|
</div>
|
|
70
77
|
<Handle
|
|
71
78
|
type="source"
|
|
72
|
-
id=
|
|
79
|
+
id={outputOneId}
|
|
80
|
+
data-testid="output-one"
|
|
73
81
|
position={edgeMarkers === "LR" ? Position.Right : Position.Bottom}
|
|
74
82
|
style={{ background: color }}
|
|
75
83
|
/>
|
|
76
84
|
<Handle
|
|
77
85
|
type="target"
|
|
78
|
-
id=
|
|
86
|
+
id={outputTwoId}
|
|
87
|
+
data-testid="output-two"
|
|
79
88
|
position={edgeMarkers === "LR" ? Position.Right : Position.Bottom}
|
|
80
89
|
style={{ background: color }}
|
|
81
90
|
/>
|
|
@@ -31,7 +31,7 @@ import { useFitToViewOnDimensionChange } from "./utils/useFitToViewOnDimensionCh
|
|
|
31
31
|
interface Props {
|
|
32
32
|
cellIds: CellId[];
|
|
33
33
|
variables: Variables;
|
|
34
|
-
cellAtoms:
|
|
34
|
+
cellAtoms: Atom<CellData>[];
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
const elementsBuilder = new VerticalElementsBuilder();
|
|
@@ -57,7 +57,7 @@ export const DependencyGraphMinimap: React.FC<PropsWithChildren<Props>> = ({
|
|
|
57
57
|
|
|
58
58
|
// If the cellIds change, update the nodes.
|
|
59
59
|
const syncChanges = useEvent(
|
|
60
|
-
(elements: { nodes:
|
|
60
|
+
(elements: { nodes: Node<NodeData>[]; edges: Edge[] }) => {
|
|
61
61
|
setNodes(elements.nodes);
|
|
62
62
|
setEdges([]);
|
|
63
63
|
},
|
|
@@ -36,7 +36,7 @@ import { useFitToViewOnDimensionChange } from "./utils/useFitToViewOnDimensionCh
|
|
|
36
36
|
interface Props {
|
|
37
37
|
cellIds: CellId[];
|
|
38
38
|
variables: Variables;
|
|
39
|
-
cellAtoms:
|
|
39
|
+
cellAtoms: Atom<CellData>[];
|
|
40
40
|
layoutDirection: LayoutDirection;
|
|
41
41
|
settings: GraphSettings;
|
|
42
42
|
}
|
|
@@ -74,7 +74,7 @@ export const DependencyGraphTree: React.FC<PropsWithChildren<Props>> = ({
|
|
|
74
74
|
const api = useReactFlow();
|
|
75
75
|
|
|
76
76
|
const syncChanges = useEvent(
|
|
77
|
-
(elements: { nodes:
|
|
77
|
+
(elements: { nodes: Node<NodeData>[]; edges: Edge[] }) => {
|
|
78
78
|
// Layout the elements
|
|
79
79
|
const result = layoutElements({
|
|
80
80
|
nodes: elements.nodes,
|
|
@@ -22,10 +22,10 @@ export function getNodeHeight(linesOfCode: number) {
|
|
|
22
22
|
interface ElementsBuilder {
|
|
23
23
|
createElements: (
|
|
24
24
|
cellIds: CellId[],
|
|
25
|
-
cellAtoms:
|
|
25
|
+
cellAtoms: Atom<CellData>[],
|
|
26
26
|
variables: Variables,
|
|
27
27
|
hidePureMarkdown: boolean,
|
|
28
|
-
) => { nodes:
|
|
28
|
+
) => { nodes: Node<NodeData>[]; edges: Edge[] };
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export class VerticalElementsBuilder implements ElementsBuilder {
|
|
@@ -69,12 +69,12 @@ export class VerticalElementsBuilder implements ElementsBuilder {
|
|
|
69
69
|
|
|
70
70
|
createElements(
|
|
71
71
|
cellIds: CellId[],
|
|
72
|
-
cellAtoms:
|
|
72
|
+
cellAtoms: Atom<CellData>[],
|
|
73
73
|
variables: Variables,
|
|
74
|
-
|
|
74
|
+
_hidePureMarkdown: boolean,
|
|
75
75
|
) {
|
|
76
76
|
let prevY = 0;
|
|
77
|
-
const nodes:
|
|
77
|
+
const nodes: Node<NodeData>[] = [];
|
|
78
78
|
const edges: Edge[] = [];
|
|
79
79
|
for (const [cellId, cellAtom] of Arrays.zip(cellIds, cellAtoms)) {
|
|
80
80
|
const node = this.createNode(cellId, cellAtom, prevY);
|
|
@@ -135,11 +135,11 @@ export class TreeElementsBuilder implements ElementsBuilder {
|
|
|
135
135
|
|
|
136
136
|
createElements(
|
|
137
137
|
cellIds: CellId[],
|
|
138
|
-
cellAtoms:
|
|
138
|
+
cellAtoms: Atom<CellData>[],
|
|
139
139
|
variables: Variables,
|
|
140
140
|
hidePureMarkdown: boolean,
|
|
141
141
|
) {
|
|
142
|
-
const nodes:
|
|
142
|
+
const nodes: Node<NodeData>[] = [];
|
|
143
143
|
const edges: Edge[] = [];
|
|
144
144
|
|
|
145
145
|
const nodesWithEdges = new Set<CellId>();
|
|
@@ -11,8 +11,8 @@ import type {
|
|
|
11
11
|
export function getNodeChanges(
|
|
12
12
|
prevNodes: Node[],
|
|
13
13
|
nextNodes: Node[],
|
|
14
|
-
):
|
|
15
|
-
const changes:
|
|
14
|
+
): (NodeAddChange | NodeRemoveChange)[] {
|
|
15
|
+
const changes: (NodeAddChange | NodeRemoveChange)[] = [];
|
|
16
16
|
const prevNodeIds = new Set(prevNodes.map((node) => node.id));
|
|
17
17
|
const nextNodeIds = new Set(nextNodes.map((node) => node.id));
|
|
18
18
|
|
|
@@ -33,8 +33,8 @@ export function getNodeChanges(
|
|
|
33
33
|
export function getEdgeChanges(
|
|
34
34
|
prevEdges: Edge[],
|
|
35
35
|
nextEdges: Edge[],
|
|
36
|
-
):
|
|
37
|
-
const changes:
|
|
36
|
+
): (EdgeAddChange | EdgeRemoveChange)[] {
|
|
37
|
+
const changes: (EdgeAddChange | EdgeRemoveChange)[] = [];
|
|
38
38
|
const prevEdgeIds = new Set(prevEdges.map((edge) => edge.id));
|
|
39
39
|
const nextEdgeIds = new Set(nextEdges.map((edge) => edge.id));
|
|
40
40
|
|