@malloy-publisher/sdk 0.0.142 → 0.0.144
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/components/Notebook/NotebookCell.d.ts +2 -1
- package/dist/index.cjs.js +46 -46
- package/dist/index.es.js +4643 -4643
- package/package.json +1 -1
- package/src/components/Notebook/Notebook.tsx +43 -39
- package/src/components/Notebook/NotebookCell.tsx +52 -39
- package/src/hooks/useDimensionalFilterRangeData.ts +2 -0
package/package.json
CHANGED
|
@@ -153,23 +153,27 @@ export default function Notebook({
|
|
|
153
153
|
async (filtersToApply: FilterSelection[] = []) => {
|
|
154
154
|
if (!isSuccess || !notebook?.notebookCells) return;
|
|
155
155
|
|
|
156
|
+
// Initialize or reset cells
|
|
157
|
+
setEnhancedCells((prev) => {
|
|
158
|
+
if (prev.length === 0) {
|
|
159
|
+
return notebook.notebookCells.map((cell) => ({ ...cell }));
|
|
160
|
+
}
|
|
161
|
+
return prev.map((cell) => ({
|
|
162
|
+
...cell,
|
|
163
|
+
result: undefined,
|
|
164
|
+
}));
|
|
165
|
+
});
|
|
166
|
+
|
|
156
167
|
setIsExecuting(true);
|
|
157
168
|
setExecutionError(null);
|
|
158
|
-
const cells: EnhancedNotebookCell[] = [];
|
|
159
169
|
|
|
160
170
|
try {
|
|
161
171
|
// Execute cells sequentially
|
|
162
172
|
for (let i = 0; i < notebook.notebookCells.length; i++) {
|
|
163
173
|
const rawCell = notebook.notebookCells[i];
|
|
164
174
|
|
|
165
|
-
// Markdown cells don't need execution
|
|
166
|
-
if (rawCell.type === "markdown")
|
|
167
|
-
cells.push({
|
|
168
|
-
type: rawCell.type,
|
|
169
|
-
text: rawCell.text,
|
|
170
|
-
});
|
|
171
|
-
continue;
|
|
172
|
-
}
|
|
175
|
+
// Markdown cells don't need execution
|
|
176
|
+
if (rawCell.type === "markdown") continue;
|
|
173
177
|
|
|
174
178
|
// Execute code cells
|
|
175
179
|
const cellText = rawCell.text || "";
|
|
@@ -179,6 +183,9 @@ export default function Notebook({
|
|
|
179
183
|
/^\s*(run|query)\s*:/m.test(cellText);
|
|
180
184
|
|
|
181
185
|
try {
|
|
186
|
+
let result: string | undefined;
|
|
187
|
+
let newSources: string[] | undefined;
|
|
188
|
+
|
|
182
189
|
if (hasQuery && modelPath && filtersToApply.length > 0) {
|
|
183
190
|
// Query cell - use models API with optional filters
|
|
184
191
|
let queryToExecute = cellText;
|
|
@@ -234,12 +241,7 @@ export default function Notebook({
|
|
|
234
241
|
versionId,
|
|
235
242
|
},
|
|
236
243
|
);
|
|
237
|
-
|
|
238
|
-
cells.push({
|
|
239
|
-
type: rawCell.type,
|
|
240
|
-
text: rawCell.text,
|
|
241
|
-
result: response.data.result,
|
|
242
|
-
});
|
|
244
|
+
result = response.data.result;
|
|
243
245
|
} else {
|
|
244
246
|
// Non-query code cell (or no filters applied) - use notebook cell execution API
|
|
245
247
|
const response =
|
|
@@ -252,24 +254,29 @@ export default function Notebook({
|
|
|
252
254
|
);
|
|
253
255
|
|
|
254
256
|
const executedCell = response.data;
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
text: rawCell.text,
|
|
258
|
-
result: executedCell.result,
|
|
259
|
-
newSources: executedCell.newSources,
|
|
260
|
-
});
|
|
257
|
+
result = executedCell.result;
|
|
258
|
+
newSources = rawCell.newSources || executedCell.newSources;
|
|
261
259
|
}
|
|
260
|
+
|
|
261
|
+
// Update state incrementally
|
|
262
|
+
setEnhancedCells((prev) => {
|
|
263
|
+
const next = [...prev];
|
|
264
|
+
// Ensure we have a cell to update (in case state was reset externally, though unlikely)
|
|
265
|
+
if (!next[i]) {
|
|
266
|
+
next[i] = { ...rawCell };
|
|
267
|
+
}
|
|
268
|
+
next[i] = {
|
|
269
|
+
...next[i],
|
|
270
|
+
result,
|
|
271
|
+
newSources,
|
|
272
|
+
};
|
|
273
|
+
return next;
|
|
274
|
+
});
|
|
262
275
|
} catch (cellError) {
|
|
263
|
-
// If a cell fails, add it without execution results
|
|
264
276
|
console.error(`Error executing cell ${i}:`, cellError);
|
|
265
|
-
|
|
266
|
-
type: rawCell.type,
|
|
267
|
-
text: rawCell.text,
|
|
268
|
-
});
|
|
277
|
+
// Don't update result on error, leave as is (undefined)
|
|
269
278
|
}
|
|
270
279
|
}
|
|
271
|
-
|
|
272
|
-
setEnhancedCells(cells);
|
|
273
280
|
} catch (error) {
|
|
274
281
|
console.error("Error executing notebook cells:", error);
|
|
275
282
|
setExecutionError(error as Error);
|
|
@@ -412,26 +419,23 @@ export default function Notebook({
|
|
|
412
419
|
)}
|
|
413
420
|
|
|
414
421
|
{/* Loading State */}
|
|
415
|
-
{
|
|
416
|
-
<Loading
|
|
417
|
-
text={
|
|
418
|
-
isExecuting
|
|
419
|
-
? "Executing Notebook..."
|
|
420
|
-
: "Fetching Notebook..."
|
|
421
|
-
}
|
|
422
|
-
/>
|
|
422
|
+
{!isSuccess && !isError && (
|
|
423
|
+
<Loading text={"Fetching Notebook..."} />
|
|
423
424
|
)}
|
|
424
425
|
|
|
425
426
|
{/* Notebook Cells */}
|
|
426
427
|
{isSuccess &&
|
|
427
|
-
|
|
428
|
-
|
|
428
|
+
(enhancedCells.length > 0
|
|
429
|
+
? enhancedCells
|
|
430
|
+
: notebook?.notebookCells || []
|
|
431
|
+
).map((cell, index) => (
|
|
429
432
|
<NotebookCell
|
|
430
|
-
cell={cell}
|
|
433
|
+
cell={cell as EnhancedNotebookCell}
|
|
431
434
|
key={index}
|
|
432
435
|
index={index}
|
|
433
436
|
resourceUri={resourceUri}
|
|
434
437
|
maxResultSize={maxResultSize}
|
|
438
|
+
isExecuting={isExecuting}
|
|
435
439
|
/>
|
|
436
440
|
))}
|
|
437
441
|
|
|
@@ -5,6 +5,7 @@ import LinkOutlinedIcon from "@mui/icons-material/LinkOutlined";
|
|
|
5
5
|
import SearchIcon from "@mui/icons-material/Search";
|
|
6
6
|
import {
|
|
7
7
|
Box,
|
|
8
|
+
CircularProgress,
|
|
8
9
|
Dialog,
|
|
9
10
|
DialogContent,
|
|
10
11
|
DialogTitle,
|
|
@@ -33,6 +34,7 @@ interface NotebookCellProps {
|
|
|
33
34
|
resourceUri: string;
|
|
34
35
|
index: number;
|
|
35
36
|
maxResultSize?: number;
|
|
37
|
+
isExecuting?: boolean;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
export function NotebookCell({
|
|
@@ -42,6 +44,7 @@ export function NotebookCell({
|
|
|
42
44
|
resourceUri,
|
|
43
45
|
index,
|
|
44
46
|
maxResultSize,
|
|
47
|
+
isExecuting,
|
|
45
48
|
}: NotebookCellProps) {
|
|
46
49
|
const [codeDialogOpen, setCodeDialogOpen] = React.useState<boolean>(false);
|
|
47
50
|
const [embeddingDialogOpen, setEmbeddingDialogOpen] =
|
|
@@ -214,45 +217,37 @@ export function NotebookCell({
|
|
|
214
217
|
marginBottom: "16px",
|
|
215
218
|
}}
|
|
216
219
|
>
|
|
217
|
-
{cell.newSources &&
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
220
|
+
{cell.newSources && cell.newSources.length > 0 && (
|
|
221
|
+
<CleanMetricCard
|
|
222
|
+
sx={{
|
|
223
|
+
position: "relative",
|
|
224
|
+
padding: "0",
|
|
225
|
+
}}
|
|
226
|
+
>
|
|
227
|
+
<Box
|
|
221
228
|
sx={{
|
|
222
|
-
|
|
223
|
-
|
|
229
|
+
display: "flex",
|
|
230
|
+
alignItems: "center",
|
|
231
|
+
justifyContent: "space-between",
|
|
232
|
+
paddingLeft: "24px",
|
|
233
|
+
paddingRight: "8px",
|
|
224
234
|
}}
|
|
225
235
|
>
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
highlightedMalloyCode
|
|
242
|
-
? `${highlightedMalloyCode.substring(0, 50)}...`
|
|
243
|
-
: highlightedMalloyCode,
|
|
244
|
-
}}
|
|
245
|
-
style={{
|
|
246
|
-
fontFamily: "monospace",
|
|
247
|
-
fontSize: "14px",
|
|
248
|
-
flex: 1,
|
|
249
|
-
whiteSpace: "nowrap",
|
|
250
|
-
overflow: "hidden",
|
|
251
|
-
textOverflow: "ellipsis",
|
|
252
|
-
marginRight: "8px",
|
|
253
|
-
}}
|
|
254
|
-
/>
|
|
255
|
-
)}
|
|
236
|
+
{/* This shouldn't be needed but there's a compiler bug */}
|
|
237
|
+
{highlightedMalloyCode && (
|
|
238
|
+
<span
|
|
239
|
+
dangerouslySetInnerHTML={{
|
|
240
|
+
__html: highlightedMalloyCode,
|
|
241
|
+
}}
|
|
242
|
+
style={{
|
|
243
|
+
fontFamily: "monospace",
|
|
244
|
+
fontSize: "14px",
|
|
245
|
+
flex: 1,
|
|
246
|
+
marginRight: "8px",
|
|
247
|
+
}}
|
|
248
|
+
/>
|
|
249
|
+
)}
|
|
250
|
+
{hasValidImport && (
|
|
256
251
|
<IconButton
|
|
257
252
|
sx={{
|
|
258
253
|
backgroundColor: "rgba(255, 255, 255, 0.9)",
|
|
@@ -270,9 +265,10 @@ export function NotebookCell({
|
|
|
270
265
|
sx={{ fontSize: "18px", color: "#666666" }}
|
|
271
266
|
/>
|
|
272
267
|
</IconButton>
|
|
273
|
-
|
|
274
|
-
</
|
|
275
|
-
|
|
268
|
+
)}
|
|
269
|
+
</Box>
|
|
270
|
+
</CleanMetricCard>
|
|
271
|
+
)}
|
|
276
272
|
</Stack>
|
|
277
273
|
)}
|
|
278
274
|
|
|
@@ -407,6 +403,23 @@ export function NotebookCell({
|
|
|
407
403
|
title="Results"
|
|
408
404
|
/>
|
|
409
405
|
|
|
406
|
+
{/* Loading state for executing code cells (not import cells) */}
|
|
407
|
+
{isExecuting &&
|
|
408
|
+
!cell.result &&
|
|
409
|
+
!hasValidImport &&
|
|
410
|
+
!(cell.newSources && cell.newSources.length > 0) && (
|
|
411
|
+
<CleanMetricCard
|
|
412
|
+
sx={{
|
|
413
|
+
display: "flex",
|
|
414
|
+
justifyContent: "center",
|
|
415
|
+
alignItems: "center",
|
|
416
|
+
minHeight: 200,
|
|
417
|
+
}}
|
|
418
|
+
>
|
|
419
|
+
<CircularProgress size={32} />
|
|
420
|
+
</CleanMetricCard>
|
|
421
|
+
)}
|
|
422
|
+
|
|
410
423
|
{cell.result && (
|
|
411
424
|
<CleanMetricCard
|
|
412
425
|
sx={{
|
|
@@ -359,6 +359,8 @@ function parseIndexQueryResult(
|
|
|
359
359
|
return cell.number_value ?? null;
|
|
360
360
|
case "boolean_cell":
|
|
361
361
|
return cell.boolean_value ?? null;
|
|
362
|
+
case "null_cell":
|
|
363
|
+
return null;
|
|
362
364
|
default:
|
|
363
365
|
console.log("Unknown cell kind: " + cell.kind);
|
|
364
366
|
return null;
|