@malloy-publisher/sdk 0.0.198-dev → 0.0.198-dev2

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.
Files changed (45) hide show
  1. package/dist/{ServerProvider-DDScRRDc.es.js → ServerProvider-BuM1usxf.es.js} +181 -177
  2. package/dist/{ServerProvider-IhQ4aYBm.cjs.js → ServerProvider-C_Mnvmgc.cjs.js} +1 -1
  3. package/dist/client/api.d.ts +61 -4
  4. package/dist/client/index.cjs.js +1 -1
  5. package/dist/client/index.es.js +1 -1
  6. package/dist/components/Package/ContentTypeIcon.d.ts +16 -0
  7. package/dist/components/Package/index.d.ts +0 -1
  8. package/dist/components/styles.d.ts +16 -0
  9. package/dist/{core-w79IMXAG.es.js → core-DfcpQGVP.es.js} +1 -1
  10. package/dist/{core-7-3Jcsb0.cjs.js → core-yDgxkpo0.cjs.js} +1 -1
  11. package/dist/index-CMA8U4-B.cjs.js +228 -0
  12. package/dist/{index-CN0_kZSF.es.js → index-Y4ooZDYA.es.js} +17654 -20603
  13. package/dist/index.cjs.js +1 -1
  14. package/dist/index.es.js +33 -34
  15. package/package.json +5 -5
  16. package/src/components/Environment/AddPackageDialog.tsx +116 -79
  17. package/src/components/Environment/DeletePackageDialog.tsx +3 -2
  18. package/src/components/Environment/Environment.tsx +44 -23
  19. package/src/components/Environment/Packages.tsx +164 -156
  20. package/src/components/Home/DeleteEnvironmentDialog.tsx +3 -2
  21. package/src/components/Home/Home.tsx +272 -389
  22. package/src/components/Model/Model.tsx +2 -2
  23. package/src/components/Model/ModelCell.tsx +1 -1
  24. package/src/components/Model/ModelExplorerDialog.tsx +1 -1
  25. package/src/components/Model/SourcesExplorer.tsx +4 -4
  26. package/src/components/Notebook/Notebook.tsx +4 -9
  27. package/src/components/Notebook/NotebookCell.tsx +10 -7
  28. package/src/components/Package/ContentTypeIcon.tsx +79 -0
  29. package/src/components/Package/Package.tsx +387 -55
  30. package/src/components/Package/index.ts +0 -1
  31. package/src/components/QueryResult/QueryResult.tsx +1 -1
  32. package/src/components/RenderedResult/RenderedResult.tsx +9 -8
  33. package/src/components/ResultsDialog.tsx +1 -1
  34. package/src/components/styles.ts +28 -15
  35. package/dist/components/Package/Config.d.ts +0 -5
  36. package/dist/components/Package/Databases.d.ts +0 -5
  37. package/dist/components/Package/FileTreeView.d.ts +0 -9
  38. package/dist/components/Package/Models.d.ts +0 -6
  39. package/dist/components/Package/Notebooks.d.ts +0 -6
  40. package/dist/index-Xo_ADux9.cjs.js +0 -233
  41. package/src/components/Package/Config.tsx +0 -97
  42. package/src/components/Package/Databases.tsx +0 -228
  43. package/src/components/Package/FileTreeView.tsx +0 -241
  44. package/src/components/Package/Models.tsx +0 -68
  45. package/src/components/Package/Notebooks.tsx +0 -77
@@ -1,97 +0,0 @@
1
- import ErrorIcon from "@mui/icons-material/ErrorOutlined";
2
- import { Box, List, ListItem, ListItemText } from "@mui/material";
3
- import { useQueryWithApiError } from "../../hooks/useQueryWithApiError";
4
- import { ApiErrorDisplay } from "../ApiErrorDisplay";
5
- import { Loading } from "../Loading";
6
- import {
7
- PackageCard,
8
- PackageCardContent,
9
- PackageSectionTitle,
10
- } from "../styles";
11
- import { parseResourceUri } from "../../utils/formatting";
12
- import { useServer } from "../ServerProvider";
13
-
14
- type Props = {
15
- resourceUri: string;
16
- };
17
-
18
- export default function Config({ resourceUri }: Props) {
19
- const { apiClients } = useServer();
20
- const {
21
- environmentName: environmentName,
22
- packageName: packageName,
23
- versionId: versionId,
24
- } = parseResourceUri(resourceUri);
25
-
26
- const { data, isSuccess, isError, error } = useQueryWithApiError({
27
- queryKey: ["package", environmentName, packageName, versionId],
28
- queryFn: () =>
29
- apiClients.packages.getPackage(
30
- environmentName,
31
- packageName,
32
- versionId,
33
- false,
34
- ),
35
- });
36
-
37
- return (
38
- <PackageCard>
39
- <PackageCardContent>
40
- <PackageSectionTitle>Package Config</PackageSectionTitle>
41
- <Box
42
- sx={{
43
- maxHeight: "200px",
44
- overflowY: "auto",
45
- }}
46
- >
47
- <List dense={true} disablePadding={true}>
48
- <ListItem dense={true} disablePadding={true}>
49
- <ListItemText
50
- primary="Name"
51
- primaryTypographyProps={{ fontWeight: "500" }}
52
- secondary={packageName}
53
- />
54
- </ListItem>
55
- {!isSuccess && !isError && (
56
- <ListItem>
57
- <Loading text="Fetching Package Metadata..." />
58
- </ListItem>
59
- )}
60
- {isSuccess &&
61
- ((data.data && (
62
- <ListItem dense={true} disablePadding={true}>
63
- <ListItemText
64
- primary="Description"
65
- primaryTypographyProps={{
66
- fontWeight: "500",
67
- }}
68
- secondary={data.data.description}
69
- />
70
- </ListItem>
71
- )) || (
72
- <ListItem
73
- disablePadding={true}
74
- dense={true}
75
- sx={{ mt: "20px" }}
76
- >
77
- <ErrorIcon
78
- sx={{
79
- color: "grey.600",
80
- mr: "10px",
81
- }}
82
- />
83
- <ListItemText primary={"No package manifest"} />
84
- </ListItem>
85
- ))}
86
- {isError && (
87
- <ApiErrorDisplay
88
- error={error}
89
- context={`${environmentName} > ${packageName} > ${versionId}`}
90
- />
91
- )}
92
- </List>
93
- </Box>
94
- </PackageCardContent>
95
- </PackageCard>
96
- );
97
- }
@@ -1,228 +0,0 @@
1
- import {
2
- Box,
3
- Dialog,
4
- DialogContent,
5
- DialogTitle,
6
- Table,
7
- TableBody,
8
- TableCell,
9
- TableContainer,
10
- TableHead,
11
- TableRow,
12
- Typography,
13
- IconButton,
14
- } from "@mui/material";
15
- import SearchIcon from "@mui/icons-material/Search";
16
- import React from "react";
17
- import { Database } from "../../client";
18
- import { useQueryWithApiError } from "../../hooks/useQueryWithApiError";
19
- import { ApiErrorDisplay } from "../ApiErrorDisplay";
20
- import { Loading } from "../Loading";
21
- import {
22
- PackageCard,
23
- PackageCardContent,
24
- PackageSectionTitle,
25
- } from "../styles";
26
- import { parseResourceUri } from "../../utils/formatting";
27
- import { useServer } from "../ServerProvider";
28
-
29
- type Props = {
30
- resourceUri: string;
31
- };
32
-
33
- export default function Databases({ resourceUri }: Props) {
34
- const { apiClients } = useServer();
35
- const {
36
- environmentName: environmentName,
37
- packageName: packageName,
38
- versionId: versionId,
39
- } = parseResourceUri(resourceUri);
40
-
41
- const [open, setOpen] = React.useState(false);
42
- const [selectedDatabase, setSelectedDatabase] =
43
- React.useState<Database | null>(null);
44
-
45
- const handleOpen = (database: Database) => {
46
- setSelectedDatabase(database);
47
- setOpen(true);
48
- };
49
-
50
- const handleClose = () => {
51
- setOpen(false);
52
- setSelectedDatabase(null);
53
- };
54
-
55
- const { data, isError, error, isSuccess } = useQueryWithApiError({
56
- queryKey: ["databases", environmentName, packageName, versionId],
57
- queryFn: () =>
58
- apiClients.databases.listDatabases(
59
- environmentName,
60
- packageName,
61
- versionId,
62
- ),
63
- });
64
- const formatRowSize = (size: number) => {
65
- if (size >= 1024 * 1024 * 1024 * 1024) {
66
- return `${(size / (1024 * 1024 * 1024)).toFixed(2)} T`;
67
- } else if (size >= 1024 * 1024 * 1024) {
68
- return `${(size / (1024 * 1024 * 1024)).toFixed(2)} G`;
69
- } else if (size >= 1024 * 1024) {
70
- return `${(size / (1024 * 1024)).toFixed(2)} M`;
71
- } else {
72
- return `${(size / 1024).toFixed(2)} K`;
73
- }
74
- };
75
- return (
76
- <>
77
- <PackageCard>
78
- <PackageCardContent>
79
- <PackageSectionTitle>Embedded Databases</PackageSectionTitle>
80
- <Box
81
- sx={{
82
- maxHeight: "200px",
83
- overflowY: "auto",
84
- }}
85
- >
86
- {!isSuccess && !isError && (
87
- <Loading text="Fetching Databases..." />
88
- )}
89
- {isError && (
90
- <ApiErrorDisplay
91
- error={error}
92
- context={`${environmentName} > ${packageName} > Databases`}
93
- />
94
- )}
95
- {isSuccess && data.data.length > 0 && (
96
- <Table
97
- size="small"
98
- sx={{
99
- borderCollapse: "collapse",
100
- "& .MuiTableCell-root": {
101
- borderBottom: "1px solid #e0e0e0",
102
- },
103
- "& .MuiTableRow-root:last-child .MuiTableCell-root":
104
- {
105
- borderBottom: "none",
106
- },
107
- }}
108
- >
109
- <TableBody>
110
- <TableRow>
111
- <TableCell>
112
- <Typography
113
- variant="body2"
114
- fontWeight="500"
115
- color="text.secondary"
116
- >
117
- Name
118
- </Typography>
119
- </TableCell>
120
- <TableCell align="right">
121
- <Typography
122
- variant="body2"
123
- fontWeight="500"
124
- color="text.secondary"
125
- >
126
- Rows
127
- </Typography>
128
- </TableCell>
129
- </TableRow>
130
- {data.data.map((database) => (
131
- <TableRow
132
- key={database.path}
133
- onClick={() => handleOpen(database)}
134
- sx={{
135
- cursor: "pointer",
136
- "&:hover": {
137
- backgroundColor: "action.hover",
138
- },
139
- }}
140
- >
141
- <TableCell component="th" scope="row">
142
- <Box
143
- sx={{
144
- display: "flex",
145
- alignItems: "center",
146
- gap: 1,
147
- }}
148
- >
149
- <Typography variant="body2">
150
- {database.path}
151
- </Typography>
152
- <SearchIcon
153
- sx={{
154
- fontSize: "1rem",
155
- color: "action.active",
156
- opacity: 0.7,
157
- }}
158
- />
159
- </Box>
160
- </TableCell>
161
- <TableCell align="right">
162
- <Typography variant="body2">
163
- {formatRowSize(database.info.rowCount)}
164
- </Typography>
165
- </TableCell>
166
- </TableRow>
167
- ))}
168
- </TableBody>
169
- </Table>
170
- )}
171
- {isSuccess && data.data.length === 0 && (
172
- <Typography variant="body2" sx={{ m: "auto" }}>
173
- No databases found
174
- </Typography>
175
- )}
176
- </Box>
177
- </PackageCardContent>
178
- </PackageCard>
179
-
180
- <Dialog open={open} onClose={handleClose} maxWidth="sm" fullWidth>
181
- <DialogTitle>
182
- {selectedDatabase?.path}
183
- <IconButton
184
- aria-label="close"
185
- onClick={handleClose}
186
- sx={{ position: "absolute", right: 8, top: 8 }}
187
- >
188
- <Box
189
- sx={{
190
- width: 24,
191
- height: 24,
192
- display: "flex",
193
- alignItems: "center",
194
- justifyContent: "center",
195
- }}
196
- >
197
- X
198
- </Box>
199
- </IconButton>
200
- </DialogTitle>
201
- <DialogContent>
202
- {selectedDatabase?.info?.columns && (
203
- <TableContainer>
204
- <Table size="small">
205
- <TableHead>
206
- <TableRow>
207
- <TableCell>Column</TableCell>
208
- <TableCell>Type</TableCell>
209
- </TableRow>
210
- </TableHead>
211
- <TableBody>
212
- {selectedDatabase.info.columns.map((column) => (
213
- <TableRow key={column.name}>
214
- <TableCell component="th" scope="row">
215
- {column.name}
216
- </TableCell>
217
- <TableCell>{column.type}</TableCell>
218
- </TableRow>
219
- ))}
220
- </TableBody>
221
- </Table>
222
- </TableContainer>
223
- )}
224
- </DialogContent>
225
- </Dialog>
226
- </>
227
- );
228
- }
@@ -1,241 +0,0 @@
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
- }
@@ -1,68 +0,0 @@
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
- }