@malloy-publisher/sdk 0.0.80 → 0.0.82
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/Model/Model.d.ts +3 -1
- package/dist/components/Model/ModelExplorer.d.ts +19 -0
- package/dist/components/Model/index.d.ts +3 -0
- package/dist/components/Model/useModelData.d.ts +8 -0
- package/dist/components/Package/index.d.ts +1 -0
- package/dist/components/Project/index.d.ts +1 -0
- package/dist/components/Workbook/BrowserWorkbookStorage.d.ts +11 -0
- package/dist/components/{MutableNotebook → Workbook}/EditableMalloyCell.d.ts +2 -2
- package/dist/components/{MutableNotebook → Workbook}/MutableCell.d.ts +3 -3
- package/dist/components/Workbook/Workbook.d.ts +9 -0
- package/dist/components/Workbook/WorkbookList.d.ts +7 -0
- package/dist/components/Workbook/WorkbookManager.d.ts +87 -0
- package/dist/components/Workbook/WorkbookStorage.d.ts +18 -0
- package/dist/components/Workbook/WorkbookStorageProvider.d.ts +12 -0
- package/dist/components/Workbook/index.d.ts +7 -0
- package/dist/components/index.d.ts +3 -1
- package/dist/index.cjs.js +67 -67
- package/dist/index.es.js +9481 -9329
- package/package.json +3 -2
- package/src/components/AnalyzePackageButton.tsx +121 -24
- package/src/components/Model/Model.tsx +19 -110
- package/src/components/Model/ModelExplorer.tsx +138 -0
- package/src/components/Model/SourcesExplorer.tsx +65 -79
- package/src/components/Model/index.ts +3 -0
- package/src/components/Model/useModelData.ts +38 -0
- package/src/components/Package/index.ts +1 -0
- package/src/components/Project/index.ts +1 -0
- package/src/components/Workbook/BrowserWorkbookStorage.ts +100 -0
- package/src/components/{MutableNotebook → Workbook}/EditableMalloyCell.tsx +2 -2
- package/src/components/{MutableNotebook → Workbook}/MutableCell.tsx +3 -3
- package/src/components/{MutableNotebook/MutableNotebook.tsx → Workbook/Workbook.tsx} +81 -57
- package/src/components/Workbook/WorkbookList.tsx +111 -0
- package/src/components/Workbook/WorkbookManager.ts +230 -0
- package/src/components/Workbook/WorkbookStorage.ts +54 -0
- package/src/components/Workbook/WorkbookStorageProvider.tsx +37 -0
- package/src/components/Workbook/index.ts +7 -0
- package/src/components/index.ts +3 -1
- package/src/components/styles.ts +0 -3
- package/dist/components/MutableNotebook/BrowserNotebookStorage.d.ts +0 -9
- package/dist/components/MutableNotebook/MutableNotebook.d.ts +0 -8
- package/dist/components/MutableNotebook/MutableNotebookList.d.ts +0 -6
- package/dist/components/MutableNotebook/NotebookStorage.d.ts +0 -11
- package/dist/components/MutableNotebook/NotebookStorageProvider.d.ts +0 -14
- package/dist/components/MutableNotebook/index.d.ts +0 -5
- package/dist/components/NotebookManager.d.ts +0 -86
- package/src/components/MutableNotebook/BrowserNotebookStorage.ts +0 -58
- package/src/components/MutableNotebook/MutableNotebookList.tsx +0 -69
- package/src/components/MutableNotebook/NotebookStorage.ts +0 -27
- package/src/components/MutableNotebook/NotebookStorageProvider.tsx +0 -43
- package/src/components/MutableNotebook/index.ts +0 -8
- package/src/components/NotebookManager.ts +0 -225
- /package/dist/components/{MutableNotebook → Workbook}/ModelPicker.d.ts +0 -0
- /package/src/components/{MutableNotebook → Workbook}/ModelPicker.tsx +0 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Box,
|
|
3
|
+
Divider,
|
|
4
|
+
List,
|
|
5
|
+
ListItem,
|
|
6
|
+
ListItemText,
|
|
7
|
+
Typography,
|
|
8
|
+
} from "@mui/material";
|
|
9
|
+
import React from "react";
|
|
10
|
+
import { useWorkbookStorage } from "./WorkbookStorageProvider";
|
|
11
|
+
import { usePackage } from "../Package";
|
|
12
|
+
import { WorkbookLocator } from "./WorkbookStorage";
|
|
13
|
+
|
|
14
|
+
interface WorkbookListProps {
|
|
15
|
+
onWorkbookClick: (
|
|
16
|
+
workbook: WorkbookLocator,
|
|
17
|
+
event: React.MouseEvent,
|
|
18
|
+
) => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function WorkbookList({ onWorkbookClick }: WorkbookListProps) {
|
|
22
|
+
const { workbookStorage } = useWorkbookStorage();
|
|
23
|
+
const packageContext = usePackage();
|
|
24
|
+
const [workbooks, setWorkbooks] = React.useState<WorkbookLocator[]>([]);
|
|
25
|
+
const [lastError, setLastError] = React.useState<string | undefined>(
|
|
26
|
+
undefined,
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
React.useEffect(() => {
|
|
30
|
+
if (workbookStorage) {
|
|
31
|
+
workbookStorage
|
|
32
|
+
.listWorkspaces(packageContext, false)
|
|
33
|
+
.then((workspaces) => {
|
|
34
|
+
const allWorkbooks: WorkbookLocator[] = [];
|
|
35
|
+
Promise.all(
|
|
36
|
+
workspaces.map(async (workspace) => {
|
|
37
|
+
await workbookStorage
|
|
38
|
+
.listWorkbooks(workspace, packageContext)
|
|
39
|
+
.then((newWorkbooks) => {
|
|
40
|
+
allWorkbooks.push(...newWorkbooks);
|
|
41
|
+
})
|
|
42
|
+
.catch((error) => {
|
|
43
|
+
setLastError(
|
|
44
|
+
`Error listing workbooks: ${error.message}`,
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
}),
|
|
48
|
+
).then(() => {
|
|
49
|
+
setWorkbooks(allWorkbooks);
|
|
50
|
+
setLastError(undefined);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}, [workbookStorage, packageContext]);
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<>
|
|
58
|
+
{lastError && (
|
|
59
|
+
<Box sx={{ mb: 2 }}>
|
|
60
|
+
<Typography color="error" variant="body2">
|
|
61
|
+
{lastError}
|
|
62
|
+
</Typography>
|
|
63
|
+
</Box>
|
|
64
|
+
)}
|
|
65
|
+
<Divider />
|
|
66
|
+
<Box
|
|
67
|
+
sx={{
|
|
68
|
+
maxHeight: "300px",
|
|
69
|
+
overflow: "auto",
|
|
70
|
+
"&::-webkit-scrollbar": {
|
|
71
|
+
width: "8px",
|
|
72
|
+
},
|
|
73
|
+
"&::-webkit-scrollbar-track": {
|
|
74
|
+
background: "transparent",
|
|
75
|
+
},
|
|
76
|
+
"&::-webkit-scrollbar-thumb": {
|
|
77
|
+
background: "rgba(0,0,0,0.2)",
|
|
78
|
+
borderRadius: "4px",
|
|
79
|
+
},
|
|
80
|
+
}}
|
|
81
|
+
>
|
|
82
|
+
<List dense>
|
|
83
|
+
{workbooks.length === 0 && (
|
|
84
|
+
<ListItem>
|
|
85
|
+
<ListItemText
|
|
86
|
+
primary="No workbooks found."
|
|
87
|
+
sx={{ textAlign: "center" }}
|
|
88
|
+
/>
|
|
89
|
+
</ListItem>
|
|
90
|
+
)}
|
|
91
|
+
{workbooks.map((workbook) => (
|
|
92
|
+
<ListItem
|
|
93
|
+
key={workbook.path}
|
|
94
|
+
onClick={(event: React.MouseEvent) =>
|
|
95
|
+
onWorkbookClick(workbook, event)
|
|
96
|
+
}
|
|
97
|
+
sx={{
|
|
98
|
+
cursor: "pointer",
|
|
99
|
+
"&:hover": {
|
|
100
|
+
backgroundColor: "action.hover",
|
|
101
|
+
},
|
|
102
|
+
}}
|
|
103
|
+
>
|
|
104
|
+
<ListItemText primary={workbook.path} />
|
|
105
|
+
</ListItem>
|
|
106
|
+
))}
|
|
107
|
+
</List>
|
|
108
|
+
</Box>
|
|
109
|
+
</>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { PackageContextProps } from "../Package";
|
|
2
|
+
import type { WorkbookLocator, WorkbookStorage } from "./WorkbookStorage";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Interface representing the data structure of a Mutable Workbook
|
|
6
|
+
* @interface WorkbookData
|
|
7
|
+
* @property {string[]} models - Array of model paths used in the workbook
|
|
8
|
+
* @property {WorkbookCellValue[]} cells - Array of cells in the workbook
|
|
9
|
+
* @property {WorkbookLocator} workbookPath - Path to the workbook file (relative to project/package)
|
|
10
|
+
*/
|
|
11
|
+
export interface WorkbookData {
|
|
12
|
+
models: string[];
|
|
13
|
+
cells: WorkbookCellValue[];
|
|
14
|
+
workbookPath: WorkbookLocator;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Interface representing a cell in the workbook
|
|
19
|
+
* @interface WorkbookCellValue
|
|
20
|
+
* @property {boolean} isMarkdown - Whether the cell is a markdown cell
|
|
21
|
+
* @property {string} [value] - The content of the cell
|
|
22
|
+
* @property {string} [result] - The result of executing the cell
|
|
23
|
+
* @property {string} [modelPath] - modelPath associated with the query in the cell
|
|
24
|
+
* @property {string} [sourceName] - Name of the source associated with the cell
|
|
25
|
+
* @property {string} [queryInfo] - Information about the query in the cell
|
|
26
|
+
*/
|
|
27
|
+
export interface WorkbookCellValue {
|
|
28
|
+
isMarkdown: boolean;
|
|
29
|
+
value?: string;
|
|
30
|
+
result?: string;
|
|
31
|
+
modelPath?: string;
|
|
32
|
+
sourceName?: string;
|
|
33
|
+
queryInfo?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Class for managing workbook operations
|
|
38
|
+
* @class WorkbookManager
|
|
39
|
+
*/
|
|
40
|
+
export class WorkbookManager {
|
|
41
|
+
private isSaved: boolean;
|
|
42
|
+
private workbookStorage: WorkbookStorage;
|
|
43
|
+
private packageContext: PackageContextProps;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Creates a new WorkbookManager instance
|
|
47
|
+
* @param {WorkbookStorage} workbookStorage - Storage implementation
|
|
48
|
+
* @param {PackageContextProps} packageContext - Package context for storage
|
|
49
|
+
* @param {WorkbookData} workbookData - Initial workbook data
|
|
50
|
+
*/
|
|
51
|
+
constructor(
|
|
52
|
+
workbookStorage: WorkbookStorage,
|
|
53
|
+
packageContext: PackageContextProps,
|
|
54
|
+
private workbookData: WorkbookData,
|
|
55
|
+
) {
|
|
56
|
+
this.workbookStorage = workbookStorage;
|
|
57
|
+
this.packageContext = packageContext;
|
|
58
|
+
if (this.workbookData) {
|
|
59
|
+
this.isSaved = true;
|
|
60
|
+
} else {
|
|
61
|
+
this.workbookData = {
|
|
62
|
+
models: [],
|
|
63
|
+
cells: [],
|
|
64
|
+
workbookPath: undefined,
|
|
65
|
+
};
|
|
66
|
+
this.isSaved = false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Gets the current workbook data
|
|
72
|
+
* @returns {WorkbookData} The current workbook data
|
|
73
|
+
*/
|
|
74
|
+
getWorkbookData(): WorkbookData {
|
|
75
|
+
return this.workbookData;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Gets the current workbook path
|
|
80
|
+
* @returns {string} The path to the workbook
|
|
81
|
+
*/
|
|
82
|
+
getWorkbookPath(): WorkbookLocator {
|
|
83
|
+
return this.workbookData.workbookPath;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Renames the workbook and updates storage
|
|
88
|
+
* @param {string} workbookPath - New path for the workbook
|
|
89
|
+
* @returns {WorkbookManager} The updated WorkbookManager instance
|
|
90
|
+
*/
|
|
91
|
+
async renameWorkbook(workbookPath: string): Promise<WorkbookManager> {
|
|
92
|
+
if (this.workbookData.workbookPath.path !== workbookPath) {
|
|
93
|
+
try {
|
|
94
|
+
await this.workbookStorage.moveWorkbook(
|
|
95
|
+
this.packageContext,
|
|
96
|
+
this.workbookData.workbookPath,
|
|
97
|
+
{
|
|
98
|
+
path: workbookPath,
|
|
99
|
+
workspace: this.workbookData.workbookPath.workspace,
|
|
100
|
+
},
|
|
101
|
+
);
|
|
102
|
+
} catch {
|
|
103
|
+
// ignore if not found
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
this.workbookData.workbookPath.path = workbookPath;
|
|
107
|
+
this.isSaved = false;
|
|
108
|
+
return await this.saveWorkbook();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
getCells(): WorkbookCellValue[] {
|
|
112
|
+
return this.workbookData.cells;
|
|
113
|
+
}
|
|
114
|
+
deleteCell(index: number): WorkbookManager {
|
|
115
|
+
this.workbookData.cells = [
|
|
116
|
+
...this.workbookData.cells.slice(0, index),
|
|
117
|
+
...this.workbookData.cells.slice(index + 1),
|
|
118
|
+
];
|
|
119
|
+
this.isSaved = false;
|
|
120
|
+
return this;
|
|
121
|
+
}
|
|
122
|
+
insertCell(index: number, cell: WorkbookCellValue): WorkbookManager {
|
|
123
|
+
this.workbookData.cells = [
|
|
124
|
+
...this.workbookData.cells.slice(0, index),
|
|
125
|
+
cell,
|
|
126
|
+
...this.workbookData.cells.slice(index),
|
|
127
|
+
];
|
|
128
|
+
this.isSaved = false;
|
|
129
|
+
return this;
|
|
130
|
+
}
|
|
131
|
+
setCell(index: number, cell: WorkbookCellValue): WorkbookManager {
|
|
132
|
+
this.workbookData.cells[index] = cell;
|
|
133
|
+
this.isSaved = false;
|
|
134
|
+
return this;
|
|
135
|
+
}
|
|
136
|
+
setModels(models: string[]): WorkbookManager {
|
|
137
|
+
this.workbookData.models = models;
|
|
138
|
+
this.isSaved = false;
|
|
139
|
+
return this;
|
|
140
|
+
}
|
|
141
|
+
getModels(): string[] {
|
|
142
|
+
return this.workbookData.models;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
updateWorkbookData(workbookData: WorkbookData): WorkbookManager {
|
|
146
|
+
this.workbookData = workbookData;
|
|
147
|
+
this.isSaved = false;
|
|
148
|
+
return this;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async saveWorkbook(): Promise<WorkbookManager> {
|
|
152
|
+
if (!this.isSaved) {
|
|
153
|
+
if (!this.workbookData.workbookPath) {
|
|
154
|
+
throw new Error("Workbook path is not set");
|
|
155
|
+
}
|
|
156
|
+
await this.workbookStorage.saveWorkbook(
|
|
157
|
+
this.packageContext,
|
|
158
|
+
this.workbookData.workbookPath,
|
|
159
|
+
JSON.stringify(this.workbookData),
|
|
160
|
+
);
|
|
161
|
+
this.isSaved = true;
|
|
162
|
+
}
|
|
163
|
+
return new WorkbookManager(
|
|
164
|
+
this.workbookStorage,
|
|
165
|
+
this.packageContext,
|
|
166
|
+
this.workbookData,
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Converts the workbook data to a Malloy workbook string.
|
|
172
|
+
* @returns {string} The Malloy workbook string
|
|
173
|
+
*/
|
|
174
|
+
toMalloyWorkbook(): string {
|
|
175
|
+
return this.workbookData.cells
|
|
176
|
+
.map((cell) => {
|
|
177
|
+
if (cell.isMarkdown) {
|
|
178
|
+
return ">>>markdown\n" + cell.value;
|
|
179
|
+
} else {
|
|
180
|
+
return (
|
|
181
|
+
">>>malloy\n" +
|
|
182
|
+
`import {${cell.sourceName}}" from '${cell.modelPath}'"\n` +
|
|
183
|
+
cell.value +
|
|
184
|
+
"\n"
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
})
|
|
188
|
+
.join("\n");
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
static newWorkbook(
|
|
192
|
+
workbookStorage: WorkbookStorage,
|
|
193
|
+
packageContext: PackageContextProps,
|
|
194
|
+
): WorkbookManager {
|
|
195
|
+
return new WorkbookManager(workbookStorage, packageContext, undefined);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Creates a new workbook manager by loading from local storage.
|
|
200
|
+
* Returns an empty instance if the workbook is not found.
|
|
201
|
+
* @param workbookStorage - The storage implementation
|
|
202
|
+
* @param userContext - The user context for storage
|
|
203
|
+
* @param workbookPath - The path to the workbook file (relative to project/package)
|
|
204
|
+
*/
|
|
205
|
+
static async loadWorkbook(
|
|
206
|
+
workbookStorage: WorkbookStorage,
|
|
207
|
+
packageContext: PackageContextProps,
|
|
208
|
+
workbookPath: WorkbookLocator,
|
|
209
|
+
): Promise<WorkbookManager> {
|
|
210
|
+
let workbookData: WorkbookData | undefined = undefined;
|
|
211
|
+
console.log("loadWorkbook", workbookPath);
|
|
212
|
+
try {
|
|
213
|
+
const saved = await workbookStorage.getWorkbook(
|
|
214
|
+
packageContext,
|
|
215
|
+
workbookPath,
|
|
216
|
+
);
|
|
217
|
+
if (saved) {
|
|
218
|
+
workbookData = JSON.parse(saved);
|
|
219
|
+
}
|
|
220
|
+
} catch {
|
|
221
|
+
// Not found, create a new workbook
|
|
222
|
+
workbookData = {
|
|
223
|
+
models: [],
|
|
224
|
+
cells: [],
|
|
225
|
+
workbookPath: workbookPath,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
return new WorkbookManager(workbookStorage, packageContext, workbookData);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { PackageContextProps } from "../Package";
|
|
2
|
+
|
|
3
|
+
export interface Workspace {
|
|
4
|
+
name: string;
|
|
5
|
+
writeable: boolean;
|
|
6
|
+
description: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface WorkbookLocator {
|
|
10
|
+
path: string;
|
|
11
|
+
workspace: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface WorkbookStorage {
|
|
15
|
+
// Lists all available workspaces for the context.
|
|
16
|
+
listWorkspaces(
|
|
17
|
+
context: PackageContextProps,
|
|
18
|
+
writeableOnly: boolean,
|
|
19
|
+
): Promise<Workspace[]>;
|
|
20
|
+
|
|
21
|
+
// Lists all available workbooks for the context.
|
|
22
|
+
// Workbooks names are like S3 paths- / denote hierarchical
|
|
23
|
+
// folders, but otherwise folders are not "real" objects
|
|
24
|
+
listWorkbooks(
|
|
25
|
+
workspace: Workspace,
|
|
26
|
+
context: PackageContextProps,
|
|
27
|
+
): Promise<WorkbookLocator[]>;
|
|
28
|
+
|
|
29
|
+
// 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>;
|
|
34
|
+
|
|
35
|
+
// Deletes the workbook at the specified path, or throws an
|
|
36
|
+
// Exception on failure
|
|
37
|
+
deleteWorkbook(
|
|
38
|
+
context: PackageContextProps,
|
|
39
|
+
path: WorkbookLocator,
|
|
40
|
+
): Promise<void>;
|
|
41
|
+
|
|
42
|
+
saveWorkbook(
|
|
43
|
+
context: PackageContextProps,
|
|
44
|
+
path: WorkbookLocator,
|
|
45
|
+
workbook: string,
|
|
46
|
+
): Promise<void>;
|
|
47
|
+
|
|
48
|
+
// Moves workbook from the "from" path to the "to" path
|
|
49
|
+
moveWorkbook(
|
|
50
|
+
context: PackageContextProps,
|
|
51
|
+
from: WorkbookLocator,
|
|
52
|
+
to: WorkbookLocator,
|
|
53
|
+
): Promise<void>;
|
|
54
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React, { createContext, useContext, useMemo } from "react";
|
|
2
|
+
import type { WorkbookStorage } from "./WorkbookStorage";
|
|
3
|
+
|
|
4
|
+
export interface WorkbookStorageProviderProps {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
workbookStorage: WorkbookStorage;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface WorkbookStorageContextValue {
|
|
10
|
+
workbookStorage: WorkbookStorage;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const WorkbookStorageContext = createContext<
|
|
14
|
+
WorkbookStorageContextValue | undefined
|
|
15
|
+
>(undefined);
|
|
16
|
+
|
|
17
|
+
export function WorkbookStorageProvider({
|
|
18
|
+
children,
|
|
19
|
+
workbookStorage,
|
|
20
|
+
}: WorkbookStorageProviderProps) {
|
|
21
|
+
const value = useMemo(() => ({ workbookStorage }), [workbookStorage]);
|
|
22
|
+
return (
|
|
23
|
+
<WorkbookStorageContext.Provider value={value}>
|
|
24
|
+
{children}
|
|
25
|
+
</WorkbookStorageContext.Provider>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function useWorkbookStorage() {
|
|
30
|
+
const context = useContext(WorkbookStorageContext);
|
|
31
|
+
if (!context) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
"useWorkbookStorage must be used within a WorkbookStorageProvider",
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return context;
|
|
37
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { WorkbookStorage } from "./WorkbookStorage";
|
|
2
|
+
export { default as Workbook } from "./Workbook";
|
|
3
|
+
export { WorkbookList } from "./WorkbookList";
|
|
4
|
+
export { WorkbookStorageProvider } from "./WorkbookStorageProvider";
|
|
5
|
+
export type { WorkbookLocator, Workspace } from "./WorkbookStorage";
|
|
6
|
+
export { BrowserWorkbookStorage } from "./BrowserWorkbookStorage";
|
|
7
|
+
export { WorkbookManager } from "./WorkbookManager";
|
package/src/components/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from "./Model";
|
|
2
2
|
export * from "./Notebook";
|
|
3
|
-
export * from "./
|
|
3
|
+
export * from "./Workbook";
|
|
4
4
|
export * from "./Package";
|
|
5
5
|
export * from "./Project";
|
|
6
6
|
export * from "./QueryResult";
|
|
@@ -10,3 +10,5 @@ export { useRouterClickHandler } from "./click_helper";
|
|
|
10
10
|
export { ServerProvider, useServer } from "./ServerProvider";
|
|
11
11
|
export type { ServerContextValue, ServerProviderProps } from "./ServerProvider";
|
|
12
12
|
export { AnalyzePackageButton } from "./AnalyzePackageButton";
|
|
13
|
+
export type { PackageContextProps } from "./Package";
|
|
14
|
+
export type { WorkbookStorage } from "./Workbook";
|
package/src/components/styles.ts
CHANGED
|
@@ -18,8 +18,6 @@ export const StyledCardMedia = styled(CardMedia)({
|
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
export const StyledExplorerPage = styled("div")({
|
|
21
|
-
display: "flex",
|
|
22
|
-
flexDirection: "column",
|
|
23
21
|
height: "100%",
|
|
24
22
|
});
|
|
25
23
|
|
|
@@ -32,7 +30,6 @@ export const StyledExplorerBanner = styled("div")({
|
|
|
32
30
|
});
|
|
33
31
|
|
|
34
32
|
export const StyledExplorerContent = styled("div")({
|
|
35
|
-
display: "flex",
|
|
36
33
|
height: "75vh",
|
|
37
34
|
width: "100%",
|
|
38
35
|
overflowY: "auto",
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { NotebookStorage, UserContext } from './NotebookStorage';
|
|
2
|
-
export declare class BrowserNotebookStorage implements NotebookStorage {
|
|
3
|
-
private makeKey;
|
|
4
|
-
listNotebooks(context: UserContext): string[];
|
|
5
|
-
getNotebook(context: UserContext, path: string): string;
|
|
6
|
-
deleteNotebook(context: UserContext, path: string): void;
|
|
7
|
-
saveNotebook(context: UserContext, path: string, notebook: string): void;
|
|
8
|
-
moveNotebook(context: UserContext, from: string, to: string): void;
|
|
9
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
interface MutableNotebookProps {
|
|
2
|
-
notebookPath?: string;
|
|
3
|
-
expandCodeCells?: boolean;
|
|
4
|
-
expandEmbeddings?: boolean;
|
|
5
|
-
hideEmbeddingIcons?: boolean;
|
|
6
|
-
}
|
|
7
|
-
export default function MutableNotebook({ notebookPath, expandCodeCells, expandEmbeddings, hideEmbeddingIcons, }: MutableNotebookProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
-
export {};
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { default as React } from 'react';
|
|
2
|
-
interface MutableNotebookListProps {
|
|
3
|
-
onNotebookClick: (notebook: string, event: React.MouseEvent) => void;
|
|
4
|
-
}
|
|
5
|
-
export declare function MutableNotebookList({ onNotebookClick, }: MutableNotebookListProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
-
export {};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export interface UserContext {
|
|
2
|
-
project: string;
|
|
3
|
-
package: string;
|
|
4
|
-
}
|
|
5
|
-
export interface NotebookStorage {
|
|
6
|
-
listNotebooks(context: UserContext): string[];
|
|
7
|
-
getNotebook(context: UserContext, path: string): string;
|
|
8
|
-
deleteNotebook(context: UserContext, path: string): void;
|
|
9
|
-
saveNotebook(context: UserContext, path: string, notebook: string): void;
|
|
10
|
-
moveNotebook(context: UserContext, from: string, to: string): void;
|
|
11
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { default as React } from 'react';
|
|
2
|
-
import { NotebookStorage, UserContext } from './NotebookStorage';
|
|
3
|
-
interface NotebookStorageProviderProps {
|
|
4
|
-
children: React.ReactNode;
|
|
5
|
-
userContext: UserContext;
|
|
6
|
-
notebookStorage: NotebookStorage;
|
|
7
|
-
}
|
|
8
|
-
interface NotebookStorageContextValue {
|
|
9
|
-
notebookStorage: NotebookStorage;
|
|
10
|
-
userContext: UserContext;
|
|
11
|
-
}
|
|
12
|
-
export default function NotebookStorageProvider({ children, userContext, notebookStorage, }: NotebookStorageProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
-
export declare function useNotebookStorage(): NotebookStorageContextValue;
|
|
14
|
-
export {};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export { BrowserNotebookStorage } from './BrowserNotebookStorage';
|
|
2
|
-
export { default as MutableNotebook } from './MutableNotebook';
|
|
3
|
-
export type { NotebookStorage, UserContext } from './NotebookStorage';
|
|
4
|
-
export { MutableNotebookList } from './MutableNotebookList';
|
|
5
|
-
export { default as NotebookStorageProvider, useNotebookStorage, } from './NotebookStorageProvider';
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { NotebookStorage, UserContext } from './MutableNotebook/NotebookStorage';
|
|
2
|
-
/**
|
|
3
|
-
* Interface representing the data structure of a Mutable Notebook
|
|
4
|
-
* @interface NotebookData
|
|
5
|
-
* @property {string[]} models - Array of model paths used in the notebook
|
|
6
|
-
* @property {NotebookCellValue[]} cells - Array of cells in the notebook
|
|
7
|
-
* @property {string} notebookPath - Path to the notebook file (relative to project/package)
|
|
8
|
-
*/
|
|
9
|
-
export interface NotebookData {
|
|
10
|
-
models: string[];
|
|
11
|
-
cells: NotebookCellValue[];
|
|
12
|
-
notebookPath: string;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Interface representing a cell in the notebook
|
|
16
|
-
* @interface NotebookCellValue
|
|
17
|
-
* @property {boolean} isMarkdown - Whether the cell is a markdown cell
|
|
18
|
-
* @property {string} [value] - The content of the cell
|
|
19
|
-
* @property {string} [result] - The result of executing the cell
|
|
20
|
-
* @property {string} [modelPath] - modelPath associated with the query in the cell
|
|
21
|
-
* @property {string} [sourceName] - Name of the source associated with the cell
|
|
22
|
-
* @property {string} [queryInfo] - Information about the query in the cell
|
|
23
|
-
*/
|
|
24
|
-
export interface NotebookCellValue {
|
|
25
|
-
isMarkdown: boolean;
|
|
26
|
-
value?: string;
|
|
27
|
-
result?: string;
|
|
28
|
-
modelPath?: string;
|
|
29
|
-
sourceName?: string;
|
|
30
|
-
queryInfo?: string;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Class for managing notebook operations
|
|
34
|
-
* @class NotebookManager
|
|
35
|
-
*/
|
|
36
|
-
export declare class NotebookManager {
|
|
37
|
-
private notebookData;
|
|
38
|
-
private isSaved;
|
|
39
|
-
private notebookStorage;
|
|
40
|
-
private userContext;
|
|
41
|
-
/**
|
|
42
|
-
* Creates a new NotebookManager instance
|
|
43
|
-
* @param {NotebookStorage} notebookStorage - Storage implementation
|
|
44
|
-
* @param {UserContext} userContext - User context for storage
|
|
45
|
-
* @param {NotebookData} notebookData - Initial notebook data
|
|
46
|
-
*/
|
|
47
|
-
constructor(notebookStorage: NotebookStorage, userContext: UserContext, notebookData: NotebookData);
|
|
48
|
-
/**
|
|
49
|
-
* Gets the current notebook data
|
|
50
|
-
* @returns {NotebookData} The current notebook data
|
|
51
|
-
*/
|
|
52
|
-
getNotebookData(): NotebookData;
|
|
53
|
-
/**
|
|
54
|
-
* Gets the current notebook path
|
|
55
|
-
* @returns {string} The path to the notebook
|
|
56
|
-
*/
|
|
57
|
-
getNotebookPath(): string;
|
|
58
|
-
/**
|
|
59
|
-
* Renames the notebook and updates storage
|
|
60
|
-
* @param {string} notebookPath - New path for the notebook
|
|
61
|
-
* @returns {NotebookManager} The updated NotebookManager instance
|
|
62
|
-
*/
|
|
63
|
-
renameNotebook(notebookPath: string): NotebookManager;
|
|
64
|
-
getCells(): NotebookCellValue[];
|
|
65
|
-
deleteCell(index: number): NotebookManager;
|
|
66
|
-
insertCell(index: number, cell: NotebookCellValue): NotebookManager;
|
|
67
|
-
setCell(index: number, cell: NotebookCellValue): NotebookManager;
|
|
68
|
-
setModels(models: string[]): NotebookManager;
|
|
69
|
-
getModels(): string[];
|
|
70
|
-
updateNotebookData(notebookData: NotebookData): NotebookManager;
|
|
71
|
-
saveNotebook(): NotebookManager;
|
|
72
|
-
/**
|
|
73
|
-
* Converts the notebook data to a Malloy notebook string.
|
|
74
|
-
* @returns {string} The Malloy notebook string
|
|
75
|
-
*/
|
|
76
|
-
toMalloyNotebook(): string;
|
|
77
|
-
static newNotebook(notebookStorage: NotebookStorage, userContext: UserContext): NotebookManager;
|
|
78
|
-
/**
|
|
79
|
-
* Creates a new notebook manager by loading from local storage.
|
|
80
|
-
* Returns an empty instance if the notebook is not found.
|
|
81
|
-
* @param notebookStorage - The storage implementation
|
|
82
|
-
* @param userContext - The user context for storage
|
|
83
|
-
* @param notebookPath - The path to the notebook file (relative to project/package)
|
|
84
|
-
*/
|
|
85
|
-
static loadNotebook(notebookStorage: NotebookStorage, userContext: UserContext, notebookPath: string): NotebookManager;
|
|
86
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import type { NotebookStorage, UserContext } from "./NotebookStorage";
|
|
2
|
-
|
|
3
|
-
export class BrowserNotebookStorage implements NotebookStorage {
|
|
4
|
-
private makeKey(context: UserContext, path?: string): string {
|
|
5
|
-
let key = `BROWSER_NOTEBOOK_STORAGE__${context.project}/${context.package}`;
|
|
6
|
-
if (path) {
|
|
7
|
-
key += `/${path}`;
|
|
8
|
-
}
|
|
9
|
-
return key;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
listNotebooks(context: UserContext): string[] {
|
|
13
|
-
const prefix = this.makeKey(context);
|
|
14
|
-
const keys: string[] = [];
|
|
15
|
-
for (let i = 0; i < localStorage.length; i++) {
|
|
16
|
-
const key = localStorage.key(i);
|
|
17
|
-
if (key && key.startsWith(prefix + "/")) {
|
|
18
|
-
// Extract the notebook path after the prefix
|
|
19
|
-
const notebookPath = key.substring(prefix.length + 1);
|
|
20
|
-
keys.push(notebookPath);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return keys;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
getNotebook(context: UserContext, path: string): string {
|
|
27
|
-
const key = this.makeKey(context, path);
|
|
28
|
-
const notebook = localStorage.getItem(key);
|
|
29
|
-
if (notebook === null) {
|
|
30
|
-
throw new Error(`Notebook not found at path: ${path}`);
|
|
31
|
-
}
|
|
32
|
-
return notebook;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
deleteNotebook(context: UserContext, path: string): void {
|
|
36
|
-
const key = this.makeKey(context, path);
|
|
37
|
-
if (localStorage.getItem(key) === null) {
|
|
38
|
-
throw new Error(`Notebook not found at path: ${path}`);
|
|
39
|
-
}
|
|
40
|
-
localStorage.removeItem(key);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
saveNotebook(context: UserContext, path: string, notebook: string): void {
|
|
44
|
-
const key = this.makeKey(context, path);
|
|
45
|
-
localStorage.setItem(key, notebook);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
moveNotebook(context: UserContext, from: string, to: string): void {
|
|
49
|
-
const fromKey = this.makeKey(context, from);
|
|
50
|
-
const toKey = this.makeKey(context, to);
|
|
51
|
-
const notebook = localStorage.getItem(fromKey);
|
|
52
|
-
if (notebook === null) {
|
|
53
|
-
throw new Error(`Notebook not found at path: ${from}`);
|
|
54
|
-
}
|
|
55
|
-
localStorage.setItem(toKey, notebook);
|
|
56
|
-
localStorage.removeItem(fromKey);
|
|
57
|
-
}
|
|
58
|
-
}
|