@marimo-team/frontend 0.16.0 → 0.16.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/assets/ConnectedDataExplorerComponent-B5cPvWoQ.js +19 -0
- package/dist/assets/{ImageComparisonComponent-fTHv1Ih0.js → ImageComparisonComponent-CqR26LSv.js} +1 -1
- package/dist/assets/{VegaLite-Bdi-TyfY.js → VegaLite-DvQDATwI.js} +1 -1
- package/dist/assets/_baseEach--KDTwKbG.js +1 -0
- package/dist/assets/_baseMap-Cu3o-eyO.js +1 -0
- package/dist/assets/{_baseUniq-CCgDNtZb.js → _baseUniq-y7ZXnMo1.js} +1 -1
- package/dist/assets/{_createAggregator-DcD0kTA5.js → _createAggregator-ZcHkHPNJ.js} +1 -1
- package/dist/assets/{agent-panel-Crv430aI.js → agent-panel-B91RoLct.js} +76 -57
- package/dist/assets/{any-language-editor-CQh552Wu.js → any-language-editor-CxfHcm5h.js} +1 -1
- package/dist/assets/{architectureDiagram-W76B3OCA-BAJeBxzt.js → architectureDiagram-W76B3OCA-BQsvK8uR.js} +1 -1
- package/dist/assets/{between-horizontal-start-Boxgxbt_.js → between-horizontal-start-BmYToIaM.js} +1 -1
- package/dist/assets/{blockDiagram-QIGZ2CNN-CL-1svEK.js → blockDiagram-QIGZ2CNN-r3HgCj4w.js} +1 -1
- package/dist/assets/{c4Diagram-FPNF74CW-BbEqbCTl.js → c4Diagram-FPNF74CW-BJbPNt41.js} +1 -1
- package/dist/assets/channel-DFaEx1fu.js +1 -0
- package/dist/assets/chat-panel-IoPMv8e2.js +3 -0
- package/dist/assets/{chunk-4BX2VUAB-C--8TXeE.js → chunk-4BX2VUAB-Dv4MZ9Hj.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-Bj00HDqq.js → chunk-55IACEB6-CM4AHquB.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-C-lhB6hN.js → chunk-FMBD7UC4-C_Zz0ENB.js} +1 -1
- package/dist/assets/{chunk-K7UQS3LO-B-pGTXPt.js → chunk-K7UQS3LO-DYSmiXYq.js} +1 -1
- package/dist/assets/{chunk-QN33PNHL-DqUzGhvm.js → chunk-QN33PNHL-QM4OPuQP.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-TntJHfSk.js → chunk-QZHKN3VN-CfAsGyeB.js} +1 -1
- package/dist/assets/{chunk-TVAH2DTR-HUJb1psV.js → chunk-TVAH2DTR-6j_Cpjsi.js} +1 -1
- package/dist/assets/{chunk-TZMSLE5B-BK3C__t3.js → chunk-TZMSLE5B-BHslFJQE.js} +1 -1
- package/dist/assets/{circle-play-DBLOv1Yu.js → circle-play-CK3UZRYQ.js} +1 -1
- package/dist/assets/classDiagram-KNZD7YFC-BsZtvV5O.js +1 -0
- package/dist/assets/classDiagram-v2-RKCZMP56-BsZtvV5O.js +1 -0
- package/dist/assets/{clear-button-BeoFbEKH.js → clear-button-C4fDVSv8.js} +1 -1
- package/dist/assets/clone-YBEvPE-s.js +1 -0
- package/dist/assets/command-palette-D7hOfvf6.js +1 -0
- package/dist/assets/{common-C7oJcmCT.js → common-D-lbuUwz.js} +1 -1
- package/dist/assets/{compile-7L0MwhyI.js → compile-DVQe1Mzk.js} +1 -1
- package/dist/assets/{cose-bilkent-S5V4N54A-BMkGLcVC.js → cose-bilkent-S5V4N54A-D-IS7WC8.js} +1 -1
- package/dist/assets/{dagre-5GWH7T2D-BJtRienS.js → dagre-5GWH7T2D-lYu-tEWT.js} +1 -1
- package/dist/assets/{data-grid-overlay-editor-DBkmGtNs.js → data-grid-overlay-editor-C5peOCit.js} +1 -1
- package/dist/assets/datasources-panel-D3NA20uZ.js +1 -0
- package/dist/assets/{dependency-graph-panel-DEdOxp2X.js → dependency-graph-panel-BGVYOfkV.js} +1 -1
- package/dist/assets/{diagram-N5W7TBWH-CmECY3nb.js → diagram-N5W7TBWH-BnvIuYUp.js} +1 -1
- package/dist/assets/{diagram-QEK2KX5R-DMOVSNKD.js → diagram-QEK2KX5R-DemedRK3.js} +1 -1
- package/dist/assets/{diagram-S2PKOQOG-BiJ96PNQ.js → diagram-S2PKOQOG-iiY7AuyH.js} +1 -1
- package/dist/assets/{documentation-panel-xULhaEv3.js → documentation-panel-C3dSwOSQ.js} +1 -1
- package/dist/assets/edit-page-C5TsEeSo.js +129 -0
- package/dist/assets/{ellipsis-vertical-BBqXIlc2.js → ellipsis-vertical-CazJl8M7.js} +1 -1
- package/dist/assets/{empty-state-B3dA3G5P.js → empty-state-DW308mFO.js} +1 -1
- package/dist/assets/{erDiagram-AWTI2OKA-MP1DiFRo.js → erDiagram-AWTI2OKA-6wQ8Ugg0.js} +1 -1
- package/dist/assets/{error-panel-Cc1sv-Ag.js → error-panel-D1VnJ1yP.js} +1 -1
- package/dist/assets/file-explorer-panel-0oVd4t-D.js +1 -0
- package/dist/assets/{flowDiagram-PVAE7QVJ-BX7caPp7.js → flowDiagram-PVAE7QVJ-C55IUWjm.js} +1 -1
- package/dist/assets/{ganttDiagram-OWAHRB6G-B462g4Yf.js → ganttDiagram-OWAHRB6G-DmqCM6ME.js} +4 -4
- package/dist/assets/{gitGraphDiagram-NY62KEGX-CGgvZ9-9.js → gitGraphDiagram-NY62KEGX-DBvhAeM_.js} +1 -1
- package/dist/assets/{glide-data-editor-C0gUFZON.js → glide-data-editor-CHNuHidQ.js} +4 -4
- package/dist/assets/{graph-CHRVBzY5.js → graph-CG6BgUWQ.js} +1 -1
- package/dist/assets/home-page-dgivXuSR.js +9 -0
- package/dist/assets/{index-Clbi_Yaq.js → index-BTGpssVX.js} +1 -1
- package/dist/assets/{index-CQDrxQ0j.js → index-BYVZlBF8.js} +1 -1
- package/dist/assets/{index-lYa_leQE.js → index-BelfnXwL.js} +1 -1
- package/dist/assets/{index-DRMm6SNo.js → index-BneyUujp.js} +1 -1
- package/dist/assets/{index-BY93Ejhl.js → index-C02SqeRj.js} +1 -1
- package/dist/assets/{index-C-8WADat.js → index-C7dtgr9A.js} +1 -1
- package/dist/assets/{index-D9UKkrr2.js → index-CAQvMTzM.js} +1 -1
- package/dist/assets/index-CGDMlQfO.css +1 -0
- package/dist/assets/index-CelXfcd8.js +580 -0
- package/dist/assets/{index-vmICa5KN.js → index-Csd6QrCV.js} +1 -1
- package/dist/assets/{index-DoRmcrKM.js → index-CtPksxf0.js} +1 -1
- package/dist/assets/{index-C1v_Z9et.js → index-Cxyk7pt-.js} +1 -1
- package/dist/assets/{index-CpTPJo4k.js → index-DAZ-9ri2.js} +1 -1
- package/dist/assets/{index-DEQvTChO.js → index-DONRrmA2.js} +1 -1
- package/dist/assets/{index-C4Tn5NvJ.js → index-Db36XTG_.js} +1 -1
- package/dist/assets/{index-z9bohSQJ.js → index-DdIhdEVw.js} +1 -1
- package/dist/assets/{index-C-GhZ7ti.js → index-M_pBKDSe.js} +1 -1
- package/dist/assets/{index-C77h_TXN.js → index-_luCZMLM.js} +1 -1
- package/dist/assets/{index-D1vmG6DS.js → index-mkubqy9-.js} +1 -1
- package/dist/assets/{index-BVgAenPd.js → index-sbO9UaUU.js} +1 -1
- package/dist/assets/{index-CWMgowgL.js → index-z4krxQ4j.js} +1 -1
- package/dist/assets/infoDiagram-STP46IZ2-wTALjfPc.js +2 -0
- package/dist/assets/{isEmpty-DU_ogP_D.js → isEmpty-CqX_YTIf.js} +1 -1
- package/dist/assets/{journeyDiagram-BIP6EPQ6-C6EgLP_Q.js → journeyDiagram-BIP6EPQ6-Y5w_Tqe_.js} +1 -1
- package/dist/assets/{kanban-definition-6OIFK2YF-BXzYO1yj.js → kanban-definition-6OIFK2YF-DbXs5Rxi.js} +1 -1
- package/dist/assets/{layout-jihVw5-i.js → layout-BCNPDACj.js} +1 -1
- package/dist/assets/{linear-C4blANlC.js → linear-uO6UVhXt.js} +1 -1
- package/dist/assets/links-Drv7cJgN.js +7 -0
- package/dist/assets/{logs-panel-D401qzZh.js → logs-panel-BEQ1eRUp.js} +1 -1
- package/dist/assets/{markdown-renderer-Cd9eYyaL.js → markdown-renderer-Dmzbb00W.js} +20 -20
- package/dist/assets/{mermaid-BEVuRz_O.js → mermaid-qRc4MXIj.js} +1 -1
- package/dist/assets/{mermaid.core-CaSnaLH0.js → mermaid.core-CvvJtCRj.js} +4 -4
- package/dist/assets/min-DYUOb1RR.js +1 -0
- package/dist/assets/{mindmap-definition-Q6HEUPPD-BXUM5MT2.js → mindmap-definition-Q6HEUPPD-G5NognM-.js} +1 -1
- package/dist/assets/{number-overlay-editor-4uWXGlPG.js → number-overlay-editor-DPr5sHFu.js} +1 -1
- package/dist/assets/outline-panel-gxQXvVi4.js +1 -0
- package/dist/assets/{packages-panel-CJL0MVlj.js → packages-panel-B1T0VPlg.js} +1 -1
- package/dist/assets/{pieDiagram-ADFJNKIX-Dxt5PVNo.js → pieDiagram-ADFJNKIX-DK9SHkfc.js} +1 -1
- package/dist/assets/{quadrantDiagram-LMRXKWRM-D4pUaA31.js → quadrantDiagram-LMRXKWRM-D1DdWF8C.js} +1 -1
- package/dist/assets/{react-plotly-cJZ0VWBq.js → react-plotly-CTwajqCb.js} +1 -1
- package/dist/assets/{requirementDiagram-4UW4RH46-DVRTjgas.js → requirementDiagram-4UW4RH46-DnjDAypr.js} +1 -1
- package/dist/assets/{run-page-BUEnMC9w.js → run-page-CQY9im22.js} +1 -1
- package/dist/assets/{sankeyDiagram-GR3RE2ED-CVFnD9C-.js → sankeyDiagram-GR3RE2ED-B67Va-ER.js} +1 -1
- package/dist/assets/{scratchpad-panel-BIgRENkI.js → scratchpad-panel-DlDfcDtW.js} +1 -1
- package/dist/assets/{secrets-panel-xY5-V_BD.js → secrets-panel-BDGyuGZA.js} +1 -1
- package/dist/assets/{sequenceDiagram-C3RYC4MD-_lY4ZN_S.js → sequenceDiagram-C3RYC4MD-DiWgZPtN.js} +1 -1
- package/dist/assets/{slides-component-DMjQomc3.css → slides-component-C-LoGC1U.css} +1 -1
- package/dist/assets/{slides-component-Xjymwj7X.js → slides-component-DhpPRtQp.js} +1 -1
- package/dist/assets/snippets-panel-CLkBXhJ2.js +1 -0
- package/dist/assets/sortBy-D4OG7w4O.js +1 -0
- package/dist/assets/{state-C4NiC9tO.js → state-Dz_3JyED.js} +1 -1
- package/dist/assets/{stateDiagram-KXAO66HF-Da0JQWCn.js → stateDiagram-KXAO66HF-ByF2AULw.js} +1 -1
- package/dist/assets/stateDiagram-v2-UMBNRL4Z-CtBJqosP.js +1 -0
- package/dist/assets/storage-Dr0CC44z.js +26 -0
- package/dist/assets/{terminal-BPwTkXae.js → terminal-BtdissBf.js} +1 -1
- package/dist/assets/{time-Dv5_Ouz_.js → time-DKdOTnQg.js} +1 -1
- package/dist/assets/{timeline-definition-XQNQX7LJ-Dxh5Zu2e.js → timeline-definition-XQNQX7LJ-DzER9bf6.js} +1 -1
- package/dist/assets/tracing-Dpx5M-u3.js +2 -0
- package/dist/assets/{tracing-panel-DAzrzNmm.js → tracing-panel-hCjBkSER.js} +2 -2
- package/dist/assets/{trash-Dc6DSjz_.js → trash-C6Ko-g5q.js} +1 -1
- package/dist/assets/{tree-jheoerAX.js → tree-BHN2gcCF.js} +6 -6
- package/dist/assets/{treemap-75Q7IDZK-IgpxeGaf.js → treemap-75Q7IDZK-DR79Mhzt.js} +27 -27
- package/dist/assets/variable-panel-PFBCFz36.js +1 -0
- package/dist/assets/{vega-component-BpfpiPKI.js → vega-component-Db6-uY4C.js} +1 -1
- package/dist/assets/worker-fHbtoWvT.js +1 -0
- package/dist/assets/{xychartDiagram-6GGTOJPD-CmNigJ31.js → xychartDiagram-6GGTOJPD-DWzBP3tZ.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +5 -4
- package/src/__mocks__/requests.ts +1 -0
- package/src/components/app-config/user-config-form.tsx +46 -1
- package/src/components/chat/acp/__tests__/__snapshots__/prompt.test.ts.snap +62 -43
- package/src/components/chat/acp/__tests__/atoms.test.ts +1 -1
- package/src/components/chat/acp/__tests__/state.test.ts +36 -36
- package/src/components/chat/acp/agent-panel.tsx +24 -27
- package/src/components/chat/acp/blocks.tsx +6 -6
- package/src/components/chat/acp/prompt.ts +62 -43
- package/src/components/chat/chat-panel.tsx +5 -1
- package/src/components/chat/markdown-renderer.tsx +6 -10
- package/src/components/chat/tool-call-accordion.tsx +52 -20
- package/src/components/data-table/SearchBar.tsx +8 -7
- package/src/components/data-table/__tests__/column_formatting.test.ts +50 -35
- package/src/components/data-table/__tests__/columns.test.tsx +38 -0
- package/src/components/data-table/__tests__/data-table.test.tsx +39 -1
- package/src/components/data-table/cell-hover-template/feature.ts +14 -0
- package/src/components/data-table/cell-hover-template/types.ts +11 -0
- package/src/components/data-table/charts/components/form-fields.tsx +41 -37
- package/src/components/data-table/charts/forms/common-chart.tsx +2 -2
- package/src/components/data-table/column-explorer-panel/column-explorer.tsx +5 -2
- package/src/components/data-table/column-formatting/feature.ts +62 -29
- package/src/components/data-table/column-formatting/types.ts +1 -0
- package/src/components/data-table/column-header.tsx +3 -1
- package/src/components/data-table/column-summary/chart-spec-model.tsx +24 -7
- package/src/components/data-table/column-summary/column-summary.tsx +18 -9
- package/src/components/data-table/columns.tsx +63 -20
- package/src/components/data-table/data-table.tsx +10 -2
- package/src/components/data-table/date-popover.tsx +85 -75
- package/src/components/data-table/filter-pills.tsx +14 -9
- package/src/components/data-table/header-items.tsx +5 -1
- package/src/components/data-table/pagination.tsx +20 -13
- package/src/components/data-table/renderers.tsx +36 -0
- package/src/components/data-table/row-viewer-panel/row-viewer.tsx +10 -8
- package/src/components/data-table/schemas.ts +16 -0
- package/src/components/datasources/column-preview.tsx +6 -2
- package/src/components/datasources/datasources.tsx +8 -12
- package/src/components/editor/Cell.tsx +2 -0
- package/src/components/editor/ai/transport/chat-transport.tsx +4 -1
- package/src/components/editor/cell/CellStatus.tsx +23 -20
- package/src/components/editor/cell/CreateCellButton.tsx +3 -4
- package/src/components/editor/cell/code/language-toggle.tsx +3 -4
- package/src/components/editor/chrome/wrapper/footer-items/machine-stats.tsx +39 -28
- package/src/components/editor/controls/notebook-menu-dropdown.tsx +4 -2
- package/src/components/editor/errors/sql-validation-errors.tsx +34 -0
- package/src/components/editor/file-tree/requesting-tree.tsx +14 -8
- package/src/components/editor/output/ConsoleOutput.tsx +13 -1
- package/src/components/editor/output/MarimoErrorOutput.tsx +60 -1
- package/src/components/editor/renderers/CellArray.tsx +3 -4
- package/src/components/editor/renderers/slides-layout/slides-layout.tsx +3 -3
- package/src/components/editor/renderers/slides-layout/types.ts +1 -0
- package/src/components/pages/home-page.tsx +4 -1
- package/src/components/slides/slides-component.tsx +1 -1
- package/src/components/slides/slides.css +6 -0
- package/src/components/terminal/theme.tsx +1 -0
- package/src/components/tracing/tracing-spec.ts +5 -4
- package/src/components/ui/range-slider.tsx +4 -2
- package/src/components/ui/slider.tsx +3 -1
- package/src/components/variables/variables-table.tsx +3 -0
- package/src/core/MarimoApp.tsx +9 -6
- package/src/core/ai/context/__tests__/registry.test.ts +6 -4
- package/src/core/ai/context/providers/cell-output.ts +4 -20
- package/src/core/ai/context/providers/error.ts +3 -1
- package/src/core/ai/context/providers/file.ts +7 -2
- package/src/core/ai/context/providers/tables.ts +3 -2
- package/src/core/ai/context/providers/variable.ts +6 -4
- package/src/core/ai/staged-cells.ts +34 -1
- package/src/core/cells/__tests__/add-missing-import.test.ts +67 -22
- package/src/core/cells/add-missing-import.ts +24 -7
- package/src/core/cells/cells.ts +26 -27
- package/src/core/cells/logs.ts +1 -1
- package/src/core/codemirror/find-replace/search-highlight.ts +3 -1
- package/src/core/codemirror/language/LanguageAdapters.ts +9 -3
- 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/languages/sql/sql-mode.ts +20 -0
- package/src/core/codemirror/language/languages/sql/sql.ts +90 -3
- package/src/core/codemirror/language/languages/sql/validation-errors.ts +79 -0
- package/src/core/codemirror/language/panel/panel.tsx +8 -2
- package/src/core/codemirror/language/panel/sql.tsx +81 -4
- package/src/core/codemirror/lsp/notebook-lsp.ts +8 -2
- package/src/core/codemirror/readonly/__tests__/extension.test.ts +1 -1
- package/src/core/codemirror/rtc/loro/awareness.ts +52 -17
- package/src/core/codemirror/rtc/loro/sync.ts +12 -4
- package/src/core/config/config-schema.ts +1 -0
- package/src/core/config/config.ts +4 -0
- package/src/core/config/feature-flag.tsx +3 -1
- package/src/core/datasets/request-registry.ts +17 -1
- package/src/core/hotkeys/hotkeys.ts +8 -4
- package/src/core/i18n/__tests__/locale-provider.test.tsx +176 -0
- package/src/core/i18n/locale-provider.tsx +35 -0
- package/src/core/i18n/with-locale.tsx +12 -0
- package/src/core/islands/bridge.ts +1 -0
- package/src/core/islands/components/web-components.tsx +13 -10
- package/src/core/islands/main.ts +1 -0
- package/src/core/kernel/RuntimeState.ts +4 -1
- package/src/core/kernel/messages.ts +3 -2
- package/src/core/network/DeferredRequestRegistry.ts +16 -4
- 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 +2 -0
- package/src/core/runtime/runtime.ts +5 -4
- package/src/core/wasm/bridge.ts +10 -1
- package/src/core/wasm/store.ts +4 -1
- package/src/core/wasm/worker/message-buffer.ts +3 -2
- package/src/core/websocket/types.ts +22 -16
- package/src/core/websocket/useMarimoWebSocket.tsx +4 -0
- package/src/hooks/useFormatting.ts +97 -0
- package/src/hooks/useTimer.ts +8 -5
- package/src/plugins/core/registerReactComponent.tsx +39 -29
- package/src/plugins/impl/DataTablePlugin.tsx +15 -4
- package/src/plugins/impl/RangeSliderPlugin.tsx +5 -3
- package/src/plugins/impl/SliderPlugin.tsx +3 -1
- package/src/plugins/impl/anywidget/model.ts +16 -5
- package/src/plugins/impl/data-editor/types.ts +7 -5
- package/src/plugins/impl/data-explorer/components/column-summary.tsx +20 -13
- package/src/plugins/impl/data-frames/DataFramePlugin.tsx +17 -5
- package/src/plugins/impl/panel/utils.ts +6 -4
- package/src/plugins/layout/OutlinePlugin.tsx +69 -0
- package/src/plugins/layout/StatPlugin.tsx +4 -1
- package/src/plugins/plugins.ts +2 -0
- package/src/stories/dataframe.stories.tsx +2 -0
- package/src/utils/__tests__/dates.test.ts +45 -24
- package/src/utils/__tests__/dom.test.ts +167 -0
- package/src/utils/__tests__/numbers.test.ts +42 -30
- package/src/utils/__tests__/once.test.ts +187 -0
- package/src/utils/dates.ts +15 -10
- package/src/utils/dom.ts +55 -0
- package/src/utils/edit-distance.ts +8 -6
- package/src/utils/errors.ts +1 -1
- package/src/utils/id-tree.tsx +21 -10
- package/src/utils/localStorage.ts +13 -4
- package/src/utils/numbers.ts +11 -11
- package/src/utils/once.ts +32 -0
- package/src/utils/paths.ts +4 -1
- package/src/utils/pluralize.ts +12 -5
- package/src/utils/python-poet/poet.ts +30 -15
- package/src/utils/time.ts +5 -1
- package/dist/assets/ConnectedDataExplorerComponent-BErMbWvG.js +0 -19
- package/dist/assets/_baseEach-CNBxBxvS.js +0 -1
- package/dist/assets/_baseMap-D1WHjKrd.js +0 -1
- package/dist/assets/channel-_2eNSz0n.js +0 -1
- package/dist/assets/chat-panel-CXh5Wl6C.js +0 -3
- package/dist/assets/classDiagram-KNZD7YFC-BGmh9POF.js +0 -1
- package/dist/assets/classDiagram-v2-RKCZMP56-BGmh9POF.js +0 -1
- package/dist/assets/clone-BFDSPAj3.js +0 -1
- package/dist/assets/command-palette-CXZiSv0I.js +0 -1
- package/dist/assets/datasources-panel-B7FbYLiy.js +0 -1
- package/dist/assets/edit-page-BrYda9VE.js +0 -129
- package/dist/assets/file-explorer-panel-Bw59Kva1.js +0 -1
- package/dist/assets/home-page-Fb2osjys.js +0 -9
- package/dist/assets/index-Cx0bsY1w.css +0 -1
- package/dist/assets/index-DKEudB02.js +0 -578
- package/dist/assets/infoDiagram-STP46IZ2-CVyrdLc8.js +0 -2
- package/dist/assets/links-D59GIweI.js +0 -7
- package/dist/assets/min-DUMu_zeK.js +0 -1
- package/dist/assets/outline-panel-DIzkvm2I.js +0 -1
- package/dist/assets/snippets-panel-CTPYW41n.js +0 -1
- package/dist/assets/sortBy-BNZKwiq_.js +0 -1
- package/dist/assets/stateDiagram-v2-UMBNRL4Z-D5lYZOOt.js +0 -1
- package/dist/assets/storage-CMdLzB_c.js +0 -26
- package/dist/assets/tracing-BCIurUfa.js +0 -2
- package/dist/assets/variable-panel-DYAiLBmF.js +0 -1
- package/dist/assets/worker-X5rxzQGQ.js +0 -1
|
@@ -93,6 +93,25 @@ export const DataTableBody = <TData,>({
|
|
|
93
93
|
handleCellsKeyDown,
|
|
94
94
|
} = useCellRangeSelection({ table });
|
|
95
95
|
|
|
96
|
+
function applyHoverTemplate(
|
|
97
|
+
template: string,
|
|
98
|
+
cells: Array<Cell<TData, unknown>>,
|
|
99
|
+
): string {
|
|
100
|
+
const variableRegex = /{{(\w+)}}/g;
|
|
101
|
+
// Map column id -> stringified value
|
|
102
|
+
const idToValue = new Map<string, string>();
|
|
103
|
+
for (const c of cells) {
|
|
104
|
+
const v = c.getValue();
|
|
105
|
+
// Prefer empty string for nulls to keep tooltip clean
|
|
106
|
+
const s = renderUnknownValue({ value: v, nullAsEmptyString: true });
|
|
107
|
+
idToValue.set(c.column.id, s);
|
|
108
|
+
}
|
|
109
|
+
return template.replaceAll(variableRegex, (_substr, varName: string) => {
|
|
110
|
+
const val = idToValue.get(varName);
|
|
111
|
+
return val === undefined ? `{{${varName}}}` : val;
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
96
115
|
const renderCells = (cells: Array<Cell<TData, unknown>>) => {
|
|
97
116
|
return cells.map((cell) => {
|
|
98
117
|
const { className, style: pinningstyle } = getPinningStyles(cell.column);
|
|
@@ -101,6 +120,7 @@ export const DataTableBody = <TData,>({
|
|
|
101
120
|
cell.getUserStyling?.() || {},
|
|
102
121
|
pinningstyle,
|
|
103
122
|
);
|
|
123
|
+
|
|
104
124
|
return (
|
|
105
125
|
<TableCell
|
|
106
126
|
tabIndex={0}
|
|
@@ -134,6 +154,8 @@ export const DataTableBody = <TData,>({
|
|
|
134
154
|
}
|
|
135
155
|
};
|
|
136
156
|
|
|
157
|
+
const hoverTemplate = table.getState().cellHoverTemplate || null;
|
|
158
|
+
|
|
137
159
|
return (
|
|
138
160
|
<TableBody onKeyDown={handleCellsKeyDown} ref={tableRef}>
|
|
139
161
|
{table.getRowModel().rows?.length ? (
|
|
@@ -145,10 +167,24 @@ export const DataTableBody = <TData,>({
|
|
|
145
167
|
const isRowViewedInPanel =
|
|
146
168
|
rowViewerPanelOpen && viewedRowIdx === rowIndex;
|
|
147
169
|
|
|
170
|
+
// Compute hover title once per row using all visible cells
|
|
171
|
+
let rowTitle: string | undefined;
|
|
172
|
+
if (hoverTemplate) {
|
|
173
|
+
const visibleCells = row.getVisibleCells?.() ?? [
|
|
174
|
+
...row.getLeftVisibleCells(),
|
|
175
|
+
...row.getCenterVisibleCells(),
|
|
176
|
+
...row.getRightVisibleCells(),
|
|
177
|
+
];
|
|
178
|
+
rowTitle = hoverTemplate
|
|
179
|
+
? applyHoverTemplate(hoverTemplate, visibleCells)
|
|
180
|
+
: undefined;
|
|
181
|
+
}
|
|
182
|
+
|
|
148
183
|
return (
|
|
149
184
|
<TableRow
|
|
150
185
|
key={row.id}
|
|
151
186
|
data-state={row.getIsSelected() && "selected"}
|
|
187
|
+
title={rowTitle}
|
|
152
188
|
// These classes ensure that empty rows (nulls) still render
|
|
153
189
|
className={cn(
|
|
154
190
|
"border-t h-6",
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
SearchIcon,
|
|
16
16
|
} from "lucide-react";
|
|
17
17
|
import { useRef, useState } from "react";
|
|
18
|
+
import { useLocale } from "react-aria";
|
|
18
19
|
import { ColumnName } from "@/components/datasources/components";
|
|
19
20
|
import { CopyClipboardIcon } from "@/components/icons/copy-icon";
|
|
20
21
|
import { KeyboardHotkeys } from "@/components/shortcuts/renderShortcut";
|
|
@@ -66,6 +67,7 @@ export const RowViewerPanel: React.FC<RowViewerPanelProps> = ({
|
|
|
66
67
|
const [searchQuery, setSearchQuery] = useState("");
|
|
67
68
|
const panelRef = useRef<HTMLDivElement>(null);
|
|
68
69
|
const searchInputRef = useRef<HTMLInputElement>(null);
|
|
70
|
+
const { locale } = useLocale();
|
|
69
71
|
|
|
70
72
|
const tooManyRows = totalRows === TOO_MANY_ROWS;
|
|
71
73
|
|
|
@@ -204,13 +206,13 @@ export const RowViewerPanel: React.FC<RowViewerPanelProps> = ({
|
|
|
204
206
|
applyColumnFormatting: (value) => value,
|
|
205
207
|
} as Column<unknown>;
|
|
206
208
|
|
|
207
|
-
const cellContent = renderCellValue(
|
|
208
|
-
mockColumn,
|
|
209
|
-
() => columnValue,
|
|
210
|
-
() => columnValue,
|
|
211
|
-
undefined,
|
|
212
|
-
"text-left break-word",
|
|
213
|
-
);
|
|
209
|
+
const cellContent = renderCellValue({
|
|
210
|
+
column: mockColumn,
|
|
211
|
+
renderValue: () => columnValue,
|
|
212
|
+
getValue: () => columnValue,
|
|
213
|
+
selectCell: undefined,
|
|
214
|
+
cellStyles: "text-left break-word",
|
|
215
|
+
});
|
|
214
216
|
|
|
215
217
|
const copyValue =
|
|
216
218
|
typeof columnValue === "object"
|
|
@@ -286,7 +288,7 @@ export const RowViewerPanel: React.FC<RowViewerPanelProps> = ({
|
|
|
286
288
|
<span className="text-xs">
|
|
287
289
|
{tooManyRows
|
|
288
290
|
? `Row ${rowIdx + 1}`
|
|
289
|
-
: `Row ${rowIdx + 1} of ${prettifyRowCount(totalRows)}`}
|
|
291
|
+
: `Row ${rowIdx + 1} of ${prettifyRowCount(totalRows, locale)}`}
|
|
290
292
|
</span>
|
|
291
293
|
<Button
|
|
292
294
|
variant="outline"
|
|
@@ -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());
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { useAtomValue } from "jotai";
|
|
4
4
|
import { PlusSquareIcon } from "lucide-react";
|
|
5
5
|
import React, { Suspense } from "react";
|
|
6
|
+
import { useLocale } from "react-aria";
|
|
6
7
|
import { maybeAddAltairImport } from "@/core/cells/add-missing-import";
|
|
7
8
|
import { useCellActions } from "@/core/cells/cells";
|
|
8
9
|
import { useLastFocusedCellId } from "@/core/cells/focus";
|
|
@@ -42,6 +43,7 @@ export const DatasetColumnPreview: React.FC<{
|
|
|
42
43
|
}> = ({ table, column, preview, onAddColumnChart, sqlTableContext }) => {
|
|
43
44
|
const { theme } = useTheme();
|
|
44
45
|
const { previewDatasetColumn } = useRequestClient();
|
|
46
|
+
const { locale } = useLocale();
|
|
45
47
|
|
|
46
48
|
const previewColumn = () => {
|
|
47
49
|
previewDatasetColumn({
|
|
@@ -107,7 +109,8 @@ export const DatasetColumnPreview: React.FC<{
|
|
|
107
109
|
refetchPreview: previewColumn,
|
|
108
110
|
});
|
|
109
111
|
|
|
110
|
-
const stats =
|
|
112
|
+
const stats =
|
|
113
|
+
preview.stats && renderStats(preview.stats, column.type, locale);
|
|
111
114
|
|
|
112
115
|
const chart = preview.chart_spec && renderChart(preview.chart_spec, theme);
|
|
113
116
|
|
|
@@ -175,6 +178,7 @@ export function renderPreviewError({
|
|
|
175
178
|
export function renderStats(
|
|
176
179
|
stats: Partial<Record<ColumnHeaderStatsKey, unknown>>,
|
|
177
180
|
dataType: DataType,
|
|
181
|
+
locale: string,
|
|
178
182
|
) {
|
|
179
183
|
return (
|
|
180
184
|
<div className="gap-x-16 gap-y-1 grid grid-cols-2-fit border rounded p-2 empty:hidden">
|
|
@@ -189,7 +193,7 @@ export function renderStats(
|
|
|
189
193
|
{convertStatsName(key as ColumnHeaderStatsKey, dataType)}
|
|
190
194
|
</span>
|
|
191
195
|
<span className="text-xs font-bold text-muted-foreground tracking-wide">
|
|
192
|
-
{prettyNumber(value)}
|
|
196
|
+
{prettyNumber(value, locale)}
|
|
193
197
|
</span>
|
|
194
198
|
<CopyClipboardIcon
|
|
195
199
|
className="h-3 w-3 invisible group-hover:visible"
|
|
@@ -304,10 +304,12 @@ const DatabaseItem: React.FC<{
|
|
|
304
304
|
}> = ({ hasSearch, engineName, database, children }) => {
|
|
305
305
|
const [isExpanded, setIsExpanded] = React.useState(false);
|
|
306
306
|
const [isSelected, setIsSelected] = React.useState(false);
|
|
307
|
+
const [prevHasSearch, setPrevHasSearch] = React.useState(hasSearch);
|
|
307
308
|
|
|
308
|
-
|
|
309
|
+
if (prevHasSearch !== hasSearch) {
|
|
310
|
+
setPrevHasSearch(hasSearch);
|
|
309
311
|
setIsExpanded(hasSearch);
|
|
310
|
-
}
|
|
312
|
+
}
|
|
311
313
|
|
|
312
314
|
return (
|
|
313
315
|
<>
|
|
@@ -399,14 +401,10 @@ const SchemaItem: React.FC<{
|
|
|
399
401
|
children: React.ReactNode;
|
|
400
402
|
hasSearch: boolean;
|
|
401
403
|
}> = ({ databaseName, schema, children, hasSearch }) => {
|
|
402
|
-
const [isExpanded, setIsExpanded] = React.useState(
|
|
404
|
+
const [isExpanded, setIsExpanded] = React.useState(hasSearch);
|
|
403
405
|
const [isSelected, setIsSelected] = React.useState(false);
|
|
404
406
|
const uniqueValue = `${databaseName}:${schema.name}`;
|
|
405
407
|
|
|
406
|
-
React.useEffect(() => {
|
|
407
|
-
setIsExpanded(hasSearch);
|
|
408
|
-
}, [hasSearch]);
|
|
409
|
-
|
|
410
408
|
if (isSchemaless(schema.name)) {
|
|
411
409
|
return children;
|
|
412
410
|
}
|
|
@@ -693,11 +691,9 @@ const DatasetColumnItem: React.FC<{
|
|
|
693
691
|
const closeAllColumns = useAtomValue(closeAllColumnsAtom);
|
|
694
692
|
const setExpandedColumns = useSetAtom(expandedColumnsAtom);
|
|
695
693
|
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
}
|
|
700
|
-
}, [closeAllColumns]);
|
|
694
|
+
if (closeAllColumns && isExpanded) {
|
|
695
|
+
setIsExpanded(false);
|
|
696
|
+
}
|
|
701
697
|
|
|
702
698
|
if (isExpanded) {
|
|
703
699
|
setExpandedColumns(
|
|
@@ -80,6 +80,7 @@ import { useDeleteCellCallback } from "./cell/useDeleteCell";
|
|
|
80
80
|
import { useRunCell } from "./cell/useRunCells";
|
|
81
81
|
import { HideCodeButton } from "./code/readonly-python-code";
|
|
82
82
|
import { cellDomProps } from "./common";
|
|
83
|
+
import { SqlValidationErrorBanner } from "./errors/sql-validation-errors";
|
|
83
84
|
import { useCellNavigationProps } from "./navigation/navigation";
|
|
84
85
|
import {
|
|
85
86
|
useTemporarilyShownCode,
|
|
@@ -653,6 +654,7 @@ const EditableCellComponent = ({
|
|
|
653
654
|
)}
|
|
654
655
|
</div>
|
|
655
656
|
</div>
|
|
657
|
+
<SqlValidationErrorBanner cellId={cellId} />
|
|
656
658
|
{cellOutput === "below" && outputArea}
|
|
657
659
|
{cellRuntime.serialization && (
|
|
658
660
|
<div className="py-1 px-2 flex items-center justify-end gap-2 last:rounded-b">
|
|
@@ -13,11 +13,14 @@ import {
|
|
|
13
13
|
export class StreamingChunkTransport<
|
|
14
14
|
UI_MESSAGE extends UIMessage,
|
|
15
15
|
> extends DefaultChatTransport<UI_MESSAGE> {
|
|
16
|
+
private onChunkReceived: (chunk: UIMessageChunk) => void;
|
|
17
|
+
|
|
16
18
|
constructor(
|
|
17
19
|
options: HttpChatTransportInitOptions<UI_MESSAGE> = {},
|
|
18
|
-
|
|
20
|
+
onChunkReceived: (chunk: UIMessageChunk) => void,
|
|
19
21
|
) {
|
|
20
22
|
super(options);
|
|
23
|
+
this.onChunkReceived = onChunkReceived;
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
protected override processResponseStream(
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
RefreshCwIcon,
|
|
6
6
|
WorkflowIcon,
|
|
7
7
|
} from "lucide-react";
|
|
8
|
+
import { useDateFormatter } from "react-aria";
|
|
8
9
|
import { MultiIcon } from "@/components/icons/multi-icon";
|
|
9
10
|
import { Logger } from "@/utils/Logger";
|
|
10
11
|
import type { CellRuntimeState } from "../../../core/cells/types";
|
|
@@ -28,26 +29,6 @@ export interface CellStatusComponentProps
|
|
|
28
29
|
uninstantiated: boolean;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
// Looks like HH:MM:SS.SSS AM/PM
|
|
32
|
-
const timeFormatter = new Intl.DateTimeFormat("en-US", {
|
|
33
|
-
hour: "numeric",
|
|
34
|
-
minute: "numeric",
|
|
35
|
-
second: "numeric",
|
|
36
|
-
fractionalSecondDigits: 3,
|
|
37
|
-
hour12: true,
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
// Looks like MM/DD HH:MM:SS.SSS AM/PM
|
|
41
|
-
const dateTimeFormatter = new Intl.DateTimeFormat("en-US", {
|
|
42
|
-
month: "numeric",
|
|
43
|
-
day: "numeric",
|
|
44
|
-
hour: "numeric",
|
|
45
|
-
minute: "numeric",
|
|
46
|
-
second: "numeric",
|
|
47
|
-
fractionalSecondDigits: 3,
|
|
48
|
-
hour12: true,
|
|
49
|
-
});
|
|
50
|
-
|
|
51
32
|
export const CellStatusComponent: React.FC<CellStatusComponentProps> = ({
|
|
52
33
|
editing,
|
|
53
34
|
status,
|
|
@@ -329,10 +310,32 @@ export const ElapsedTime = (props: { elapsedTime: string }) => {
|
|
|
329
310
|
const LastRanTime = (props: { lastRanTime: number }) => {
|
|
330
311
|
const date = new Date(props.lastRanTime * 1000);
|
|
331
312
|
const today = new Date();
|
|
313
|
+
|
|
314
|
+
// Looks like HH:MM:SS.SSS AM/PM
|
|
315
|
+
const timeFormatter = useDateFormatter({
|
|
316
|
+
hour: "numeric",
|
|
317
|
+
minute: "numeric",
|
|
318
|
+
second: "numeric",
|
|
319
|
+
fractionalSecondDigits: 3,
|
|
320
|
+
hour12: true,
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
// Looks like MM/DD HH:MM:SS.SSS AM/PM
|
|
324
|
+
const dateTimeFormatter = useDateFormatter({
|
|
325
|
+
month: "numeric",
|
|
326
|
+
day: "numeric",
|
|
327
|
+
hour: "numeric",
|
|
328
|
+
minute: "numeric",
|
|
329
|
+
second: "numeric",
|
|
330
|
+
fractionalSecondDigits: 3,
|
|
331
|
+
hour12: true,
|
|
332
|
+
});
|
|
333
|
+
|
|
332
334
|
const formatter =
|
|
333
335
|
date.toDateString() === today.toDateString()
|
|
334
336
|
? timeFormatter
|
|
335
337
|
: dateTimeFormatter;
|
|
338
|
+
|
|
336
339
|
return (
|
|
337
340
|
<span>
|
|
338
341
|
Ran at{" "}
|
|
@@ -9,8 +9,7 @@ import {
|
|
|
9
9
|
} from "@/components/ui/context-menu";
|
|
10
10
|
import { maybeAddMarimoImport } from "@/core/cells/add-missing-import";
|
|
11
11
|
import { useCellActions } from "@/core/cells/cells";
|
|
12
|
-
import {
|
|
13
|
-
import { SQLLanguageAdapter } from "@/core/codemirror/language/languages/sql/sql";
|
|
12
|
+
import { LanguageAdapters } from "@/core/codemirror/language/LanguageAdapters";
|
|
14
13
|
import {
|
|
15
14
|
getConnectionTooltip,
|
|
16
15
|
isAppInteractionDisabled,
|
|
@@ -103,7 +102,7 @@ const CreateCellButtonContextMenu = (props: {
|
|
|
103
102
|
evt.stopPropagation();
|
|
104
103
|
maybeAddMarimoImport({ autoInstantiate: true, createNewCell });
|
|
105
104
|
onClick({
|
|
106
|
-
code:
|
|
105
|
+
code: LanguageAdapters.markdown.defaultCode,
|
|
107
106
|
hideCode: true,
|
|
108
107
|
});
|
|
109
108
|
}}
|
|
@@ -118,7 +117,7 @@ const CreateCellButtonContextMenu = (props: {
|
|
|
118
117
|
onSelect={(evt) => {
|
|
119
118
|
evt.stopPropagation();
|
|
120
119
|
maybeAddMarimoImport({ autoInstantiate: true, createNewCell });
|
|
121
|
-
onClick({ code:
|
|
120
|
+
onClick({ code: LanguageAdapters.sql.defaultCode });
|
|
122
121
|
}}
|
|
123
122
|
>
|
|
124
123
|
<div className="mr-3 text-muted-foreground">
|
|
@@ -7,8 +7,7 @@ import { useMemo } from "react";
|
|
|
7
7
|
import { Button } from "@/components/ui/button";
|
|
8
8
|
import { Tooltip } from "@/components/ui/tooltip";
|
|
9
9
|
import { switchLanguage } from "@/core/codemirror/language/extension";
|
|
10
|
-
import {
|
|
11
|
-
import { SQLLanguageAdapter } from "@/core/codemirror/language/languages/sql/sql";
|
|
10
|
+
import { LanguageAdapters } from "@/core/codemirror/language/LanguageAdapters";
|
|
12
11
|
import type { LanguageAdapter } from "@/core/codemirror/language/types";
|
|
13
12
|
import { Functions } from "@/utils/functions";
|
|
14
13
|
import { MarkdownIcon, PythonIcon } from "./icons";
|
|
@@ -27,11 +26,11 @@ export const LanguageToggles: React.FC<LanguageTogglesProps> = ({
|
|
|
27
26
|
onAfterToggle,
|
|
28
27
|
}) => {
|
|
29
28
|
const canUseMarkdown = useMemo(
|
|
30
|
-
() =>
|
|
29
|
+
() => LanguageAdapters.markdown.isSupported(code) || code.trim() === "",
|
|
31
30
|
[code],
|
|
32
31
|
);
|
|
33
32
|
const canUseSQL = useMemo(
|
|
34
|
-
() =>
|
|
33
|
+
() => LanguageAdapters.sql.isSupported(code) || code.trim() === "",
|
|
35
34
|
[code],
|
|
36
35
|
);
|
|
37
36
|
|
|
@@ -4,6 +4,7 @@ import { useAtomValue } from "jotai";
|
|
|
4
4
|
import { CpuIcon, MemoryStickIcon, MicrochipIcon } from "lucide-react";
|
|
5
5
|
import type React from "react";
|
|
6
6
|
import { useState } from "react";
|
|
7
|
+
import { useNumberFormatter } from "react-aria";
|
|
7
8
|
import { Tooltip } from "@/components/ui/tooltip";
|
|
8
9
|
import { connectionAtom } from "@/core/network/connection";
|
|
9
10
|
import { useRequestClient } from "@/core/network/requests";
|
|
@@ -56,23 +57,42 @@ const MemoryUsageBar: React.FC<{
|
|
|
56
57
|
}> = ({ memory, kernel, server }) => {
|
|
57
58
|
const { percent, total, available } = memory;
|
|
58
59
|
const roundedPercent = Math.round(percent);
|
|
60
|
+
|
|
61
|
+
const gbFormatter = useNumberFormatter({
|
|
62
|
+
maximumFractionDigits: 2,
|
|
63
|
+
});
|
|
64
|
+
const mbFormatter = useNumberFormatter({
|
|
65
|
+
maximumFractionDigits: 0,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const formatBytes = (bytes: number): string => {
|
|
69
|
+
if (bytes > 1024 * 1024 * 1024) {
|
|
70
|
+
return `${gbFormatter.format(bytes / (1024 * 1024 * 1024))} GB`;
|
|
71
|
+
}
|
|
72
|
+
return `${mbFormatter.format(bytes / (1024 * 1024))} MB`;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const formatGB = (bytes: number): string => {
|
|
76
|
+
return gbFormatter.format(bytes / (1024 * 1024 * 1024));
|
|
77
|
+
};
|
|
78
|
+
|
|
59
79
|
return (
|
|
60
80
|
<Tooltip
|
|
61
81
|
delayDuration={200}
|
|
62
82
|
content={
|
|
63
83
|
<div className="flex flex-col gap-1">
|
|
64
84
|
<span>
|
|
65
|
-
<b>computer memory:</b> {
|
|
66
|
-
({roundedPercent}%)
|
|
85
|
+
<b>computer memory:</b> {formatGB(total - available)} /{" "}
|
|
86
|
+
{formatGB(total)} GB ({roundedPercent}%)
|
|
67
87
|
</span>
|
|
68
88
|
{server?.memory && (
|
|
69
89
|
<span>
|
|
70
|
-
<b>marimo server:</b> {
|
|
90
|
+
<b>marimo server:</b> {formatBytes(server.memory)}
|
|
71
91
|
</span>
|
|
72
92
|
)}
|
|
73
93
|
{kernel?.memory && (
|
|
74
94
|
<span>
|
|
75
|
-
<b>kernel:</b> {
|
|
95
|
+
<b>kernel:</b> {formatBytes(kernel.memory)}
|
|
76
96
|
</span>
|
|
77
97
|
)}
|
|
78
98
|
</div>
|
|
@@ -122,6 +142,20 @@ const GPUBar: React.FC<{ gpus: GPU[] }> = ({ gpus }) => {
|
|
|
122
142
|
gpus.length,
|
|
123
143
|
);
|
|
124
144
|
|
|
145
|
+
const gbFormatter = useNumberFormatter({
|
|
146
|
+
maximumFractionDigits: 2,
|
|
147
|
+
});
|
|
148
|
+
const mbFormatter = useNumberFormatter({
|
|
149
|
+
maximumFractionDigits: 0,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
const formatBytes = (bytes: number): string => {
|
|
153
|
+
if (bytes > 1024 * 1024 * 1024) {
|
|
154
|
+
return `${gbFormatter.format(bytes / (1024 * 1024 * 1024))} GB`;
|
|
155
|
+
}
|
|
156
|
+
return `${mbFormatter.format(bytes / (1024 * 1024))} MB`;
|
|
157
|
+
};
|
|
158
|
+
|
|
125
159
|
return (
|
|
126
160
|
<Tooltip
|
|
127
161
|
delayDuration={200}
|
|
@@ -132,7 +166,7 @@ const GPUBar: React.FC<{ gpus: GPU[] }> = ({ gpus }) => {
|
|
|
132
166
|
<b>
|
|
133
167
|
GPU {gpu.index} ({gpu.name}):
|
|
134
168
|
</b>{" "}
|
|
135
|
-
{
|
|
169
|
+
{formatBytes(gpu.memory.used)} / {formatBytes(gpu.memory.total)} (
|
|
136
170
|
{Math.round(gpu.memory.percent)}%)
|
|
137
171
|
</span>
|
|
138
172
|
))}
|
|
@@ -160,26 +194,3 @@ const Bar: React.FC<{ percent: number; colorClassName?: string }> = ({
|
|
|
160
194
|
</div>
|
|
161
195
|
);
|
|
162
196
|
};
|
|
163
|
-
|
|
164
|
-
function asGBorMB(bytes: number): string {
|
|
165
|
-
if (bytes > 1024 * 1024 * 1024) {
|
|
166
|
-
return `${asGB(bytes)} GB`;
|
|
167
|
-
}
|
|
168
|
-
return `${asMB(bytes)} MB`;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
function asMB(bytes: number) {
|
|
172
|
-
// 0 decimal places
|
|
173
|
-
const format = new Intl.NumberFormat("en-US", {
|
|
174
|
-
maximumFractionDigits: 0,
|
|
175
|
-
});
|
|
176
|
-
return format.format(bytes / (1024 * 1024));
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function asGB(bytes: number) {
|
|
180
|
-
// At most 2 decimal places
|
|
181
|
-
const format = new Intl.NumberFormat("en-US", {
|
|
182
|
-
maximumFractionDigits: 2,
|
|
183
|
-
});
|
|
184
|
-
return format.format(bytes / (1024 * 1024 * 1024));
|
|
185
|
-
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { MenuIcon } from "lucide-react";
|
|
4
4
|
import React from "react";
|
|
5
|
+
import { useLocale } from "react-aria";
|
|
5
6
|
import { Button } from "@/components/editor/inputs/Inputs";
|
|
6
7
|
import {
|
|
7
8
|
DropdownMenu,
|
|
@@ -33,7 +34,7 @@ export const NotebookMenuDropdown: React.FC<Props> = ({
|
|
|
33
34
|
tooltip = "Actions",
|
|
34
35
|
}) => {
|
|
35
36
|
const actions = useNotebookActions();
|
|
36
|
-
|
|
37
|
+
const { locale } = useLocale();
|
|
37
38
|
// Create tooltip content with keyboard shortcut decoration
|
|
38
39
|
const tooltipContent = (
|
|
39
40
|
<div className="flex flex-col gap-2">
|
|
@@ -148,7 +149,8 @@ export const NotebookMenuDropdown: React.FC<Props> = ({
|
|
|
148
149
|
);
|
|
149
150
|
})}
|
|
150
151
|
<DropdownMenuSeparator />
|
|
151
|
-
<div className="flex-1 px-2 text-xs text-muted-foreground">
|
|
152
|
+
<div className="flex-1 px-2 text-xs text-muted-foreground flex flex-col gap-1">
|
|
153
|
+
<span>Locale: {locale}</span>
|
|
152
154
|
<span>Version: {getMarimoVersion()}</span>
|
|
153
155
|
</div>
|
|
154
156
|
</DropdownMenuContent>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/* Copyright 2024 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { AlertCircleIcon } from "lucide-react";
|
|
4
|
+
import type { CellId } from "@/core/cells/ids";
|
|
5
|
+
import { useSqlValidationErrorsForCell } from "@/core/codemirror/language/languages/sql/validation-errors";
|
|
6
|
+
|
|
7
|
+
export const SqlValidationErrorBanner = ({ cellId }: { cellId: CellId }) => {
|
|
8
|
+
const error = useSqlValidationErrorsForCell(cellId);
|
|
9
|
+
|
|
10
|
+
if (!error) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<div className="p-3 text-sm flex flex-col text-muted-foreground gap-1.5 bg-destructive/5">
|
|
16
|
+
<div className="flex items-start gap-1.5">
|
|
17
|
+
<AlertCircleIcon size={13} className="mt-[3px] text-destructive" />
|
|
18
|
+
<p>
|
|
19
|
+
<span className="font-bold text-destructive">{error.errorType}:</span>{" "}
|
|
20
|
+
{error.errorMessage}
|
|
21
|
+
</p>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
{error.codeblock && (
|
|
25
|
+
<pre
|
|
26
|
+
lang="sql"
|
|
27
|
+
className="text-xs bg-muted rounded p-2 pb-0 mx-3 overflow-x-auto font-mono whitespace-pre-wrap"
|
|
28
|
+
>
|
|
29
|
+
{error.codeblock}
|
|
30
|
+
</pre>
|
|
31
|
+
)}
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
34
|
+
};
|
|
@@ -13,15 +13,21 @@ import { type FilePath, PathBuilder } from "@/utils/paths";
|
|
|
13
13
|
|
|
14
14
|
export class RequestingTree {
|
|
15
15
|
private delegate = new SimpleTree<FileInfo>([]);
|
|
16
|
+
private callbacks: {
|
|
17
|
+
listFiles: EditRequests["sendListFiles"];
|
|
18
|
+
createFileOrFolder: EditRequests["sendCreateFileOrFolder"];
|
|
19
|
+
deleteFileOrFolder: EditRequests["sendDeleteFileOrFolder"];
|
|
20
|
+
renameFileOrFolder: EditRequests["sendRenameFileOrFolder"];
|
|
21
|
+
};
|
|
16
22
|
|
|
17
|
-
constructor(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
constructor(callbacks: {
|
|
24
|
+
listFiles: EditRequests["sendListFiles"];
|
|
25
|
+
createFileOrFolder: EditRequests["sendCreateFileOrFolder"];
|
|
26
|
+
deleteFileOrFolder: EditRequests["sendDeleteFileOrFolder"];
|
|
27
|
+
renameFileOrFolder: EditRequests["sendRenameFileOrFolder"];
|
|
28
|
+
}) {
|
|
29
|
+
this.callbacks = callbacks;
|
|
30
|
+
}
|
|
25
31
|
|
|
26
32
|
private rootPath: FilePath = "" as FilePath;
|
|
27
33
|
private onChange: (data: FileInfo[]) => void = Functions.NOOP;
|
|
@@ -14,6 +14,7 @@ import type { OutputMessage } from "@/core/kernel/messages";
|
|
|
14
14
|
import { useSelectAllContent } from "@/hooks/useSelectAllContent";
|
|
15
15
|
import { cn } from "@/utils/cn";
|
|
16
16
|
import { copyToClipboard } from "@/utils/copy";
|
|
17
|
+
import { ansiToPlainText, parseHtmlContent } from "@/utils/dom";
|
|
17
18
|
import { invariant } from "@/utils/invariant";
|
|
18
19
|
import { Strings } from "@/utils/strings";
|
|
19
20
|
import { NameCellContentEditable } from "../actions/name-cell-input";
|
|
@@ -124,7 +125,18 @@ const ConsoleOutputInternal = (props: Props): React.ReactNode => {
|
|
|
124
125
|
onClick={() => {
|
|
125
126
|
const text = reversedOutputs
|
|
126
127
|
.filter((output) => output.channel !== "pdb")
|
|
127
|
-
.map((output) =>
|
|
128
|
+
.map((output) => {
|
|
129
|
+
// If starts with `<`, then assume it's HTML
|
|
130
|
+
if (
|
|
131
|
+
typeof output.data === "string" &&
|
|
132
|
+
output.data.startsWith("<")
|
|
133
|
+
) {
|
|
134
|
+
return parseHtmlContent(output.data);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Otherwise, convert the ANSI to HTML, then parse as HTML
|
|
138
|
+
return ansiToPlainText(Strings.asString(output.data));
|
|
139
|
+
})
|
|
128
140
|
.join("\n");
|
|
129
141
|
void copyToClipboard(text);
|
|
130
142
|
}}
|