@marimo-team/frontend 0.22.1-dev2 → 0.22.1-dev21
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-BhOfvmd2.js → ConnectedDataExplorerComponent-Bgd8MpO7.js} +1 -1
- package/dist/assets/{JsonOutput-DK6QFpxq.js → JsonOutput-CYRewW_n.js} +10 -10
- package/dist/assets/{add-cell-with-ai-C9CXMDL-.js → add-cell-with-ai-CJL5NwHh.js} +24 -24
- package/dist/assets/{add-connection-dialog-uUw1BwGd.js → add-connection-dialog-_oI2JBU2.js} +1 -1
- package/dist/assets/{agent-panel-CKXYOD10.js → agent-panel-frCoZBMf.js} +1 -1
- package/dist/assets/ai-model-dropdown-CMj49xMg.js +5 -0
- package/dist/assets/{app-config-button-B4_Fzop6.js → app-config-button-DCVf5Azv.js} +1 -1
- package/dist/assets/{cell-editor-DsXpgc4r.js → cell-editor-nJeqD5Xq.js} +1 -1
- package/dist/assets/{chat-display-CRKEYeok.js → chat-display-DnlV-Vjp.js} +1 -1
- package/dist/assets/chat-panel-BrH9Bycd.js +3 -0
- package/dist/assets/{chat-ui-CQB2SbzK.js → chat-ui-gEEIyfNV.js} +1 -1
- package/dist/assets/{column-preview-CWOsM3UD.js → column-preview-PiH54hAW.js} +1 -1
- package/dist/assets/{command-palette-BXM1GCVc.js → command-palette-CrC7ohqO.js} +1 -1
- package/dist/assets/{edit-page-BXQVe56n.js → edit-page-idaINdSX.js} +7 -7
- package/dist/assets/{file-explorer-panel-QFaPxpp8.js → file-explorer-panel-sS4HTA69.js} +1 -1
- package/dist/assets/{form-CoRP5wCe.js → form-B-BLUzr3.js} +1 -1
- package/dist/assets/{formats-C_TavbEL.js → formats-N7VZhahg.js} +1 -1
- package/dist/assets/{home-page-GHJ3-S70.js → home-page-Lm5CjxXF.js} +1 -1
- package/dist/assets/{hooks-CfqzfU-0.js → hooks-ChIFqb9W.js} +1 -1
- package/dist/assets/index-CCazW2UV.css +2 -0
- package/dist/assets/index-eeNpwqOH.js +35 -0
- package/dist/assets/{layout-FSEZfgnG.js → layout-BlYB96ph.js} +1 -1
- package/dist/assets/{markdown-renderer-wLZT8no0.js → markdown-renderer-CYb9pckL.js} +1 -1
- package/dist/assets/{packages-panel-CwbHm9uC.js → packages-panel-C7RTPIUf.js} +1 -1
- package/dist/assets/{panels-BhaV1xQQ.js → panels-qPMPLlzN.js} +1 -1
- package/dist/assets/{run-page-BtSGYy1m.js → run-page-Cqmrl9SW.js} +1 -1
- package/dist/assets/{scratchpad-panel-riBRfLg4.js → scratchpad-panel-Ddw1KV8R.js} +1 -1
- package/dist/assets/{session-panel-B2ux2cYO.js → session-panel-DTp3QX73.js} +1 -1
- package/dist/assets/{state-LRco7VGF.js → state-Nag9RDED.js} +1 -1
- package/dist/assets/{useNotebookActions-C2iPqhjB.js → useNotebookActions-CG6L_-9T.js} +1 -1
- package/dist/assets/{utils-BDlGlVyF.js → utils-DWFl4LEP.js} +3 -3
- package/dist/assets/{vega-component-DiFt6ZG4.js → vega-component-BAuy1PqH.js} +1 -1
- package/dist/index.html +9 -9
- package/package.json +1 -1
- package/src/__tests__/branded.ts +6 -0
- package/src/components/chat/chat-panel.tsx +2 -1
- package/src/components/data-table/TableBottomBar.tsx +12 -1
- package/src/components/data-table/TableTopBar.tsx +31 -35
- package/src/components/data-table/charts/charts.tsx +40 -11
- package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
- package/src/components/data-table/data-table.tsx +6 -1
- package/src/components/data-table/loading-table.tsx +4 -1
- package/src/components/data-table/range-focus/cell-selection-stats.tsx +3 -1
- package/src/components/data-table/row-viewer-panel/row-viewer.tsx +1 -1
- package/src/components/data-table/table-explorer-panel/table-explorer-panel.tsx +2 -2
- package/src/components/editor/ai/add-cell-with-ai.tsx +2 -1
- package/src/components/editor/chrome/panels/context-aware-panel/context-aware-panel.tsx +1 -1
- package/src/components/editor/chrome/wrapper/footer-items/lsp-status.tsx +2 -1
- package/src/core/cells/__tests__/apply-transaction.test.ts +12 -11
- package/src/core/cells/document-changes.ts +9 -9
- package/src/core/codemirror/copilot/__tests__/transport.test.ts +128 -2
- package/src/core/codemirror/copilot/client.ts +9 -2
- package/src/core/codemirror/copilot/language-server.ts +11 -0
- package/src/core/codemirror/copilot/transport.ts +32 -6
- package/src/core/islands/__tests__/bridge.test.ts +20 -10
- package/src/core/network/__tests__/requests-lazy.test.ts +30 -14
- package/src/core/websocket/useMarimoKernelConnection.tsx +5 -11
- package/src/core/websocket/useWebSocket.tsx +3 -1
- package/src/css/app/Cell.css +22 -1
- package/src/css/table.css +17 -0
- package/src/plugins/impl/DataTablePlugin.tsx +1 -0
- package/src/plugins/impl/anywidget/AnyWidgetPlugin.tsx +2 -11
- package/src/plugins/impl/vega/__tests__/utils.test.ts +68 -0
- package/src/plugins/impl/vega/utils.ts +14 -5
- package/src/plugins/impl/vega/vega.css +2 -1
- package/src/utils/json/base64.ts +2 -5
- package/src/utils/time.ts +4 -2
- package/src/utils/typed.ts +2 -2
- package/dist/assets/ai-model-dropdown-Ck6NNlZH.js +0 -5
- package/dist/assets/chat-panel-CYkuZYzq.js +0 -3
- package/dist/assets/index-BFY3jw7I.css +0 -2
- package/dist/assets/index-e_bkIEdq.js +0 -35
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import type { RowSelectionState, Table } from "@tanstack/react-table";
|
|
5
5
|
import { useLocale } from "react-aria";
|
|
6
6
|
import type { GetRowIds } from "@/plugins/impl/DataTablePlugin";
|
|
7
|
+
import { cn } from "@/utils/cn";
|
|
7
8
|
import { Events } from "@/utils/events";
|
|
8
9
|
import { prettyNumber } from "@/utils/numbers";
|
|
9
10
|
import { Button } from "../ui/button";
|
|
@@ -21,6 +22,8 @@ interface TableBottomBarProps<TData> {
|
|
|
21
22
|
getRowIds?: GetRowIds;
|
|
22
23
|
showPageSizeSelector?: boolean;
|
|
23
24
|
tableLoading?: boolean;
|
|
25
|
+
part?: string;
|
|
26
|
+
className?: string;
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
export const TableBottomBar = <TData,>({
|
|
@@ -32,6 +35,8 @@ export const TableBottomBar = <TData,>({
|
|
|
32
35
|
getRowIds,
|
|
33
36
|
showPageSizeSelector,
|
|
34
37
|
tableLoading,
|
|
38
|
+
part,
|
|
39
|
+
className,
|
|
35
40
|
}: TableBottomBarProps<TData>) => {
|
|
36
41
|
const { locale } = useLocale();
|
|
37
42
|
const handleSelectAllRows = (value: boolean) => {
|
|
@@ -143,7 +148,13 @@ export const TableBottomBar = <TData,>({
|
|
|
143
148
|
};
|
|
144
149
|
|
|
145
150
|
return (
|
|
146
|
-
<div
|
|
151
|
+
<div
|
|
152
|
+
part={part}
|
|
153
|
+
className={cn(
|
|
154
|
+
"flex lg:grid lg:grid-cols-[1fr_auto_1fr] items-center shrink-0",
|
|
155
|
+
className,
|
|
156
|
+
)}
|
|
157
|
+
>
|
|
147
158
|
<div className="flex flex-col text-sm text-muted-foreground px-2 shrink-0">
|
|
148
159
|
<div className="flex items-center gap-1">{renderTotal()}</div>
|
|
149
160
|
<CellSelectionStats table={table} className="lg:hidden" />
|
|
@@ -69,43 +69,39 @@ export const TableTopBar: React.FC<TableTopBarProps> = ({
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
return (
|
|
72
|
-
<div className="flex items-center h-10 px-2 border-b gap-
|
|
73
|
-
{/* always-visible search */}
|
|
72
|
+
<div className="flex items-center h-10 px-2 border-b gap-2">
|
|
74
73
|
{onSearchQueryChange && enableSearch && (
|
|
75
|
-
<div className="flex items-center">
|
|
76
|
-
<
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
)}
|
|
103
|
-
</div>
|
|
74
|
+
<div className="flex flex-1 items-center gap-1 px-2 rounded-sm focus-within:ring-1 focus-within:ring-border transition-shadow">
|
|
75
|
+
<SearchIcon className="w-4 h-4 text-muted-foreground shrink-0" />
|
|
76
|
+
<input
|
|
77
|
+
ref={inputRef}
|
|
78
|
+
type="text"
|
|
79
|
+
className="h-6 border-none bg-transparent focus:outline-hidden text-sm w-full min-w-0"
|
|
80
|
+
value={internalValue}
|
|
81
|
+
onKeyDown={(e) => {
|
|
82
|
+
if (e.key === "Escape") {
|
|
83
|
+
setInternalValue("");
|
|
84
|
+
inputRef.current?.blur();
|
|
85
|
+
}
|
|
86
|
+
}}
|
|
87
|
+
onChange={(e) => setInternalValue(e.target.value)}
|
|
88
|
+
placeholder="Search..."
|
|
89
|
+
/>
|
|
90
|
+
{reloading && <Spinner size="small" />}
|
|
91
|
+
{internalValue && (
|
|
92
|
+
<Button
|
|
93
|
+
variant="text"
|
|
94
|
+
size="xs"
|
|
95
|
+
className="h-5 w-5 p-0 shrink-0"
|
|
96
|
+
onClick={() => setInternalValue("")}
|
|
97
|
+
>
|
|
98
|
+
<XIcon className="w-3 h-3 text-muted-foreground" />
|
|
99
|
+
</Button>
|
|
100
|
+
)}
|
|
104
101
|
</div>
|
|
105
102
|
)}
|
|
106
103
|
|
|
107
|
-
|
|
108
|
-
<div className="flex items-center gap-1 shrink-0">
|
|
104
|
+
<div className="flex items-center shrink-0">
|
|
109
105
|
{showChartBuilder && (
|
|
110
106
|
<Button
|
|
111
107
|
variant="text"
|
|
@@ -117,7 +113,7 @@ export const TableTopBar: React.FC<TableTopBarProps> = ({
|
|
|
117
113
|
onClick={toggleDisplayHeader}
|
|
118
114
|
>
|
|
119
115
|
<ChartSplineIcon className="w-3.5 h-3.5" />
|
|
120
|
-
|
|
116
|
+
Visualize
|
|
121
117
|
</Button>
|
|
122
118
|
)}
|
|
123
119
|
{showTableExplorer && togglePanel && (
|
|
@@ -131,7 +127,7 @@ export const TableTopBar: React.FC<TableTopBarProps> = ({
|
|
|
131
127
|
onClick={() => togglePanel(PANEL_TYPES.ROW_VIEWER)}
|
|
132
128
|
>
|
|
133
129
|
<PanelRightIcon className="w-3.5 h-3.5" />
|
|
134
|
-
|
|
130
|
+
Explorer
|
|
135
131
|
</Button>
|
|
136
132
|
)}
|
|
137
133
|
{downloadAs && <ExportMenu downloadAs={downloadAs} />}
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
XIcon,
|
|
14
14
|
} from "lucide-react";
|
|
15
15
|
import type { JSX } from "react";
|
|
16
|
-
import React, { useMemo, useState } from "react";
|
|
16
|
+
import React, { useMemo, useRef, useState } from "react";
|
|
17
17
|
import { type UseFormReturn, useForm } from "react-hook-form";
|
|
18
18
|
import useResizeObserver from "use-resize-observer";
|
|
19
19
|
import { PythonIcon } from "@/components/editor/cell/code/icons";
|
|
@@ -61,6 +61,7 @@ export interface TablePanelProps {
|
|
|
61
61
|
totalRows: number | TooManyRows;
|
|
62
62
|
columns: number;
|
|
63
63
|
displayHeader: boolean;
|
|
64
|
+
onCloseChartBuilder?: () => void;
|
|
64
65
|
getDataUrl?: GetDataUrl;
|
|
65
66
|
fieldTypes?: FieldTypesWithExternalType | null;
|
|
66
67
|
}
|
|
@@ -74,12 +75,33 @@ export const TablePanel: React.FC<TablePanelProps> = ({
|
|
|
74
75
|
getDataUrl,
|
|
75
76
|
fieldTypes,
|
|
76
77
|
displayHeader,
|
|
78
|
+
onCloseChartBuilder,
|
|
77
79
|
}) => {
|
|
78
80
|
const [tabsMap, saveTabsMap] = useAtom(tabsStorageAtom);
|
|
79
81
|
const tabs = cellId ? (tabsMap.get(cellId) ?? []) : [];
|
|
80
82
|
|
|
81
|
-
const [tabNum, setTabNum] = useState(0);
|
|
82
83
|
const [selectedTab, setSelectedTab] = useState(DEFAULT_TAB_NAME);
|
|
84
|
+
const [tabCounter, setTabCounter] = useState(tabs.length);
|
|
85
|
+
const prevDisplayHeader = useRef(displayHeader);
|
|
86
|
+
|
|
87
|
+
// Auto-create a default chart tab when chart builder opens with no tabs
|
|
88
|
+
if (
|
|
89
|
+
displayHeader &&
|
|
90
|
+
!prevDisplayHeader.current &&
|
|
91
|
+
tabs.length === 0 &&
|
|
92
|
+
cellId
|
|
93
|
+
) {
|
|
94
|
+
prevDisplayHeader.current = displayHeader;
|
|
95
|
+
const tabName = getChartTabName(0, NEW_CHART_TYPE);
|
|
96
|
+
const newTabs = new Map(tabsMap);
|
|
97
|
+
newTabs.set(cellId, [
|
|
98
|
+
{ tabName, chartType: NEW_CHART_TYPE, config: getChartDefaults() },
|
|
99
|
+
]);
|
|
100
|
+
saveTabsMap(newTabs);
|
|
101
|
+
setTabCounter(1);
|
|
102
|
+
setSelectedTab(tabName);
|
|
103
|
+
}
|
|
104
|
+
prevDisplayHeader.current = displayHeader;
|
|
83
105
|
|
|
84
106
|
if (!displayHeader || (tabs.length === 0 && !displayHeader)) {
|
|
85
107
|
return dataTable;
|
|
@@ -89,7 +111,7 @@ export const TablePanel: React.FC<TablePanelProps> = ({
|
|
|
89
111
|
if (!cellId) {
|
|
90
112
|
return;
|
|
91
113
|
}
|
|
92
|
-
const tabName = getChartTabName(
|
|
114
|
+
const tabName = getChartTabName(tabCounter, NEW_CHART_TYPE);
|
|
93
115
|
|
|
94
116
|
const newTabs = new Map(tabsMap);
|
|
95
117
|
newTabs.set(cellId, [
|
|
@@ -102,7 +124,7 @@ export const TablePanel: React.FC<TablePanelProps> = ({
|
|
|
102
124
|
]);
|
|
103
125
|
|
|
104
126
|
saveTabsMap(newTabs);
|
|
105
|
-
|
|
127
|
+
setTabCounter(tabCounter + 1);
|
|
106
128
|
setSelectedTab(tabName);
|
|
107
129
|
};
|
|
108
130
|
|
|
@@ -110,14 +132,21 @@ export const TablePanel: React.FC<TablePanelProps> = ({
|
|
|
110
132
|
if (!cellId) {
|
|
111
133
|
return;
|
|
112
134
|
}
|
|
135
|
+
const deletedIndex = tabs.findIndex((tab) => tab.tabName === tabName);
|
|
136
|
+
const remaining = tabs.filter((tab) => tab.tabName !== tabName);
|
|
113
137
|
const newTabs = new Map(tabsMap);
|
|
114
|
-
newTabs.set(
|
|
115
|
-
cellId,
|
|
116
|
-
tabs.filter((tab) => tab.tabName !== tabName),
|
|
117
|
-
);
|
|
138
|
+
newTabs.set(cellId, remaining);
|
|
118
139
|
saveTabsMap(newTabs);
|
|
119
|
-
|
|
120
|
-
|
|
140
|
+
|
|
141
|
+
if (remaining.length === 0) {
|
|
142
|
+
onCloseChartBuilder?.();
|
|
143
|
+
} else if (tabName === selectedTab) {
|
|
144
|
+
if (deletedIndex < remaining.length) {
|
|
145
|
+
setSelectedTab(remaining[deletedIndex].tabName);
|
|
146
|
+
} else {
|
|
147
|
+
setSelectedTab(remaining[remaining.length - 1].tabName);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
121
150
|
};
|
|
122
151
|
|
|
123
152
|
const saveTabChart = ({
|
|
@@ -178,7 +207,7 @@ export const TablePanel: React.FC<TablePanelProps> = ({
|
|
|
178
207
|
|
|
179
208
|
return (
|
|
180
209
|
<Tabs value={selectedTab} className="-mt-1">
|
|
181
|
-
<TabsList>
|
|
210
|
+
<TabsList part="table-tabs">
|
|
182
211
|
<TabsTrigger
|
|
183
212
|
className="text-xs"
|
|
184
213
|
value={DEFAULT_TAB_NAME}
|
|
@@ -283,7 +283,10 @@ const DataTableInternal = <TData,>({
|
|
|
283
283
|
<div className={cn(wrapperClassName, "flex flex-col space-y-1")}>
|
|
284
284
|
<FilterPills filters={filters} table={table} />
|
|
285
285
|
<CellSelectionProvider>
|
|
286
|
-
<div
|
|
286
|
+
<div
|
|
287
|
+
part="table-wrapper"
|
|
288
|
+
className={cn(className || "rounded-md border overflow-hidden")}
|
|
289
|
+
>
|
|
287
290
|
<TableTopBar
|
|
288
291
|
enableSearch={enableSearch}
|
|
289
292
|
searchQuery={searchQuery}
|
|
@@ -313,6 +316,8 @@ const DataTableInternal = <TData,>({
|
|
|
313
316
|
</Table>
|
|
314
317
|
</div>
|
|
315
318
|
<TableBottomBar
|
|
319
|
+
part="table-footer"
|
|
320
|
+
className="border-t border-border pt-1.5 pb-0.5"
|
|
316
321
|
totalColumns={totalColumns}
|
|
317
322
|
pagination={pagination}
|
|
318
323
|
selection={selection}
|
|
@@ -24,7 +24,10 @@ export const LoadingTable = ({
|
|
|
24
24
|
|
|
25
25
|
return (
|
|
26
26
|
<div className={cn(wrapperClassName, "flex flex-col space-y-2")}>
|
|
27
|
-
<div
|
|
27
|
+
<div
|
|
28
|
+
part="table-wrapper"
|
|
29
|
+
className={cn(className || "rounded-md border")}
|
|
30
|
+
>
|
|
28
31
|
<Table>
|
|
29
32
|
<TableHeader>
|
|
30
33
|
{Array.from({ length: 1 }).map((_, i) => (
|
|
@@ -34,7 +34,9 @@ export const CellSelectionStats = <TData,>({
|
|
|
34
34
|
if (dataCellCount < 2) {
|
|
35
35
|
return (
|
|
36
36
|
<Tooltip content="Select multiple cells to see stats">
|
|
37
|
-
<span
|
|
37
|
+
<span
|
|
38
|
+
className={cn("text-xs text-muted-foreground/80 italic", className)}
|
|
39
|
+
>
|
|
38
40
|
No selection
|
|
39
41
|
</span>
|
|
40
42
|
</Tooltip>
|
|
@@ -247,7 +247,7 @@ export const RowViewerPanel: React.FC<RowViewerPanelProps> = ({
|
|
|
247
247
|
|
|
248
248
|
return (
|
|
249
249
|
<div
|
|
250
|
-
className="flex flex-col gap-3
|
|
250
|
+
className="flex flex-col gap-3 focus:outline-hidden"
|
|
251
251
|
ref={panelRef}
|
|
252
252
|
tabIndex={-1}
|
|
253
253
|
onKeyDown={handleKeyDown}
|
|
@@ -42,7 +42,7 @@ export interface TableExplorerPanelProps {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
const tabTriggerClassName =
|
|
45
|
-
"text-
|
|
45
|
+
"text-[13px] uppercase tracking-wide font-semibold cursor-pointer transition-colors";
|
|
46
46
|
const activeClassName = "text-primary";
|
|
47
47
|
const inactiveClassName = "hover:text-foreground";
|
|
48
48
|
|
|
@@ -110,7 +110,7 @@ export const TableExplorerPanel: React.FC<TableExplorerPanelProps> = ({
|
|
|
110
110
|
<Tabs
|
|
111
111
|
value={resolvedTab}
|
|
112
112
|
onValueChange={(value) => onTabChange(value as PanelType)}
|
|
113
|
-
className="
|
|
113
|
+
className="flex flex-col min-w-[350px]"
|
|
114
114
|
>
|
|
115
115
|
<Fill name={SlotNames.CONTEXT_AWARE_PANEL_HEADER}>
|
|
116
116
|
<div className="flex items-center gap-1">
|
|
@@ -122,7 +122,7 @@ export const AddCellWithAI: React.FC<{
|
|
|
122
122
|
transport: new StreamingChunkTransport(
|
|
123
123
|
{
|
|
124
124
|
api: runtimeManager.getAiURL("completion").toString(),
|
|
125
|
-
headers: runtimeManager.headers(),
|
|
125
|
+
headers: () => runtimeManager.headers(),
|
|
126
126
|
prepareSendMessagesRequest: async (options) => {
|
|
127
127
|
const completionBody = await buildCompletionRequestBody(
|
|
128
128
|
options.messages,
|
|
@@ -136,6 +136,7 @@ export const AddCellWithAI: React.FC<{
|
|
|
136
136
|
};
|
|
137
137
|
|
|
138
138
|
return {
|
|
139
|
+
api: runtimeManager.getAiURL("completion").toString(),
|
|
139
140
|
body: body,
|
|
140
141
|
};
|
|
141
142
|
},
|
|
@@ -101,7 +101,7 @@ export const ContextAwarePanel: React.FC = () => {
|
|
|
101
101
|
const renderBody = () => {
|
|
102
102
|
return (
|
|
103
103
|
<div className="pb-7 mb-4 h-full overflow-auto">
|
|
104
|
-
<div className="
|
|
104
|
+
<div className="px-3 py-2 border-b flex justify-between items-center">
|
|
105
105
|
{renderModeToggle()}
|
|
106
106
|
<Slot name={SlotNames.CONTEXT_AWARE_PANEL_HEADER} />
|
|
107
107
|
<Button
|
|
@@ -13,6 +13,7 @@ import type {
|
|
|
13
13
|
LspRestartRequest,
|
|
14
14
|
LspRestartResponse,
|
|
15
15
|
} from "@/core/network/types";
|
|
16
|
+
import { isWasm } from "@/core/wasm/utils";
|
|
16
17
|
import { isAppConnected } from "@/core/websocket/connection-utils";
|
|
17
18
|
import { useAsyncData } from "@/hooks/useAsyncData";
|
|
18
19
|
import { useInterval } from "@/hooks/useInterval";
|
|
@@ -26,7 +27,7 @@ export const LspStatus: React.FC = () => {
|
|
|
26
27
|
const setLspHealth = useSetAtom(lspHealthAtom);
|
|
27
28
|
|
|
28
29
|
const { isFetching, data, refetch } = useAsyncData(async () => {
|
|
29
|
-
if (!isAppConnected(connection)) {
|
|
30
|
+
if (isWasm() || !isAppConnected(connection)) {
|
|
30
31
|
return null;
|
|
31
32
|
}
|
|
32
33
|
|
|
@@ -18,6 +18,7 @@ import { python } from "@codemirror/lang-python";
|
|
|
18
18
|
import { EditorState } from "@codemirror/state";
|
|
19
19
|
import { EditorView } from "@codemirror/view";
|
|
20
20
|
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
|
21
|
+
import { cellId } from "@/__tests__/branded";
|
|
21
22
|
import type { CellHandle } from "@/components/editor/notebook-cell";
|
|
22
23
|
import { adaptiveLanguageConfiguration } from "@/core/codemirror/language/extension";
|
|
23
24
|
import { OverridingHotkeyProvider } from "@/core/hotkeys/hotkeys";
|
|
@@ -121,7 +122,7 @@ describe("applyTransactionChanges edge cases", () => {
|
|
|
121
122
|
apply([
|
|
122
123
|
{
|
|
123
124
|
type: "create-cell",
|
|
124
|
-
cellId: "new-cell",
|
|
125
|
+
cellId: cellId("new-cell"),
|
|
125
126
|
code: "configured",
|
|
126
127
|
name: "",
|
|
127
128
|
config: { hide_code: true, disabled: true, column: 1 },
|
|
@@ -141,12 +142,12 @@ describe("applyTransactionChanges edge cases", () => {
|
|
|
141
142
|
apply([
|
|
142
143
|
{
|
|
143
144
|
type: "create-cell",
|
|
144
|
-
cellId: "new-cell",
|
|
145
|
+
cellId: cellId("new-cell"),
|
|
145
146
|
code: "new",
|
|
146
147
|
name: "",
|
|
147
148
|
config: {},
|
|
148
149
|
},
|
|
149
|
-
{ type: "move-cell", cellId: "new-cell", before: a },
|
|
150
|
+
{ type: "move-cell", cellId: cellId("new-cell"), before: a },
|
|
150
151
|
]);
|
|
151
152
|
expect(pretty(state)).toMatchInlineSnapshot(`
|
|
152
153
|
"
|
|
@@ -162,12 +163,12 @@ describe("applyTransactionChanges edge cases", () => {
|
|
|
162
163
|
apply([
|
|
163
164
|
{
|
|
164
165
|
type: "create-cell",
|
|
165
|
-
cellId: "new-cell",
|
|
166
|
+
cellId: cellId("new-cell"),
|
|
166
167
|
code: "initial",
|
|
167
168
|
name: "",
|
|
168
169
|
config: {},
|
|
169
170
|
},
|
|
170
|
-
{ type: "set-code", cellId: "new-cell", code: "updated" },
|
|
171
|
+
{ type: "set-code", cellId: cellId("new-cell"), code: "updated" },
|
|
171
172
|
]);
|
|
172
173
|
expect(pretty(state)).toMatchInlineSnapshot(`
|
|
173
174
|
"
|
|
@@ -182,12 +183,12 @@ describe("applyTransactionChanges edge cases", () => {
|
|
|
182
183
|
apply([
|
|
183
184
|
{
|
|
184
185
|
type: "create-cell",
|
|
185
|
-
cellId: "ephemeral",
|
|
186
|
+
cellId: cellId("ephemeral"),
|
|
186
187
|
code: "tmp",
|
|
187
188
|
name: "",
|
|
188
189
|
config: {},
|
|
189
190
|
},
|
|
190
|
-
{ type: "delete-cell", cellId: "ephemeral" },
|
|
191
|
+
{ type: "delete-cell", cellId: cellId("ephemeral") },
|
|
191
192
|
]);
|
|
192
193
|
expect(pretty(state)).toMatchInlineSnapshot(`
|
|
193
194
|
"
|
|
@@ -228,7 +229,7 @@ describe("applyTransactionChanges edge cases", () => {
|
|
|
228
229
|
it("move-cell with missing after anchor falls back to end", () => {
|
|
229
230
|
setup("a", "b");
|
|
230
231
|
const [a] = state.cellIds.inOrderIds;
|
|
231
|
-
apply([{ type: "move-cell", cellId: a, after: "nonexistent"
|
|
232
|
+
apply([{ type: "move-cell", cellId: a, after: cellId("nonexistent") }]);
|
|
232
233
|
expect(pretty(state)).toMatchInlineSnapshot(`
|
|
233
234
|
"
|
|
234
235
|
1: 'b'
|
|
@@ -240,7 +241,7 @@ describe("applyTransactionChanges edge cases", () => {
|
|
|
240
241
|
it("move-cell with missing before anchor falls back to start", () => {
|
|
241
242
|
setup("a", "b");
|
|
242
243
|
const [, b] = state.cellIds.inOrderIds;
|
|
243
|
-
apply([{ type: "move-cell", cellId: b, before: "nonexistent"
|
|
244
|
+
apply([{ type: "move-cell", cellId: b, before: cellId("nonexistent") }]);
|
|
244
245
|
expect(pretty(state)).toMatchInlineSnapshot(`
|
|
245
246
|
"
|
|
246
247
|
1: 'b'
|
|
@@ -254,8 +255,8 @@ describe("applyTransactionChanges edge cases", () => {
|
|
|
254
255
|
apply([
|
|
255
256
|
{
|
|
256
257
|
type: "move-cell",
|
|
257
|
-
cellId: "nonexistent"
|
|
258
|
-
after: "0"
|
|
258
|
+
cellId: cellId("nonexistent"),
|
|
259
|
+
after: cellId("0"),
|
|
259
260
|
},
|
|
260
261
|
]);
|
|
261
262
|
expect(pretty(state)).toMatchInlineSnapshot(`
|
|
@@ -425,7 +425,7 @@ export function fromDocumentChanges(
|
|
|
425
425
|
cellId,
|
|
426
426
|
before,
|
|
427
427
|
code: change.code,
|
|
428
|
-
newCellId: change.cellId
|
|
428
|
+
newCellId: change.cellId,
|
|
429
429
|
autoFocus: false,
|
|
430
430
|
hideCode: change.config?.hide_code ?? false,
|
|
431
431
|
},
|
|
@@ -433,14 +433,14 @@ export function fromDocumentChanges(
|
|
|
433
433
|
if (change.name) {
|
|
434
434
|
actions.push({
|
|
435
435
|
type: "updateCellName",
|
|
436
|
-
payload: { cellId: change.cellId
|
|
436
|
+
payload: { cellId: change.cellId, name: change.name },
|
|
437
437
|
});
|
|
438
438
|
}
|
|
439
439
|
if (change.config?.disabled != null || change.config?.column != null) {
|
|
440
440
|
actions.push({
|
|
441
441
|
type: "updateCellConfig",
|
|
442
442
|
payload: {
|
|
443
|
-
cellId: change.cellId
|
|
443
|
+
cellId: change.cellId,
|
|
444
444
|
config: {
|
|
445
445
|
...(change.config.disabled != null && {
|
|
446
446
|
disabled: change.config.disabled,
|
|
@@ -460,7 +460,7 @@ export function fromDocumentChanges(
|
|
|
460
460
|
case "delete-cell":
|
|
461
461
|
actions.push({
|
|
462
462
|
type: "deleteCell",
|
|
463
|
-
payload: { cellId: change.cellId
|
|
463
|
+
payload: { cellId: change.cellId },
|
|
464
464
|
});
|
|
465
465
|
break;
|
|
466
466
|
|
|
@@ -471,7 +471,7 @@ export function fromDocumentChanges(
|
|
|
471
471
|
// missing. No-ops if the cell itself doesn't exist.
|
|
472
472
|
case "move-cell": {
|
|
473
473
|
const ids = [...getCurrentCellIds()];
|
|
474
|
-
const cellId = change.cellId
|
|
474
|
+
const cellId = change.cellId;
|
|
475
475
|
const idx = ids.indexOf(cellId);
|
|
476
476
|
if (idx < 0) {
|
|
477
477
|
break;
|
|
@@ -507,7 +507,7 @@ export function fromDocumentChanges(
|
|
|
507
507
|
case "reorder-cells":
|
|
508
508
|
actions.push({
|
|
509
509
|
type: "setCellIds",
|
|
510
|
-
payload: { cellIds: change.cellIds
|
|
510
|
+
payload: { cellIds: change.cellIds },
|
|
511
511
|
});
|
|
512
512
|
break;
|
|
513
513
|
|
|
@@ -518,7 +518,7 @@ export function fromDocumentChanges(
|
|
|
518
518
|
actions.push({
|
|
519
519
|
type: "setCellCodes",
|
|
520
520
|
payload: {
|
|
521
|
-
ids: [change.cellId
|
|
521
|
+
ids: [change.cellId],
|
|
522
522
|
codes: [change.code],
|
|
523
523
|
codeIsStale: true,
|
|
524
524
|
},
|
|
@@ -530,7 +530,7 @@ export function fromDocumentChanges(
|
|
|
530
530
|
case "set-name":
|
|
531
531
|
actions.push({
|
|
532
532
|
type: "updateCellName",
|
|
533
|
-
payload: { cellId: change.cellId
|
|
533
|
+
payload: { cellId: change.cellId, name: change.name },
|
|
534
534
|
});
|
|
535
535
|
break;
|
|
536
536
|
|
|
@@ -542,7 +542,7 @@ export function fromDocumentChanges(
|
|
|
542
542
|
actions.push({
|
|
543
543
|
type: "updateCellConfig",
|
|
544
544
|
payload: {
|
|
545
|
-
cellId: change.cellId
|
|
545
|
+
cellId: change.cellId,
|
|
546
546
|
config: {
|
|
547
547
|
...(change.hideCode != null && { hide_code: change.hideCode }),
|
|
548
548
|
...(change.disabled != null && { disabled: change.disabled }),
|