datajunction-ui 0.0.1-a44.dev2 → 0.0.1-a44.dev5

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datajunction-ui",
3
- "version": "0.0.1-a44.dev2",
3
+ "version": "0.0.1-a44.dev5",
4
4
  "description": "DataJunction Metrics Platform UI",
5
5
  "module": "src/index.tsx",
6
6
  "repository": {
@@ -101,9 +101,7 @@ describe('AddEditNodePage submission failed', () => {
101
101
  status: 404,
102
102
  });
103
103
 
104
- expect(
105
- await screen.getByText('Update failed, Some tags were not found'),
106
- ).toBeInTheDocument();
104
+ expect(await screen.getByText('Update failed')).toBeInTheDocument();
107
105
  });
108
106
  }, 60000);
109
107
  });
@@ -24,6 +24,7 @@ import { DisplayNameField } from './DisplayNameField';
24
24
  import { DescriptionField } from './DescriptionField';
25
25
  import { NodeModeField } from './NodeModeField';
26
26
  import { RequiredDimensionsSelect } from './RequiredDimensionsSelect';
27
+ import LoadingIcon from '../../icons/LoadingIcon';
27
28
 
28
29
  class Action {
29
30
  static Add = new Action('add');
@@ -63,19 +64,18 @@ export function AddEditNodePage() {
63
64
  return errors;
64
65
  };
65
66
 
66
- const handleSubmit = (values, { setSubmitting, setStatus }) => {
67
+ const handleSubmit = async (values, { setSubmitting, setStatus }) => {
67
68
  if (action === Action.Add) {
68
- setTimeout(() => {
69
- createNode(values, setStatus);
69
+ await createNode(values, setStatus).then(_ => {
70
+ window.scrollTo({ top: 0, left: 0, behavior: 'smooth' });
70
71
  setSubmitting(false);
71
- }, 400);
72
+ });
72
73
  } else {
73
- setTimeout(() => {
74
- patchNode(values, setStatus);
74
+ await patchNode(values, setStatus).then(_ => {
75
+ window.scrollTo({ top: 0, left: 0, behavior: 'smooth' });
75
76
  setSubmitting(false);
76
- }, 400);
77
+ });
77
78
  }
78
- window.scrollTo({ top: 0, left: 0, behavior: 'smooth' });
79
79
  };
80
80
 
81
81
  const pageTitle =
@@ -169,7 +169,7 @@ export function AddEditNodePage() {
169
169
  });
170
170
  } else {
171
171
  setStatus({
172
- failure: `${json.message}, ${tagsResponse.json.message}`,
172
+ failure: `${json.message}`,
173
173
  });
174
174
  }
175
175
  };
@@ -410,7 +410,12 @@ export function AddEditNodePage() {
410
410
  <NodeModeField />
411
411
 
412
412
  <button type="submit" disabled={isSubmitting}>
413
- {action === Action.Add ? 'Create' : 'Save'} {nodeType}
413
+ {isSubmitting ? (
414
+ <LoadingIcon />
415
+ ) : (
416
+ (action === Action.Add ? 'Create ' : 'Save ') +
417
+ (nodeType ? nodeType : '')
418
+ )}
414
419
  </button>
415
420
  </>
416
421
  )}
@@ -3,7 +3,8 @@ import * as React from 'react';
3
3
  import DJClientContext from '../../providers/djclient';
4
4
  import { ErrorMessage, Field, Form, Formik } from 'formik';
5
5
  import { displayMessageAfterSubmit, labelize } from '../../../utils/form';
6
- import {ConfigField} from "./MaterializationConfigField";
6
+ import { ConfigField } from './MaterializationConfigField';
7
+ import LoadingIcon from '../../icons/LoadingIcon';
7
8
 
8
9
  export default function AddMaterializationPopover({ node, onSubmit }) {
9
10
  const djClient = useContext(DJClientContext).DataJunctionAPI;
@@ -34,29 +35,34 @@ export default function AddMaterializationPopover({ node, onSubmit }) {
34
35
  };
35
36
  }, [djClient, setPopoverAnchor]);
36
37
 
37
- const configureMaterialization = async (
38
- values,
39
- { setSubmitting, setStatus },
40
- ) => {
41
- setSubmitting(false);
38
+ const materialize = async (values, setStatus) => {
42
39
  const config = {};
43
40
  config.spark = values.spark_config;
44
41
  config.lookback_window = values.lookback_window;
45
- const response = await djClient.materialize(
42
+ const { status, json } = await djClient.materialize(
46
43
  values.node,
47
44
  values.job_type,
48
45
  values.strategy,
49
46
  values.schedule,
50
47
  config,
51
48
  );
52
- if (response.status === 200 || response.status === 201) {
53
- setStatus({ success: response.json.message });
49
+ if (status === 200 || status === 201) {
50
+ setStatus({ success: json.message });
54
51
  } else {
55
52
  setStatus({
56
- failure: `${response.json.message}`,
53
+ failure: `${json.message}`,
57
54
  });
58
55
  }
59
- // window.location.reload();
56
+ };
57
+
58
+ const configureMaterialization = async (
59
+ values,
60
+ { setSubmitting, setStatus },
61
+ ) => {
62
+ await materialize(values, setStatus).then(_ => {
63
+ window.scrollTo({ top: 0, left: 0, behavior: 'smooth' });
64
+ setSubmitting(false);
65
+ });
60
66
  };
61
67
 
62
68
  return (
@@ -88,13 +94,14 @@ export default function AddMaterializationPopover({ node, onSubmit }) {
88
94
  <Formik
89
95
  initialValues={{
90
96
  node: node?.name,
91
- job_type: node?.type === 'cube' ? 'druid_cube' : 'spark_sql',
97
+ job_type:
98
+ node?.type === 'cube' ? 'druid_metrics_cube' : 'spark_sql',
92
99
  strategy: 'full',
93
100
  schedule: '@daily',
94
101
  lookback_window: '1 DAY',
95
102
  spark_config: {
96
- "spark.executor.memory": "16g",
97
- "spark.memory.fraction": "0.3"
103
+ 'spark.executor.memory': '16g',
104
+ 'spark.memory.fraction': '0.3',
98
105
  },
99
106
  }}
100
107
  onSubmit={configureMaterialization}
@@ -108,9 +115,21 @@ export default function AddMaterializationPopover({ node, onSubmit }) {
108
115
  <label htmlFor="job_type">Job Type</label>
109
116
  <Field as="select" name="job_type">
110
117
  <>
111
- <option key={'druid_measures_cube'} value={'druid_measures_cube'}>Druid Measures Cube (Pre-Agg Cube)</option>
112
- <option key={'druid_metrics_cube'} value={'druid_metrics_cube'}>Druid Metrics Cube (Post-Agg Cube)</option>
113
- <option key={'spark_sql'} value={'spark_sql'}>Iceberg Table</option>
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>
114
133
  </>
115
134
  </Field>
116
135
  </span>
@@ -129,7 +148,10 @@ export default function AddMaterializationPopover({ node, onSubmit }) {
129
148
  <option key={'full'} value={'full'}>
130
149
  Full
131
150
  </option>
132
- <option key={'incremental_time'} value={'incremental_time'}>
151
+ <option
152
+ key={'incremental_time'}
153
+ value={'incremental_time'}
154
+ >
133
155
  Incremental Time
134
156
  </option>
135
157
  </>
@@ -159,17 +181,20 @@ export default function AddMaterializationPopover({ node, onSubmit }) {
159
181
  />
160
182
  </div>
161
183
  <br />
162
- <ConfigField value={{
163
- "spark.executor.memory": "16g",
164
- "spark.memory.fraction": "0.3"
165
- }}/>
184
+ <ConfigField
185
+ value={{
186
+ 'spark.executor.memory': '16g',
187
+ 'spark.memory.fraction': '0.3',
188
+ }}
189
+ />
166
190
  <button
167
191
  className="add_node"
168
192
  type="submit"
169
193
  aria-label="SaveEditColumn"
170
194
  aria-hidden="false"
195
+ disabled={isSubmitting}
171
196
  >
172
- Save
197
+ {isSubmitting ? <LoadingIcon /> : 'Save'}
173
198
  </button>
174
199
  </Form>
175
200
  );
@@ -11,7 +11,7 @@ export const ConfigField = ({ djClient, value }) => {
11
11
  const jsonExt = langs.json();
12
12
 
13
13
  const updateFormik = val => {
14
- formik.setFieldValue('spark_config', val);
14
+ formik.setFieldValue('spark_config', JSON.parse(val));
15
15
  };
16
16
 
17
17
  return (
@@ -30,7 +30,7 @@ export const ConfigField = ({ djClient, value }) => {
30
30
  id={'spark_config'}
31
31
  name={'spark_config'}
32
32
  extensions={[jsonExt]}
33
- value={JSON.stringify(value, null, " ")}
33
+ value={JSON.stringify(value, null, ' ')}
34
34
  options={{
35
35
  theme: 'default',
36
36
  lineNumbers: true,
@@ -15,8 +15,11 @@ const NodeLineage = djNode => {
15
15
  col.attributes.some(attr => attr.attribute_type.name === 'primary_key'),
16
16
  )
17
17
  .map(col => col.name);
18
- const dimensionLinkForeignKeys = node.dimension_links ? node.dimension_links
19
- .flatMap(link => Object.keys(link.foreign_keys).map(key => key.split('.').slice(-1))) : [];
18
+ const dimensionLinkForeignKeys = node.dimension_links
19
+ ? node.dimension_links.flatMap(link =>
20
+ Object.keys(link.foreign_keys).map(key => key.split('.').slice(-1)),
21
+ )
22
+ : [];
20
23
  const column_names = node.columns
21
24
  .map(col => {
22
25
  return {
@@ -51,11 +54,19 @@ const NodeLineage = djNode => {
51
54
  };
52
55
 
53
56
  const dimensionEdges = node => {
54
- return node.dimension_links === undefined ? [] : node.dimension_links
55
- .flatMap(link => {
56
- return Object.keys(link.foreign_keys).map(fk => {
57
+ return node.dimension_links === undefined
58
+ ? []
59
+ : node.dimension_links.flatMap(link => {
60
+ return Object.keys(link.foreign_keys).map(fk => {
57
61
  return {
58
- id: link.dimension.name + '->' + node.name + '=' + link.foreign_keys[fk] + '->' + fk,
62
+ id:
63
+ link.dimension.name +
64
+ '->' +
65
+ node.name +
66
+ '=' +
67
+ link.foreign_keys[fk] +
68
+ '->' +
69
+ fk,
59
70
  source: link.dimension.name,
60
71
  sourceHandle: link.foreign_keys[fk],
61
72
  target: node.name,
@@ -72,9 +83,8 @@ const NodeLineage = djNode => {
72
83
  stroke: '#b0b9c2',
73
84
  },
74
85
  };
75
- }
76
- )
77
- });
86
+ });
87
+ });
78
88
  };
79
89
 
80
90
  const parentEdges = node => {
@@ -134,8 +134,7 @@ export default function NodeMaterializationTab({ node, djClient }) {
134
134
  <div className="table-vertical">
135
135
  <div>
136
136
  <h2>Materializations</h2>
137
- {node ?
138
- <AddMaterializationPopover node={node} /> : <></>}
137
+ {node ? <AddMaterializationPopover node={node} /> : <></>}
139
138
  {materializations.length > 0 ? (
140
139
  <table
141
140
  className="card-inner-table table"