datajunction-ui 0.0.1-a35.dev0 → 0.0.1-a37
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/package.json +1 -1
- package/src/app/components/forms/Action.jsx +8 -0
- package/src/app/components/forms/NodeNameField.jsx +64 -0
- package/src/app/components/forms/NodeTagsInput.jsx +61 -0
- package/src/app/index.tsx +18 -0
- package/src/app/pages/AddEditNodePage/__tests__/AddEditNodePageFormFailed.test.jsx +1 -1
- package/src/app/pages/AddEditNodePage/__tests__/AddEditNodePageFormSuccess.test.jsx +2 -5
- package/src/app/pages/AddEditNodePage/index.jsx +16 -7
- package/src/app/pages/CubeBuilderPage/DimensionsSelect.jsx +154 -0
- package/src/app/pages/CubeBuilderPage/Loadable.jsx +16 -0
- package/src/app/pages/CubeBuilderPage/MetricsSelect.jsx +79 -0
- package/src/app/pages/CubeBuilderPage/__tests__/index.test.jsx +405 -0
- package/src/app/pages/CubeBuilderPage/index.jsx +254 -0
- package/src/app/pages/NamespacePage/index.jsx +5 -0
- package/src/app/pages/NodePage/AddBackfillPopover.jsx +13 -6
- package/src/app/pages/NodePage/AddMaterializationPopover.jsx +47 -24
- package/src/app/pages/NodePage/NodeInfoTab.jsx +6 -1
- package/src/app/pages/NodePage/NodeMaterializationTab.jsx +44 -32
- package/src/app/pages/NodePage/__tests__/AddBackfillPopover.test.jsx +0 -1
- package/src/app/pages/NodePage/__tests__/AddMaterializationPopover.test.jsx +84 -0
- package/src/app/pages/NodePage/__tests__/__snapshots__/NodePage.test.jsx.snap +78 -174
- package/src/app/services/DJService.js +66 -12
- package/src/app/services/__tests__/DJService.test.jsx +72 -7
- package/src/styles/index.css +4 -0
- package/src/styles/node-creation.scss +12 -0
|
@@ -2,27 +2,24 @@ import { useContext, useEffect, useRef, useState } from 'react';
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import DJClientContext from '../../providers/djclient';
|
|
4
4
|
import { ErrorMessage, Field, Form, Formik } from 'formik';
|
|
5
|
-
import { FormikSelect } from '../AddEditNodePage/FormikSelect';
|
|
6
|
-
import EditIcon from '../../icons/EditIcon';
|
|
7
5
|
import { displayMessageAfterSubmit, labelize } from '../../../utils/form';
|
|
8
6
|
|
|
9
7
|
export default function AddMaterializationPopover({ node, onSubmit }) {
|
|
10
8
|
const djClient = useContext(DJClientContext).DataJunctionAPI;
|
|
11
9
|
const [popoverAnchor, setPopoverAnchor] = useState(false);
|
|
12
|
-
const [
|
|
13
|
-
const [
|
|
10
|
+
const [options, setOptions] = useState([]);
|
|
11
|
+
const [jobs, setJobs] = useState([]);
|
|
14
12
|
|
|
15
13
|
const ref = useRef(null);
|
|
16
14
|
|
|
17
15
|
useEffect(() => {
|
|
18
16
|
const fetchData = async () => {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
? engines[0].name + '__' + engines[0].version
|
|
24
|
-
: '',
|
|
17
|
+
const options = await djClient.materializationInfo();
|
|
18
|
+
setOptions(options);
|
|
19
|
+
const allowedJobs = options.job_types?.filter(job =>
|
|
20
|
+
job.allowed_node_types.includes(node.type),
|
|
25
21
|
);
|
|
22
|
+
setJobs(allowedJobs);
|
|
26
23
|
};
|
|
27
24
|
fetchData().catch(console.error);
|
|
28
25
|
const handleClickOutside = event => {
|
|
@@ -41,14 +38,15 @@ export default function AddMaterializationPopover({ node, onSubmit }) {
|
|
|
41
38
|
{ setSubmitting, setStatus },
|
|
42
39
|
) => {
|
|
43
40
|
setSubmitting(false);
|
|
44
|
-
const
|
|
45
|
-
|
|
41
|
+
const config = JSON.parse(values.config);
|
|
42
|
+
config.lookback_window = values.lookback_window;
|
|
43
|
+
console.log('values', values);
|
|
46
44
|
const response = await djClient.materialize(
|
|
47
45
|
values.node,
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
values.job_type,
|
|
47
|
+
values.strategy,
|
|
50
48
|
values.schedule,
|
|
51
|
-
|
|
49
|
+
config,
|
|
52
50
|
);
|
|
53
51
|
if (response.status === 200 || response.status === 201) {
|
|
54
52
|
setStatus({ success: 'Saved!' });
|
|
@@ -65,7 +63,7 @@ export default function AddMaterializationPopover({ node, onSubmit }) {
|
|
|
65
63
|
<>
|
|
66
64
|
<button
|
|
67
65
|
className="edit_button"
|
|
68
|
-
aria-label="
|
|
66
|
+
aria-label="AddMaterialization"
|
|
69
67
|
tabIndex="0"
|
|
70
68
|
onClick={() => {
|
|
71
69
|
setPopoverAnchor(!popoverAnchor);
|
|
@@ -90,9 +88,11 @@ export default function AddMaterializationPopover({ node, onSubmit }) {
|
|
|
90
88
|
<Formik
|
|
91
89
|
initialValues={{
|
|
92
90
|
node: node?.name,
|
|
93
|
-
|
|
91
|
+
job_type: 'spark_sql',
|
|
92
|
+
strategy: 'full',
|
|
94
93
|
config: '{"spark": {"spark.executor.memory": "6g"}}',
|
|
95
94
|
schedule: '@daily',
|
|
95
|
+
lookback_window: '1 DAY',
|
|
96
96
|
}}
|
|
97
97
|
onSubmit={configureMaterialization}
|
|
98
98
|
>
|
|
@@ -101,16 +101,15 @@ export default function AddMaterializationPopover({ node, onSubmit }) {
|
|
|
101
101
|
<Form>
|
|
102
102
|
<h2>Configure Materialization</h2>
|
|
103
103
|
{displayMessageAfterSubmit(status)}
|
|
104
|
-
<span data-testid="
|
|
105
|
-
<label htmlFor="
|
|
106
|
-
<Field as="select" name="
|
|
104
|
+
<span data-testid="job-type">
|
|
105
|
+
<label htmlFor="job_type">Job Type</label>
|
|
106
|
+
<Field as="select" name="job_type">
|
|
107
107
|
<>
|
|
108
|
-
{
|
|
109
|
-
<option
|
|
110
|
-
{
|
|
108
|
+
{jobs?.map(job => (
|
|
109
|
+
<option key={job.name} value={job.name}>
|
|
110
|
+
{job.label}
|
|
111
111
|
</option>
|
|
112
112
|
))}
|
|
113
|
-
<option value=""></option>
|
|
114
113
|
</>
|
|
115
114
|
</Field>
|
|
116
115
|
</span>
|
|
@@ -122,6 +121,18 @@ export default function AddMaterializationPopover({ node, onSubmit }) {
|
|
|
122
121
|
/>
|
|
123
122
|
<br />
|
|
124
123
|
<br />
|
|
124
|
+
<span data-testid="edit-partition">
|
|
125
|
+
<label htmlFor="strategy">Strategy</label>
|
|
126
|
+
<Field as="select" name="strategy">
|
|
127
|
+
<>
|
|
128
|
+
{options.strategies?.map(strategy => (
|
|
129
|
+
<option value={strategy.name}>{strategy.label}</option>
|
|
130
|
+
))}
|
|
131
|
+
</>
|
|
132
|
+
</Field>
|
|
133
|
+
</span>
|
|
134
|
+
<br />
|
|
135
|
+
<br />
|
|
125
136
|
<label htmlFor="schedule">Schedule</label>
|
|
126
137
|
<Field
|
|
127
138
|
type="text"
|
|
@@ -132,6 +143,18 @@ export default function AddMaterializationPopover({ node, onSubmit }) {
|
|
|
132
143
|
/>
|
|
133
144
|
<br />
|
|
134
145
|
<br />
|
|
146
|
+
<div className="DescriptionInput">
|
|
147
|
+
<ErrorMessage name="description" component="span" />
|
|
148
|
+
<label htmlFor="Config">Lookback Window</label>
|
|
149
|
+
<Field
|
|
150
|
+
type="text"
|
|
151
|
+
name="lookback_window"
|
|
152
|
+
id="lookback_window"
|
|
153
|
+
placeholder="1 DAY"
|
|
154
|
+
default="1 DAY"
|
|
155
|
+
/>
|
|
156
|
+
</div>
|
|
157
|
+
<br />
|
|
135
158
|
<div className="DescriptionInput">
|
|
136
159
|
<ErrorMessage name="description" component="span" />
|
|
137
160
|
<label htmlFor="Config">Config</label>
|
|
@@ -76,7 +76,12 @@ export default function NodeInfoTab({ node }) {
|
|
|
76
76
|
aria-label="CubeElement"
|
|
77
77
|
aria-hidden="false"
|
|
78
78
|
>
|
|
79
|
-
<a href={`/nodes/${cubeElem.node_name}`}>
|
|
79
|
+
<a href={`/nodes/${cubeElem.node_name}`}>
|
|
80
|
+
{cubeElem.type === 'dimension'
|
|
81
|
+
? labelize(cubeElem.node_name.split('.').slice(-1)[0]) + ' → '
|
|
82
|
+
: ''}
|
|
83
|
+
{cubeElem.display_name}
|
|
84
|
+
</a>
|
|
80
85
|
<span
|
|
81
86
|
className={`badge node_type__${
|
|
82
87
|
cubeElem.type === 'metric' ? cubeElem.type : 'dimension'
|
|
@@ -53,11 +53,9 @@ export default function NodeMaterializationTab({ node, djClient }) {
|
|
|
53
53
|
<div className={`cron-description`}>{cron(materialization)} </div>
|
|
54
54
|
</td>
|
|
55
55
|
<td>
|
|
56
|
-
{materialization.
|
|
57
|
-
<br />
|
|
58
|
-
{materialization.engine.version}
|
|
59
|
-
<ClientCodePopover code={materialization.clientCode} />
|
|
56
|
+
{materialization.job?.replace('MaterializationJob', '').toUpperCase()}
|
|
60
57
|
</td>
|
|
58
|
+
<td>{materialization.strategy?.toUpperCase()}</td>
|
|
61
59
|
<td>
|
|
62
60
|
{node.columns
|
|
63
61
|
.filter(col => col.partition !== null)
|
|
@@ -90,27 +88,34 @@ export default function NodeMaterializationTab({ node, djClient }) {
|
|
|
90
88
|
</div>
|
|
91
89
|
))}
|
|
92
90
|
</td>
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
<
|
|
97
|
-
<div
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
<
|
|
102
|
-
{backfill.spec.
|
|
103
|
-
</
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
91
|
+
{materializations[0].strategy === 'incremental_time' ? (
|
|
92
|
+
<td>
|
|
93
|
+
{materialization.backfills.map(backfill => (
|
|
94
|
+
<a href={backfill.urls[0]} className="partitionLink">
|
|
95
|
+
<div
|
|
96
|
+
className="partition__full"
|
|
97
|
+
key={backfill.spec.column_name}
|
|
98
|
+
>
|
|
99
|
+
<div className="partition__header">
|
|
100
|
+
{partitionColumnsMap[backfill.spec.column_name]}
|
|
101
|
+
</div>
|
|
102
|
+
<div className="partition__body">
|
|
103
|
+
<span className="badge partition_value">
|
|
104
|
+
{backfill.spec.range[0]}
|
|
105
|
+
</span>
|
|
106
|
+
to
|
|
107
|
+
<span className="badge partition_value">
|
|
108
|
+
{backfill.spec.range[1]}
|
|
109
|
+
</span>
|
|
110
|
+
</div>
|
|
108
111
|
</div>
|
|
109
|
-
</
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
</a>
|
|
113
|
+
))}
|
|
114
|
+
<AddBackfillPopover node={node} materialization={materialization} />
|
|
115
|
+
</td>
|
|
116
|
+
) : (
|
|
117
|
+
<></>
|
|
118
|
+
)}
|
|
114
119
|
<td>
|
|
115
120
|
{materialization.urls.map((url, idx) => (
|
|
116
121
|
<a href={url} key={`url-${idx}`}>
|
|
@@ -118,6 +123,9 @@ export default function NodeMaterializationTab({ node, djClient }) {
|
|
|
118
123
|
</a>
|
|
119
124
|
))}
|
|
120
125
|
</td>
|
|
126
|
+
<td>
|
|
127
|
+
<ClientCodePopover code={materialization.clientCode} />
|
|
128
|
+
</td>
|
|
121
129
|
</tr>
|
|
122
130
|
));
|
|
123
131
|
};
|
|
@@ -136,10 +144,15 @@ export default function NodeMaterializationTab({ node, djClient }) {
|
|
|
136
144
|
<thead className="fs-7 fw-bold text-gray-400 border-bottom-0">
|
|
137
145
|
<tr>
|
|
138
146
|
<th className="text-start">Schedule</th>
|
|
139
|
-
<th>
|
|
147
|
+
<th>Job Type</th>
|
|
148
|
+
<th>Strategy</th>
|
|
140
149
|
<th>Partitions</th>
|
|
141
|
-
<th>Output Tables</th>
|
|
142
|
-
|
|
150
|
+
<th>Intended Output Tables</th>
|
|
151
|
+
{materializations[0].strategy === 'incremental_time' ? (
|
|
152
|
+
<th>Backfills</th>
|
|
153
|
+
) : (
|
|
154
|
+
<></>
|
|
155
|
+
)}
|
|
143
156
|
<th>URLs</th>
|
|
144
157
|
</tr>
|
|
145
158
|
</thead>
|
|
@@ -171,16 +184,13 @@ export default function NodeMaterializationTab({ node, djClient }) {
|
|
|
171
184
|
>
|
|
172
185
|
<thead className="fs-7 fw-bold text-gray-400 border-bottom-0">
|
|
173
186
|
<tr>
|
|
174
|
-
<th className="text-start">
|
|
175
|
-
<th>Schema</th>
|
|
176
|
-
<th>Table</th>
|
|
187
|
+
<th className="text-start">Output Dataset</th>
|
|
177
188
|
<th>Valid Through</th>
|
|
178
189
|
<th>Partitions</th>
|
|
179
190
|
</tr>
|
|
180
191
|
</thead>
|
|
181
192
|
<tbody>
|
|
182
193
|
<tr>
|
|
183
|
-
<td>{node.availability.schema_}</td>
|
|
184
194
|
<td>
|
|
185
195
|
{
|
|
186
196
|
<div
|
|
@@ -203,7 +213,9 @@ export default function NodeMaterializationTab({ node, djClient }) {
|
|
|
203
213
|
</div>
|
|
204
214
|
}
|
|
205
215
|
</td>
|
|
206
|
-
<td>
|
|
216
|
+
<td>
|
|
217
|
+
{new Date(node.availability.valid_through_ts).toISOString()}
|
|
218
|
+
</td>
|
|
207
219
|
<td>
|
|
208
220
|
<span
|
|
209
221
|
className={`badge partition_value`}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, fireEvent, waitFor, screen } from '@testing-library/react';
|
|
3
|
+
import DJClientContext from '../../../providers/djclient';
|
|
4
|
+
import AddMaterializationPopover from '../AddMaterializationPopover';
|
|
5
|
+
import { mocks } from '../../../../mocks/mockNodes';
|
|
6
|
+
|
|
7
|
+
const mockDjClient = {
|
|
8
|
+
DataJunctionAPI: {
|
|
9
|
+
materialize: jest.fn(),
|
|
10
|
+
materializationInfo: jest.fn(),
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
describe('<AddMaterializationPopover />', () => {
|
|
15
|
+
it('renders correctly and handles form submission', async () => {
|
|
16
|
+
// Mock onSubmit function
|
|
17
|
+
const onSubmitMock = jest.fn();
|
|
18
|
+
mockDjClient.DataJunctionAPI.materialize.mockReturnValue({
|
|
19
|
+
status: 201,
|
|
20
|
+
});
|
|
21
|
+
mockDjClient.DataJunctionAPI.materializationInfo.mockReturnValue({
|
|
22
|
+
status: 200,
|
|
23
|
+
json: {
|
|
24
|
+
job_types: [
|
|
25
|
+
{
|
|
26
|
+
name: 'spark_sql',
|
|
27
|
+
label: 'Spark SQL',
|
|
28
|
+
description: 'Spark SQL materialization job',
|
|
29
|
+
allowed_node_types: ['transform', 'dimension', 'cube'],
|
|
30
|
+
job_class: 'SparkSqlMaterializationJob',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'druid_cube',
|
|
34
|
+
label: 'Druid Cube',
|
|
35
|
+
description:
|
|
36
|
+
'Used to materialize a cube to Druid for low-latency access to a set of metrics and dimensions. While the logical cube definition is at the level of metrics and dimensions, a materialized Druid cube will reference measures and dimensions, with rollup configured on the measures where appropriate.',
|
|
37
|
+
allowed_node_types: ['cube'],
|
|
38
|
+
job_class: 'DruidCubeMaterializationJob',
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
strategies: [
|
|
42
|
+
{
|
|
43
|
+
name: 'full',
|
|
44
|
+
label: 'Full',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'snapshot',
|
|
48
|
+
label: 'Snapshot',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'incremental_time',
|
|
52
|
+
label: 'Incremental Time',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'view',
|
|
56
|
+
label: 'View',
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Render the component
|
|
63
|
+
const { getByText } = render(
|
|
64
|
+
<DJClientContext.Provider value={mockDjClient}>
|
|
65
|
+
<AddMaterializationPopover
|
|
66
|
+
node={mocks.mockMetricNode}
|
|
67
|
+
onSubmit={onSubmitMock}
|
|
68
|
+
/>
|
|
69
|
+
</DJClientContext.Provider>,
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
// Open the popover
|
|
73
|
+
fireEvent.click(getByText('+ Add Materialization'));
|
|
74
|
+
|
|
75
|
+
// Save the materialization
|
|
76
|
+
fireEvent.click(getByText('Save'));
|
|
77
|
+
|
|
78
|
+
// Expect setAttributes to be called
|
|
79
|
+
await waitFor(() => {
|
|
80
|
+
expect(mockDjClient.DataJunctionAPI.materialize).toHaveBeenCalled();
|
|
81
|
+
expect(getByText('Saved!')).toBeInTheDocument();
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
});
|
|
@@ -107,16 +107,16 @@ exports[`<NodePage /> renders the NodeMaterialization tab with materializations
|
|
|
107
107
|
Schedule
|
|
108
108
|
</th>
|
|
109
109
|
<th>
|
|
110
|
-
|
|
110
|
+
Job Type
|
|
111
111
|
</th>
|
|
112
112
|
<th>
|
|
113
|
-
|
|
113
|
+
Strategy
|
|
114
114
|
</th>
|
|
115
115
|
<th>
|
|
116
|
-
|
|
116
|
+
Partitions
|
|
117
117
|
</th>
|
|
118
118
|
<th>
|
|
119
|
-
|
|
119
|
+
Intended Output Tables
|
|
120
120
|
</th>
|
|
121
121
|
<th>
|
|
122
122
|
URLs
|
|
@@ -141,9 +141,80 @@ exports[`<NodePage /> renders the NodeMaterialization tab with materializations
|
|
|
141
141
|
</div>
|
|
142
142
|
</td>
|
|
143
143
|
<td>
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
144
|
+
SPARKSQL
|
|
145
|
+
</td>
|
|
146
|
+
<td />
|
|
147
|
+
<td />
|
|
148
|
+
<td>
|
|
149
|
+
<div
|
|
150
|
+
class="table__full"
|
|
151
|
+
>
|
|
152
|
+
<div
|
|
153
|
+
class="table__header"
|
|
154
|
+
>
|
|
155
|
+
<svg
|
|
156
|
+
class="bi bi-table"
|
|
157
|
+
fill="currentColor"
|
|
158
|
+
height="16"
|
|
159
|
+
viewBox="0 0 16 16"
|
|
160
|
+
width="16"
|
|
161
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
162
|
+
>
|
|
163
|
+
<path
|
|
164
|
+
d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm15 2h-4v3h4V4zm0 4h-4v3h4V8zm0 4h-4v3h3a1 1 0 0 0 1-1v-2zm-5 3v-3H6v3h4zm-5 0v-3H1v2a1 1 0 0 0 1 1h3zm-4-4h4V8H1v3zm0-4h4V4H1v3zm5-3v3h4V4H6zm4 4H6v3h4V8z"
|
|
165
|
+
/>
|
|
166
|
+
</svg>
|
|
167
|
+
|
|
168
|
+
<span
|
|
169
|
+
class="entity-info"
|
|
170
|
+
>
|
|
171
|
+
common.a
|
|
172
|
+
</span>
|
|
173
|
+
</div>
|
|
174
|
+
<div
|
|
175
|
+
class="table__body upstream_tables"
|
|
176
|
+
/>
|
|
177
|
+
</div>
|
|
178
|
+
<div
|
|
179
|
+
class="table__full"
|
|
180
|
+
>
|
|
181
|
+
<div
|
|
182
|
+
class="table__header"
|
|
183
|
+
>
|
|
184
|
+
<svg
|
|
185
|
+
class="bi bi-table"
|
|
186
|
+
fill="currentColor"
|
|
187
|
+
height="16"
|
|
188
|
+
viewBox="0 0 16 16"
|
|
189
|
+
width="16"
|
|
190
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
191
|
+
>
|
|
192
|
+
<path
|
|
193
|
+
d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm15 2h-4v3h4V4zm0 4h-4v3h4V8zm0 4h-4v3h3a1 1 0 0 0 1-1v-2zm-5 3v-3H6v3h4zm-5 0v-3H1v2a1 1 0 0 0 1 1h3zm-4-4h4V8H1v3zm0-4h4V4H1v3zm5-3v3h4V4H6zm4 4H6v3h4V8z"
|
|
194
|
+
/>
|
|
195
|
+
</svg>
|
|
196
|
+
|
|
197
|
+
<span
|
|
198
|
+
class="entity-info"
|
|
199
|
+
>
|
|
200
|
+
common.b
|
|
201
|
+
</span>
|
|
202
|
+
</div>
|
|
203
|
+
<div
|
|
204
|
+
class="table__body upstream_tables"
|
|
205
|
+
/>
|
|
206
|
+
</div>
|
|
207
|
+
</td>
|
|
208
|
+
<td>
|
|
209
|
+
<a
|
|
210
|
+
href="http://fake.url/job"
|
|
211
|
+
>
|
|
212
|
+
[
|
|
213
|
+
1
|
|
214
|
+
]
|
|
215
|
+
</a>
|
|
216
|
+
</td>
|
|
217
|
+
<td>
|
|
147
218
|
<button
|
|
148
219
|
aria-label="code-button"
|
|
149
220
|
class="code-button"
|
|
@@ -230,173 +301,6 @@ exports[`<NodePage /> renders the NodeMaterialization tab with materializations
|
|
|
230
301
|
</pre>
|
|
231
302
|
</div>
|
|
232
303
|
</td>
|
|
233
|
-
<td />
|
|
234
|
-
<td>
|
|
235
|
-
<div
|
|
236
|
-
class="table__full"
|
|
237
|
-
>
|
|
238
|
-
<div
|
|
239
|
-
class="table__header"
|
|
240
|
-
>
|
|
241
|
-
<svg
|
|
242
|
-
class="bi bi-table"
|
|
243
|
-
fill="currentColor"
|
|
244
|
-
height="16"
|
|
245
|
-
viewBox="0 0 16 16"
|
|
246
|
-
width="16"
|
|
247
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
248
|
-
>
|
|
249
|
-
<path
|
|
250
|
-
d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm15 2h-4v3h4V4zm0 4h-4v3h4V8zm0 4h-4v3h3a1 1 0 0 0 1-1v-2zm-5 3v-3H6v3h4zm-5 0v-3H1v2a1 1 0 0 0 1 1h3zm-4-4h4V8H1v3zm0-4h4V4H1v3zm5-3v3h4V4H6zm4 4H6v3h4V8z"
|
|
251
|
-
/>
|
|
252
|
-
</svg>
|
|
253
|
-
|
|
254
|
-
<span
|
|
255
|
-
class="entity-info"
|
|
256
|
-
>
|
|
257
|
-
common.a
|
|
258
|
-
</span>
|
|
259
|
-
</div>
|
|
260
|
-
<div
|
|
261
|
-
class="table__body upstream_tables"
|
|
262
|
-
/>
|
|
263
|
-
</div>
|
|
264
|
-
<div
|
|
265
|
-
class="table__full"
|
|
266
|
-
>
|
|
267
|
-
<div
|
|
268
|
-
class="table__header"
|
|
269
|
-
>
|
|
270
|
-
<svg
|
|
271
|
-
class="bi bi-table"
|
|
272
|
-
fill="currentColor"
|
|
273
|
-
height="16"
|
|
274
|
-
viewBox="0 0 16 16"
|
|
275
|
-
width="16"
|
|
276
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
277
|
-
>
|
|
278
|
-
<path
|
|
279
|
-
d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm15 2h-4v3h4V4zm0 4h-4v3h4V8zm0 4h-4v3h3a1 1 0 0 0 1-1v-2zm-5 3v-3H6v3h4zm-5 0v-3H1v2a1 1 0 0 0 1 1h3zm-4-4h4V8H1v3zm0-4h4V4H1v3zm5-3v3h4V4H6zm4 4H6v3h4V8z"
|
|
280
|
-
/>
|
|
281
|
-
</svg>
|
|
282
|
-
|
|
283
|
-
<span
|
|
284
|
-
class="entity-info"
|
|
285
|
-
>
|
|
286
|
-
common.b
|
|
287
|
-
</span>
|
|
288
|
-
</div>
|
|
289
|
-
<div
|
|
290
|
-
class="table__body upstream_tables"
|
|
291
|
-
/>
|
|
292
|
-
</div>
|
|
293
|
-
</td>
|
|
294
|
-
<td>
|
|
295
|
-
<a
|
|
296
|
-
class="partitionLink"
|
|
297
|
-
>
|
|
298
|
-
<div
|
|
299
|
-
class="partition__full"
|
|
300
|
-
>
|
|
301
|
-
<div
|
|
302
|
-
class="partition__header"
|
|
303
|
-
/>
|
|
304
|
-
<div
|
|
305
|
-
class="partition__body"
|
|
306
|
-
>
|
|
307
|
-
<span
|
|
308
|
-
class="badge partition_value"
|
|
309
|
-
>
|
|
310
|
-
20230101
|
|
311
|
-
</span>
|
|
312
|
-
to
|
|
313
|
-
<span
|
|
314
|
-
class="badge partition_value"
|
|
315
|
-
>
|
|
316
|
-
20230102
|
|
317
|
-
</span>
|
|
318
|
-
</div>
|
|
319
|
-
</div>
|
|
320
|
-
</a>
|
|
321
|
-
<button
|
|
322
|
-
aria-label="AddBackfill"
|
|
323
|
-
class="edit_button"
|
|
324
|
-
tabindex="0"
|
|
325
|
-
>
|
|
326
|
-
<span
|
|
327
|
-
class="add_node"
|
|
328
|
-
>
|
|
329
|
-
+ Add Backfill
|
|
330
|
-
</span>
|
|
331
|
-
</button>
|
|
332
|
-
<div
|
|
333
|
-
class="fade modal-backdrop in"
|
|
334
|
-
style="display: none;"
|
|
335
|
-
/>
|
|
336
|
-
<div
|
|
337
|
-
aria-label="client-code"
|
|
338
|
-
class="centerPopover"
|
|
339
|
-
role="dialog"
|
|
340
|
-
style="display: none; width: 50%;"
|
|
341
|
-
>
|
|
342
|
-
<form
|
|
343
|
-
action="#"
|
|
344
|
-
>
|
|
345
|
-
<h2>
|
|
346
|
-
Run Backfill
|
|
347
|
-
</h2>
|
|
348
|
-
<span
|
|
349
|
-
data-testid="edit-partition"
|
|
350
|
-
>
|
|
351
|
-
<label
|
|
352
|
-
for="engine"
|
|
353
|
-
style="padding-bottom: 1rem;"
|
|
354
|
-
>
|
|
355
|
-
Engine
|
|
356
|
-
</label>
|
|
357
|
-
<select
|
|
358
|
-
disabled=""
|
|
359
|
-
id="engine"
|
|
360
|
-
name="engine"
|
|
361
|
-
>
|
|
362
|
-
<option
|
|
363
|
-
value="spark"
|
|
364
|
-
>
|
|
365
|
-
spark
|
|
366
|
-
|
|
367
|
-
2.4.4
|
|
368
|
-
</option>
|
|
369
|
-
</select>
|
|
370
|
-
</span>
|
|
371
|
-
<br />
|
|
372
|
-
<br />
|
|
373
|
-
<label
|
|
374
|
-
for="partition"
|
|
375
|
-
style="padding-bottom: 1rem;"
|
|
376
|
-
>
|
|
377
|
-
Partition Range
|
|
378
|
-
</label>
|
|
379
|
-
<br />
|
|
380
|
-
<button
|
|
381
|
-
aria-hidden="false"
|
|
382
|
-
aria-label="SaveEditColumn"
|
|
383
|
-
class="add_node"
|
|
384
|
-
type="submit"
|
|
385
|
-
>
|
|
386
|
-
Save
|
|
387
|
-
</button>
|
|
388
|
-
</form>
|
|
389
|
-
</div>
|
|
390
|
-
</td>
|
|
391
|
-
<td>
|
|
392
|
-
<a
|
|
393
|
-
href="http://fake.url/job"
|
|
394
|
-
>
|
|
395
|
-
[
|
|
396
|
-
1
|
|
397
|
-
]
|
|
398
|
-
</a>
|
|
399
|
-
</td>
|
|
400
304
|
</tr>
|
|
401
305
|
</tbody>
|
|
402
306
|
</table>
|