datajunction-ui 0.0.1-a46 → 0.0.1-a46.dev3
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/Makefile +0 -5
- package/package.json +2 -2
- package/src/app/pages/NodePage/AddBackfillPopover.jsx +51 -46
- package/src/app/pages/NodePage/AddMaterializationPopover.jsx +24 -33
- package/src/app/pages/NodePage/MaterializationConfigField.jsx +31 -38
- package/src/app/pages/NodePage/NodeMaterializationTab.jsx +110 -179
- package/src/app/pages/NodePage/__tests__/AddBackfillPopover.test.jsx +3 -13
- package/src/app/pages/NodePage/__tests__/NodePage.test.jsx +5 -12
- package/src/app/pages/NodePage/__tests__/__snapshots__/NodePage.test.jsx.snap +191 -276
- package/src/app/services/DJService.js +25 -26
- package/src/app/services/__tests__/DJService.test.jsx +21 -37
- package/src/mocks/mockNodes.jsx +7 -61
- package/src/styles/index.css +11 -113
- package/src/app/components/NodeMaterializationDelete.jsx +0 -80
- package/src/app/pages/NodePage/PartitionValueForm.jsx +0 -60
package/Makefile
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "datajunction-ui",
|
|
3
|
-
"version": "0.0.1a46",
|
|
3
|
+
"version": "0.0.1a46.dev3",
|
|
4
4
|
"description": "DataJunction Metrics Platform UI",
|
|
5
5
|
"module": "src/index.tsx",
|
|
6
6
|
"repository": {
|
|
@@ -166,7 +166,7 @@
|
|
|
166
166
|
"global": {
|
|
167
167
|
"statements": 89,
|
|
168
168
|
"branches": 75,
|
|
169
|
-
"lines":
|
|
169
|
+
"lines": 90,
|
|
170
170
|
"functions": 85
|
|
171
171
|
}
|
|
172
172
|
}
|
|
@@ -3,8 +3,6 @@ import * as React from 'react';
|
|
|
3
3
|
import DJClientContext from '../../providers/djclient';
|
|
4
4
|
import { Field, Form, Formik } from 'formik';
|
|
5
5
|
import { displayMessageAfterSubmit } from '../../../utils/form';
|
|
6
|
-
import PartitionValueForm from './PartitionValueForm';
|
|
7
|
-
import LoadingIcon from '../../icons/LoadingIcon';
|
|
8
6
|
|
|
9
7
|
export default function AddBackfillPopover({
|
|
10
8
|
node,
|
|
@@ -28,39 +26,30 @@ export default function AddBackfillPopover({
|
|
|
28
26
|
}, [setPopoverAnchor]);
|
|
29
27
|
|
|
30
28
|
const partitionColumns = node.columns.filter(col => col.partition !== null);
|
|
29
|
+
|
|
30
|
+
const temporalPartitionColumns = partitionColumns.filter(
|
|
31
|
+
col => col.partition.type_ === 'temporal',
|
|
32
|
+
);
|
|
33
|
+
|
|
31
34
|
const initialValues = {
|
|
32
35
|
node: node.name,
|
|
33
36
|
materializationName: materialization.name,
|
|
34
|
-
|
|
37
|
+
partitionColumn:
|
|
38
|
+
temporalPartitionColumns.length > 0
|
|
39
|
+
? temporalPartitionColumns[0].name
|
|
40
|
+
: '',
|
|
41
|
+
from: '',
|
|
42
|
+
to: '',
|
|
35
43
|
};
|
|
36
44
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
initialValues.partitionValues[partitionCol.name] = {
|
|
40
|
-
from: '',
|
|
41
|
-
to: '',
|
|
42
|
-
};
|
|
43
|
-
} else {
|
|
44
|
-
initialValues.partitionValues[partitionCol.name] = '';
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const runBackfill = async (values, setStatus) => {
|
|
45
|
+
const savePartition = async (values, { setSubmitting, setStatus }) => {
|
|
46
|
+
setSubmitting(false);
|
|
49
47
|
const response = await djClient.runBackfill(
|
|
50
48
|
values.node,
|
|
51
49
|
values.materializationName,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
columnName: entry[0],
|
|
56
|
-
range: [entry[1].from, entry[1].to],
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
return {
|
|
60
|
-
columnName: entry[0],
|
|
61
|
-
values: [entry[1]],
|
|
62
|
-
};
|
|
63
|
-
}),
|
|
50
|
+
values.partitionColumn,
|
|
51
|
+
values.from,
|
|
52
|
+
values.to,
|
|
64
53
|
);
|
|
65
54
|
if (response.status === 200 || response.status === 201) {
|
|
66
55
|
setStatus({ success: 'Saved!' });
|
|
@@ -69,26 +58,21 @@ export default function AddBackfillPopover({
|
|
|
69
58
|
failure: `${response.json.message}`,
|
|
70
59
|
});
|
|
71
60
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const submitBackfill = async (values, { setSubmitting, setStatus }) => {
|
|
75
|
-
await runBackfill(values, setStatus).then(_ => {
|
|
76
|
-
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' });
|
|
77
|
-
setSubmitting(false);
|
|
78
|
-
});
|
|
61
|
+
onSubmit();
|
|
62
|
+
window.location.reload();
|
|
79
63
|
};
|
|
80
64
|
|
|
81
65
|
return (
|
|
82
66
|
<>
|
|
83
67
|
<button
|
|
84
|
-
className="edit_button
|
|
68
|
+
className="edit_button"
|
|
85
69
|
aria-label="AddBackfill"
|
|
86
70
|
tabIndex="0"
|
|
87
71
|
onClick={() => {
|
|
88
72
|
setPopoverAnchor(!popoverAnchor);
|
|
89
73
|
}}
|
|
90
74
|
>
|
|
91
|
-
<span className="
|
|
75
|
+
<span className="add_node">+ Add Backfill</span>
|
|
92
76
|
</button>
|
|
93
77
|
<div
|
|
94
78
|
className="fade modal-backdrop in"
|
|
@@ -101,12 +85,10 @@ export default function AddBackfillPopover({
|
|
|
101
85
|
style={{
|
|
102
86
|
display: popoverAnchor === false ? 'none' : 'block',
|
|
103
87
|
width: '50%',
|
|
104
|
-
minWidth: '800px',
|
|
105
|
-
left: '-25%',
|
|
106
88
|
}}
|
|
107
89
|
ref={ref}
|
|
108
90
|
>
|
|
109
|
-
<Formik initialValues={initialValues} onSubmit={
|
|
91
|
+
<Formik initialValues={initialValues} onSubmit={savePartition}>
|
|
110
92
|
{function Render({ isSubmitting, status, setFieldValue }) {
|
|
111
93
|
return (
|
|
112
94
|
<Form>
|
|
@@ -133,17 +115,41 @@ export default function AddBackfillPopover({
|
|
|
133
115
|
<br />
|
|
134
116
|
<br />
|
|
135
117
|
<label htmlFor="partition" style={{ paddingBottom: '1rem' }}>
|
|
136
|
-
Partition
|
|
118
|
+
Partition Range
|
|
137
119
|
</label>
|
|
138
120
|
{node.columns
|
|
139
121
|
.filter(col => col.partition !== null)
|
|
140
122
|
.map(col => {
|
|
141
123
|
return (
|
|
142
|
-
<
|
|
143
|
-
|
|
144
|
-
materialization={materialization}
|
|
124
|
+
<div
|
|
125
|
+
className="partition__full"
|
|
145
126
|
key={col.name}
|
|
146
|
-
|
|
127
|
+
style={{ width: '50%' }}
|
|
128
|
+
>
|
|
129
|
+
<div className="partition__header">
|
|
130
|
+
{col.display_name}
|
|
131
|
+
</div>
|
|
132
|
+
<div className="partition__body">
|
|
133
|
+
<span style={{ padding: '0.5rem' }}>From</span>{' '}
|
|
134
|
+
<Field
|
|
135
|
+
type="text"
|
|
136
|
+
name="from"
|
|
137
|
+
id={`${col.name}__from`}
|
|
138
|
+
placeholder="20230101"
|
|
139
|
+
default="20230101"
|
|
140
|
+
style={{ width: '7rem', paddingRight: '1rem' }}
|
|
141
|
+
/>{' '}
|
|
142
|
+
<span style={{ padding: '0.5rem' }}>To</span>
|
|
143
|
+
<Field
|
|
144
|
+
type="text"
|
|
145
|
+
name="to"
|
|
146
|
+
id={`${col.name}__to`}
|
|
147
|
+
placeholder="20230102"
|
|
148
|
+
default="20230102"
|
|
149
|
+
style={{ width: '7rem' }}
|
|
150
|
+
/>
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
147
153
|
);
|
|
148
154
|
})}
|
|
149
155
|
<br />
|
|
@@ -152,9 +158,8 @@ export default function AddBackfillPopover({
|
|
|
152
158
|
type="submit"
|
|
153
159
|
aria-label="SaveEditColumn"
|
|
154
160
|
aria-hidden="false"
|
|
155
|
-
disabled={isSubmitting}
|
|
156
161
|
>
|
|
157
|
-
|
|
162
|
+
Save
|
|
158
163
|
</button>
|
|
159
164
|
</Form>
|
|
160
165
|
);
|
|
@@ -39,9 +39,6 @@ export default function AddMaterializationPopover({ node, onSubmit }) {
|
|
|
39
39
|
const config = {};
|
|
40
40
|
config.spark = values.spark_config;
|
|
41
41
|
config.lookback_window = values.lookback_window;
|
|
42
|
-
if (!values.job_type) {
|
|
43
|
-
values.job_type = 'spark_sql';
|
|
44
|
-
}
|
|
45
42
|
const { status, json } = await djClient.materialize(
|
|
46
43
|
values.node,
|
|
47
44
|
values.job_type,
|
|
@@ -51,7 +48,6 @@ export default function AddMaterializationPopover({ node, onSubmit }) {
|
|
|
51
48
|
);
|
|
52
49
|
if (status === 200 || status === 201) {
|
|
53
50
|
setStatus({ success: json.message });
|
|
54
|
-
window.location.reload();
|
|
55
51
|
} else {
|
|
56
52
|
setStatus({
|
|
57
53
|
failure: `${json.message}`,
|
|
@@ -115,41 +111,36 @@ export default function AddMaterializationPopover({ node, onSubmit }) {
|
|
|
115
111
|
<Form>
|
|
116
112
|
<h2>Configure Materialization</h2>
|
|
117
113
|
{displayMessageAfterSubmit(status)}
|
|
118
|
-
|
|
119
|
-
<
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
</Field>
|
|
141
|
-
<br />
|
|
142
|
-
<br />
|
|
143
|
-
</span>
|
|
144
|
-
) : (
|
|
145
|
-
''
|
|
146
|
-
)}
|
|
114
|
+
<span data-testid="job-type">
|
|
115
|
+
<label htmlFor="job_type">Job Type</label>
|
|
116
|
+
<Field as="select" name="job_type">
|
|
117
|
+
<>
|
|
118
|
+
<option
|
|
119
|
+
key={'druid_measures_cube'}
|
|
120
|
+
value={'druid_measures_cube'}
|
|
121
|
+
>
|
|
122
|
+
Druid Measures Cube (Pre-Agg Cube)
|
|
123
|
+
</option>
|
|
124
|
+
<option
|
|
125
|
+
key={'druid_metrics_cube'}
|
|
126
|
+
value={'druid_metrics_cube'}
|
|
127
|
+
>
|
|
128
|
+
Druid Metrics Cube (Post-Agg Cube)
|
|
129
|
+
</option>
|
|
130
|
+
<option key={'spark_sql'} value={'spark_sql'}>
|
|
131
|
+
Iceberg Table
|
|
132
|
+
</option>
|
|
133
|
+
</>
|
|
134
|
+
</Field>
|
|
135
|
+
</span>
|
|
147
136
|
<input
|
|
148
137
|
hidden={true}
|
|
149
138
|
name="node"
|
|
150
139
|
value={node?.name}
|
|
151
140
|
readOnly={true}
|
|
152
141
|
/>
|
|
142
|
+
<br />
|
|
143
|
+
<br />
|
|
153
144
|
<span data-testid="edit-partition">
|
|
154
145
|
<label htmlFor="strategy">Strategy</label>
|
|
155
146
|
<Field as="select" name="strategy">
|
|
@@ -16,45 +16,38 @@ export const ConfigField = ({ djClient, value }) => {
|
|
|
16
16
|
|
|
17
17
|
return (
|
|
18
18
|
<div className="DescriptionInput">
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
19
|
+
<ErrorMessage name="spark_config" component="span" />
|
|
20
|
+
<label htmlFor="SparkConfig">Spark Config</label>
|
|
21
|
+
<Field
|
|
22
|
+
type="textarea"
|
|
23
|
+
style={{ display: 'none' }}
|
|
24
|
+
as="textarea"
|
|
25
|
+
name="spark_config"
|
|
26
|
+
id="SparkConfig"
|
|
27
|
+
/>
|
|
28
|
+
<div role="button" tabIndex={0} className="relative flex bg-[#282a36]">
|
|
29
|
+
<CodeMirror
|
|
30
|
+
id={'spark_config'}
|
|
31
|
+
name={'spark_config'}
|
|
32
|
+
extensions={[jsonExt]}
|
|
33
|
+
value={JSON.stringify(value, null, ' ')}
|
|
34
|
+
options={{
|
|
35
|
+
theme: 'default',
|
|
36
|
+
lineNumbers: true,
|
|
37
|
+
}}
|
|
38
|
+
width="100%"
|
|
39
|
+
height="170px"
|
|
40
|
+
style={{
|
|
41
|
+
margin: '0 0 23px 0',
|
|
42
|
+
flex: 1,
|
|
43
|
+
fontSize: '150%',
|
|
44
|
+
textAlign: 'left',
|
|
45
|
+
}}
|
|
46
|
+
onChange={(value, viewUpdate) => {
|
|
47
|
+
updateFormik(value);
|
|
48
|
+
}}
|
|
32
49
|
/>
|
|
33
|
-
|
|
34
|
-
<CodeMirror
|
|
35
|
-
id={'spark_config'}
|
|
36
|
-
name={'spark_config'}
|
|
37
|
-
extensions={[jsonExt]}
|
|
38
|
-
value={JSON.stringify(value, null, ' ')}
|
|
39
|
-
options={{
|
|
40
|
-
theme: 'default',
|
|
41
|
-
lineNumbers: true,
|
|
42
|
-
}}
|
|
43
|
-
width="100%"
|
|
44
|
-
height="170px"
|
|
45
|
-
style={{
|
|
46
|
-
margin: '0 0 23px 0',
|
|
47
|
-
flex: 1,
|
|
48
|
-
fontSize: '150%',
|
|
49
|
-
textAlign: 'left',
|
|
50
|
-
}}
|
|
51
|
-
onChange={(value, viewUpdate) => {
|
|
52
|
-
updateFormik(value);
|
|
53
|
-
}}
|
|
54
|
-
/>
|
|
55
|
-
</div>
|
|
56
|
-
</details>{' '}
|
|
57
|
-
<></>
|
|
50
|
+
</div>
|
|
58
51
|
</div>
|
|
59
52
|
);
|
|
60
53
|
};
|