@malloy-publisher/sdk 0.0.87 → 0.0.89
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/client/api.d.ts +280 -16
- package/dist/components/AnalyzePackageButton.d.ts +6 -1
- package/dist/components/Workbook/BrowserWorkbookStorage.d.ts +6 -8
- package/dist/components/Workbook/Workbook.d.ts +3 -1
- package/dist/components/Workbook/WorkbookManager.d.ts +3 -6
- package/dist/components/Workbook/WorkbookStorage.d.ts +6 -7
- package/dist/index.cjs.js +75 -75
- package/dist/index.es.js +8710 -9001
- package/dist/markdown-editor.css +0 -1
- package/dist/sdk.css +1 -1
- package/package.json +1 -1
- package/src/components/AnalyzePackageButton.tsx +32 -32
- package/src/components/Workbook/BrowserWorkbookStorage.ts +16 -54
- package/src/components/Workbook/MutableCell.tsx +16 -47
- package/src/components/Workbook/Workbook.tsx +56 -42
- package/src/components/Workbook/WorkbookList.tsx +20 -24
- package/src/components/Workbook/WorkbookManager.ts +5 -24
- package/src/components/Workbook/WorkbookStorage.ts +6 -26
|
@@ -58,6 +58,7 @@ export function MutableCell({
|
|
|
58
58
|
onDelete,
|
|
59
59
|
addButtonCallback,
|
|
60
60
|
}: NotebookCellProps) {
|
|
61
|
+
const [value, setValue] = useState(cell.value);
|
|
61
62
|
const [codeExpanded, setCodeExpanded] =
|
|
62
63
|
React.useState<boolean>(expandCodeCell);
|
|
63
64
|
const [embeddingExpanded, setEmbeddingExpanded] =
|
|
@@ -83,13 +84,9 @@ export function MutableCell({
|
|
|
83
84
|
setHighlightedMalloyCode(code);
|
|
84
85
|
});
|
|
85
86
|
}, [cell]);
|
|
86
|
-
const [value, setValue] = useState(cell.value);
|
|
87
87
|
React.useEffect(() => {
|
|
88
88
|
document.documentElement.setAttribute("data-color-mode", "light");
|
|
89
89
|
});
|
|
90
|
-
const updateMarkdown = useDebounce((newValue: string) => {
|
|
91
|
-
onCellChange({ ...cell, value: newValue });
|
|
92
|
-
});
|
|
93
90
|
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
|
94
91
|
|
|
95
92
|
const handleDeleteConfirm = () => {
|
|
@@ -98,7 +95,7 @@ export function MutableCell({
|
|
|
98
95
|
};
|
|
99
96
|
const noSources = sourceAndPaths.length === 0;
|
|
100
97
|
|
|
101
|
-
const saveResult = () => {
|
|
98
|
+
const saveResult = React.useCallback(() => {
|
|
102
99
|
// Get the current modelPath and sourceName from the selected source
|
|
103
100
|
const currentSource = sourceAndPaths[selectedSourceIndex];
|
|
104
101
|
const modelPath = currentSource?.modelPath || cell.modelPath || "";
|
|
@@ -109,7 +106,7 @@ export function MutableCell({
|
|
|
109
106
|
// the stringified JSON objects that are stored in the cell.
|
|
110
107
|
onCellChange({
|
|
111
108
|
...cell,
|
|
112
|
-
value: query.query,
|
|
109
|
+
value: cell.isMarkdown ? value : query.query,
|
|
113
110
|
result: query.malloyResult
|
|
114
111
|
? JSON.stringify(query.malloyResult)
|
|
115
112
|
: undefined,
|
|
@@ -119,7 +116,7 @@ export function MutableCell({
|
|
|
119
116
|
sourceName,
|
|
120
117
|
modelPath,
|
|
121
118
|
});
|
|
122
|
-
};
|
|
119
|
+
}, [cell, value, query, onCellChange, selectedSourceIndex, sourceAndPaths]);
|
|
123
120
|
|
|
124
121
|
const deleteButton = (
|
|
125
122
|
<Tooltip title="Delete Cell">
|
|
@@ -160,11 +157,15 @@ export function MutableCell({
|
|
|
160
157
|
</DialogActions>
|
|
161
158
|
</Dialog>
|
|
162
159
|
);
|
|
160
|
+
const saveAndClose = () => {
|
|
161
|
+
saveResult();
|
|
162
|
+
onClose();
|
|
163
|
+
};
|
|
163
164
|
const buttons = cell.isMarkdown ? (
|
|
164
165
|
<>
|
|
165
166
|
{editingMarkdown ? (
|
|
166
167
|
<Tooltip title="Save">
|
|
167
|
-
<IconButton size="small" onClick={
|
|
168
|
+
<IconButton size="small" onClick={saveAndClose}>
|
|
168
169
|
<CheckIcon />
|
|
169
170
|
</IconButton>
|
|
170
171
|
</Tooltip>
|
|
@@ -207,13 +208,7 @@ export function MutableCell({
|
|
|
207
208
|
)}
|
|
208
209
|
{editingMalloy && (
|
|
209
210
|
<Tooltip title="Save">
|
|
210
|
-
<IconButton
|
|
211
|
-
size="small"
|
|
212
|
-
onClick={() => {
|
|
213
|
-
saveResult();
|
|
214
|
-
onClose();
|
|
215
|
-
}}
|
|
216
|
-
>
|
|
211
|
+
<IconButton size="small" onClick={saveAndClose}>
|
|
217
212
|
<CheckIcon />
|
|
218
213
|
</IconButton>
|
|
219
214
|
</Tooltip>
|
|
@@ -230,22 +225,15 @@ export function MutableCell({
|
|
|
230
225
|
);
|
|
231
226
|
|
|
232
227
|
const isEditing = editingMalloy || editingMarkdown;
|
|
233
|
-
|
|
234
228
|
const editingButtons = editingMarkdown ? (
|
|
235
229
|
<Tooltip title="Save">
|
|
236
|
-
<IconButton size="small" onClick={
|
|
230
|
+
<IconButton size="small" onClick={saveAndClose}>
|
|
237
231
|
<CheckIcon />
|
|
238
232
|
</IconButton>
|
|
239
233
|
</Tooltip>
|
|
240
234
|
) : editingMalloy ? (
|
|
241
235
|
<Tooltip title="Save">
|
|
242
|
-
<IconButton
|
|
243
|
-
size="small"
|
|
244
|
-
onClick={() => {
|
|
245
|
-
saveResult();
|
|
246
|
-
onClose();
|
|
247
|
-
}}
|
|
248
|
-
>
|
|
236
|
+
<IconButton size="small" onClick={saveAndClose}>
|
|
249
237
|
<CheckIcon />
|
|
250
238
|
</IconButton>
|
|
251
239
|
</Tooltip>
|
|
@@ -305,12 +293,12 @@ export function MutableCell({
|
|
|
305
293
|
autoFocus
|
|
306
294
|
onChange={(newValue) => {
|
|
307
295
|
setValue(newValue);
|
|
308
|
-
|
|
296
|
+
onCellChange({ ...cell, value: newValue });
|
|
309
297
|
}}
|
|
310
298
|
onBlur={() => {
|
|
311
299
|
saveResult();
|
|
312
300
|
if (!isHovered) {
|
|
313
|
-
|
|
301
|
+
saveAndClose();
|
|
314
302
|
}
|
|
315
303
|
}}
|
|
316
304
|
/>
|
|
@@ -331,9 +319,9 @@ export function MutableCell({
|
|
|
331
319
|
"& blockquote": { mt: 0.5, mb: 0.5 },
|
|
332
320
|
}}
|
|
333
321
|
>
|
|
334
|
-
{value ? (
|
|
322
|
+
{cell.value ? (
|
|
335
323
|
<Box onClick={onEdit} sx={{ cursor: "pointer" }}>
|
|
336
|
-
<Markdown>{value}</Markdown>
|
|
324
|
+
<Markdown>{cell.value}</Markdown>
|
|
337
325
|
</Box>
|
|
338
326
|
) : (
|
|
339
327
|
<Box onClick={onEdit} sx={{ cursor: "pointer" }}>
|
|
@@ -469,22 +457,3 @@ export function MutableCell({
|
|
|
469
457
|
</StyledCard>
|
|
470
458
|
);
|
|
471
459
|
}
|
|
472
|
-
|
|
473
|
-
function useDebounce<T>(callback: (value: T) => void, delay: number = 2000) {
|
|
474
|
-
const timeoutRef = React.useRef<ReturnType<typeof setTimeout> | undefined>(
|
|
475
|
-
undefined,
|
|
476
|
-
);
|
|
477
|
-
|
|
478
|
-
return React.useCallback(
|
|
479
|
-
(value: T) => {
|
|
480
|
-
if (timeoutRef.current) {
|
|
481
|
-
clearTimeout(timeoutRef.current);
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
timeoutRef.current = setTimeout(() => {
|
|
485
|
-
callback(value);
|
|
486
|
-
}, delay);
|
|
487
|
-
},
|
|
488
|
-
[callback, delay],
|
|
489
|
-
);
|
|
490
|
-
}
|
|
@@ -18,10 +18,8 @@ import {
|
|
|
18
18
|
import Stack from "@mui/material/Stack";
|
|
19
19
|
import React from "react";
|
|
20
20
|
import { Configuration, ModelsApi } from "../../client";
|
|
21
|
-
import { useRouterClickHandler } from "../click_helper";
|
|
22
21
|
import { SourceAndPath } from "../Model/SourcesExplorer";
|
|
23
22
|
import { WorkbookManager } from "./WorkbookManager";
|
|
24
|
-
import { usePackage } from "../Package";
|
|
25
23
|
import { useServer } from "../ServerProvider";
|
|
26
24
|
import { StyledCard, StyledCardContent, StyledCardMedia } from "../styles";
|
|
27
25
|
import { MutableCell } from "./MutableCell";
|
|
@@ -31,6 +29,7 @@ import * as Malloy from "@malloydata/malloy-interfaces";
|
|
|
31
29
|
import { ModelPicker } from "./ModelPicker";
|
|
32
30
|
import { getAxiosConfig } from "../../hooks";
|
|
33
31
|
import { WorkbookLocator } from "./WorkbookStorage";
|
|
32
|
+
import { useRouterClickHandler } from "../click_helper";
|
|
34
33
|
|
|
35
34
|
const modelsApi = new ModelsApi(new Configuration());
|
|
36
35
|
|
|
@@ -39,6 +38,8 @@ interface WorkbookProps {
|
|
|
39
38
|
expandCodeCells?: boolean;
|
|
40
39
|
expandEmbeddings?: boolean;
|
|
41
40
|
hideEmbeddingIcons?: boolean;
|
|
41
|
+
defaultProjectName?: string;
|
|
42
|
+
defaultPackageName?: string;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
interface PathToSources {
|
|
@@ -51,20 +52,16 @@ export default function Workbook({
|
|
|
51
52
|
expandCodeCells,
|
|
52
53
|
expandEmbeddings,
|
|
53
54
|
hideEmbeddingIcons,
|
|
55
|
+
defaultProjectName,
|
|
56
|
+
defaultPackageName,
|
|
54
57
|
}: WorkbookProps) {
|
|
55
58
|
const navigate = useRouterClickHandler();
|
|
56
|
-
const packageContext = usePackage();
|
|
57
|
-
const { projectName, packageName, versionId } = packageContext;
|
|
58
59
|
const { server, getAccessToken } = useServer();
|
|
59
60
|
const { workbookStorage } = useWorkbookStorage();
|
|
61
|
+
const [success, setSuccess] = React.useState<string | undefined>(undefined);
|
|
60
62
|
const [lastError, setLastError] = React.useState<string | undefined>(
|
|
61
63
|
undefined,
|
|
62
64
|
);
|
|
63
|
-
if (!projectName || !packageName) {
|
|
64
|
-
throw new Error(
|
|
65
|
-
"Project and package must be provided via PubliserPackageProvider",
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
65
|
if (!workbookStorage) {
|
|
69
66
|
throw new Error(
|
|
70
67
|
"Workbook storage be provided via WorkbookStorageProvider",
|
|
@@ -92,17 +89,20 @@ export default function Workbook({
|
|
|
92
89
|
setMenuIndex(null);
|
|
93
90
|
};
|
|
94
91
|
const handleAddCell = (isMarkdown: boolean, index: number) => {
|
|
95
|
-
workbookData
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
92
|
+
if (!workbookData) return;
|
|
93
|
+
setWorkbookData(
|
|
94
|
+
workbookData.insertCell(index, {
|
|
95
|
+
isMarkdown,
|
|
96
|
+
value: "",
|
|
97
|
+
}),
|
|
98
|
+
);
|
|
100
99
|
if (isMarkdown) {
|
|
101
100
|
setEditingMarkdownIndex(index);
|
|
102
101
|
} else {
|
|
103
102
|
setEditingMalloyIndex(index);
|
|
104
103
|
}
|
|
105
104
|
handleMenuClose();
|
|
105
|
+
console.log("handleAddCell", isMarkdown, index);
|
|
106
106
|
};
|
|
107
107
|
|
|
108
108
|
const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false);
|
|
@@ -110,19 +110,22 @@ export default function Workbook({
|
|
|
110
110
|
setDeleteDialogOpen(true);
|
|
111
111
|
};
|
|
112
112
|
|
|
113
|
-
const handleDeleteConfirm = async (
|
|
114
|
-
if (workbookPath && workbookStorage
|
|
113
|
+
const handleDeleteConfirm = async () => {
|
|
114
|
+
if (workbookPath && workbookStorage) {
|
|
115
115
|
await workbookStorage
|
|
116
|
-
.deleteWorkbook(
|
|
116
|
+
.deleteWorkbook(workbookPath)
|
|
117
117
|
.then(() => {
|
|
118
118
|
setLastError(undefined);
|
|
119
|
+
setSuccess(undefined);
|
|
119
120
|
})
|
|
120
121
|
.catch((error) => {
|
|
121
122
|
setLastError(`Error deleting workbook: ${error.message}`);
|
|
123
|
+
setSuccess(undefined);
|
|
122
124
|
});
|
|
123
125
|
}
|
|
124
126
|
setDeleteDialogOpen(false);
|
|
125
|
-
|
|
127
|
+
// TODO(jjs) - on delete event
|
|
128
|
+
navigate(`/${defaultProjectName}/${defaultPackageName}`);
|
|
126
129
|
};
|
|
127
130
|
|
|
128
131
|
const handleDeleteCancel = () => {
|
|
@@ -130,11 +133,17 @@ export default function Workbook({
|
|
|
130
133
|
};
|
|
131
134
|
|
|
132
135
|
const saveWorkbook = React.useCallback(async () => {
|
|
136
|
+
if (!workbookData) {
|
|
137
|
+
console.log("No workbook data ref");
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
133
140
|
try {
|
|
134
141
|
setWorkbookData(await workbookData.saveWorkbook());
|
|
135
142
|
setLastError(undefined);
|
|
143
|
+
setSuccess("Workbook saved");
|
|
136
144
|
} catch (error) {
|
|
137
145
|
setLastError(`Error saving workbook: ${error.message}`);
|
|
146
|
+
setSuccess(undefined);
|
|
138
147
|
}
|
|
139
148
|
}, [workbookData]);
|
|
140
149
|
React.useEffect(() => {
|
|
@@ -159,10 +168,10 @@ export default function Workbook({
|
|
|
159
168
|
promises.push(
|
|
160
169
|
modelsApi
|
|
161
170
|
.getModel(
|
|
162
|
-
|
|
163
|
-
|
|
171
|
+
defaultProjectName,
|
|
172
|
+
defaultPackageName,
|
|
164
173
|
model,
|
|
165
|
-
|
|
174
|
+
undefined,
|
|
166
175
|
await getAxiosConfig(server, getAccessToken),
|
|
167
176
|
)
|
|
168
177
|
.then((data) => ({
|
|
@@ -193,24 +202,21 @@ export default function Workbook({
|
|
|
193
202
|
// Work this cannot depend on sourceAndPaths because it will cause an infinite loop.
|
|
194
203
|
getAccessToken,
|
|
195
204
|
workbookData,
|
|
196
|
-
|
|
197
|
-
|
|
205
|
+
defaultPackageName,
|
|
206
|
+
defaultProjectName,
|
|
198
207
|
server,
|
|
199
|
-
versionId,
|
|
200
208
|
]);
|
|
201
209
|
|
|
202
210
|
React.useEffect(() => {
|
|
203
211
|
if (!workbookPath) {
|
|
204
212
|
return;
|
|
205
213
|
}
|
|
206
|
-
WorkbookManager.loadWorkbook(
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
)
|
|
211
|
-
|
|
212
|
-
});
|
|
213
|
-
}, [workbookPath, workbookStorage, packageContext]);
|
|
214
|
+
WorkbookManager.loadWorkbook(workbookStorage, workbookPath).then(
|
|
215
|
+
(workbookData) => {
|
|
216
|
+
setWorkbookData(workbookData);
|
|
217
|
+
},
|
|
218
|
+
);
|
|
219
|
+
}, [workbookPath, workbookStorage]);
|
|
214
220
|
|
|
215
221
|
if (!workbookData) {
|
|
216
222
|
return <div>Loading...</div>;
|
|
@@ -271,13 +277,21 @@ export default function Workbook({
|
|
|
271
277
|
return (
|
|
272
278
|
<StyledCard variant="outlined">
|
|
273
279
|
<StyledCardContent>
|
|
274
|
-
{
|
|
275
|
-
<Box sx={{
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
280
|
+
<Box sx={{ mb: 2 }}>
|
|
281
|
+
<Box sx={{ minHeight: "24px" }}>
|
|
282
|
+
{lastError ? (
|
|
283
|
+
<Typography color="error" variant="body2">
|
|
284
|
+
{lastError}
|
|
285
|
+
</Typography>
|
|
286
|
+
) : success ? (
|
|
287
|
+
<Typography color="success" variant="body2">
|
|
288
|
+
{success}
|
|
289
|
+
</Typography>
|
|
290
|
+
) : (
|
|
291
|
+
<span> </span>
|
|
292
|
+
)}
|
|
279
293
|
</Box>
|
|
280
|
-
|
|
294
|
+
</Box>
|
|
281
295
|
<Stack
|
|
282
296
|
sx={{
|
|
283
297
|
flexDirection: "row",
|
|
@@ -305,7 +319,7 @@ export default function Workbook({
|
|
|
305
319
|
ml: 1,
|
|
306
320
|
}}
|
|
307
321
|
>
|
|
308
|
-
{`${
|
|
322
|
+
{`${workbookPath.workspace} > ${workbookPath.path}`}
|
|
309
323
|
</Typography>
|
|
310
324
|
</Stack>
|
|
311
325
|
<Stack sx={{ display: "flex", flexDirection: "row", gap: 1 }}>
|
|
@@ -356,7 +370,7 @@ export default function Workbook({
|
|
|
356
370
|
Cancel
|
|
357
371
|
</Button>
|
|
358
372
|
<Button
|
|
359
|
-
onClick={
|
|
373
|
+
onClick={handleDeleteConfirm}
|
|
360
374
|
color="error"
|
|
361
375
|
autoFocus
|
|
362
376
|
size="small"
|
|
@@ -416,7 +430,7 @@ export default function Workbook({
|
|
|
416
430
|
key={`${index}-${workbookData.getCells().length}`}
|
|
417
431
|
>
|
|
418
432
|
<MutableCell
|
|
419
|
-
key={`${index}-${cell.isMarkdown}-${workbookPath}-${
|
|
433
|
+
key={`${index}-${cell.isMarkdown}-${workbookPath.workspace}-${workbookPath.path}`}
|
|
420
434
|
cell={cell}
|
|
421
435
|
addButtonCallback={(isMarkdown) =>
|
|
422
436
|
plusButton(isMarkdown, index)
|
|
@@ -433,7 +447,6 @@ export default function Workbook({
|
|
|
433
447
|
}}
|
|
434
448
|
onCellChange={(cell) => {
|
|
435
449
|
setWorkbookData(workbookData.setCell(index, cell));
|
|
436
|
-
saveWorkbook();
|
|
437
450
|
}}
|
|
438
451
|
onEdit={() => {
|
|
439
452
|
if (cell.isMarkdown) {
|
|
@@ -448,6 +461,7 @@ export default function Workbook({
|
|
|
448
461
|
} else {
|
|
449
462
|
setEditingMalloyIndex(undefined);
|
|
450
463
|
}
|
|
464
|
+
saveWorkbook();
|
|
451
465
|
}}
|
|
452
466
|
/>
|
|
453
467
|
</React.Fragment>
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
} from "@mui/material";
|
|
9
9
|
import React from "react";
|
|
10
10
|
import { useWorkbookStorage } from "./WorkbookStorageProvider";
|
|
11
|
-
import { usePackage } from "../Package";
|
|
12
11
|
import { WorkbookLocator } from "./WorkbookStorage";
|
|
13
12
|
|
|
14
13
|
interface WorkbookListProps {
|
|
@@ -20,7 +19,6 @@ interface WorkbookListProps {
|
|
|
20
19
|
|
|
21
20
|
export function WorkbookList({ onWorkbookClick }: WorkbookListProps) {
|
|
22
21
|
const { workbookStorage } = useWorkbookStorage();
|
|
23
|
-
const packageContext = usePackage();
|
|
24
22
|
const [workbooks, setWorkbooks] = React.useState<WorkbookLocator[]>([]);
|
|
25
23
|
const [lastError, setLastError] = React.useState<string | undefined>(
|
|
26
24
|
undefined,
|
|
@@ -28,30 +26,28 @@ export function WorkbookList({ onWorkbookClick }: WorkbookListProps) {
|
|
|
28
26
|
|
|
29
27
|
React.useEffect(() => {
|
|
30
28
|
if (workbookStorage) {
|
|
31
|
-
workbookStorage
|
|
32
|
-
|
|
33
|
-
.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
setWorkbooks(allWorkbooks);
|
|
50
|
-
setLastError(undefined);
|
|
51
|
-
});
|
|
29
|
+
workbookStorage.listWorkspaces(false).then((workspaces) => {
|
|
30
|
+
const allWorkbooks: WorkbookLocator[] = [];
|
|
31
|
+
Promise.all(
|
|
32
|
+
workspaces.map(async (workspace) => {
|
|
33
|
+
await workbookStorage
|
|
34
|
+
.listWorkbooks(workspace)
|
|
35
|
+
.then((newWorkbooks) => {
|
|
36
|
+
allWorkbooks.push(...newWorkbooks);
|
|
37
|
+
})
|
|
38
|
+
.catch((error) => {
|
|
39
|
+
setLastError(
|
|
40
|
+
`Error listing workbooks: ${error.message}`,
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
}),
|
|
44
|
+
).then(() => {
|
|
45
|
+
setWorkbooks(allWorkbooks);
|
|
46
|
+
setLastError(undefined);
|
|
52
47
|
});
|
|
48
|
+
});
|
|
53
49
|
}
|
|
54
|
-
}, [workbookStorage
|
|
50
|
+
}, [workbookStorage]);
|
|
55
51
|
|
|
56
52
|
return (
|
|
57
53
|
<>
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { PackageContextProps } from "../Package";
|
|
2
1
|
import type { WorkbookLocator, WorkbookStorage } from "./WorkbookStorage";
|
|
3
2
|
|
|
4
3
|
/**
|
|
@@ -40,21 +39,17 @@ export interface WorkbookCellValue {
|
|
|
40
39
|
export class WorkbookManager {
|
|
41
40
|
private isSaved: boolean;
|
|
42
41
|
private workbookStorage: WorkbookStorage;
|
|
43
|
-
private packageContext: PackageContextProps;
|
|
44
42
|
|
|
45
43
|
/**
|
|
46
44
|
* Creates a new WorkbookManager instance
|
|
47
45
|
* @param {WorkbookStorage} workbookStorage - Storage implementation
|
|
48
|
-
* @param {PackageContextProps} packageContext - Package context for storage
|
|
49
46
|
* @param {WorkbookData} workbookData - Initial workbook data
|
|
50
47
|
*/
|
|
51
48
|
constructor(
|
|
52
49
|
workbookStorage: WorkbookStorage,
|
|
53
|
-
packageContext: PackageContextProps,
|
|
54
50
|
private workbookData: WorkbookData,
|
|
55
51
|
) {
|
|
56
52
|
this.workbookStorage = workbookStorage;
|
|
57
|
-
this.packageContext = packageContext;
|
|
58
53
|
if (this.workbookData) {
|
|
59
54
|
this.isSaved = true;
|
|
60
55
|
} else {
|
|
@@ -92,7 +87,6 @@ export class WorkbookManager {
|
|
|
92
87
|
if (this.workbookData.workbookPath.path !== workbookPath) {
|
|
93
88
|
try {
|
|
94
89
|
await this.workbookStorage.moveWorkbook(
|
|
95
|
-
this.packageContext,
|
|
96
90
|
this.workbookData.workbookPath,
|
|
97
91
|
{
|
|
98
92
|
path: workbookPath,
|
|
@@ -154,17 +148,12 @@ export class WorkbookManager {
|
|
|
154
148
|
throw new Error("Workbook path is not set");
|
|
155
149
|
}
|
|
156
150
|
await this.workbookStorage.saveWorkbook(
|
|
157
|
-
this.packageContext,
|
|
158
151
|
this.workbookData.workbookPath,
|
|
159
152
|
JSON.stringify(this.workbookData),
|
|
160
153
|
);
|
|
161
154
|
this.isSaved = true;
|
|
162
155
|
}
|
|
163
|
-
return new WorkbookManager(
|
|
164
|
-
this.workbookStorage,
|
|
165
|
-
this.packageContext,
|
|
166
|
-
this.workbookData,
|
|
167
|
-
);
|
|
156
|
+
return new WorkbookManager(this.workbookStorage, this.workbookData);
|
|
168
157
|
}
|
|
169
158
|
|
|
170
159
|
/**
|
|
@@ -188,11 +177,8 @@ export class WorkbookManager {
|
|
|
188
177
|
.join("\n");
|
|
189
178
|
}
|
|
190
179
|
|
|
191
|
-
static newWorkbook(
|
|
192
|
-
workbookStorage
|
|
193
|
-
packageContext: PackageContextProps,
|
|
194
|
-
): WorkbookManager {
|
|
195
|
-
return new WorkbookManager(workbookStorage, packageContext, undefined);
|
|
180
|
+
static newWorkbook(workbookStorage: WorkbookStorage): WorkbookManager {
|
|
181
|
+
return new WorkbookManager(workbookStorage, undefined);
|
|
196
182
|
}
|
|
197
183
|
|
|
198
184
|
/**
|
|
@@ -204,16 +190,11 @@ export class WorkbookManager {
|
|
|
204
190
|
*/
|
|
205
191
|
static async loadWorkbook(
|
|
206
192
|
workbookStorage: WorkbookStorage,
|
|
207
|
-
packageContext: PackageContextProps,
|
|
208
193
|
workbookPath: WorkbookLocator,
|
|
209
194
|
): Promise<WorkbookManager> {
|
|
210
195
|
let workbookData: WorkbookData | undefined = undefined;
|
|
211
|
-
console.log("loadWorkbook", workbookPath);
|
|
212
196
|
try {
|
|
213
|
-
const saved = await workbookStorage.getWorkbook(
|
|
214
|
-
packageContext,
|
|
215
|
-
workbookPath,
|
|
216
|
-
);
|
|
197
|
+
const saved = await workbookStorage.getWorkbook(workbookPath);
|
|
217
198
|
if (saved) {
|
|
218
199
|
workbookData = JSON.parse(saved);
|
|
219
200
|
}
|
|
@@ -225,6 +206,6 @@ export class WorkbookManager {
|
|
|
225
206
|
workbookPath: workbookPath,
|
|
226
207
|
};
|
|
227
208
|
}
|
|
228
|
-
return new WorkbookManager(workbookStorage,
|
|
209
|
+
return new WorkbookManager(workbookStorage, workbookData);
|
|
229
210
|
}
|
|
230
211
|
}
|
|
@@ -13,42 +13,22 @@ export interface WorkbookLocator {
|
|
|
13
13
|
|
|
14
14
|
export interface WorkbookStorage {
|
|
15
15
|
// Lists all available workspaces for the context.
|
|
16
|
-
listWorkspaces(
|
|
17
|
-
context: PackageContextProps,
|
|
18
|
-
writeableOnly: boolean,
|
|
19
|
-
): Promise<Workspace[]>;
|
|
16
|
+
listWorkspaces(writeableOnly: boolean): Promise<Workspace[]>;
|
|
20
17
|
|
|
21
18
|
// Lists all available workbooks for the context.
|
|
22
19
|
// Workbooks names are like S3 paths- / denote hierarchical
|
|
23
20
|
// folders, but otherwise folders are not "real" objects
|
|
24
|
-
listWorkbooks(
|
|
25
|
-
workspace: Workspace,
|
|
26
|
-
context: PackageContextProps,
|
|
27
|
-
): Promise<WorkbookLocator[]>;
|
|
21
|
+
listWorkbooks(workspace: Workspace): Promise<WorkbookLocator[]>;
|
|
28
22
|
|
|
29
23
|
// Returns the workbook at the specific path, throws an exception if no such workbook exists (or cannot be accessed)
|
|
30
|
-
getWorkbook(
|
|
31
|
-
context: PackageContextProps,
|
|
32
|
-
path: WorkbookLocator,
|
|
33
|
-
): Promise<string>;
|
|
24
|
+
getWorkbook(path: WorkbookLocator): Promise<string>;
|
|
34
25
|
|
|
35
26
|
// Deletes the workbook at the specified path, or throws an
|
|
36
27
|
// Exception on failure
|
|
37
|
-
deleteWorkbook(
|
|
38
|
-
context: PackageContextProps,
|
|
39
|
-
path: WorkbookLocator,
|
|
40
|
-
): Promise<void>;
|
|
28
|
+
deleteWorkbook(path: WorkbookLocator): Promise<void>;
|
|
41
29
|
|
|
42
|
-
saveWorkbook(
|
|
43
|
-
context: PackageContextProps,
|
|
44
|
-
path: WorkbookLocator,
|
|
45
|
-
workbook: string,
|
|
46
|
-
): Promise<void>;
|
|
30
|
+
saveWorkbook(path: WorkbookLocator, workbook: string): Promise<void>;
|
|
47
31
|
|
|
48
32
|
// Moves workbook from the "from" path to the "to" path
|
|
49
|
-
moveWorkbook(
|
|
50
|
-
context: PackageContextProps,
|
|
51
|
-
from: WorkbookLocator,
|
|
52
|
-
to: WorkbookLocator,
|
|
53
|
-
): Promise<void>;
|
|
33
|
+
moveWorkbook(from: WorkbookLocator, to: WorkbookLocator): Promise<void>;
|
|
54
34
|
}
|