@malloy-publisher/sdk 0.0.81 → 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 +1 -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/index.cjs.js +61 -61
- package/dist/index.es.js +6897 -6874
- package/package.json +1 -1
- package/src/components/Model/Model.tsx +17 -114
- 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/styles.ts +0 -3
package/package.json
CHANGED
|
@@ -1,34 +1,24 @@
|
|
|
1
1
|
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
|
|
2
2
|
import LinkOutlinedIcon from "@mui/icons-material/LinkOutlined";
|
|
3
3
|
import {
|
|
4
|
-
Box,
|
|
5
4
|
CardActions,
|
|
6
5
|
Collapse,
|
|
7
6
|
Divider,
|
|
8
7
|
IconButton,
|
|
9
8
|
Stack,
|
|
10
|
-
Tab,
|
|
11
|
-
Tabs,
|
|
12
9
|
Tooltip,
|
|
13
10
|
Typography,
|
|
14
11
|
} from "@mui/material";
|
|
15
12
|
import React, { useEffect } from "react";
|
|
16
|
-
import { Configuration, ModelsApi, CompiledModel } from "../../client";
|
|
17
13
|
import { highlight } from "../highlighter";
|
|
18
|
-
import { StyledCard, StyledCardContent
|
|
19
|
-
import { ModelCell } from "./ModelCell";
|
|
14
|
+
import { StyledCard, StyledCardContent } from "../styles";
|
|
20
15
|
import { ApiErrorDisplay } from "../ApiErrorDisplay";
|
|
21
16
|
|
|
22
17
|
import "@malloydata/malloy-explorer/styles.css";
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
QueryExplorerResult,
|
|
26
|
-
SourceExplorerComponent,
|
|
27
|
-
} from "./SourcesExplorer";
|
|
18
|
+
import { QueryExplorerResult } from "./SourcesExplorer";
|
|
28
19
|
import { Loading } from "../Loading";
|
|
29
|
-
import {
|
|
30
|
-
|
|
31
|
-
const modelsApi = new ModelsApi(new Configuration());
|
|
20
|
+
import { ModelExplorer } from "./ModelExplorer";
|
|
21
|
+
import { useModelData } from "./useModelData";
|
|
32
22
|
|
|
33
23
|
interface ModelProps {
|
|
34
24
|
modelPath: string;
|
|
@@ -46,6 +36,7 @@ interface ModelProps {
|
|
|
46
36
|
|
|
47
37
|
export default function Model({
|
|
48
38
|
modelPath,
|
|
39
|
+
versionId,
|
|
49
40
|
expandResults,
|
|
50
41
|
hideResultIcons,
|
|
51
42
|
expandEmbeddings,
|
|
@@ -56,9 +47,8 @@ export default function Model({
|
|
|
56
47
|
React.useState<boolean>(false);
|
|
57
48
|
const [highlightedEmbedCode, setHighlightedEmbedCode] =
|
|
58
49
|
React.useState<string>();
|
|
59
|
-
const [selectedTab, setSelectedTab] = React.useState(0);
|
|
60
50
|
|
|
61
|
-
const {
|
|
51
|
+
const { isError, isLoading, error } = useModelData(modelPath, versionId);
|
|
62
52
|
const modelCodeSnippet = getModelCodeSnippet(modelPath);
|
|
63
53
|
useEffect(() => {
|
|
64
54
|
highlight(modelCodeSnippet, "typescript").then((code) => {
|
|
@@ -66,33 +56,13 @@ export default function Model({
|
|
|
66
56
|
});
|
|
67
57
|
}, [embeddingExpanded, modelCodeSnippet]);
|
|
68
58
|
|
|
69
|
-
const { data, isError, isLoading, error } =
|
|
70
|
-
useQueryWithApiError<CompiledModel>({
|
|
71
|
-
queryKey: ["package", projectName, packageName, modelPath, versionId],
|
|
72
|
-
queryFn: async (config) => {
|
|
73
|
-
const response = await modelsApi.getModel(
|
|
74
|
-
projectName,
|
|
75
|
-
packageName,
|
|
76
|
-
modelPath,
|
|
77
|
-
versionId,
|
|
78
|
-
config,
|
|
79
|
-
);
|
|
80
|
-
return response.data;
|
|
81
|
-
},
|
|
82
|
-
});
|
|
83
|
-
|
|
84
59
|
if (isLoading) {
|
|
85
60
|
return <Loading text="Fetching Model..." />;
|
|
86
61
|
}
|
|
87
62
|
|
|
88
63
|
if (isError) {
|
|
89
64
|
console.log("error", error);
|
|
90
|
-
return
|
|
91
|
-
<ApiErrorDisplay
|
|
92
|
-
error={error}
|
|
93
|
-
context={`${packageName} > ${modelPath}`}
|
|
94
|
-
/>
|
|
95
|
-
);
|
|
65
|
+
return <ApiErrorDisplay error={error} context={`Model > ${modelPath}`} />;
|
|
96
66
|
}
|
|
97
67
|
return (
|
|
98
68
|
<StyledCard variant="outlined">
|
|
@@ -100,39 +70,9 @@ export default function Model({
|
|
|
100
70
|
<Stack
|
|
101
71
|
sx={{
|
|
102
72
|
flexDirection: "row",
|
|
103
|
-
justifyContent: "
|
|
73
|
+
justifyContent: "flex-end",
|
|
104
74
|
}}
|
|
105
75
|
>
|
|
106
|
-
{Array.isArray(data.sourceInfos) &&
|
|
107
|
-
data.sourceInfos.length > 0 && (
|
|
108
|
-
<Tabs
|
|
109
|
-
value={selectedTab}
|
|
110
|
-
onChange={(_, newValue) => setSelectedTab(newValue)}
|
|
111
|
-
variant="scrollable"
|
|
112
|
-
scrollButtons="auto"
|
|
113
|
-
sx={{
|
|
114
|
-
borderBottom: 1,
|
|
115
|
-
borderColor: "divider",
|
|
116
|
-
minHeight: 36,
|
|
117
|
-
}}
|
|
118
|
-
>
|
|
119
|
-
{data.sourceInfos.map((source, idx) => {
|
|
120
|
-
let sourceInfo;
|
|
121
|
-
try {
|
|
122
|
-
sourceInfo = JSON.parse(source);
|
|
123
|
-
} catch {
|
|
124
|
-
sourceInfo = { name: String(idx) };
|
|
125
|
-
}
|
|
126
|
-
return (
|
|
127
|
-
<Tab
|
|
128
|
-
key={sourceInfo.name || idx}
|
|
129
|
-
label={sourceInfo.name || `Source ${idx + 1}`}
|
|
130
|
-
sx={{ minHeight: 36 }}
|
|
131
|
-
/>
|
|
132
|
-
);
|
|
133
|
-
})}
|
|
134
|
-
</Tabs>
|
|
135
|
-
)}
|
|
136
76
|
{!hideEmbeddingIcons && (
|
|
137
77
|
<CardActions
|
|
138
78
|
sx={{
|
|
@@ -196,52 +136,15 @@ export default function Model({
|
|
|
196
136
|
</Collapse>
|
|
197
137
|
<Divider />
|
|
198
138
|
</StyledCardContent>
|
|
199
|
-
<
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
data.sourceInfos[selectedTab],
|
|
209
|
-
),
|
|
210
|
-
}}
|
|
211
|
-
onChange={onChange}
|
|
212
|
-
/>
|
|
213
|
-
)}
|
|
214
|
-
{data.queries?.length > 0 && (
|
|
215
|
-
<StyledCard
|
|
216
|
-
variant="outlined"
|
|
217
|
-
sx={{ padding: "0px 10px 0px 10px" }}
|
|
218
|
-
>
|
|
219
|
-
<StyledCardContent sx={{ p: "10px" }}>
|
|
220
|
-
<Typography variant="subtitle1">
|
|
221
|
-
Named Queries
|
|
222
|
-
</Typography>
|
|
223
|
-
</StyledCardContent>
|
|
224
|
-
<Stack spacing={1} component="section">
|
|
225
|
-
{data.queries.map((query) => (
|
|
226
|
-
<ModelCell
|
|
227
|
-
key={query.name}
|
|
228
|
-
modelPath={modelPath}
|
|
229
|
-
queryName={query.name}
|
|
230
|
-
expandResult={expandResults}
|
|
231
|
-
hideResultIcon={hideResultIcons}
|
|
232
|
-
expandEmbedding={expandEmbeddings}
|
|
233
|
-
hideEmbeddingIcon={hideEmbeddingIcons}
|
|
234
|
-
noView={true}
|
|
235
|
-
annotations={query.annotations}
|
|
236
|
-
/>
|
|
237
|
-
))}
|
|
238
|
-
</Stack>
|
|
239
|
-
<Box height="10px" />
|
|
240
|
-
</StyledCard>
|
|
241
|
-
)}
|
|
242
|
-
<Box height="5px" />
|
|
243
|
-
</Stack>
|
|
244
|
-
</StyledCardMedia>
|
|
139
|
+
<ModelExplorer
|
|
140
|
+
modelPath={modelPath}
|
|
141
|
+
versionId={versionId}
|
|
142
|
+
expandResults={expandResults}
|
|
143
|
+
hideResultIcons={hideResultIcons}
|
|
144
|
+
expandEmbeddings={expandEmbeddings}
|
|
145
|
+
hideEmbeddingIcons={hideEmbeddingIcons}
|
|
146
|
+
onChange={onChange}
|
|
147
|
+
/>
|
|
245
148
|
</StyledCard>
|
|
246
149
|
);
|
|
247
150
|
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Box, Stack, Typography, Tabs, Tab } from "@mui/material";
|
|
3
|
+
import { StyledCard, StyledCardContent } from "../styles";
|
|
4
|
+
import { ModelCell } from "./ModelCell";
|
|
5
|
+
import {
|
|
6
|
+
QueryExplorerResult,
|
|
7
|
+
SourceExplorerComponent,
|
|
8
|
+
} from "./SourcesExplorer";
|
|
9
|
+
import { ApiErrorDisplay } from "../ApiErrorDisplay";
|
|
10
|
+
import { Loading } from "../Loading";
|
|
11
|
+
import { useModelData } from "./useModelData";
|
|
12
|
+
|
|
13
|
+
export interface ModelExplorerProps {
|
|
14
|
+
modelPath: string;
|
|
15
|
+
versionId?: string;
|
|
16
|
+
/** Display options forwarded to ModelCell */
|
|
17
|
+
expandResults?: boolean;
|
|
18
|
+
hideResultIcons?: boolean;
|
|
19
|
+
expandEmbeddings?: boolean;
|
|
20
|
+
hideEmbeddingIcons?: boolean;
|
|
21
|
+
/** Callback when the explorer changes (e.g. when a query is selected). */
|
|
22
|
+
onChange?: (query: QueryExplorerResult) => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* ModelExplorer renders the main explorer UI for a Malloy model. It shows the
|
|
27
|
+
* selected source (via `SourceExplorerComponent`) along with the list of named
|
|
28
|
+
* queries for that model. This logic was originally embedded inside `Model.tsx`
|
|
29
|
+
* but has been extracted for easier reuse.
|
|
30
|
+
*/
|
|
31
|
+
export function ModelExplorer({
|
|
32
|
+
modelPath,
|
|
33
|
+
versionId,
|
|
34
|
+
expandResults,
|
|
35
|
+
hideResultIcons,
|
|
36
|
+
expandEmbeddings,
|
|
37
|
+
hideEmbeddingIcons,
|
|
38
|
+
onChange,
|
|
39
|
+
}: ModelExplorerProps) {
|
|
40
|
+
const [selectedTab, setSelectedTab] = React.useState(0);
|
|
41
|
+
|
|
42
|
+
const { data, isError, isLoading, error } = useModelData(
|
|
43
|
+
modelPath,
|
|
44
|
+
versionId,
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
if (isLoading) {
|
|
48
|
+
return <Loading text="Fetching Model..." />;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (isError) {
|
|
52
|
+
console.log("error", error);
|
|
53
|
+
return (
|
|
54
|
+
<ApiErrorDisplay
|
|
55
|
+
error={error}
|
|
56
|
+
context={`ModelExplorer > ${modelPath}`}
|
|
57
|
+
/>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<Stack spacing={2} component="section">
|
|
63
|
+
{/* Render the tabs for source selection */}
|
|
64
|
+
{Array.isArray(data.sourceInfos) && data.sourceInfos.length > 0 && (
|
|
65
|
+
<Stack sx={{ flexDirection: "row", justifyContent: "flex-start" }}>
|
|
66
|
+
<Tabs
|
|
67
|
+
value={selectedTab}
|
|
68
|
+
onChange={(_, newValue) => setSelectedTab(newValue)}
|
|
69
|
+
variant="scrollable"
|
|
70
|
+
scrollButtons="auto"
|
|
71
|
+
sx={{
|
|
72
|
+
borderBottom: 1,
|
|
73
|
+
borderColor: "divider",
|
|
74
|
+
minHeight: 36,
|
|
75
|
+
}}
|
|
76
|
+
>
|
|
77
|
+
{data.sourceInfos.map((source, idx) => {
|
|
78
|
+
let sourceInfo;
|
|
79
|
+
try {
|
|
80
|
+
sourceInfo = JSON.parse(source);
|
|
81
|
+
} catch {
|
|
82
|
+
sourceInfo = { name: String(idx) };
|
|
83
|
+
}
|
|
84
|
+
return (
|
|
85
|
+
<Tab
|
|
86
|
+
key={sourceInfo.name || idx}
|
|
87
|
+
label={sourceInfo.name || `Source ${idx + 1}`}
|
|
88
|
+
sx={{ minHeight: 36 }}
|
|
89
|
+
/>
|
|
90
|
+
);
|
|
91
|
+
})}
|
|
92
|
+
</Tabs>
|
|
93
|
+
</Stack>
|
|
94
|
+
)}
|
|
95
|
+
|
|
96
|
+
{/* Render the selected source info */}
|
|
97
|
+
{Array.isArray(data.sourceInfos) && data.sourceInfos.length > 0 && (
|
|
98
|
+
<SourceExplorerComponent
|
|
99
|
+
sourceAndPath={{
|
|
100
|
+
modelPath,
|
|
101
|
+
sourceInfo: JSON.parse(data.sourceInfos[selectedTab]),
|
|
102
|
+
}}
|
|
103
|
+
onChange={onChange}
|
|
104
|
+
/>
|
|
105
|
+
)}
|
|
106
|
+
|
|
107
|
+
{/* Render the named queries */}
|
|
108
|
+
{data.queries?.length > 0 && (
|
|
109
|
+
<StyledCard
|
|
110
|
+
variant="outlined"
|
|
111
|
+
sx={{ padding: "0px 10px 0px 10px" }}
|
|
112
|
+
>
|
|
113
|
+
<StyledCardContent sx={{ p: "10px" }}>
|
|
114
|
+
<Typography variant="subtitle1">Named Queries</Typography>
|
|
115
|
+
</StyledCardContent>
|
|
116
|
+
|
|
117
|
+
<Stack spacing={1} component="section">
|
|
118
|
+
{data.queries.map((query) => (
|
|
119
|
+
<ModelCell
|
|
120
|
+
key={query.name}
|
|
121
|
+
modelPath={modelPath}
|
|
122
|
+
queryName={query.name}
|
|
123
|
+
expandResult={expandResults}
|
|
124
|
+
hideResultIcon={hideResultIcons}
|
|
125
|
+
expandEmbedding={expandEmbeddings}
|
|
126
|
+
hideEmbeddingIcon={hideEmbeddingIcons}
|
|
127
|
+
noView={true}
|
|
128
|
+
annotations={query.annotations}
|
|
129
|
+
/>
|
|
130
|
+
))}
|
|
131
|
+
</Stack>
|
|
132
|
+
<Box height="10px" />
|
|
133
|
+
</StyledCard>
|
|
134
|
+
)}
|
|
135
|
+
<Box height="5px" />
|
|
136
|
+
</Stack>
|
|
137
|
+
);
|
|
138
|
+
}
|
|
@@ -235,7 +235,7 @@ function SourceExplorerComponentInner({
|
|
|
235
235
|
|
|
236
236
|
const onQueryChange = React.useCallback(
|
|
237
237
|
(malloyQuery: Malloy.Query) => {
|
|
238
|
-
setQuery({ ...query, malloyQuery });
|
|
238
|
+
setQuery({ ...query, malloyQuery, malloyResult: undefined });
|
|
239
239
|
},
|
|
240
240
|
[query],
|
|
241
241
|
);
|
|
@@ -243,88 +243,75 @@ function SourceExplorerComponentInner({
|
|
|
243
243
|
if (oldSourceInfo !== sourceAndPath.sourceInfo.name) {
|
|
244
244
|
return <div>Loading...</div>;
|
|
245
245
|
}
|
|
246
|
-
|
|
247
246
|
return (
|
|
248
|
-
<
|
|
249
|
-
<
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
247
|
+
<StyledExplorerContent key={sourceAndPath.sourceInfo.name}>
|
|
248
|
+
<MalloyExplorerProvider
|
|
249
|
+
source={sourceAndPath.sourceInfo}
|
|
250
|
+
query={query?.malloyQuery}
|
|
251
|
+
onQueryChange={onQueryChange}
|
|
252
|
+
focusedNestViewPath={focusedNestViewPath}
|
|
253
|
+
onFocusedNestViewPathChange={setFocusedNestViewPath}
|
|
254
|
+
onDrill={(params) => {
|
|
255
|
+
console.info(params);
|
|
256
|
+
}}
|
|
257
|
+
>
|
|
258
|
+
<div
|
|
259
|
+
style={{
|
|
260
|
+
display: "flex",
|
|
261
|
+
height: "100%",
|
|
262
|
+
overflowY: "auto",
|
|
258
263
|
}}
|
|
259
264
|
>
|
|
260
|
-
<
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
}
|
|
265
|
+
<ResizableCollapsiblePanel
|
|
266
|
+
isInitiallyExpanded={true}
|
|
267
|
+
initialWidth={180}
|
|
268
|
+
minWidth={180}
|
|
269
|
+
icon="database"
|
|
270
|
+
title={sourceAndPath.sourceInfo.name}
|
|
266
271
|
>
|
|
267
|
-
<
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
+
<SourcePanel
|
|
273
|
+
onRefresh={() => setQuery(emptyQueryExplorerResult())}
|
|
274
|
+
/>
|
|
275
|
+
</ResizableCollapsiblePanel>
|
|
276
|
+
<ResizableCollapsiblePanel
|
|
277
|
+
isInitiallyExpanded={true}
|
|
278
|
+
initialWidth={280}
|
|
279
|
+
minWidth={280}
|
|
280
|
+
icon="filterSliders"
|
|
281
|
+
title="Query"
|
|
282
|
+
>
|
|
283
|
+
<QueryPanel
|
|
284
|
+
runQuery={() => {
|
|
285
|
+
mutation.mutate();
|
|
272
286
|
}}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
source={sourceAndPath.sourceInfo}
|
|
302
|
-
draftQuery={query?.malloyQuery}
|
|
303
|
-
setDraftQuery={(malloyQuery) =>
|
|
304
|
-
setQuery({ ...query, malloyQuery: malloyQuery })
|
|
305
|
-
}
|
|
306
|
-
submittedQuery={
|
|
307
|
-
query?.malloyQuery
|
|
308
|
-
? {
|
|
309
|
-
executionState: mutation.isPending
|
|
310
|
-
? "running"
|
|
311
|
-
: "finished",
|
|
312
|
-
response: {
|
|
313
|
-
result: query.malloyResult,
|
|
314
|
-
},
|
|
315
|
-
query: query.malloyQuery,
|
|
316
|
-
queryResolutionStartMillis: Date.now(),
|
|
317
|
-
onCancel: mutation.reset,
|
|
318
|
-
}
|
|
319
|
-
: undefined
|
|
320
|
-
}
|
|
321
|
-
options={{ showRawQuery: true }}
|
|
322
|
-
/>
|
|
323
|
-
</div>
|
|
324
|
-
</div>
|
|
325
|
-
</MalloyExplorerProvider>
|
|
326
|
-
</StyledExplorerContent>
|
|
327
|
-
</StyledExplorerPage>
|
|
287
|
+
/>
|
|
288
|
+
</ResizableCollapsiblePanel>
|
|
289
|
+
<ResultPanel
|
|
290
|
+
source={sourceAndPath.sourceInfo}
|
|
291
|
+
draftQuery={query?.malloyQuery}
|
|
292
|
+
setDraftQuery={(malloyQuery) =>
|
|
293
|
+
setQuery({ ...query, malloyQuery: malloyQuery })
|
|
294
|
+
}
|
|
295
|
+
submittedQuery={
|
|
296
|
+
query?.malloyQuery
|
|
297
|
+
? {
|
|
298
|
+
executionState: mutation.isPending
|
|
299
|
+
? "running"
|
|
300
|
+
: "finished",
|
|
301
|
+
response: {
|
|
302
|
+
result: query.malloyResult,
|
|
303
|
+
},
|
|
304
|
+
query: query.malloyQuery,
|
|
305
|
+
queryResolutionStartMillis: Date.now(),
|
|
306
|
+
onCancel: mutation.reset,
|
|
307
|
+
}
|
|
308
|
+
: undefined
|
|
309
|
+
}
|
|
310
|
+
options={{ showRawQuery: true }}
|
|
311
|
+
/>
|
|
312
|
+
</div>
|
|
313
|
+
</MalloyExplorerProvider>
|
|
314
|
+
</StyledExplorerContent>
|
|
328
315
|
);
|
|
329
316
|
}
|
|
330
317
|
|
|
@@ -366,7 +353,6 @@ export function SourceExplorerComponent(props: SourceExplorerComponentProps) {
|
|
|
366
353
|
<StyledExplorerContent>
|
|
367
354
|
<div
|
|
368
355
|
style={{
|
|
369
|
-
display: "flex",
|
|
370
356
|
alignItems: "center",
|
|
371
357
|
justifyContent: "center",
|
|
372
358
|
height: "200px",
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export { default as Model } from "./Model";
|
|
2
|
+
export { ModelExplorer } from "./ModelExplorer";
|
|
2
3
|
export { SourcesExplorer } from "./SourcesExplorer";
|
|
3
4
|
export { SourceExplorerComponent } from "./SourcesExplorer";
|
|
4
5
|
export type { SourceAndPath } from "./SourcesExplorer";
|
|
6
|
+
export { useModelData } from "./useModelData";
|
|
7
|
+
export type { ModelExplorerProps } from "./ModelExplorer";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Configuration, ModelsApi, CompiledModel } from "../../client";
|
|
2
|
+
import { usePackage } from "../Package/PackageProvider";
|
|
3
|
+
import { useQueryWithApiError } from "../../hooks/useQueryWithApiError";
|
|
4
|
+
|
|
5
|
+
const modelsApi = new ModelsApi(new Configuration());
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Custom hook for fetching model data. Combines usePackage context with
|
|
9
|
+
* useQueryWithApiError to fetch a compiled model.
|
|
10
|
+
*/
|
|
11
|
+
export function useModelData(modelPath: string, versionId?: string) {
|
|
12
|
+
const {
|
|
13
|
+
projectName,
|
|
14
|
+
packageName,
|
|
15
|
+
versionId: packageVersionId,
|
|
16
|
+
} = usePackage();
|
|
17
|
+
const effectiveVersionId = versionId || packageVersionId;
|
|
18
|
+
|
|
19
|
+
return useQueryWithApiError<CompiledModel>({
|
|
20
|
+
queryKey: [
|
|
21
|
+
"package",
|
|
22
|
+
projectName,
|
|
23
|
+
packageName,
|
|
24
|
+
modelPath,
|
|
25
|
+
effectiveVersionId,
|
|
26
|
+
],
|
|
27
|
+
queryFn: async (config) => {
|
|
28
|
+
const response = await modelsApi.getModel(
|
|
29
|
+
projectName,
|
|
30
|
+
packageName,
|
|
31
|
+
modelPath,
|
|
32
|
+
effectiveVersionId,
|
|
33
|
+
config,
|
|
34
|
+
);
|
|
35
|
+
return response.data;
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
}
|
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",
|