datajunction-ui 0.0.1-a42.dev0 → 0.0.1-a43.dev0
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/index.tsx +1 -0
- package/src/app/pages/AddEditNodePage/AlertMessage.jsx +10 -0
- package/src/app/pages/AddEditNodePage/DescriptionField.jsx +17 -0
- package/src/app/pages/AddEditNodePage/DisplayNameField.jsx +16 -0
- package/src/app/pages/AddEditNodePage/FormikSelect.jsx +2 -0
- package/src/app/pages/AddEditNodePage/FullNameField.jsx +3 -2
- package/src/app/pages/AddEditNodePage/MetricMetadataFields.jsx +60 -0
- package/src/app/pages/AddEditNodePage/MetricQueryField.jsx +71 -0
- package/src/app/pages/AddEditNodePage/NamespaceField.jsx +40 -0
- package/src/app/pages/AddEditNodePage/NodeModeField.jsx +14 -0
- package/src/app/pages/AddEditNodePage/NodeQueryField.jsx +5 -3
- package/src/app/pages/AddEditNodePage/PrimaryKeySelect.jsx +61 -0
- package/src/app/pages/AddEditNodePage/RequiredDimensionsSelect.jsx +54 -0
- package/src/app/pages/AddEditNodePage/TagsField.jsx +47 -0
- package/src/app/pages/AddEditNodePage/UpstreamNodeField.jsx +49 -0
- package/src/app/pages/AddEditNodePage/__tests__/AddEditNodePageFormFailed.test.jsx +2 -1
- package/src/app/pages/AddEditNodePage/__tests__/AddEditNodePageFormSuccess.test.jsx +150 -14
- package/src/app/pages/AddEditNodePage/__tests__/index.test.jsx +35 -8
- package/src/app/pages/AddEditNodePage/index.jsx +177 -232
- package/src/app/pages/CubeBuilderPage/MetricsSelect.jsx +0 -1
- package/src/app/pages/CubeBuilderPage/__tests__/index.test.jsx +1 -1
- package/src/app/pages/CubeBuilderPage/index.jsx +1 -1
- package/src/app/pages/NodePage/AddMaterializationPopover.jsx +0 -1
- package/src/app/pages/NodePage/NodeHistory.jsx +1 -1
- package/src/app/pages/NodePage/NodeInfoTab.jsx +54 -13
- package/src/app/pages/NodePage/__tests__/NodePage.test.jsx +34 -28
- package/src/app/pages/NodePage/__tests__/__snapshots__/NodePage.test.jsx.snap +2 -18
- package/src/app/pages/NodePage/index.jsx +30 -27
- package/src/app/pages/Root/index.tsx +3 -2
- package/src/app/services/DJService.js +37 -0
- package/src/app/services/__tests__/DJService.test.jsx +23 -0
- package/src/mocks/mockNodes.jsx +63 -0
- package/src/styles/index.css +6 -0
- package/src/styles/node-creation.scss +63 -5
- package/dj.internal.db +0 -0
|
@@ -271,7 +271,7 @@ describe('<NodePage />', () => {
|
|
|
271
271
|
},
|
|
272
272
|
};
|
|
273
273
|
|
|
274
|
-
it('renders the NodeInfo tab correctly', async () => {
|
|
274
|
+
it('renders the NodeInfo tab correctly for a metric node', async () => {
|
|
275
275
|
const djClient = mockDJClient();
|
|
276
276
|
djClient.DataJunctionAPI.node.mockReturnValue(mocks.mockMetricNode);
|
|
277
277
|
djClient.DataJunctionAPI.metric.mockReturnValue(mocks.mockMetricNode);
|
|
@@ -281,9 +281,9 @@ describe('<NodePage />', () => {
|
|
|
281
281
|
</DJClientContext.Provider>
|
|
282
282
|
);
|
|
283
283
|
const { container } = render(
|
|
284
|
-
<MemoryRouter initialEntries={['/nodes/default.num_repair_orders']}>
|
|
284
|
+
<MemoryRouter initialEntries={['/nodes/default.num_repair_orders/info']}>
|
|
285
285
|
<Routes>
|
|
286
|
-
<Route path="nodes/:name" element={element} />
|
|
286
|
+
<Route path="nodes/:name/:tab" element={element} />
|
|
287
287
|
</Routes>
|
|
288
288
|
</MemoryRouter>,
|
|
289
289
|
);
|
|
@@ -292,7 +292,6 @@ describe('<NodePage />', () => {
|
|
|
292
292
|
expect(djClient.DataJunctionAPI.node).toHaveBeenCalledWith(
|
|
293
293
|
'default.num_repair_orders',
|
|
294
294
|
);
|
|
295
|
-
userEvent.click(screen.getByRole('button', { name: 'Info' }));
|
|
296
295
|
|
|
297
296
|
expect(
|
|
298
297
|
screen.getByRole('dialog', { name: 'NodeName' }),
|
|
@@ -316,8 +315,8 @@ describe('<NodePage />', () => {
|
|
|
316
315
|
);
|
|
317
316
|
|
|
318
317
|
expect(
|
|
319
|
-
screen.getByRole('dialog', { name: '
|
|
320
|
-
).toHaveTextContent('
|
|
318
|
+
screen.getByRole('dialog', { name: 'RequiredDimensions' }),
|
|
319
|
+
).toHaveTextContent('');
|
|
321
320
|
|
|
322
321
|
expect(
|
|
323
322
|
screen.getByRole('dialog', { name: 'DisplayName' }),
|
|
@@ -411,14 +410,15 @@ describe('<NodePage />', () => {
|
|
|
411
410
|
</DJClientContext.Provider>
|
|
412
411
|
);
|
|
413
412
|
render(
|
|
414
|
-
<MemoryRouter
|
|
413
|
+
<MemoryRouter
|
|
414
|
+
initialEntries={['/nodes/default.num_repair_orders/columns']}
|
|
415
|
+
>
|
|
415
416
|
<Routes>
|
|
416
|
-
<Route path="nodes/:name" element={element} />
|
|
417
|
+
<Route path="nodes/:name/:tab" element={element} />
|
|
417
418
|
</Routes>
|
|
418
419
|
</MemoryRouter>,
|
|
419
420
|
);
|
|
420
421
|
await waitFor(() => {
|
|
421
|
-
fireEvent.click(screen.getByRole('button', { name: 'Columns' }));
|
|
422
422
|
expect(djClient.DataJunctionAPI.columns).toHaveBeenCalledWith(
|
|
423
423
|
mocks.mockMetricNode,
|
|
424
424
|
);
|
|
@@ -484,9 +484,11 @@ describe('<NodePage />', () => {
|
|
|
484
484
|
</DJClientContext.Provider>
|
|
485
485
|
);
|
|
486
486
|
const { container } = render(
|
|
487
|
-
<MemoryRouter
|
|
487
|
+
<MemoryRouter
|
|
488
|
+
initialEntries={['/nodes/default.num_repair_orders/history']}
|
|
489
|
+
>
|
|
488
490
|
<Routes>
|
|
489
|
-
<Route path="nodes/:name" element={element} />
|
|
491
|
+
<Route path="nodes/:name/:tab" element={element} />
|
|
490
492
|
</Routes>
|
|
491
493
|
</MemoryRouter>,
|
|
492
494
|
);
|
|
@@ -543,14 +545,12 @@ describe('<NodePage />', () => {
|
|
|
543
545
|
'Status changed from valid to invalid Caused by a change in upstream default.repair_order_details',
|
|
544
546
|
),
|
|
545
547
|
);
|
|
546
|
-
screen.debug();
|
|
547
548
|
});
|
|
548
549
|
});
|
|
549
550
|
|
|
550
551
|
it('renders compiled sql correctly', async () => {
|
|
551
552
|
const djClient = mockDJClient();
|
|
552
|
-
djClient.DataJunctionAPI.node.mockReturnValue(mocks.
|
|
553
|
-
djClient.DataJunctionAPI.metric.mockReturnValue(mocks.mockMetricNode);
|
|
553
|
+
djClient.DataJunctionAPI.node.mockReturnValue(mocks.mockTransformNode);
|
|
554
554
|
djClient.DataJunctionAPI.columns.mockReturnValue(mocks.metricNodeColumns);
|
|
555
555
|
djClient.DataJunctionAPI.compiledSql.mockReturnValue('select 1');
|
|
556
556
|
|
|
@@ -560,7 +560,7 @@ describe('<NodePage />', () => {
|
|
|
560
560
|
</DJClientContext.Provider>
|
|
561
561
|
);
|
|
562
562
|
render(
|
|
563
|
-
<MemoryRouter initialEntries={[
|
|
563
|
+
<MemoryRouter initialEntries={[`/nodes/${mocks.mockTransformNode.name}`]}>
|
|
564
564
|
<Routes>
|
|
565
565
|
<Route path="nodes/:name" element={element} />
|
|
566
566
|
</Routes>
|
|
@@ -569,7 +569,7 @@ describe('<NodePage />', () => {
|
|
|
569
569
|
await waitFor(() => {
|
|
570
570
|
fireEvent.click(screen.getByRole('checkbox', { name: 'ToggleSwitch' }));
|
|
571
571
|
expect(djClient.DataJunctionAPI.compiledSql).toHaveBeenCalledWith(
|
|
572
|
-
mocks.
|
|
572
|
+
mocks.mockTransformNode.name,
|
|
573
573
|
);
|
|
574
574
|
});
|
|
575
575
|
});
|
|
@@ -587,9 +587,11 @@ describe('<NodePage />', () => {
|
|
|
587
587
|
</DJClientContext.Provider>
|
|
588
588
|
);
|
|
589
589
|
render(
|
|
590
|
-
<MemoryRouter
|
|
590
|
+
<MemoryRouter
|
|
591
|
+
initialEntries={['/nodes/default.num_repair_orders/materializations']}
|
|
592
|
+
>
|
|
591
593
|
<Routes>
|
|
592
|
-
<Route path="nodes/:name" element={element} />
|
|
594
|
+
<Route path="nodes/:name/:tab" element={element} />
|
|
593
595
|
</Routes>
|
|
594
596
|
</MemoryRouter>,
|
|
595
597
|
);
|
|
@@ -620,9 +622,11 @@ describe('<NodePage />', () => {
|
|
|
620
622
|
</DJClientContext.Provider>
|
|
621
623
|
);
|
|
622
624
|
render(
|
|
623
|
-
<MemoryRouter
|
|
625
|
+
<MemoryRouter
|
|
626
|
+
initialEntries={['/nodes/default.num_repair_orders/materializations']}
|
|
627
|
+
>
|
|
624
628
|
<Routes>
|
|
625
|
-
<Route path="nodes/:name" element={element} />
|
|
629
|
+
<Route path="nodes/:name/:tab" element={element} />
|
|
626
630
|
</Routes>
|
|
627
631
|
</MemoryRouter>,
|
|
628
632
|
);
|
|
@@ -658,9 +662,9 @@ describe('<NodePage />', () => {
|
|
|
658
662
|
</DJClientContext.Provider>
|
|
659
663
|
);
|
|
660
664
|
render(
|
|
661
|
-
<MemoryRouter initialEntries={['/nodes/default.num_repair_orders']}>
|
|
665
|
+
<MemoryRouter initialEntries={['/nodes/default.num_repair_orders/sql']}>
|
|
662
666
|
<Routes>
|
|
663
|
-
<Route path="nodes/:name" element={element} />
|
|
667
|
+
<Route path="nodes/:name/:tab" element={element} />
|
|
664
668
|
</Routes>
|
|
665
669
|
</MemoryRouter>,
|
|
666
670
|
);
|
|
@@ -689,9 +693,11 @@ describe('<NodePage />', () => {
|
|
|
689
693
|
</DJClientContext.Provider>
|
|
690
694
|
);
|
|
691
695
|
render(
|
|
692
|
-
<MemoryRouter
|
|
696
|
+
<MemoryRouter
|
|
697
|
+
initialEntries={['/nodes/default.num_repair_orders/lineage']}
|
|
698
|
+
>
|
|
693
699
|
<Routes>
|
|
694
|
-
<Route path="nodes/:name" element={element} />
|
|
700
|
+
<Route path="nodes/:name/:tab" element={element} />
|
|
695
701
|
</Routes>
|
|
696
702
|
</MemoryRouter>,
|
|
697
703
|
);
|
|
@@ -715,9 +721,9 @@ describe('<NodePage />', () => {
|
|
|
715
721
|
</DJClientContext.Provider>
|
|
716
722
|
);
|
|
717
723
|
render(
|
|
718
|
-
<MemoryRouter initialEntries={['/nodes/default.num_repair_orders']}>
|
|
724
|
+
<MemoryRouter initialEntries={['/nodes/default.num_repair_orders/graph']}>
|
|
719
725
|
<Routes>
|
|
720
|
-
<Route path="nodes/:name" element={element} />
|
|
726
|
+
<Route path="nodes/:name/:tab" element={element} />
|
|
721
727
|
</Routes>
|
|
722
728
|
</MemoryRouter>,
|
|
723
729
|
);
|
|
@@ -742,9 +748,9 @@ describe('<NodePage />', () => {
|
|
|
742
748
|
</DJClientContext.Provider>
|
|
743
749
|
);
|
|
744
750
|
render(
|
|
745
|
-
<MemoryRouter initialEntries={['/nodes/default.dispatcher']}>
|
|
751
|
+
<MemoryRouter initialEntries={['/nodes/default.dispatcher/linked']}>
|
|
746
752
|
<Routes>
|
|
747
|
-
<Route path="nodes/:name" element={element} />
|
|
753
|
+
<Route path="nodes/:name/:tab" element={element} />
|
|
748
754
|
</Routes>
|
|
749
755
|
</MemoryRouter>,
|
|
750
756
|
);
|
|
@@ -100,35 +100,19 @@ exports[`<NodePage /> renders the NodeHistory tab correctly 1`] = `
|
|
|
100
100
|
</table>
|
|
101
101
|
`;
|
|
102
102
|
|
|
103
|
-
exports[`<NodePage /> renders the NodeInfo tab correctly 1`] = `
|
|
103
|
+
exports[`<NodePage /> renders the NodeInfo tab correctly for a metric node 1`] = `
|
|
104
104
|
HTMLCollection [
|
|
105
105
|
<code
|
|
106
106
|
class="language-sql"
|
|
107
107
|
style="white-space: pre;"
|
|
108
108
|
>
|
|
109
|
-
<span
|
|
110
|
-
style="color: rgb(0, 153, 153);"
|
|
111
|
-
>
|
|
112
|
-
SELECT
|
|
113
|
-
</span>
|
|
114
|
-
<span>
|
|
115
|
-
|
|
116
|
-
</span>
|
|
117
109
|
<span
|
|
118
110
|
class="hljs-built_in"
|
|
119
111
|
>
|
|
120
112
|
count
|
|
121
113
|
</span>
|
|
122
114
|
<span>
|
|
123
|
-
(repair_order_id)
|
|
124
|
-
</span>
|
|
125
|
-
<span
|
|
126
|
-
style="color: rgb(0, 153, 153);"
|
|
127
|
-
>
|
|
128
|
-
FROM
|
|
129
|
-
</span>
|
|
130
|
-
<span>
|
|
131
|
-
default.repair_orders
|
|
115
|
+
(repair_order_id)
|
|
132
116
|
</span>
|
|
133
117
|
</code>,
|
|
134
118
|
]
|
|
@@ -16,16 +16,22 @@ import NodeColumnLineage from './NodeLineageTab';
|
|
|
16
16
|
import EditIcon from '../../icons/EditIcon';
|
|
17
17
|
import AlertIcon from '../../icons/AlertIcon';
|
|
18
18
|
import NodeDimensionsTab from './NodeDimensionsTab';
|
|
19
|
+
import { useNavigate } from 'react-router-dom';
|
|
19
20
|
|
|
20
21
|
export function NodePage() {
|
|
21
22
|
const djClient = useContext(DJClientContext).DataJunctionAPI;
|
|
23
|
+
const navigate = useNavigate();
|
|
24
|
+
|
|
25
|
+
const { name, tab } = useParams();
|
|
26
|
+
|
|
22
27
|
const [state, setState] = useState({
|
|
23
|
-
selectedTab:
|
|
28
|
+
selectedTab: tab || 'info',
|
|
24
29
|
});
|
|
25
30
|
|
|
26
31
|
const [node, setNode] = useState();
|
|
27
32
|
|
|
28
33
|
const onClickTab = id => () => {
|
|
34
|
+
navigate(`/nodes/${name}/${id}`);
|
|
29
35
|
setState({ selectedTab: id });
|
|
30
36
|
};
|
|
31
37
|
|
|
@@ -41,24 +47,23 @@ export function NodePage() {
|
|
|
41
47
|
) : null;
|
|
42
48
|
};
|
|
43
49
|
|
|
44
|
-
const { name } = useParams();
|
|
45
|
-
|
|
46
50
|
useEffect(() => {
|
|
47
51
|
const fetchData = async () => {
|
|
48
52
|
const data = await djClient.node(name);
|
|
49
53
|
data.createNodeClientCode = await djClient.clientCode(name);
|
|
50
|
-
setNode(data);
|
|
51
54
|
if (data.type === 'metric') {
|
|
52
55
|
const metric = await djClient.metric(name);
|
|
53
56
|
data.dimensions = metric.dimensions;
|
|
54
57
|
data.metric_metadata = metric.metric_metadata;
|
|
55
|
-
|
|
58
|
+
data.required_dimensions = metric.required_dimensions;
|
|
59
|
+
data.upstream_node = metric.upstream_node;
|
|
60
|
+
data.expression = metric.expression;
|
|
56
61
|
}
|
|
57
62
|
if (data.type === 'cube') {
|
|
58
63
|
const cube = await djClient.cube(name);
|
|
59
64
|
data.cube_elements = cube.cube_elements;
|
|
60
|
-
setNode(data);
|
|
61
65
|
}
|
|
66
|
+
setNode(data);
|
|
62
67
|
};
|
|
63
68
|
fetchData().catch(console.error);
|
|
64
69
|
}, [djClient, name]);
|
|
@@ -66,84 +71,82 @@ export function NodePage() {
|
|
|
66
71
|
const tabsList = node => {
|
|
67
72
|
return [
|
|
68
73
|
{
|
|
69
|
-
id:
|
|
74
|
+
id: 'info',
|
|
70
75
|
name: 'Info',
|
|
71
76
|
display: true,
|
|
72
77
|
},
|
|
73
78
|
{
|
|
74
|
-
id:
|
|
79
|
+
id: 'columns',
|
|
75
80
|
name: 'Columns',
|
|
76
81
|
display: true,
|
|
77
82
|
},
|
|
78
83
|
{
|
|
79
|
-
id:
|
|
84
|
+
id: 'graph',
|
|
80
85
|
name: 'Graph',
|
|
81
86
|
display: true,
|
|
82
87
|
},
|
|
83
88
|
{
|
|
84
|
-
id:
|
|
89
|
+
id: 'history',
|
|
85
90
|
name: 'History',
|
|
86
91
|
display: true,
|
|
87
92
|
},
|
|
88
93
|
{
|
|
89
|
-
id:
|
|
94
|
+
id: 'sql',
|
|
90
95
|
name: 'SQL',
|
|
91
96
|
display: node?.type !== 'dimension' && node?.type !== 'source',
|
|
92
97
|
},
|
|
93
98
|
{
|
|
94
|
-
id:
|
|
99
|
+
id: 'materializations',
|
|
95
100
|
name: 'Materializations',
|
|
96
101
|
display: node?.type !== 'source',
|
|
97
102
|
},
|
|
98
103
|
{
|
|
99
|
-
id:
|
|
104
|
+
id: 'linked',
|
|
100
105
|
name: 'Linked Nodes',
|
|
101
106
|
display: node?.type === 'dimension',
|
|
102
107
|
},
|
|
103
108
|
{
|
|
104
|
-
id:
|
|
109
|
+
id: 'lineage',
|
|
105
110
|
name: 'Lineage',
|
|
106
111
|
display: node?.type === 'metric',
|
|
107
112
|
},
|
|
108
113
|
{
|
|
109
|
-
id:
|
|
114
|
+
id: 'dimensions',
|
|
110
115
|
name: 'Dimensions',
|
|
111
116
|
display: node?.type !== 'cube',
|
|
112
117
|
},
|
|
113
118
|
];
|
|
114
119
|
};
|
|
115
|
-
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
120
|
let tabToDisplay = null;
|
|
121
|
+
|
|
119
122
|
switch (state.selectedTab) {
|
|
120
|
-
case
|
|
123
|
+
case 'info':
|
|
121
124
|
tabToDisplay =
|
|
122
125
|
node && node.message === undefined ? <NodeInfoTab node={node} /> : '';
|
|
123
126
|
break;
|
|
124
|
-
case
|
|
127
|
+
case 'columns':
|
|
125
128
|
tabToDisplay = <NodeColumnTab node={node} djClient={djClient} />;
|
|
126
129
|
break;
|
|
127
|
-
case
|
|
130
|
+
case 'graph':
|
|
128
131
|
tabToDisplay = <NodeLineage djNode={node} djClient={djClient} />;
|
|
129
132
|
break;
|
|
130
|
-
case
|
|
133
|
+
case 'history':
|
|
131
134
|
tabToDisplay = <NodeHistory node={node} djClient={djClient} />;
|
|
132
135
|
break;
|
|
133
|
-
case
|
|
136
|
+
case 'sql':
|
|
134
137
|
tabToDisplay =
|
|
135
138
|
node?.type === 'metric' ? <NodeSQLTab djNode={node} /> : <br />;
|
|
136
139
|
break;
|
|
137
|
-
case
|
|
140
|
+
case 'materializations':
|
|
138
141
|
tabToDisplay = <NodeMaterializationTab node={node} djClient={djClient} />;
|
|
139
142
|
break;
|
|
140
|
-
case
|
|
143
|
+
case 'linked':
|
|
141
144
|
tabToDisplay = <NodesWithDimension node={node} djClient={djClient} />;
|
|
142
145
|
break;
|
|
143
|
-
case
|
|
146
|
+
case 'lineage':
|
|
144
147
|
tabToDisplay = <NodeColumnLineage djNode={node} djClient={djClient} />;
|
|
145
148
|
break;
|
|
146
|
-
case
|
|
149
|
+
case 'dimensions':
|
|
147
150
|
tabToDisplay = <NodeDimensionsTab node={node} djClient={djClient} />;
|
|
148
151
|
break;
|
|
149
152
|
default: /* istanbul ignore next */
|
|
@@ -24,10 +24,11 @@ export function Root() {
|
|
|
24
24
|
<div className="container d-flex align-items-center justify-content-between">
|
|
25
25
|
<div className="header">
|
|
26
26
|
<div className="logo">
|
|
27
|
-
<
|
|
27
|
+
<a href={'/'} style={{textTransform: 'none', textDecoration: 'none', color: '#000'}}>
|
|
28
|
+
<h2>
|
|
28
29
|
<DJLogo />
|
|
29
30
|
Data<b>Junction</b>
|
|
30
|
-
</h2>
|
|
31
|
+
</h2></a>
|
|
31
32
|
</div>
|
|
32
33
|
<Search />
|
|
33
34
|
<div className="menu">
|
|
@@ -60,6 +60,14 @@ export const DataJunctionAPI = {
|
|
|
60
60
|
).json();
|
|
61
61
|
},
|
|
62
62
|
|
|
63
|
+
nodesWithType: async function (nodeType) {
|
|
64
|
+
return await (
|
|
65
|
+
await fetch(`${DJ_URL}/nodes/?node_type=${nodeType}`, {
|
|
66
|
+
credentials: 'include',
|
|
67
|
+
})
|
|
68
|
+
).json();
|
|
69
|
+
},
|
|
70
|
+
|
|
63
71
|
nodeDetails: async () => {
|
|
64
72
|
return await (
|
|
65
73
|
await fetch(`${DJ_URL}/nodes/details/`, {
|
|
@@ -68,6 +76,31 @@ export const DataJunctionAPI = {
|
|
|
68
76
|
).json();
|
|
69
77
|
},
|
|
70
78
|
|
|
79
|
+
validateNode: async function (
|
|
80
|
+
nodeType,
|
|
81
|
+
name,
|
|
82
|
+
display_name,
|
|
83
|
+
description,
|
|
84
|
+
query,
|
|
85
|
+
) {
|
|
86
|
+
const response = await fetch(`${DJ_URL}/nodes/validate`, {
|
|
87
|
+
method: 'POST',
|
|
88
|
+
headers: {
|
|
89
|
+
'Content-Type': 'application/json',
|
|
90
|
+
},
|
|
91
|
+
body: JSON.stringify({
|
|
92
|
+
name: name,
|
|
93
|
+
display_name: display_name,
|
|
94
|
+
description: description,
|
|
95
|
+
query: query,
|
|
96
|
+
type: nodeType,
|
|
97
|
+
mode: 'published',
|
|
98
|
+
}),
|
|
99
|
+
credentials: 'include',
|
|
100
|
+
});
|
|
101
|
+
return { status: response.status, json: await response.json() };
|
|
102
|
+
},
|
|
103
|
+
|
|
71
104
|
createNode: async function (
|
|
72
105
|
nodeType,
|
|
73
106
|
name,
|
|
@@ -79,6 +112,7 @@ export const DataJunctionAPI = {
|
|
|
79
112
|
primary_key,
|
|
80
113
|
metric_direction,
|
|
81
114
|
metric_unit,
|
|
115
|
+
required_dimensions,
|
|
82
116
|
) {
|
|
83
117
|
const metricMetadata =
|
|
84
118
|
metric_direction || metric_unit
|
|
@@ -101,6 +135,7 @@ export const DataJunctionAPI = {
|
|
|
101
135
|
namespace: namespace,
|
|
102
136
|
primary_key: primary_key,
|
|
103
137
|
metric_metadata: metricMetadata,
|
|
138
|
+
required_dimensions: required_dimensions,
|
|
104
139
|
}),
|
|
105
140
|
credentials: 'include',
|
|
106
141
|
});
|
|
@@ -116,6 +151,7 @@ export const DataJunctionAPI = {
|
|
|
116
151
|
primary_key,
|
|
117
152
|
metric_direction,
|
|
118
153
|
metric_unit,
|
|
154
|
+
required_dimensions,
|
|
119
155
|
) {
|
|
120
156
|
try {
|
|
121
157
|
const metricMetadata =
|
|
@@ -137,6 +173,7 @@ export const DataJunctionAPI = {
|
|
|
137
173
|
mode: mode,
|
|
138
174
|
primary_key: primary_key,
|
|
139
175
|
metric_metadata: metricMetadata,
|
|
176
|
+
required_dimensions: required_dimensions,
|
|
140
177
|
}),
|
|
141
178
|
credentials: 'include',
|
|
142
179
|
});
|
|
@@ -65,6 +65,18 @@ describe('DataJunctionAPI', () => {
|
|
|
65
65
|
});
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
+
it('calls nodesWithType correctly', async () => {
|
|
69
|
+
const nodeType = 'transform';
|
|
70
|
+
fetch.mockResponseOnce(JSON.stringify({}));
|
|
71
|
+
await DataJunctionAPI.nodesWithType(nodeType);
|
|
72
|
+
expect(fetch).toHaveBeenCalledWith(
|
|
73
|
+
`${DJ_URL}/nodes/?node_type=${nodeType}`,
|
|
74
|
+
{
|
|
75
|
+
credentials: 'include',
|
|
76
|
+
},
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
|
|
68
80
|
it('calls createNode correctly', async () => {
|
|
69
81
|
const sampleArgs = [
|
|
70
82
|
'type',
|
|
@@ -266,6 +278,17 @@ describe('DataJunctionAPI', () => {
|
|
|
266
278
|
});
|
|
267
279
|
});
|
|
268
280
|
|
|
281
|
+
it('calls listMetricMetadata correctly', async () => {
|
|
282
|
+
const nodeType = 'transform';
|
|
283
|
+
fetch.mockResponseOnce(JSON.stringify({}));
|
|
284
|
+
await DataJunctionAPI.listMetricMetadata();
|
|
285
|
+
expect(fetch).toHaveBeenCalledWith(`${DJ_URL}/metrics/metadata`, {
|
|
286
|
+
method: 'GET',
|
|
287
|
+
headers: { 'Content-Type': 'application/json' },
|
|
288
|
+
credentials: 'include',
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
|
|
269
292
|
it('calls namespaces correctly', async () => {
|
|
270
293
|
fetch.mockResponseOnce(JSON.stringify({}));
|
|
271
294
|
await DataJunctionAPI.namespaces();
|
package/src/mocks/mockNodes.jsx
CHANGED
|
@@ -1,4 +1,63 @@
|
|
|
1
1
|
export const mocks = {
|
|
2
|
+
metricMetadata: {
|
|
3
|
+
directions: ['higher_is_better', 'lower_is_better', 'neutral'],
|
|
4
|
+
units: [
|
|
5
|
+
{ name: 'dollar', label: 'Dollar' },
|
|
6
|
+
{ name: 'second', label: 'Second' },
|
|
7
|
+
],
|
|
8
|
+
},
|
|
9
|
+
mockTransformNode: {
|
|
10
|
+
namespace: 'default',
|
|
11
|
+
node_revision_id: 15,
|
|
12
|
+
node_id: 15,
|
|
13
|
+
type: 'transform',
|
|
14
|
+
name: 'default.repair_order_transform',
|
|
15
|
+
display_name: 'Default: Repair Order Transform',
|
|
16
|
+
version: 'v1.0',
|
|
17
|
+
status: 'valid',
|
|
18
|
+
mode: 'published',
|
|
19
|
+
catalog: {
|
|
20
|
+
name: 'warehouse',
|
|
21
|
+
engines: [],
|
|
22
|
+
},
|
|
23
|
+
schema_: null,
|
|
24
|
+
table: null,
|
|
25
|
+
description: 'Repair order dimension',
|
|
26
|
+
query:
|
|
27
|
+
'SELECT repair_order_id, municipality_id, hard_hat_id, dispatcher_id FROM default.repair_orders',
|
|
28
|
+
availability: null,
|
|
29
|
+
columns: [
|
|
30
|
+
{
|
|
31
|
+
name: 'repair_order_id',
|
|
32
|
+
display_name: 'Repair Order Id',
|
|
33
|
+
type: 'int',
|
|
34
|
+
attributes: [],
|
|
35
|
+
dimension: null,
|
|
36
|
+
partition: null,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'municipality_id',
|
|
40
|
+
display_name: 'Municipality Id',
|
|
41
|
+
type: 'string',
|
|
42
|
+
attributes: [],
|
|
43
|
+
dimension: null,
|
|
44
|
+
partition: null,
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
updated_at: '2024-01-24T16:39:14.029366+00:00',
|
|
48
|
+
materializations: [],
|
|
49
|
+
parents: [
|
|
50
|
+
{
|
|
51
|
+
name: 'default.repair_orders',
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
metric_metadata: null,
|
|
55
|
+
dimension_links: [],
|
|
56
|
+
created_at: '2024-01-24T16:39:14.028077+00:00',
|
|
57
|
+
tags: [],
|
|
58
|
+
current_version: 'v1.0',
|
|
59
|
+
missing_table: false,
|
|
60
|
+
},
|
|
2
61
|
mockMetricNode: {
|
|
3
62
|
namespace: 'default',
|
|
4
63
|
node_revision_id: 23,
|
|
@@ -217,6 +276,10 @@ export const mocks = {
|
|
|
217
276
|
},
|
|
218
277
|
direction: 'neutral',
|
|
219
278
|
},
|
|
279
|
+
upstream_node: 'default.repair_orders',
|
|
280
|
+
expression: 'count(repair_order_id)',
|
|
281
|
+
aggregate_expression: 'count(repair_order_id)',
|
|
282
|
+
required_dimensions: [],
|
|
220
283
|
},
|
|
221
284
|
attributes: [
|
|
222
285
|
{
|