@malloy-publisher/sdk 0.0.201 → 0.0.202
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/Package/FileTreeView.d.ts +9 -0
- package/dist/components/Package/Models.d.ts +6 -0
- package/dist/components/Package/index.d.ts +1 -0
- package/dist/{core-B3IQNPBD.es.js → core-B3A61KGJ.es.js} +1 -1
- package/dist/{core-GkjltsUf.cjs.js → core-CKNmRclF.cjs.js} +1 -1
- package/dist/{index-uW-ZBpF2.es.js → index-B0i0wzpF.es.js} +19410 -16503
- package/dist/index-C2OvwukW.cjs.js +234 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +42 -41
- package/package.json +1 -1
- package/src/components/Package/FileTreeView.tsx +241 -0
- package/src/components/Package/Models.tsx +68 -0
- package/src/components/Package/index.ts +1 -0
- package/dist/index-BpoC5QHF.cjs.js +0 -229
package/dist/index.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-C2OvwukW.cjs.js"),o=require("./ServerProvider-BSyxB6sf.cjs.js");exports.AnalyzePackageButton=e.AnalyzePackageButton;exports.BrowserWorkbookStorage=e.BrowserWorkbookStorage;exports.ConnectionExplorer=e.ConnectionExplorer;exports.DimensionFilter=e.DimensionFilter;exports.EmbeddedQueryResult=e.EmbeddedQueryResult;exports.Environment=e.Environment;exports.Home=e.Home;exports.Loading=e.Loading;exports.Model=e.Model;exports.ModelExplorer=e.ModelExplorer;exports.ModelExplorerDialog=e.ModelExplorerDialog;exports.Models=e.Models;exports.Notebook=e.Notebook;exports.Package=e.Package;exports.Packages=e.Packages;exports.QueryResult=e.QueryResult;exports.RenderedResult=e.RenderedResult;exports.ResultContainer=e.ResultContainer;exports.SourceExplorerComponent=e.SourceExplorerComponent;exports.SourcesExplorer=e.SourcesExplorer;exports.Workbook=e.Workbook;exports.WorkbookList=e.WorkbookList;exports.WorkbookManager=e.WorkbookManager;exports.WorkbookStorageProvider=e.WorkbookStorageProvider;exports.createEmbeddedQueryResult=e.createEmbeddedQueryResult;exports.encodeResourceUri=e.encodeResourceUri;exports.extractDimensionSpecs=e.extractDimensionSpecs;exports.extractSourceFromQuery=e.extractSourceFromQuery;exports.generateFilterClause=e.generateFilterClause;exports.getDimensionKey=e.getDimensionKey;exports.getJoinedSources=e.getJoinedSources;exports.injectWhereClause=e.injectWhereClause;exports.makeDimensionKey=e.makeDimensionKey;exports.parseAllSourceInfos=e.parseAllSourceInfos;exports.parseDimensionFilterAnnotation=e.parseDimensionFilterAnnotation;exports.parseNotebookFilterAnnotation=e.parseNotebookFilterAnnotation;exports.parseResourceUri=e.parseResourceUri;exports.useDimensionFilters=e.useDimensionFilters;exports.useDimensionFiltersFromSpec=e.useDimensionFiltersFromSpec;exports.useDimensionFiltersQuery=e.useDimensionFiltersQuery;exports.useDimensionalFilterRangeData=e.useDimensionalFilterRangeData;exports.useGivensForm=e.useGivensForm;exports.useModelData=e.useModelData;exports.useModelGivens=e.useModelGivens;exports.useRawQueryData=e.useRawQueryData;exports.useRouterClickHandler=e.useRouterClickHandler;exports.ServerProvider=o.ServerProvider;exports.useServer=o.useServer;
|
package/dist/index.es.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as a,
|
|
2
|
-
import { S as
|
|
1
|
+
import { A as a, J as o, C as r, D as n, y as i, E as t, H as l, L as u, M as m, o as d, q as c, x as k, N as p, v as D, P as g, Q as S, R as F, F as R, r as x, S as y, W as b, G as E, K as v, I as M, B as C, a0 as Q, g as W, i as P, j as A, X as f, k as B, l as G, Y as H, p as K, m as L, n as N, $ as U, O as j, T as w, U as I, V as J, _ as h, t as q, Z as z, u as O, e as T } from "./index-B0i0wzpF.es.js";
|
|
2
|
+
import { S as X, u as Y } from "./ServerProvider-DSnbMlP3.es.js";
|
|
3
3
|
export {
|
|
4
4
|
a as AnalyzePackageButton,
|
|
5
5
|
o as BrowserWorkbookStorage,
|
|
@@ -7,45 +7,46 @@ export {
|
|
|
7
7
|
n as DimensionFilter,
|
|
8
8
|
i as EmbeddedQueryResult,
|
|
9
9
|
t as Environment,
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
l as Home,
|
|
11
|
+
u as Loading,
|
|
12
12
|
m as Model,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
k as
|
|
16
|
-
p as
|
|
17
|
-
D as
|
|
18
|
-
g as
|
|
19
|
-
S as
|
|
20
|
-
F as
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
x as
|
|
24
|
-
y as
|
|
25
|
-
b as
|
|
26
|
-
E as
|
|
27
|
-
v as
|
|
13
|
+
d as ModelExplorer,
|
|
14
|
+
c as ModelExplorerDialog,
|
|
15
|
+
k as Models,
|
|
16
|
+
p as Notebook,
|
|
17
|
+
D as Package,
|
|
18
|
+
g as Packages,
|
|
19
|
+
S as QueryResult,
|
|
20
|
+
F as RenderedResult,
|
|
21
|
+
R as ResultContainer,
|
|
22
|
+
X as ServerProvider,
|
|
23
|
+
x as SourceExplorerComponent,
|
|
24
|
+
y as SourcesExplorer,
|
|
25
|
+
b as Workbook,
|
|
26
|
+
E as WorkbookList,
|
|
27
|
+
v as WorkbookManager,
|
|
28
|
+
M as WorkbookStorageProvider,
|
|
28
29
|
C as createEmbeddedQueryResult,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
30
|
+
Q as encodeResourceUri,
|
|
31
|
+
W as extractDimensionSpecs,
|
|
32
|
+
P as extractSourceFromQuery,
|
|
33
|
+
A as generateFilterClause,
|
|
34
|
+
f as getDimensionKey,
|
|
35
|
+
B as getJoinedSources,
|
|
36
|
+
G as injectWhereClause,
|
|
37
|
+
H as makeDimensionKey,
|
|
38
|
+
K as parseAllSourceInfos,
|
|
39
|
+
L as parseDimensionFilterAnnotation,
|
|
40
|
+
N as parseNotebookFilterAnnotation,
|
|
41
|
+
U as parseResourceUri,
|
|
42
|
+
j as useDimensionFilters,
|
|
43
|
+
w as useDimensionFiltersFromSpec,
|
|
44
|
+
I as useDimensionFiltersQuery,
|
|
45
|
+
J as useDimensionalFilterRangeData,
|
|
46
|
+
h as useGivensForm,
|
|
47
|
+
q as useModelData,
|
|
48
|
+
z as useModelGivens,
|
|
49
|
+
O as useRawQueryData,
|
|
50
|
+
T as useRouterClickHandler,
|
|
51
|
+
Y as useServer
|
|
51
52
|
};
|
package/package.json
CHANGED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import {
|
|
3
|
+
TreeItem2Content,
|
|
4
|
+
TreeItem2Label,
|
|
5
|
+
TreeItem2Root,
|
|
6
|
+
TreeItem2IconContainer,
|
|
7
|
+
} from "@mui/x-tree-view/TreeItem2";
|
|
8
|
+
import { RichTreeView } from "@mui/x-tree-view/RichTreeView";
|
|
9
|
+
import { TreeItem2Provider } from "@mui/x-tree-view/TreeItem2Provider";
|
|
10
|
+
import { TreeViewBaseItem } from "@mui/x-tree-view/models";
|
|
11
|
+
import {
|
|
12
|
+
unstable_useTreeItem2 as useTreeItem2,
|
|
13
|
+
UseTreeItem2Parameters,
|
|
14
|
+
} from "@mui/x-tree-view/useTreeItem2";
|
|
15
|
+
import { TreeItem2Icon } from "@mui/x-tree-view/TreeItem2Icon";
|
|
16
|
+
import FolderIcon from "@mui/icons-material/FolderOutlined";
|
|
17
|
+
import ArticleIcon from "@mui/icons-material/ArticleOutlined";
|
|
18
|
+
import ErrorIcon from "@mui/icons-material/ErrorOutlined";
|
|
19
|
+
import { TransitionProps } from "@mui/material/transitions";
|
|
20
|
+
import { animated, useSpring } from "@react-spring/web";
|
|
21
|
+
import Collapse from "@mui/material/Collapse";
|
|
22
|
+
import DnsIcon from "@mui/icons-material/DnsOutlined";
|
|
23
|
+
import DataArrayIcon from "@mui/icons-material/DataArrayOutlined";
|
|
24
|
+
import { Database, Model } from "../../client";
|
|
25
|
+
import { Typography, Tooltip } from "@mui/material";
|
|
26
|
+
|
|
27
|
+
interface FiieTreeViewProps {
|
|
28
|
+
items: Model[] | Database[];
|
|
29
|
+
defaultExpandedItems: string[];
|
|
30
|
+
onClickTreeNode?: (to: string, event?: React.MouseEvent) => void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function FileTreeView({
|
|
34
|
+
items,
|
|
35
|
+
defaultExpandedItems,
|
|
36
|
+
onClickTreeNode,
|
|
37
|
+
}: FiieTreeViewProps) {
|
|
38
|
+
return (
|
|
39
|
+
<RichTreeView
|
|
40
|
+
items={getTreeView(items, onClickTreeNode)}
|
|
41
|
+
defaultExpandedItems={defaultExpandedItems}
|
|
42
|
+
slots={{ item: CustomTreeItem }}
|
|
43
|
+
/>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const AnimatedCollapse = animated(Collapse);
|
|
48
|
+
|
|
49
|
+
function TransitionComponent(props: TransitionProps) {
|
|
50
|
+
const style = useSpring({
|
|
51
|
+
to: {
|
|
52
|
+
opacity: props.in ? 1 : 0,
|
|
53
|
+
transform: `translate3d(0,${props.in ? 0 : 20}px,0)`,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return <AnimatedCollapse style={style} {...props} />;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
type FileType = "directory" | "model" | "notebook" | "database" | "unknown";
|
|
61
|
+
|
|
62
|
+
type ExtendedTreeItemProps = {
|
|
63
|
+
id: string;
|
|
64
|
+
label: string;
|
|
65
|
+
fileType: FileType;
|
|
66
|
+
selectable: boolean;
|
|
67
|
+
link: ((event?: React.MouseEvent) => void) | undefined;
|
|
68
|
+
error?: string;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
interface CustomLabelProps {
|
|
72
|
+
item: ExtendedTreeItemProps;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function CustomTreeItem2Label({ item, ...other }: CustomLabelProps) {
|
|
76
|
+
const label = (
|
|
77
|
+
<TreeItem2Label
|
|
78
|
+
{...other}
|
|
79
|
+
sx={{
|
|
80
|
+
display: "flex",
|
|
81
|
+
alignItems: "center",
|
|
82
|
+
color: item.error ? "error.main" : "grey.600",
|
|
83
|
+
}}
|
|
84
|
+
>
|
|
85
|
+
{(item.fileType === "directory" && <FolderIcon />) ||
|
|
86
|
+
(item.fileType === "notebook" && <ArticleIcon />) ||
|
|
87
|
+
(item.fileType === "model" && <DataArrayIcon />) ||
|
|
88
|
+
(item.fileType == "database" && <DnsIcon />) || <ErrorIcon />}
|
|
89
|
+
<Typography
|
|
90
|
+
variant="body2"
|
|
91
|
+
sx={{ marginLeft: "5px" }}
|
|
92
|
+
color={
|
|
93
|
+
item.error
|
|
94
|
+
? "error.main"
|
|
95
|
+
: item.link
|
|
96
|
+
? "primary.main"
|
|
97
|
+
: "grey.600"
|
|
98
|
+
}
|
|
99
|
+
>
|
|
100
|
+
{item.label}
|
|
101
|
+
</Typography>
|
|
102
|
+
</TreeItem2Label>
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
return item.error ? (
|
|
106
|
+
<Tooltip title={item.error} placement="right">
|
|
107
|
+
{label}
|
|
108
|
+
</Tooltip>
|
|
109
|
+
) : (
|
|
110
|
+
label
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
interface CustomTreeItemProps
|
|
115
|
+
extends Omit<UseTreeItem2Parameters, "rootRef">,
|
|
116
|
+
Omit<React.HTMLAttributes<HTMLLIElement>, "onFocus"> {}
|
|
117
|
+
|
|
118
|
+
const CustomTreeItem = React.forwardRef(function CustomTreeItem(
|
|
119
|
+
props: CustomTreeItemProps,
|
|
120
|
+
ref: React.Ref<HTMLLIElement>,
|
|
121
|
+
) {
|
|
122
|
+
const { id, itemId, label, children, disabled, ...other } = props;
|
|
123
|
+
const {
|
|
124
|
+
getRootProps,
|
|
125
|
+
getContentProps,
|
|
126
|
+
getLabelProps,
|
|
127
|
+
getIconContainerProps,
|
|
128
|
+
getGroupTransitionProps,
|
|
129
|
+
status,
|
|
130
|
+
publicAPI,
|
|
131
|
+
} = useTreeItem2({
|
|
132
|
+
id,
|
|
133
|
+
itemId,
|
|
134
|
+
children,
|
|
135
|
+
label,
|
|
136
|
+
disabled,
|
|
137
|
+
rootRef: ref,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
const item = publicAPI.getItem(itemId);
|
|
141
|
+
|
|
142
|
+
// Disable select and focus. We want to either click through to a model or notebook or just exapnd
|
|
143
|
+
// collapse
|
|
144
|
+
status.selected = false;
|
|
145
|
+
status.focused = false;
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<TreeItem2Provider itemId={itemId}>
|
|
149
|
+
<TreeItem2Root {...getRootProps(other)}>
|
|
150
|
+
<TreeItem2Content
|
|
151
|
+
{...getContentProps()}
|
|
152
|
+
{...(item.link && {
|
|
153
|
+
onClick: (event) => item.link(event),
|
|
154
|
+
})}
|
|
155
|
+
sx={{
|
|
156
|
+
// If the item is not selectable, disable pointer events.
|
|
157
|
+
pointerEvents: !item.selectable && "none",
|
|
158
|
+
}}
|
|
159
|
+
>
|
|
160
|
+
<TreeItem2IconContainer {...getIconContainerProps()}>
|
|
161
|
+
<TreeItem2Icon status={status} />
|
|
162
|
+
</TreeItem2IconContainer>
|
|
163
|
+
<CustomTreeItem2Label
|
|
164
|
+
{...getLabelProps({
|
|
165
|
+
item,
|
|
166
|
+
})}
|
|
167
|
+
/>
|
|
168
|
+
</TreeItem2Content>
|
|
169
|
+
{children && <TransitionComponent {...getGroupTransitionProps()} />}
|
|
170
|
+
</TreeItem2Root>
|
|
171
|
+
</TreeItem2Provider>
|
|
172
|
+
);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
function getTreeView(
|
|
176
|
+
metadataEntries: Model[] | Database[],
|
|
177
|
+
onClickTreeNode: (to: string, event?: React.MouseEvent) => void,
|
|
178
|
+
): TreeViewBaseItem<ExtendedTreeItemProps>[] {
|
|
179
|
+
const tree = new Map<string, unknown>();
|
|
180
|
+
metadataEntries.map((entry: Model | Database) => {
|
|
181
|
+
let node = tree;
|
|
182
|
+
const pathParts = entry.path.split("/");
|
|
183
|
+
pathParts.forEach((part, index) => {
|
|
184
|
+
if (index === pathParts.length - 1) {
|
|
185
|
+
node.set(part, entry);
|
|
186
|
+
} else if (!node.has(part)) {
|
|
187
|
+
node.set(part, new Map<string, unknown>());
|
|
188
|
+
node = node.get(part) as Map<string, unknown>;
|
|
189
|
+
} else {
|
|
190
|
+
node = node.get(part) as Map<string, unknown>;
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
return getTreeViewRecursive(tree, "", onClickTreeNode);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function getTreeViewRecursive(
|
|
198
|
+
node: Map<string, unknown>,
|
|
199
|
+
path: string,
|
|
200
|
+
onClickNode: (to: string, event?: React.MouseEvent) => void,
|
|
201
|
+
): TreeViewBaseItem<ExtendedTreeItemProps>[] {
|
|
202
|
+
const treeViewItems: TreeViewBaseItem<ExtendedTreeItemProps>[] = [];
|
|
203
|
+
node.forEach((value, key) => {
|
|
204
|
+
const fileType =
|
|
205
|
+
(key.endsWith(".malloy") && "model") ||
|
|
206
|
+
(key.endsWith(".malloynb") && "notebook") ||
|
|
207
|
+
(key.endsWith(".parquet") && "database") ||
|
|
208
|
+
"unknown";
|
|
209
|
+
if (fileType !== "unknown") {
|
|
210
|
+
// This is a model or database.
|
|
211
|
+
const entry = value as Model | Database;
|
|
212
|
+
treeViewItems.push({
|
|
213
|
+
id: path + key,
|
|
214
|
+
label: key,
|
|
215
|
+
fileType: fileType,
|
|
216
|
+
link:
|
|
217
|
+
fileType === "model" || fileType === "notebook"
|
|
218
|
+
? (event) => onClickNode(path + key, event)
|
|
219
|
+
: undefined,
|
|
220
|
+
selectable: fileType === "model" || fileType === "notebook",
|
|
221
|
+
error: "error" in entry ? entry.error : undefined,
|
|
222
|
+
});
|
|
223
|
+
} else {
|
|
224
|
+
// This is a directory.
|
|
225
|
+
const childPath = path + key + "/";
|
|
226
|
+
treeViewItems.push({
|
|
227
|
+
id: childPath,
|
|
228
|
+
label: key,
|
|
229
|
+
fileType: "directory",
|
|
230
|
+
selectable: true,
|
|
231
|
+
link: undefined,
|
|
232
|
+
children: getTreeViewRecursive(
|
|
233
|
+
value as Map<string, unknown>,
|
|
234
|
+
childPath,
|
|
235
|
+
onClickNode,
|
|
236
|
+
),
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
return treeViewItems;
|
|
241
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Box, Typography } from "@mui/material";
|
|
2
|
+
import { useQueryWithApiError } from "../../hooks/useQueryWithApiError";
|
|
3
|
+
import { ApiErrorDisplay } from "../ApiErrorDisplay";
|
|
4
|
+
import { Loading } from "../Loading";
|
|
5
|
+
import {
|
|
6
|
+
PackageCard,
|
|
7
|
+
PackageCardContent,
|
|
8
|
+
PackageSectionTitle,
|
|
9
|
+
} from "../styles";
|
|
10
|
+
import { FileTreeView } from "./FileTreeView";
|
|
11
|
+
import { parseResourceUri } from "../../utils/formatting";
|
|
12
|
+
import { useServer } from "../ServerProvider";
|
|
13
|
+
|
|
14
|
+
const DEFAULT_EXPANDED_FOLDERS = ["notebooks/", "models/"];
|
|
15
|
+
|
|
16
|
+
interface ModelsProps {
|
|
17
|
+
onClickModelFile: (to: string, event?: React.MouseEvent) => void;
|
|
18
|
+
resourceUri: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default function Models({ onClickModelFile, resourceUri }: ModelsProps) {
|
|
22
|
+
const {
|
|
23
|
+
environmentName: environmentName,
|
|
24
|
+
packageName: packageName,
|
|
25
|
+
versionId: versionId,
|
|
26
|
+
} = parseResourceUri(resourceUri);
|
|
27
|
+
const { apiClients } = useServer();
|
|
28
|
+
|
|
29
|
+
const { data, isError, error, isSuccess } = useQueryWithApiError({
|
|
30
|
+
queryKey: ["models", environmentName, packageName, versionId],
|
|
31
|
+
queryFn: () =>
|
|
32
|
+
apiClients.models.listModels(environmentName, packageName, versionId),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<PackageCard>
|
|
37
|
+
<PackageCardContent>
|
|
38
|
+
<PackageSectionTitle>Semantic Models</PackageSectionTitle>
|
|
39
|
+
<Box
|
|
40
|
+
sx={{
|
|
41
|
+
maxHeight: "200px",
|
|
42
|
+
overflowY: "auto",
|
|
43
|
+
}}
|
|
44
|
+
>
|
|
45
|
+
{!isSuccess && !isError && <Loading text="Fetching Models..." />}
|
|
46
|
+
{isError && (
|
|
47
|
+
<ApiErrorDisplay
|
|
48
|
+
error={error}
|
|
49
|
+
context={`${environmentName} > ${packageName} > Models`}
|
|
50
|
+
/>
|
|
51
|
+
)}
|
|
52
|
+
{isSuccess && data.data.length > 0 && (
|
|
53
|
+
<FileTreeView
|
|
54
|
+
items={data.data.sort((a, b) => {
|
|
55
|
+
return a.path.localeCompare(b.path);
|
|
56
|
+
})}
|
|
57
|
+
onClickTreeNode={onClickModelFile}
|
|
58
|
+
defaultExpandedItems={DEFAULT_EXPANDED_FOLDERS}
|
|
59
|
+
/>
|
|
60
|
+
)}
|
|
61
|
+
{isSuccess && data.data.length === 0 && (
|
|
62
|
+
<Typography variant="body2">No models found</Typography>
|
|
63
|
+
)}
|
|
64
|
+
</Box>
|
|
65
|
+
</PackageCardContent>
|
|
66
|
+
</PackageCard>
|
|
67
|
+
);
|
|
68
|
+
}
|