@malloy-publisher/sdk 0.0.119 → 0.0.121
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/ServerProvider-49yj-aFb.cjs.js +1 -0
- package/dist/{ServerProvider-v0TajMUn.es.js → ServerProvider-BDgL8SVP.es.js} +355 -429
- package/dist/client/api.d.ts +285 -276
- package/dist/client/configuration.d.ts +1 -1
- package/dist/client/index.cjs.js +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.es.js +43 -46
- package/dist/components/ServerProvider.d.ts +1 -3
- package/dist/index.cjs.js +71 -71
- package/dist/index.es.js +17730 -17824
- package/package.json +1 -1
- package/src/components/Connections/common.ts +2 -0
- package/src/components/Model/Model.tsx +10 -10
- package/src/components/Model/ModelCell.tsx +10 -8
- package/src/components/Model/SourcesExplorer.tsx +7 -6
- package/src/components/Notebook/NotebookCell.tsx +4 -4
- package/src/components/Package/Package.tsx +7 -11
- package/src/components/Project/ConnectionExplorer.tsx +119 -149
- package/src/components/QueryResult/QueryResult.tsx +9 -7
- package/src/components/ServerProvider.tsx +0 -4
- package/src/hooks/useRawQueryData.ts +8 -6
- package/dist/ServerProvider-Bx3fsDOb.cjs.js +0 -1
- package/dist/components/Package/Schedules.d.ts +0 -5
- package/src/components/Package/Schedules.tsx +0 -114
package/package.json
CHANGED
|
@@ -188,6 +188,7 @@ export const connectionFieldsByType: Record<
|
|
|
188
188
|
type: "text",
|
|
189
189
|
},
|
|
190
190
|
],
|
|
191
|
+
duckdb: [],
|
|
191
192
|
};
|
|
192
193
|
|
|
193
194
|
export const attributesFieldName: Record<ConnectionTypeEnum, string> = {
|
|
@@ -196,4 +197,5 @@ export const attributesFieldName: Record<ConnectionTypeEnum, string> = {
|
|
|
196
197
|
snowflake: "snowflakeConnection",
|
|
197
198
|
trino: "trinoConnection",
|
|
198
199
|
mysql: "mysqlConnection",
|
|
200
|
+
duckdb: "duckdbConnection",
|
|
199
201
|
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "@malloydata/malloy-explorer/styles.css";
|
|
2
|
+
import LinkOutlinedIcon from "@mui/icons-material/LinkOutlined";
|
|
3
|
+
import ZoomOutMapIcon from "@mui/icons-material/ZoomOutMap";
|
|
2
4
|
import {
|
|
3
5
|
Box,
|
|
4
6
|
IconButton,
|
|
@@ -7,17 +9,15 @@ import {
|
|
|
7
9
|
Tooltip,
|
|
8
10
|
Typography,
|
|
9
11
|
} from "@mui/material";
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import "
|
|
13
|
-
import { QueryExplorerResult } from "./SourcesExplorer";
|
|
12
|
+
import React, { useState } from "react";
|
|
13
|
+
import { parseResourceUri } from "../../utils/formatting";
|
|
14
|
+
import { ApiErrorDisplay } from "../ApiErrorDisplay";
|
|
14
15
|
import { Loading } from "../Loading";
|
|
16
|
+
import { ModelCell } from "./ModelCell";
|
|
15
17
|
import { ModelExplorer } from "./ModelExplorer";
|
|
16
18
|
import { ModelExplorerDialog } from "./ModelExplorerDialog";
|
|
17
|
-
import {
|
|
19
|
+
import { QueryExplorerResult } from "./SourcesExplorer";
|
|
18
20
|
import { useModelData } from "./useModelData";
|
|
19
|
-
import React, { useState } from "react";
|
|
20
|
-
import { parseResourceUri } from "../../utils/formatting";
|
|
21
21
|
|
|
22
22
|
interface ModelProps {
|
|
23
23
|
onChange?: (query: QueryExplorerResult) => void;
|
|
@@ -103,8 +103,8 @@ export default function Model({ onChange, resourceUri }: ModelProps) {
|
|
|
103
103
|
>
|
|
104
104
|
Sources
|
|
105
105
|
</Typography>
|
|
106
|
-
<Tooltip title="Click to copy
|
|
107
|
-
<
|
|
106
|
+
<Tooltip title="Click to copy link">
|
|
107
|
+
<LinkOutlinedIcon
|
|
108
108
|
sx={{
|
|
109
109
|
fontSize: "24px",
|
|
110
110
|
color: "#666666",
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { Box, Typography, IconButton } from "@mui/material";
|
|
2
1
|
import SearchIcon from "@mui/icons-material/Search";
|
|
2
|
+
import { Box, IconButton, Typography } from "@mui/material";
|
|
3
3
|
import React, { useEffect } from "react";
|
|
4
4
|
import { useQueryWithApiError } from "../../hooks/useQueryWithApiError";
|
|
5
|
+
import { parseResourceUri } from "../../utils/formatting";
|
|
5
6
|
import { highlight } from "../highlighter";
|
|
6
7
|
import ResultContainer from "../RenderedResult/ResultContainer";
|
|
7
8
|
import ResultsDialog from "../ResultsDialog";
|
|
8
|
-
import { CleanMetricCard, CleanNotebookCell } from "../styles";
|
|
9
|
-
import { parseResourceUri } from "../../utils/formatting";
|
|
10
9
|
import { useServer } from "../ServerProvider";
|
|
10
|
+
import { CleanMetricCard, CleanNotebookCell } from "../styles";
|
|
11
11
|
|
|
12
12
|
interface ModelCellProps {
|
|
13
13
|
sourceName?: string;
|
|
@@ -37,14 +37,16 @@ export function ModelCell({
|
|
|
37
37
|
} = useQueryWithApiError({
|
|
38
38
|
queryKey: ["namedQueryResult", resourceUri, queryName],
|
|
39
39
|
queryFn: () =>
|
|
40
|
-
apiClients.
|
|
40
|
+
apiClients.models.executeQueryModel(
|
|
41
41
|
projectName,
|
|
42
42
|
packageName,
|
|
43
43
|
modelPath,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
{
|
|
45
|
+
query: undefined,
|
|
46
|
+
sourceName: undefined,
|
|
47
|
+
queryName: queryName,
|
|
48
|
+
versionId: versionId,
|
|
49
|
+
},
|
|
48
50
|
),
|
|
49
51
|
enabled: true, // Always execute
|
|
50
52
|
});
|
|
@@ -173,15 +173,16 @@ function SourceExplorerComponentInner({
|
|
|
173
173
|
...query,
|
|
174
174
|
query: malloy,
|
|
175
175
|
});
|
|
176
|
-
return apiClients.
|
|
176
|
+
return apiClients.models.executeQueryModel(
|
|
177
177
|
projectName,
|
|
178
178
|
packageName,
|
|
179
179
|
sourceAndPath.modelPath,
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
180
|
+
{
|
|
181
|
+
query: malloy,
|
|
182
|
+
sourceName: undefined,
|
|
183
|
+
queryName: undefined,
|
|
184
|
+
versionId: versionId,
|
|
185
|
+
},
|
|
185
186
|
);
|
|
186
187
|
},
|
|
187
188
|
onSuccess: (data) => {
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import CloseIcon from "@mui/icons-material/Close";
|
|
2
2
|
import CodeIcon from "@mui/icons-material/Code";
|
|
3
3
|
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
|
|
4
|
+
import LinkOutlinedIcon from "@mui/icons-material/LinkOutlined";
|
|
4
5
|
import SearchIcon from "@mui/icons-material/Search";
|
|
5
|
-
import ShareIcon from "@mui/icons-material/Share";
|
|
6
6
|
import {
|
|
7
7
|
Box,
|
|
8
8
|
Dialog,
|
|
9
9
|
DialogContent,
|
|
10
10
|
DialogTitle,
|
|
11
11
|
IconButton,
|
|
12
|
+
Snackbar,
|
|
12
13
|
Stack,
|
|
13
14
|
Tooltip,
|
|
14
15
|
Typography,
|
|
15
|
-
Snackbar,
|
|
16
16
|
} from "@mui/material";
|
|
17
17
|
import Markdown from "markdown-to-jsx";
|
|
18
18
|
import React, { useEffect, useState } from "react";
|
|
@@ -176,8 +176,8 @@ export function NotebookCell({
|
|
|
176
176
|
justifyContent="space-between"
|
|
177
177
|
>
|
|
178
178
|
<Markdown>{cell.text}</Markdown>
|
|
179
|
-
<Tooltip title="Click to copy
|
|
180
|
-
<
|
|
179
|
+
<Tooltip title="Click to copy link">
|
|
180
|
+
<LinkOutlinedIcon
|
|
181
181
|
sx={{
|
|
182
182
|
fontSize: "24px",
|
|
183
183
|
color: "#666666",
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Box, Grid } from "@mui/material";
|
|
2
|
+
import { encodeResourceUri, parseResourceUri } from "../../utils/formatting";
|
|
2
3
|
import { Notebook } from "../Notebook";
|
|
3
|
-
import Config from "./Config";
|
|
4
|
-
import Connections from "./Connections";
|
|
5
|
-
import Databases from "./Databases";
|
|
6
|
-
import Models from "./Models";
|
|
7
|
-
import Notebooks from "./Notebooks";
|
|
8
|
-
import Schedules from "./Schedules";
|
|
9
4
|
import {
|
|
10
5
|
PackageCard,
|
|
11
6
|
PackageCardContent,
|
|
12
7
|
PackageSectionTitle,
|
|
13
8
|
} from "../styles";
|
|
14
|
-
import
|
|
9
|
+
import Config from "./Config";
|
|
10
|
+
import Connections from "./Connections";
|
|
11
|
+
import Databases from "./Databases";
|
|
12
|
+
import Models from "./Models";
|
|
13
|
+
import Notebooks from "./Notebooks";
|
|
15
14
|
|
|
16
15
|
const README_NOTEBOOK = "README.malloynb";
|
|
17
16
|
|
|
@@ -59,9 +58,6 @@ export default function Package({
|
|
|
59
58
|
<Grid size={{ xs: 12, md: 6 }}>
|
|
60
59
|
<Connections resourceUri={resourceUri} />
|
|
61
60
|
</Grid>
|
|
62
|
-
<Grid size={{ xs: 12, md: 12 }}>
|
|
63
|
-
<Schedules resourceUri={resourceUri} />
|
|
64
|
-
</Grid>
|
|
65
61
|
<Grid size={{ xs: 12, md: 12 }}>
|
|
66
62
|
<PackageCard>
|
|
67
63
|
<PackageCardContent>
|
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import {
|
|
3
2
|
Box,
|
|
3
|
+
Divider,
|
|
4
|
+
FormControlLabel,
|
|
5
|
+
Grid,
|
|
4
6
|
List,
|
|
5
7
|
ListItemButton,
|
|
6
8
|
ListItemText,
|
|
7
|
-
Typography,
|
|
8
|
-
Divider,
|
|
9
9
|
Paper,
|
|
10
|
-
Grid,
|
|
11
10
|
Switch,
|
|
12
|
-
FormControlLabel,
|
|
13
11
|
Table,
|
|
14
12
|
TableBody,
|
|
15
13
|
TableCell,
|
|
16
14
|
TableContainer,
|
|
17
15
|
TableHead,
|
|
18
16
|
TableRow,
|
|
19
|
-
|
|
17
|
+
Typography,
|
|
20
18
|
} from "@mui/material";
|
|
21
|
-
import
|
|
22
|
-
import { Loading } from "../Loading";
|
|
19
|
+
import React from "react";
|
|
23
20
|
import { useQueryWithApiError } from "../../hooks/useQueryWithApiError";
|
|
24
21
|
import { parseResourceUri } from "../../utils/formatting";
|
|
22
|
+
import { ApiErrorDisplay } from "../ApiErrorDisplay";
|
|
23
|
+
import { Loading } from "../Loading";
|
|
25
24
|
import { useServer } from "../ServerProvider";
|
|
26
25
|
|
|
27
26
|
interface ConnectionExplorerProps {
|
|
@@ -37,19 +36,27 @@ export default function ConnectionExplorer({
|
|
|
37
36
|
}: ConnectionExplorerProps) {
|
|
38
37
|
const { apiClients } = useServer();
|
|
39
38
|
const { projectName: projectName } = parseResourceUri(resourceUri);
|
|
40
|
-
const [selectedTable, setSelectedTable] = React.useState<
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
const [selectedTable, setSelectedTable] = React.useState<
|
|
40
|
+
| { resource: string; columns: Array<{ name: string; type: string }> }
|
|
41
|
+
| undefined
|
|
42
|
+
>(undefined);
|
|
43
43
|
const [selectedSchema, setSelectedSchema] = React.useState<string | null>(
|
|
44
44
|
schema || null,
|
|
45
45
|
);
|
|
46
46
|
const [showHiddenSchemas, setShowHiddenSchemas] = React.useState(false);
|
|
47
|
-
const {
|
|
48
|
-
|
|
47
|
+
const {
|
|
48
|
+
data: schemasData,
|
|
49
|
+
isError: schemasError,
|
|
50
|
+
isLoading: schemasLoading,
|
|
51
|
+
error: schemasErrorObj,
|
|
52
|
+
} = useQueryWithApiError({
|
|
53
|
+
queryKey: ["schemas", projectName, connectionName],
|
|
49
54
|
queryFn: () =>
|
|
50
55
|
apiClients.connections.listSchemas(projectName, connectionName),
|
|
51
56
|
});
|
|
52
57
|
|
|
58
|
+
const availableSchemas = schemasData?.data || [];
|
|
59
|
+
|
|
53
60
|
return (
|
|
54
61
|
<Grid container spacing={1}>
|
|
55
62
|
{!schema && (
|
|
@@ -82,74 +89,49 @@ export default function ConnectionExplorer({
|
|
|
82
89
|
<Box
|
|
83
90
|
sx={{ mt: "2px", maxHeight: "600px", overflowY: "auto" }}
|
|
84
91
|
>
|
|
85
|
-
{
|
|
86
|
-
{
|
|
92
|
+
{schemasLoading && <Loading text="Loading schemas..." />}
|
|
93
|
+
{schemasError && (
|
|
87
94
|
<ApiErrorDisplay
|
|
88
|
-
error={
|
|
89
|
-
context={`${projectName} > ${connectionName}`}
|
|
95
|
+
error={schemasErrorObj}
|
|
96
|
+
context={`${projectName} > ${connectionName} > Schemas`}
|
|
90
97
|
/>
|
|
91
98
|
)}
|
|
92
|
-
{
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
.sort((a, b) => {
|
|
103
|
-
if (a.isDefault === b.isDefault) return 0;
|
|
104
|
-
return a.isDefault ? -1 : 1;
|
|
105
|
-
})
|
|
106
|
-
.map(
|
|
99
|
+
{!schemasLoading &&
|
|
100
|
+
!schemasError &&
|
|
101
|
+
availableSchemas.length === 0 && (
|
|
102
|
+
<Typography variant="body2">No Schemas</Typography>
|
|
103
|
+
)}
|
|
104
|
+
{!schemasLoading &&
|
|
105
|
+
!schemasError &&
|
|
106
|
+
availableSchemas.length > 0 && (
|
|
107
|
+
<List dense disablePadding>
|
|
108
|
+
{availableSchemas.map(
|
|
107
109
|
(schema: {
|
|
108
110
|
name: string;
|
|
109
|
-
|
|
110
|
-
description?: string;
|
|
111
|
+
isHidden: boolean;
|
|
111
112
|
}) => {
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const item = (
|
|
113
|
+
const schemaName = schema.name;
|
|
114
|
+
const isHidden = schema.isHidden;
|
|
115
|
+
if (isHidden && !showHiddenSchemas) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
const isSelected =
|
|
119
|
+
selectedSchema === schemaName;
|
|
120
|
+
return (
|
|
122
121
|
<ListItemButton
|
|
123
|
-
key={
|
|
124
|
-
selected={
|
|
125
|
-
selectedSchema === schema.name
|
|
126
|
-
}
|
|
122
|
+
key={schemaName}
|
|
123
|
+
selected={isSelected}
|
|
127
124
|
onClick={() =>
|
|
128
|
-
setSelectedSchema(
|
|
125
|
+
setSelectedSchema(schemaName)
|
|
129
126
|
}
|
|
130
127
|
>
|
|
131
|
-
<ListItemText
|
|
132
|
-
primary={schema.name}
|
|
133
|
-
secondary={firstLine}
|
|
134
|
-
/>
|
|
128
|
+
<ListItemText primary={schemaName} />
|
|
135
129
|
</ListItemButton>
|
|
136
130
|
);
|
|
137
|
-
|
|
138
|
-
return hasDescription ? (
|
|
139
|
-
<Tooltip
|
|
140
|
-
key={schema.name}
|
|
141
|
-
title={fullDescription}
|
|
142
|
-
arrow
|
|
143
|
-
>
|
|
144
|
-
{item}
|
|
145
|
-
</Tooltip>
|
|
146
|
-
) : (
|
|
147
|
-
item
|
|
148
|
-
);
|
|
149
131
|
},
|
|
150
132
|
)}
|
|
151
|
-
|
|
152
|
-
|
|
133
|
+
</List>
|
|
134
|
+
)}
|
|
153
135
|
</Box>
|
|
154
136
|
</Paper>
|
|
155
137
|
</Grid>
|
|
@@ -160,8 +142,8 @@ export default function ConnectionExplorer({
|
|
|
160
142
|
<TablesInSchema
|
|
161
143
|
connectionName={connectionName}
|
|
162
144
|
schemaName={selectedSchema}
|
|
163
|
-
onTableClick={(
|
|
164
|
-
setSelectedTable(
|
|
145
|
+
onTableClick={(table) => {
|
|
146
|
+
setSelectedTable(table);
|
|
165
147
|
}}
|
|
166
148
|
resourceUri={resourceUri}
|
|
167
149
|
/>
|
|
@@ -169,14 +151,9 @@ export default function ConnectionExplorer({
|
|
|
169
151
|
)}
|
|
170
152
|
</Grid>
|
|
171
153
|
<Grid size={{ xs: 12, md: schema ? 6 : 4 }}>
|
|
172
|
-
{selectedTable &&
|
|
154
|
+
{selectedTable && (
|
|
173
155
|
<Paper sx={{ p: 1, m: 0 }}>
|
|
174
|
-
<TableSchemaViewer
|
|
175
|
-
connectionName={connectionName}
|
|
176
|
-
schemaName={selectedSchema}
|
|
177
|
-
tableName={selectedTable}
|
|
178
|
-
resourceUri={resourceUri}
|
|
179
|
-
/>
|
|
156
|
+
<TableSchemaViewer table={selectedTable} />
|
|
180
157
|
</Paper>
|
|
181
158
|
)}
|
|
182
159
|
</Grid>
|
|
@@ -185,76 +162,42 @@ export default function ConnectionExplorer({
|
|
|
185
162
|
}
|
|
186
163
|
|
|
187
164
|
type TableSchemaViewerProps = {
|
|
188
|
-
|
|
189
|
-
schemaName: string;
|
|
190
|
-
tableName: string;
|
|
191
|
-
resourceUri: string;
|
|
165
|
+
table: { resource: string; columns: Array<{ name: string; type: string }> };
|
|
192
166
|
};
|
|
193
167
|
|
|
194
|
-
function TableSchemaViewer({
|
|
195
|
-
connectionName,
|
|
196
|
-
schemaName,
|
|
197
|
-
tableName,
|
|
198
|
-
resourceUri,
|
|
199
|
-
}: TableSchemaViewerProps) {
|
|
200
|
-
const { apiClients } = useServer();
|
|
201
|
-
const { projectName: projectName } = parseResourceUri(resourceUri);
|
|
202
|
-
const { data, isSuccess, isError, error, isLoading } = useQueryWithApiError({
|
|
203
|
-
queryKey: [
|
|
204
|
-
"tablePathSchema",
|
|
205
|
-
projectName,
|
|
206
|
-
connectionName,
|
|
207
|
-
schemaName,
|
|
208
|
-
tableName,
|
|
209
|
-
],
|
|
210
|
-
queryFn: () =>
|
|
211
|
-
apiClients.connections.getTablesource(
|
|
212
|
-
projectName,
|
|
213
|
-
connectionName,
|
|
214
|
-
tableName,
|
|
215
|
-
`${schemaName}.${tableName}`,
|
|
216
|
-
),
|
|
217
|
-
});
|
|
218
|
-
|
|
168
|
+
function TableSchemaViewer({ table }: TableSchemaViewerProps) {
|
|
219
169
|
return (
|
|
220
170
|
<>
|
|
221
171
|
<Typography variant="overline" fontWeight="bold">
|
|
222
|
-
Schema: {
|
|
172
|
+
Schema: {table.resource}
|
|
223
173
|
</Typography>
|
|
224
174
|
<Divider />
|
|
225
175
|
<Box sx={{ mt: "10px", maxHeight: "600px", overflowY: "auto" }}>
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
</TableRow>
|
|
252
|
-
),
|
|
253
|
-
)}
|
|
254
|
-
</TableBody>
|
|
255
|
-
</Table>
|
|
256
|
-
</TableContainer>
|
|
257
|
-
)}
|
|
176
|
+
<TableContainer>
|
|
177
|
+
<Table
|
|
178
|
+
size="small"
|
|
179
|
+
sx={{ "& .MuiTableCell-root": { padding: "10px" } }}
|
|
180
|
+
>
|
|
181
|
+
<TableHead>
|
|
182
|
+
<TableRow>
|
|
183
|
+
<TableCell>NAME</TableCell>
|
|
184
|
+
<TableCell>TYPE</TableCell>
|
|
185
|
+
</TableRow>
|
|
186
|
+
</TableHead>
|
|
187
|
+
<TableBody>
|
|
188
|
+
{table.columns
|
|
189
|
+
?.sort((a: { name: string }, b: { name: string }) =>
|
|
190
|
+
a.name.localeCompare(b.name),
|
|
191
|
+
)
|
|
192
|
+
?.map((column: { name: string; type: string }) => (
|
|
193
|
+
<TableRow key={column.name}>
|
|
194
|
+
<TableCell>{column.name}</TableCell>
|
|
195
|
+
<TableCell>{column.type}</TableCell>
|
|
196
|
+
</TableRow>
|
|
197
|
+
))}
|
|
198
|
+
</TableBody>
|
|
199
|
+
</Table>
|
|
200
|
+
</TableContainer>
|
|
258
201
|
</Box>
|
|
259
202
|
</>
|
|
260
203
|
);
|
|
@@ -263,7 +206,10 @@ function TableSchemaViewer({
|
|
|
263
206
|
interface TablesInSchemaProps {
|
|
264
207
|
connectionName: string;
|
|
265
208
|
schemaName: string;
|
|
266
|
-
onTableClick: (
|
|
209
|
+
onTableClick: (table: {
|
|
210
|
+
resource: string;
|
|
211
|
+
columns: Array<{ name: string; type: string }>;
|
|
212
|
+
}) => void;
|
|
267
213
|
resourceUri: string;
|
|
268
214
|
}
|
|
269
215
|
|
|
@@ -299,19 +245,43 @@ function TablesInSchema({
|
|
|
299
245
|
context={`${projectName} > ${connectionName} > ${schemaName}`}
|
|
300
246
|
/>
|
|
301
247
|
)}
|
|
302
|
-
{isSuccess && data
|
|
248
|
+
{isSuccess && data?.data?.length === 0 && (
|
|
303
249
|
<Typography variant="body2">No Tables</Typography>
|
|
304
250
|
)}
|
|
305
|
-
{isSuccess && data.data.length > 0 && (
|
|
251
|
+
{isSuccess && data?.data && data.data.length > 0 && (
|
|
306
252
|
<List dense disablePadding>
|
|
307
|
-
{data.data
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
253
|
+
{data.data
|
|
254
|
+
.sort(
|
|
255
|
+
(a: { resource: string }, b: { resource: string }) => {
|
|
256
|
+
// Extract table names for sorting
|
|
257
|
+
const tableNameA =
|
|
258
|
+
a.resource.split(".").pop() || a.resource;
|
|
259
|
+
const tableNameB =
|
|
260
|
+
b.resource.split(".").pop() || b.resource;
|
|
261
|
+
return tableNameA.localeCompare(tableNameB);
|
|
262
|
+
},
|
|
263
|
+
)
|
|
264
|
+
.map(
|
|
265
|
+
(table: {
|
|
266
|
+
resource: string;
|
|
267
|
+
columns: Array<{ name: string; type: string }>;
|
|
268
|
+
}) => {
|
|
269
|
+
// Extract table name from resource path (e.g., "schema.table_name" -> "table_name")
|
|
270
|
+
const tableName =
|
|
271
|
+
table.resource.split(".").pop() || table.resource;
|
|
272
|
+
return (
|
|
273
|
+
<ListItemButton
|
|
274
|
+
key={table.resource}
|
|
275
|
+
onClick={() => onTableClick(table)}
|
|
276
|
+
>
|
|
277
|
+
<ListItemText
|
|
278
|
+
primary={tableName}
|
|
279
|
+
secondary={`${table.columns.length} columns`}
|
|
280
|
+
/>
|
|
281
|
+
</ListItemButton>
|
|
282
|
+
);
|
|
283
|
+
},
|
|
284
|
+
)}
|
|
315
285
|
</List>
|
|
316
286
|
)}
|
|
317
287
|
</Box>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Suspense, lazy } from "react";
|
|
2
|
-
import { ApiErrorDisplay } from "../ApiErrorDisplay";
|
|
3
|
-
import { Loading } from "../Loading";
|
|
4
2
|
import { useQueryWithApiError } from "../../hooks/useQueryWithApiError";
|
|
5
3
|
import { parseResourceUri } from "../../utils/formatting";
|
|
4
|
+
import { ApiErrorDisplay } from "../ApiErrorDisplay";
|
|
5
|
+
import { Loading } from "../Loading";
|
|
6
6
|
import { useServer } from "../ServerProvider";
|
|
7
7
|
|
|
8
8
|
const RenderedResult = lazy(() => import("../RenderedResult/RenderedResult"));
|
|
@@ -77,14 +77,16 @@ export default function QueryResult({
|
|
|
77
77
|
const { data, isSuccess, isError, error } = useQueryWithApiError({
|
|
78
78
|
queryKey: [resourceUri, query, sourceName, queryName],
|
|
79
79
|
queryFn: () =>
|
|
80
|
-
apiClients.
|
|
80
|
+
apiClients.models.executeQueryModel(
|
|
81
81
|
projectName,
|
|
82
82
|
packageName,
|
|
83
83
|
modelPath,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
{
|
|
85
|
+
query: query,
|
|
86
|
+
sourceName: sourceName,
|
|
87
|
+
queryName: queryName,
|
|
88
|
+
versionId: versionId,
|
|
89
|
+
},
|
|
88
90
|
),
|
|
89
91
|
});
|
|
90
92
|
|
|
@@ -8,8 +8,6 @@ import {
|
|
|
8
8
|
NotebooksApi,
|
|
9
9
|
PackagesApi,
|
|
10
10
|
ProjectsApi,
|
|
11
|
-
QueryresultsApi,
|
|
12
|
-
SchedulesApi,
|
|
13
11
|
WatchModeApi,
|
|
14
12
|
} from "../client";
|
|
15
13
|
import { Configuration } from "../client/configuration";
|
|
@@ -65,14 +63,12 @@ const getApiClients = (
|
|
|
65
63
|
const config = new Configuration({ basePath });
|
|
66
64
|
|
|
67
65
|
return {
|
|
68
|
-
queryResults: new QueryresultsApi(config, basePath, axiosInstance),
|
|
69
66
|
models: new ModelsApi(config, basePath, axiosInstance),
|
|
70
67
|
projects: new ProjectsApi(config, basePath, axiosInstance),
|
|
71
68
|
packages: new PackagesApi(config, basePath, axiosInstance),
|
|
72
69
|
notebooks: new NotebooksApi(config, basePath, axiosInstance),
|
|
73
70
|
connections: new ConnectionsApi(config, basePath, axiosInstance),
|
|
74
71
|
databases: new DatabasesApi(config, basePath, axiosInstance),
|
|
75
|
-
schedules: new SchedulesApi(config, basePath, axiosInstance),
|
|
76
72
|
watchMode: new WatchModeApi(config, basePath, axiosInstance),
|
|
77
73
|
};
|
|
78
74
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { useServer } from "../components/ServerProvider";
|
|
1
2
|
import { parseResourceUri } from "../utils/formatting";
|
|
2
3
|
import { useQueryWithApiError } from "./useQueryWithApiError";
|
|
3
|
-
import { useServer } from "../components/ServerProvider";
|
|
4
4
|
|
|
5
5
|
interface UseRawQueryDataProps {
|
|
6
6
|
modelPath: string;
|
|
@@ -35,14 +35,16 @@ export function useRawQueryData({
|
|
|
35
35
|
queryName,
|
|
36
36
|
],
|
|
37
37
|
queryFn: () =>
|
|
38
|
-
apiClients.
|
|
38
|
+
apiClients.models.executeQueryModel(
|
|
39
39
|
projectName,
|
|
40
40
|
packageName,
|
|
41
41
|
modelPath,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
{
|
|
43
|
+
query: query,
|
|
44
|
+
sourceName: sourceName,
|
|
45
|
+
queryName: queryName,
|
|
46
|
+
versionId: versionId,
|
|
47
|
+
},
|
|
46
48
|
),
|
|
47
49
|
enabled,
|
|
48
50
|
});
|