@malloy-publisher/sdk 0.0.205 → 0.0.207
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-UAgM1ojG.cjs.js +1 -0
- package/dist/{ServerProvider-CV37_sr_.es.js → ServerProvider-jpXNccQX.es.js} +919 -1311
- package/dist/client/api.d.ts +356 -416
- package/dist/client/index.cjs.js +1 -1
- package/dist/client/index.es.js +53 -55
- package/dist/components/Materializations/CreateMaterializationDialog.d.ts +0 -1
- package/dist/components/Materializations/ManifestView.d.ts +6 -7
- package/dist/components/Materializations/utils.d.ts +20 -16
- package/dist/components/ServerProvider.d.ts +1 -2
- package/dist/components/given/GivenInput.d.ts +13 -8
- package/dist/{core-C2sQrwVu.es.js → core-AOmIKwkc.es.js} +1 -1
- package/dist/{core-BWQQVODR.cjs.js → core-D1ZybzhJ.cjs.js} +1 -1
- package/dist/hooks/useGivensForm.d.ts +0 -2
- package/dist/{index-Dky6W6d1.cjs.js → index-Di675Z82.cjs.js} +77 -77
- package/dist/{index-CBRWGN55.es.js → index-eoQZlIjY.es.js} +8184 -8157
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +2 -2
- package/package.json +1 -1
- package/src/components/Materializations/CreateMaterializationDialog.tsx +6 -20
- package/src/components/Materializations/ManifestView.tsx +29 -46
- package/src/components/Materializations/MaterializationDetailDialog.tsx +104 -74
- package/src/components/Materializations/MaterializationRunsList.tsx +2 -1
- package/src/components/Materializations/Materializations.tsx +13 -85
- package/src/components/Materializations/utils.ts +60 -27
- package/src/components/Model/Model.tsx +39 -0
- package/src/components/Notebook/Notebook.tsx +22 -9
- package/src/components/Package/Package.tsx +1 -1
- package/src/components/ServerProvider.tsx +0 -2
- package/src/components/given/GivenInput.tsx +54 -31
- package/src/hooks/useGivensForm.ts +0 -12
- package/dist/ServerProvider-Ci6NBOLe.cjs.js +0 -1
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-Di675Z82.cjs.js"),o=require("./ServerProvider-UAgM1ojG.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.Materializations=e.Materializations;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.PageViewer=e.PageViewer;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, O as o, C as r, D as n, F as i, E as t, H as l, L as u, M as m, o as d, q as c, r as k, y as p, N as g, x as D, P as S, B as F, Q as R, R as x, I as y, t as b, S as E, W as M, J as v, T as C, K as P, G as Q, a2 as W, g as A, i as f, j as w, Z as B, k as G, l as H, _ as K, p as L, m as N, n as U, a1 as j, U as z, V as I, X as J, Y as V, a0 as h, v as q, $ as O, u as T, e as X } from "./index-
|
|
2
|
-
import { S as Z, u as _ } from "./ServerProvider-
|
|
1
|
+
import { A as a, O as o, C as r, D as n, F as i, E as t, H as l, L as u, M as m, o as d, q as c, r as k, y as p, N as g, x as D, P as S, B as F, Q as R, R as x, I as y, t as b, S as E, W as M, J as v, T as C, K as P, G as Q, a2 as W, g as A, i as f, j as w, Z as B, k as G, l as H, _ as K, p as L, m as N, n as U, a1 as j, U as z, V as I, X as J, Y as V, a0 as h, v as q, $ as O, u as T, e as X } from "./index-eoQZlIjY.es.js";
|
|
2
|
+
import { S as Z, u as _ } from "./ServerProvider-jpXNccQX.es.js";
|
|
3
3
|
export {
|
|
4
4
|
a as AnalyzePackageButton,
|
|
5
5
|
o as BrowserWorkbookStorage,
|
package/package.json
CHANGED
|
@@ -14,10 +14,7 @@ import {
|
|
|
14
14
|
import { useState } from "react";
|
|
15
15
|
|
|
16
16
|
type CreateMaterializationDialogProps = {
|
|
17
|
-
onSubmit: (opts: {
|
|
18
|
-
forceRefresh: boolean;
|
|
19
|
-
autoLoadManifest: boolean;
|
|
20
|
-
}) => Promise<unknown>;
|
|
17
|
+
onSubmit: (opts: { forceRefresh: boolean }) => Promise<unknown>;
|
|
21
18
|
isSubmitting: boolean;
|
|
22
19
|
disabled?: boolean;
|
|
23
20
|
disabledReason?: string;
|
|
@@ -31,13 +28,12 @@ export default function CreateMaterializationDialog({
|
|
|
31
28
|
}: CreateMaterializationDialogProps) {
|
|
32
29
|
const [open, setOpen] = useState(false);
|
|
33
30
|
const [forceRefresh, setForceRefresh] = useState(false);
|
|
34
|
-
const [autoLoadManifest, setAutoLoadManifest] = useState(true);
|
|
35
31
|
|
|
36
32
|
const handleClose = () => setOpen(false);
|
|
37
33
|
|
|
38
34
|
const handleRun = async () => {
|
|
39
35
|
try {
|
|
40
|
-
await onSubmit({ forceRefresh
|
|
36
|
+
await onSubmit({ forceRefresh });
|
|
41
37
|
setOpen(false);
|
|
42
38
|
} catch {
|
|
43
39
|
// The mutation surfaces the error through the caller's Snackbar;
|
|
@@ -79,8 +75,9 @@ export default function CreateMaterializationDialog({
|
|
|
79
75
|
</DialogTitle>
|
|
80
76
|
<DialogContent>
|
|
81
77
|
<DialogContentText sx={{ mb: 2 }}>
|
|
82
|
-
|
|
83
|
-
|
|
78
|
+
Materialize every persist source in this package: compile,
|
|
79
|
+
build the tables, and load them so queries serve from the
|
|
80
|
+
materialized tables.
|
|
84
81
|
</DialogContentText>
|
|
85
82
|
<FormGroup>
|
|
86
83
|
<FormControlLabel
|
|
@@ -94,17 +91,6 @@ export default function CreateMaterializationDialog({
|
|
|
94
91
|
}
|
|
95
92
|
label="Force refresh (rebuild even if unchanged)"
|
|
96
93
|
/>
|
|
97
|
-
<FormControlLabel
|
|
98
|
-
control={
|
|
99
|
-
<Switch
|
|
100
|
-
checked={autoLoadManifest}
|
|
101
|
-
onChange={(event) =>
|
|
102
|
-
setAutoLoadManifest(event.target.checked)
|
|
103
|
-
}
|
|
104
|
-
/>
|
|
105
|
-
}
|
|
106
|
-
label="Auto-load manifest after build"
|
|
107
|
-
/>
|
|
108
94
|
</FormGroup>
|
|
109
95
|
</DialogContent>
|
|
110
96
|
<DialogActions>
|
|
@@ -114,7 +100,7 @@ export default function CreateMaterializationDialog({
|
|
|
114
100
|
loading={isSubmitting}
|
|
115
101
|
onClick={handleRun}
|
|
116
102
|
>
|
|
117
|
-
|
|
103
|
+
Materialize
|
|
118
104
|
</Button>
|
|
119
105
|
</DialogActions>
|
|
120
106
|
</Dialog>
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import RefreshIcon from "@mui/icons-material/Refresh";
|
|
2
1
|
import {
|
|
3
2
|
Box,
|
|
4
|
-
Button,
|
|
5
3
|
Stack,
|
|
6
4
|
Table,
|
|
7
5
|
TableBody,
|
|
@@ -11,67 +9,42 @@ import {
|
|
|
11
9
|
Typography,
|
|
12
10
|
} from "@mui/material";
|
|
13
11
|
import { ManifestEntry } from "../../client";
|
|
14
|
-
import { ApiError, ApiErrorDisplay } from "../ApiErrorDisplay";
|
|
15
12
|
import { MONO_FONT_FAMILY } from "../styles";
|
|
13
|
+
import { formatTimestamp } from "./utils";
|
|
16
14
|
|
|
17
15
|
type ManifestViewProps = {
|
|
18
16
|
entries: { [buildId: string]: ManifestEntry } | undefined;
|
|
19
|
-
|
|
20
|
-
isReloading: boolean;
|
|
21
|
-
isError?: boolean;
|
|
22
|
-
error?: ApiError | null;
|
|
23
|
-
onReload: () => void;
|
|
17
|
+
builtAt?: string;
|
|
24
18
|
};
|
|
25
19
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
error,
|
|
32
|
-
onReload,
|
|
33
|
-
}: ManifestViewProps) {
|
|
20
|
+
/**
|
|
21
|
+
* Read-only view of a materialization's build manifest: the physical tables
|
|
22
|
+
* produced from the build plan, carried on the materialization resource.
|
|
23
|
+
*/
|
|
24
|
+
export default function ManifestView({ entries, builtAt }: ManifestViewProps) {
|
|
34
25
|
const rows = Object.entries(entries ?? {});
|
|
35
26
|
|
|
36
27
|
return (
|
|
37
28
|
<Box>
|
|
38
29
|
<Stack
|
|
39
30
|
direction="row"
|
|
40
|
-
alignItems="
|
|
31
|
+
alignItems="baseline"
|
|
41
32
|
justifyContent="space-between"
|
|
42
|
-
sx={{ mb: 1 }}
|
|
43
33
|
>
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
>
|
|
49
|
-
|
|
50
|
-
</Typography>
|
|
51
|
-
<Typography variant="body2" color="text.secondary">
|
|
52
|
-
Tables produced by materializing this package
|
|
34
|
+
<Typography variant="subtitle2" gutterBottom>
|
|
35
|
+
Build manifest
|
|
36
|
+
</Typography>
|
|
37
|
+
{builtAt && (
|
|
38
|
+
<Typography variant="caption" color="text.secondary">
|
|
39
|
+
Built {formatTimestamp(builtAt)}
|
|
53
40
|
</Typography>
|
|
54
|
-
</Box>
|
|
55
|
-
{mutable && (
|
|
56
|
-
<Button
|
|
57
|
-
size="small"
|
|
58
|
-
startIcon={<RefreshIcon />}
|
|
59
|
-
loading={isReloading}
|
|
60
|
-
onClick={onReload}
|
|
61
|
-
aria-label="Reload manifest"
|
|
62
|
-
>
|
|
63
|
-
Reload manifest
|
|
64
|
-
</Button>
|
|
65
41
|
)}
|
|
66
42
|
</Stack>
|
|
67
|
-
|
|
68
|
-
{isError ? (
|
|
69
|
-
<ApiErrorDisplay error={error ?? null} context="Build manifest" />
|
|
70
|
-
) : rows.length === 0 ? (
|
|
43
|
+
{rows.length === 0 ? (
|
|
71
44
|
<Typography
|
|
72
45
|
variant="body2"
|
|
73
46
|
color="text.secondary"
|
|
74
|
-
sx={{
|
|
47
|
+
sx={{ fontStyle: "italic" }}
|
|
75
48
|
>
|
|
76
49
|
No materialized tables yet.
|
|
77
50
|
</Typography>
|
|
@@ -79,18 +52,28 @@ export default function ManifestView({
|
|
|
79
52
|
<Table size="small">
|
|
80
53
|
<TableHead>
|
|
81
54
|
<TableRow>
|
|
82
|
-
<TableCell>
|
|
55
|
+
<TableCell>Source</TableCell>
|
|
83
56
|
<TableCell>Table name</TableCell>
|
|
57
|
+
<TableCell>Connection</TableCell>
|
|
58
|
+
<TableCell>Realization</TableCell>
|
|
59
|
+
<TableCell align="right">Rows</TableCell>
|
|
84
60
|
</TableRow>
|
|
85
61
|
</TableHead>
|
|
86
62
|
<TableBody>
|
|
87
63
|
{rows.map(([buildId, entry]) => (
|
|
88
64
|
<TableRow key={buildId}>
|
|
89
65
|
<TableCell sx={{ fontFamily: MONO_FONT_FAMILY }}>
|
|
90
|
-
{buildId}
|
|
66
|
+
{entry.sourceName ?? buildId}
|
|
91
67
|
</TableCell>
|
|
92
68
|
<TableCell sx={{ fontFamily: MONO_FONT_FAMILY }}>
|
|
93
|
-
{entry.
|
|
69
|
+
{entry.physicalTableName ?? "-"}
|
|
70
|
+
</TableCell>
|
|
71
|
+
<TableCell sx={{ fontFamily: MONO_FONT_FAMILY }}>
|
|
72
|
+
{entry.connectionName ?? "-"}
|
|
73
|
+
</TableCell>
|
|
74
|
+
<TableCell>{entry.realization ?? "-"}</TableCell>
|
|
75
|
+
<TableCell align="right">
|
|
76
|
+
{entry.rowCount ?? "-"}
|
|
94
77
|
</TableCell>
|
|
95
78
|
</TableRow>
|
|
96
79
|
))}
|
|
@@ -16,11 +16,13 @@ import {
|
|
|
16
16
|
} from "@mui/material";
|
|
17
17
|
import { Materialization } from "../../client";
|
|
18
18
|
import { MONO_FONT_FAMILY } from "../styles";
|
|
19
|
+
import ManifestView from "./ManifestView";
|
|
19
20
|
import {
|
|
20
21
|
formatDuration,
|
|
21
|
-
|
|
22
|
+
formatTimestamp,
|
|
22
23
|
parseMetadata,
|
|
23
24
|
statusColor,
|
|
25
|
+
statusLabel,
|
|
24
26
|
} from "./utils";
|
|
25
27
|
|
|
26
28
|
type MaterializationDetailDialogProps = {
|
|
@@ -33,8 +35,7 @@ export default function MaterializationDetailDialog({
|
|
|
33
35
|
onClose,
|
|
34
36
|
}: MaterializationDetailDialogProps) {
|
|
35
37
|
const meta = materialization ? parseMetadata(materialization) : {};
|
|
36
|
-
const
|
|
37
|
-
const gcErrors = meta.gcErrors ?? [];
|
|
38
|
+
const planSources = Object.values(materialization?.buildPlan?.sources ?? {});
|
|
38
39
|
|
|
39
40
|
return (
|
|
40
41
|
<Dialog
|
|
@@ -50,7 +51,7 @@ export default function MaterializationDetailDialog({
|
|
|
50
51
|
<Stack direction="row" alignItems="center" spacing={1.5}>
|
|
51
52
|
<Chip
|
|
52
53
|
size="small"
|
|
53
|
-
label={materialization.status
|
|
54
|
+
label={statusLabel(materialization.status)}
|
|
54
55
|
color={statusColor(materialization.status)}
|
|
55
56
|
/>
|
|
56
57
|
<Typography
|
|
@@ -69,14 +70,42 @@ export default function MaterializationDetailDialog({
|
|
|
69
70
|
</IconButton>
|
|
70
71
|
</DialogTitle>
|
|
71
72
|
<DialogContent dividers>
|
|
72
|
-
<
|
|
73
|
+
<Box
|
|
74
|
+
sx={{
|
|
75
|
+
display: "grid",
|
|
76
|
+
gridTemplateColumns:
|
|
77
|
+
"repeat(auto-fit, minmax(150px, 1fr))",
|
|
78
|
+
gap: 2,
|
|
79
|
+
mb: 3,
|
|
80
|
+
}}
|
|
81
|
+
>
|
|
82
|
+
<DetailField
|
|
83
|
+
label="Package"
|
|
84
|
+
value={materialization.packageName ?? "—"}
|
|
85
|
+
/>
|
|
86
|
+
<DetailField
|
|
87
|
+
label="Mode"
|
|
88
|
+
value={
|
|
89
|
+
materialization.pauseBetweenPhases
|
|
90
|
+
? "Two-round"
|
|
91
|
+
: "Auto-run"
|
|
92
|
+
}
|
|
93
|
+
/>
|
|
94
|
+
<DetailField
|
|
95
|
+
label="Force refresh"
|
|
96
|
+
value={meta.forceRefresh ? "Yes" : "No"}
|
|
97
|
+
/>
|
|
73
98
|
<DetailField
|
|
74
99
|
label="Started"
|
|
75
|
-
value={
|
|
100
|
+
value={formatTimestamp(
|
|
76
101
|
materialization.startedAt ??
|
|
77
102
|
materialization.createdAt,
|
|
78
103
|
)}
|
|
79
104
|
/>
|
|
105
|
+
<DetailField
|
|
106
|
+
label="Completed"
|
|
107
|
+
value={formatTimestamp(materialization.completedAt)}
|
|
108
|
+
/>
|
|
80
109
|
<DetailField
|
|
81
110
|
label="Duration"
|
|
82
111
|
value={formatDuration(
|
|
@@ -92,10 +121,18 @@ export default function MaterializationDetailDialog({
|
|
|
92
121
|
label="Sources skipped"
|
|
93
122
|
value={`${meta.sourcesSkipped ?? 0}`}
|
|
94
123
|
/>
|
|
95
|
-
|
|
124
|
+
<DetailField
|
|
125
|
+
label="Created"
|
|
126
|
+
value={formatTimestamp(materialization.createdAt)}
|
|
127
|
+
/>
|
|
128
|
+
<DetailField
|
|
129
|
+
label="Updated"
|
|
130
|
+
value={formatTimestamp(materialization.updatedAt)}
|
|
131
|
+
/>
|
|
132
|
+
</Box>
|
|
96
133
|
|
|
97
134
|
{materialization.error && (
|
|
98
|
-
<Box sx={{ mb:
|
|
135
|
+
<Box sx={{ mb: 3 }}>
|
|
99
136
|
<Typography
|
|
100
137
|
variant="subtitle2"
|
|
101
138
|
color="error"
|
|
@@ -115,76 +152,69 @@ export default function MaterializationDetailDialog({
|
|
|
115
152
|
</Box>
|
|
116
153
|
)}
|
|
117
154
|
|
|
118
|
-
<
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
{sources.length === 0 ? (
|
|
122
|
-
<Typography
|
|
123
|
-
variant="body2"
|
|
124
|
-
color="text.secondary"
|
|
125
|
-
sx={{ fontStyle: "italic" }}
|
|
126
|
-
>
|
|
127
|
-
No per-source results recorded.
|
|
155
|
+
<Box sx={{ mb: 3 }}>
|
|
156
|
+
<Typography variant="subtitle2" gutterBottom>
|
|
157
|
+
Build plan
|
|
128
158
|
</Typography>
|
|
129
|
-
|
|
130
|
-
<Table size="small">
|
|
131
|
-
<TableHead>
|
|
132
|
-
<TableRow>
|
|
133
|
-
<TableCell>Source</TableCell>
|
|
134
|
-
<TableCell>Table</TableCell>
|
|
135
|
-
<TableCell>Status</TableCell>
|
|
136
|
-
<TableCell align="right">Duration</TableCell>
|
|
137
|
-
</TableRow>
|
|
138
|
-
</TableHead>
|
|
139
|
-
<TableBody>
|
|
140
|
-
{sources.map((source, index) => (
|
|
141
|
-
<TableRow
|
|
142
|
-
key={
|
|
143
|
-
source.buildId ?? source.sourceName ?? index
|
|
144
|
-
}
|
|
145
|
-
>
|
|
146
|
-
<TableCell
|
|
147
|
-
sx={{ fontFamily: MONO_FONT_FAMILY }}
|
|
148
|
-
>
|
|
149
|
-
{source.sourceName ?? "-"}
|
|
150
|
-
</TableCell>
|
|
151
|
-
<TableCell
|
|
152
|
-
sx={{ fontFamily: MONO_FONT_FAMILY }}
|
|
153
|
-
>
|
|
154
|
-
{source.tableName ?? "-"}
|
|
155
|
-
</TableCell>
|
|
156
|
-
<TableCell>{source.status ?? "-"}</TableCell>
|
|
157
|
-
<TableCell align="right">
|
|
158
|
-
{source.durationMs !== undefined
|
|
159
|
-
? `${Math.round(source.durationMs)}ms`
|
|
160
|
-
: "-"}
|
|
161
|
-
</TableCell>
|
|
162
|
-
</TableRow>
|
|
163
|
-
))}
|
|
164
|
-
</TableBody>
|
|
165
|
-
</Table>
|
|
166
|
-
)}
|
|
167
|
-
|
|
168
|
-
{gcErrors.length > 0 && (
|
|
169
|
-
<Box sx={{ mt: 2 }}>
|
|
159
|
+
{planSources.length === 0 ? (
|
|
170
160
|
<Typography
|
|
171
|
-
variant="
|
|
172
|
-
color="
|
|
173
|
-
|
|
161
|
+
variant="body2"
|
|
162
|
+
color="text.secondary"
|
|
163
|
+
sx={{ fontStyle: "italic" }}
|
|
174
164
|
>
|
|
175
|
-
|
|
165
|
+
No build plan yet.
|
|
176
166
|
</Typography>
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
167
|
+
) : (
|
|
168
|
+
<Table size="small">
|
|
169
|
+
<TableHead>
|
|
170
|
+
<TableRow>
|
|
171
|
+
<TableCell>Source</TableCell>
|
|
172
|
+
<TableCell>Connection</TableCell>
|
|
173
|
+
<TableCell>Dialect</TableCell>
|
|
174
|
+
<TableCell align="right">Columns</TableCell>
|
|
175
|
+
<TableCell>Build ID</TableCell>
|
|
176
|
+
</TableRow>
|
|
177
|
+
</TableHead>
|
|
178
|
+
<TableBody>
|
|
179
|
+
{planSources.map((source) => (
|
|
180
|
+
<TableRow key={source.sourceID}>
|
|
181
|
+
<TableCell
|
|
182
|
+
sx={{ fontFamily: MONO_FONT_FAMILY }}
|
|
183
|
+
>
|
|
184
|
+
{source.name}
|
|
185
|
+
</TableCell>
|
|
186
|
+
<TableCell
|
|
187
|
+
sx={{ fontFamily: MONO_FONT_FAMILY }}
|
|
188
|
+
>
|
|
189
|
+
{source.connectionName}
|
|
190
|
+
</TableCell>
|
|
191
|
+
<TableCell>
|
|
192
|
+
{source.dialect ?? "-"}
|
|
193
|
+
</TableCell>
|
|
194
|
+
<TableCell align="right">
|
|
195
|
+
{source.columns?.length ?? 0}
|
|
196
|
+
</TableCell>
|
|
197
|
+
<TableCell
|
|
198
|
+
sx={{
|
|
199
|
+
fontFamily: MONO_FONT_FAMILY,
|
|
200
|
+
fontSize: "0.75rem",
|
|
201
|
+
wordBreak: "break-all",
|
|
202
|
+
maxWidth: 220,
|
|
203
|
+
}}
|
|
204
|
+
>
|
|
205
|
+
{source.buildId}
|
|
206
|
+
</TableCell>
|
|
207
|
+
</TableRow>
|
|
208
|
+
))}
|
|
209
|
+
</TableBody>
|
|
210
|
+
</Table>
|
|
211
|
+
)}
|
|
212
|
+
</Box>
|
|
213
|
+
|
|
214
|
+
<ManifestView
|
|
215
|
+
entries={materialization.manifest?.entries}
|
|
216
|
+
builtAt={materialization.manifest?.builtAt}
|
|
217
|
+
/>
|
|
188
218
|
</DialogContent>
|
|
189
219
|
</>
|
|
190
220
|
)}
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
isTerminalStatus,
|
|
28
28
|
parseMetadata,
|
|
29
29
|
statusColor,
|
|
30
|
+
statusLabel,
|
|
30
31
|
} from "./utils";
|
|
31
32
|
|
|
32
33
|
type MaterializationRunsListProps = {
|
|
@@ -141,7 +142,7 @@ function MaterializationRow({
|
|
|
141
142
|
<Box sx={{ display: "flex", alignItems: "center", gap: 0.5 }}>
|
|
142
143
|
<Chip
|
|
143
144
|
size="small"
|
|
144
|
-
label={materialization.status
|
|
145
|
+
label={statusLabel(materialization.status)}
|
|
145
146
|
color={statusColor(materialization.status)}
|
|
146
147
|
variant={active ? "filled" : "outlined"}
|
|
147
148
|
/>
|
|
@@ -8,12 +8,8 @@ import {
|
|
|
8
8
|
Typography,
|
|
9
9
|
} from "@mui/material";
|
|
10
10
|
import { useQueryClient } from "@tanstack/react-query";
|
|
11
|
-
import React, {
|
|
12
|
-
import {
|
|
13
|
-
ManifestActionActionEnum,
|
|
14
|
-
Materialization,
|
|
15
|
-
MaterializationActionActionEnum,
|
|
16
|
-
} from "../../client";
|
|
11
|
+
import React, { useState } from "react";
|
|
12
|
+
import { Materialization, MaterializationActionActionEnum } from "../../client";
|
|
17
13
|
import {
|
|
18
14
|
useMutationWithApiError,
|
|
19
15
|
useQueryWithApiError,
|
|
@@ -23,7 +19,6 @@ import { ApiErrorDisplay } from "../ApiErrorDisplay";
|
|
|
23
19
|
import { Loading } from "../Loading";
|
|
24
20
|
import { useServer } from "../ServerProvider";
|
|
25
21
|
import CreateMaterializationDialog from "./CreateMaterializationDialog";
|
|
26
|
-
import ManifestView from "./ManifestView";
|
|
27
22
|
import MaterializationDetailDialog from "./MaterializationDetailDialog";
|
|
28
23
|
import MaterializationRunsList from "./MaterializationRunsList";
|
|
29
24
|
import { isActiveStatus } from "./utils";
|
|
@@ -75,57 +70,28 @@ export default function Materializations({
|
|
|
75
70
|
},
|
|
76
71
|
});
|
|
77
72
|
|
|
78
|
-
const manifestQuery = useQueryWithApiError({
|
|
79
|
-
queryKey: ["manifest", environmentName, packageName],
|
|
80
|
-
queryFn: () =>
|
|
81
|
-
apiClients.manifests.getManifest(environmentName, packageName),
|
|
82
|
-
});
|
|
83
|
-
|
|
84
73
|
const invalidateList = () =>
|
|
85
74
|
queryClient.invalidateQueries({
|
|
86
75
|
queryKey: ["materializations", environmentName, packageName],
|
|
87
76
|
});
|
|
88
|
-
const invalidateManifest = () =>
|
|
89
|
-
queryClient.invalidateQueries({
|
|
90
|
-
queryKey: ["manifest", environmentName, packageName],
|
|
91
|
-
});
|
|
92
77
|
|
|
78
|
+
// Auto-run: the publisher compiles, builds every persist source, and loads
|
|
79
|
+
// the resulting manifest in a single pass.
|
|
93
80
|
const createMaterialization = useMutationWithApiError({
|
|
94
|
-
mutationFn:
|
|
95
|
-
|
|
96
|
-
autoLoadManifest: boolean;
|
|
97
|
-
}) => {
|
|
98
|
-
const created =
|
|
99
|
-
await apiClients.materializations.createMaterialization(
|
|
100
|
-
environmentName,
|
|
101
|
-
packageName,
|
|
102
|
-
{
|
|
103
|
-
forceRefresh: opts.forceRefresh,
|
|
104
|
-
autoLoadManifest: opts.autoLoadManifest,
|
|
105
|
-
},
|
|
106
|
-
);
|
|
107
|
-
const id = created.data?.id;
|
|
108
|
-
if (!id) {
|
|
109
|
-
throw new Error(
|
|
110
|
-
"Server did not return a materialization id; nothing was started.",
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
await apiClients.materializations.materializationAction(
|
|
81
|
+
mutationFn: (opts: { forceRefresh: boolean }) =>
|
|
82
|
+
apiClients.materializations.createMaterialization(
|
|
114
83
|
environmentName,
|
|
115
84
|
packageName,
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
},
|
|
85
|
+
{
|
|
86
|
+
forceRefresh: opts.forceRefresh,
|
|
87
|
+
},
|
|
88
|
+
),
|
|
121
89
|
onSuccess() {
|
|
122
|
-
setNotificationMessage("Materialization
|
|
90
|
+
setNotificationMessage("Materialization requested");
|
|
123
91
|
invalidateList();
|
|
124
92
|
},
|
|
125
93
|
onError(error) {
|
|
126
94
|
setNotificationMessage(error.message);
|
|
127
|
-
// A create can succeed (a PENDING row now exists) before the start
|
|
128
|
-
// action fails; refetch so that row surfaces and polling resumes.
|
|
129
95
|
invalidateList();
|
|
130
96
|
},
|
|
131
97
|
});
|
|
@@ -163,22 +129,6 @@ export default function Materializations({
|
|
|
163
129
|
},
|
|
164
130
|
});
|
|
165
131
|
|
|
166
|
-
const reloadManifest = useMutationWithApiError({
|
|
167
|
-
mutationFn: () =>
|
|
168
|
-
apiClients.manifests.manifestAction(
|
|
169
|
-
environmentName,
|
|
170
|
-
packageName,
|
|
171
|
-
ManifestActionActionEnum.Reload,
|
|
172
|
-
),
|
|
173
|
-
onSuccess() {
|
|
174
|
-
setNotificationMessage("Manifest reloaded");
|
|
175
|
-
invalidateManifest();
|
|
176
|
-
},
|
|
177
|
-
onError(error) {
|
|
178
|
-
setNotificationMessage(error.message);
|
|
179
|
-
},
|
|
180
|
-
});
|
|
181
|
-
|
|
182
132
|
const materializations = (listQuery.data?.data ?? []) as Materialization[];
|
|
183
133
|
const selected =
|
|
184
134
|
materializations.find((row) => row.id === selectedId) ?? null;
|
|
@@ -188,19 +138,6 @@ export default function Materializations({
|
|
|
188
138
|
stopMaterialization.isPending ||
|
|
189
139
|
deleteMaterialization.isPending;
|
|
190
140
|
|
|
191
|
-
// When the last active run finishes, a build with autoLoadManifest enabled
|
|
192
|
-
// may have written new manifest entries, so refetch the manifest once on
|
|
193
|
-
// that active-to-terminal transition.
|
|
194
|
-
const wasActive = useRef(hasActive);
|
|
195
|
-
useEffect(() => {
|
|
196
|
-
if (wasActive.current && !hasActive) {
|
|
197
|
-
queryClient.invalidateQueries({
|
|
198
|
-
queryKey: ["manifest", environmentName, packageName],
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
wasActive.current = hasActive;
|
|
202
|
-
}, [hasActive, queryClient, environmentName, packageName]);
|
|
203
|
-
|
|
204
141
|
return (
|
|
205
142
|
<Container
|
|
206
143
|
maxWidth={false}
|
|
@@ -244,8 +181,8 @@ export default function Materializations({
|
|
|
244
181
|
Materializations
|
|
245
182
|
</Typography>
|
|
246
183
|
<Typography variant="body2" color="text.secondary">
|
|
247
|
-
|
|
248
|
-
tables
|
|
184
|
+
Materialize the persist sources in {packageName} into
|
|
185
|
+
tables and serve queries from them
|
|
249
186
|
</Typography>
|
|
250
187
|
</Box>
|
|
251
188
|
{mutable && (
|
|
@@ -295,15 +232,6 @@ export default function Materializations({
|
|
|
295
232
|
)}
|
|
296
233
|
</Box>
|
|
297
234
|
|
|
298
|
-
<ManifestView
|
|
299
|
-
entries={manifestQuery.data?.data?.entries}
|
|
300
|
-
mutable={mutable}
|
|
301
|
-
isReloading={reloadManifest.isPending}
|
|
302
|
-
isError={manifestQuery.isError}
|
|
303
|
-
error={manifestQuery.error}
|
|
304
|
-
onReload={() => reloadManifest.mutate()}
|
|
305
|
-
/>
|
|
306
|
-
|
|
307
235
|
<MaterializationDetailDialog
|
|
308
236
|
materialization={selected}
|
|
309
237
|
onClose={() => setSelectedId(null)}
|