datajunction-ui 0.0.1-a45.dev14 → 0.0.1-a46.dev1

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-a45.dev14",
3
+ "version": "0.0.1a46.dev1",
4
4
  "description": "DataJunction Metrics Platform UI",
5
5
  "module": "src/index.tsx",
6
6
  "repository": {
@@ -94,7 +94,7 @@ export function NamespacePage() {
94
94
  </span>
95
95
  </td>
96
96
  <td>
97
- <NodeStatus node={node} />
97
+ <NodeStatus node={node} revalidate={false} />
98
98
  </td>
99
99
  <td>
100
100
  <span className="status">{node.mode}</span>
@@ -1,28 +1,101 @@
1
- import { Component } from 'react';
1
+ import { Component, useContext, useEffect, useRef, useState } from 'react';
2
2
  import ValidIcon from '../../icons/ValidIcon';
3
3
  import InvalidIcon from '../../icons/InvalidIcon';
4
+ import DJClientContext from '../../providers/djclient';
5
+ import { foundation } from 'react-syntax-highlighter/src/styles/hljs';
6
+ import { Light as SyntaxHighlighter } from 'react-syntax-highlighter';
7
+ import markdown from 'react-syntax-highlighter/dist/cjs/languages/hljs/markdown';
8
+ import * as React from 'react';
9
+ import { AlertMessage } from '../AddEditNodePage/AlertMessage';
10
+ import AlertIcon from '../../icons/AlertIcon';
11
+ import { labelize } from '../../../utils/form';
4
12
 
5
- export default class NodeStatus extends Component {
6
- render() {
7
- const { node } = this.props;
8
- return (
13
+ SyntaxHighlighter.registerLanguage('markdown', markdown);
14
+
15
+ export default function NodeStatus({ node, revalidate = true }) {
16
+ const MAX_ERROR_LENGTH = 200;
17
+ const djClient = useContext(DJClientContext).DataJunctionAPI;
18
+ const [validation, setValidation] = useState([]);
19
+
20
+ const [codeAnchor, setCodeAnchor] = useState(false);
21
+ const ref = useRef(null);
22
+
23
+ useEffect(() => {
24
+ if (revalidate) {
25
+ const fetchData = async () => {
26
+ setValidation(await djClient.revalidate(node.name));
27
+ };
28
+ fetchData().catch(console.error);
29
+ }
30
+ }, [djClient, node, revalidate]);
31
+
32
+ const displayValidation =
33
+ revalidate && validation?.errors?.length > 0 ? (
9
34
  <>
10
- {node?.status === 'valid' ? (
11
- <span
12
- className="status__valid status"
13
- style={{ alignContent: 'center' }}
14
- >
15
- <ValidIcon />
16
- </span>
17
- ) : (
18
- <span
19
- className="status__invalid status"
20
- style={{ alignContent: 'center' }}
21
- >
22
- <InvalidIcon />
23
- </span>
24
- )}
35
+ <button
36
+ className="badge"
37
+ style={{
38
+ backgroundColor: '#b34b00',
39
+ fontSize: '15px',
40
+ outline: '0',
41
+ border: '0',
42
+ cursor: 'pointer',
43
+ }}
44
+ onClick={() => setCodeAnchor(!codeAnchor)}
45
+ >
46
+ ⚠ {validation?.errors?.length} error
47
+ {validation?.errors?.length > 1 ? 's' : ''}
48
+ </button>
49
+ <div
50
+ className="popover"
51
+ ref={ref}
52
+ style={{
53
+ display: codeAnchor === false ? 'none' : 'block',
54
+ border: 'none',
55
+ paddingTop: '0px !important',
56
+ marginTop: '0px',
57
+ backgroundColor: 'transparent',
58
+ }}
59
+ >
60
+ {validation?.errors?.map((error, idx) => (
61
+ <div className="validation_error">
62
+ <b
63
+ style={{
64
+ color: '#b34b00',
65
+ }}
66
+ >
67
+ {labelize(error.type.toLowerCase())}:
68
+ </b>{' '}
69
+ {error.message.length > MAX_ERROR_LENGTH
70
+ ? error.message.slice(0, MAX_ERROR_LENGTH - 1) + '...'
71
+ : error.message}
72
+ </div>
73
+ ))}
74
+ </div>
25
75
  </>
76
+ ) : (
77
+ <></>
26
78
  );
27
- }
79
+
80
+ return (
81
+ <>
82
+ {revalidate && validation?.errors?.length > 0 ? (
83
+ displayValidation
84
+ ) : validation?.status === 'valid' || node?.status === 'valid' ? (
85
+ <span
86
+ className="status__valid status"
87
+ style={{ alignContent: 'center' }}
88
+ >
89
+ <ValidIcon />
90
+ </span>
91
+ ) : (
92
+ <span
93
+ className="status__invalid status"
94
+ style={{ alignContent: 'center' }}
95
+ >
96
+ <InvalidIcon />
97
+ </span>
98
+ )}
99
+ </>
100
+ );
28
101
  }
@@ -0,0 +1,63 @@
1
+ import { useContext, useEffect, useRef, useState } from 'react';
2
+ import * as React from 'react';
3
+ import DJClientContext from '../../providers/djclient';
4
+ import { Field, Form, Formik } from 'formik';
5
+ import { displayMessageAfterSubmit } from '../../../utils/form';
6
+
7
+ export default function PartitionValueForm({ col, materialization }) {
8
+ if (col.partition.type_ === 'temporal') {
9
+ return (
10
+ <>
11
+ <div
12
+ className="partition__full"
13
+ key={col.name}
14
+ style={{ width: '50%' }}
15
+ >
16
+ <div className="partition__header">{col.display_name}</div>
17
+ <div className="partition__body">
18
+ <span style={{ padding: '0.5rem' }}>From</span>{' '}
19
+ <Field
20
+ type="text"
21
+ name={`partitionValues.['${col.name}'].from`}
22
+ id={`${col.name}.from`}
23
+ placeholder="20230101"
24
+ default="20230101"
25
+ style={{ width: '7rem', paddingRight: '1rem' }}
26
+ />{' '}
27
+ <span style={{ padding: '0.5rem' }}>To</span>
28
+ <Field
29
+ type="text"
30
+ name={`partitionValues.['${col.name}'].to`}
31
+ id={`${col.name}.to`}
32
+ placeholder="20230102"
33
+ default="20230102"
34
+ style={{ width: '7rem' }}
35
+ />
36
+ </div>
37
+ </div>
38
+ </>
39
+ );
40
+ } else {
41
+ return (
42
+ <>
43
+ <div
44
+ className="partition__full"
45
+ key={col.name}
46
+ style={{ width: '50%' }}
47
+ >
48
+ <div className="partition__header">{col.display_name}</div>
49
+ <div className="partition__body">
50
+ <Field
51
+ type="text"
52
+ name={`partitionValues.['${col.name}']`}
53
+ id={col.name}
54
+ placeholder=""
55
+ default=""
56
+ style={{ width: '7rem', paddingRight: '1rem' }}
57
+ />
58
+ </div>
59
+ </div>
60
+ </>
61
+ );
62
+ }
63
+ }
@@ -844,4 +844,15 @@ export const DataJunctionAPI = {
844
844
  })
845
845
  ).json();
846
846
  },
847
+ revalidate: async function (node) {
848
+ return await (
849
+ await fetch(`${DJ_URL}/nodes/${node}/validate`, {
850
+ method: 'POST',
851
+ headers: {
852
+ 'Content-Type': 'application/json',
853
+ },
854
+ credentials: 'include',
855
+ })
856
+ ).json();
857
+ },
847
858
  };
@@ -1202,3 +1202,18 @@ pre {
1202
1202
  text-transform: uppercase;
1203
1203
  padding-left: 10px;
1204
1204
  }
1205
+
1206
+ .validation_error {
1207
+ border: #b34b0025 1px solid;
1208
+ border-left: #b34b00 5px solid;
1209
+ padding-left: 20px;
1210
+ padding-top: 5px;
1211
+ padding-bottom: 5px;
1212
+ font-size: small;
1213
+ width: 600px;
1214
+ word-wrap: break-word;
1215
+ margin-top: 3px;
1216
+ background-color: #ffffff;
1217
+ margin-bottom: 3px;
1218
+ margin-left: -20px;
1219
+ }