@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/index.cjs.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-BpoC5QHF.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.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;
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, I as o, C as r, D as n, x as i, E as t, H as u, L as l, M as m, o as c, q as d, N as k, v as p, P as D, Q as g, R as S, B as F, r as R, S as x, W as y, F as b, J as E, G as v, y as C, $ as M, g as Q, i as W, j as P, V as A, k as f, l as B, X as G, p as H, m as K, n as L, _ as N, K as U, O as j, T as w, U as I, Z as J, t as h, Y as q, u as z, e as O } from "./index-uW-ZBpF2.es.js";
2
- import { S as V, u as X } from "./ServerProvider-DSnbMlP3.es.js";
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
- u as Home,
11
- l as Loading,
10
+ l as Home,
11
+ u as Loading,
12
12
  m as Model,
13
- c as ModelExplorer,
14
- d as ModelExplorerDialog,
15
- k as Notebook,
16
- p as Package,
17
- D as Packages,
18
- g as QueryResult,
19
- S as RenderedResult,
20
- F as ResultContainer,
21
- V as ServerProvider,
22
- R as SourceExplorerComponent,
23
- x as SourcesExplorer,
24
- y as Workbook,
25
- b as WorkbookList,
26
- E as WorkbookManager,
27
- v as WorkbookStorageProvider,
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
- M as encodeResourceUri,
30
- Q as extractDimensionSpecs,
31
- W as extractSourceFromQuery,
32
- P as generateFilterClause,
33
- A as getDimensionKey,
34
- f as getJoinedSources,
35
- B as injectWhereClause,
36
- G as makeDimensionKey,
37
- H as parseAllSourceInfos,
38
- K as parseDimensionFilterAnnotation,
39
- L as parseNotebookFilterAnnotation,
40
- N as parseResourceUri,
41
- U as useDimensionFilters,
42
- j as useDimensionFiltersFromSpec,
43
- w as useDimensionFiltersQuery,
44
- I as useDimensionalFilterRangeData,
45
- J as useGivensForm,
46
- h as useModelData,
47
- q as useModelGivens,
48
- z as useRawQueryData,
49
- O as useRouterClickHandler,
50
- X as useServer
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@malloy-publisher/sdk",
3
3
  "description": "Malloy Publisher SDK",
4
- "version": "0.0.201",
4
+ "version": "0.0.202",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs.js",
7
7
  "module": "dist/index.es.js",
@@ -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
+ }
@@ -1 +1,2 @@
1
1
  export { default as Package } from "./Package";
2
+ export { default as Models } from "./Models";