datajunction-ui 0.0.1-a44.dev5 → 0.0.1-a45.dev14
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 +3 -1
- package/src/app/components/NodeListActions.jsx +69 -0
- package/src/app/components/__tests__/NodeListActions.test.jsx +94 -0
- package/src/app/icons/CommitIcon.jsx +45 -0
- package/src/app/icons/DiffIcon.jsx +63 -0
- package/src/app/index.tsx +5 -0
- package/src/app/pages/AddEditNodePage/NodeQueryField.jsx +3 -0
- package/src/app/pages/AddEditNodePage/QueryTesterSection.jsx +62 -0
- package/src/app/pages/NamespacePage/index.jsx +2 -6
- package/src/app/pages/NodePage/NodeHistory.jsx +149 -171
- package/src/app/pages/NodePage/NodeInfoTab.jsx +33 -0
- package/src/app/pages/NodePage/RevisionDiff.jsx +200 -0
- package/src/app/pages/NodePage/__tests__/AddMaterializationPopover.test.jsx +1 -1
- package/src/app/pages/NodePage/__tests__/NodePage.test.jsx +3 -8
- package/src/app/pages/NodePage/__tests__/RevisionDiff.test.jsx +164 -0
- package/src/app/pages/NodePage/__tests__/__snapshots__/NodePage.test.jsx.snap +0 -100
- package/src/app/pages/NodePage/index.jsx +1 -0
- package/src/app/pages/QueryRunner.jsx +31 -0
- package/src/app/services/DJService.js +45 -0
- package/src/app/services/__tests__/DJService.test.jsx +107 -0
- package/src/index.tsx +1 -0
- package/src/mocks/mockNodes.jsx +48 -0
- package/src/styles/index.css +89 -0
- package/src/styles/node-creation.scss +9 -0
- package/src/app/components/DeleteNode.jsx +0 -55
- package/src/app/components/__tests__/DeleteNode.test.jsx +0 -53
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, waitFor, screen } from '@testing-library/react';
|
|
3
|
+
import RevisionDiff from '../RevisionDiff';
|
|
4
|
+
import DJClientContext from '../../../providers/djclient';
|
|
5
|
+
import { NodePage } from '../Loadable';
|
|
6
|
+
import { MemoryRouter, Route, Routes } from 'react-router-dom';
|
|
7
|
+
|
|
8
|
+
describe('<RevisionDiff />', () => {
|
|
9
|
+
const mockDjClient = {
|
|
10
|
+
DataJunctionAPI: {
|
|
11
|
+
revisions: jest.fn(),
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const mockNodesWithDimension = [
|
|
16
|
+
{
|
|
17
|
+
node_revision_id: 1,
|
|
18
|
+
node_id: 1,
|
|
19
|
+
type: 'dimension',
|
|
20
|
+
name: 'default.repair_order',
|
|
21
|
+
display_name: 'Repair Orders',
|
|
22
|
+
version: 'v1.0',
|
|
23
|
+
status: 'valid',
|
|
24
|
+
mode: 'published',
|
|
25
|
+
catalog: {
|
|
26
|
+
id: 1,
|
|
27
|
+
uuid: '0fc18295-e1a2-4c3c-b72a-894725c12488',
|
|
28
|
+
created_at: '2023-08-21T16:48:51.146121+00:00',
|
|
29
|
+
updated_at: '2023-08-21T16:48:51.146122+00:00',
|
|
30
|
+
extra_params: {},
|
|
31
|
+
name: 'warehouse',
|
|
32
|
+
},
|
|
33
|
+
description: 'Repair order dimension',
|
|
34
|
+
query:
|
|
35
|
+
'SELECT repair_order_id, municipality_id, hard_hat_id, order_date, ' +
|
|
36
|
+
'dispatcher_id FROM default.repair_orders',
|
|
37
|
+
availability: null,
|
|
38
|
+
columns: [
|
|
39
|
+
{
|
|
40
|
+
name: 'repair_order_id',
|
|
41
|
+
type: 'int',
|
|
42
|
+
attributes: [],
|
|
43
|
+
dimension: {
|
|
44
|
+
name: 'default.repair_order',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'municipality_id',
|
|
49
|
+
type: 'int',
|
|
50
|
+
attributes: [],
|
|
51
|
+
dimension: null,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'hard_hat_id',
|
|
55
|
+
type: 'int',
|
|
56
|
+
attributes: [],
|
|
57
|
+
dimension: null,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'order_date',
|
|
61
|
+
type: 'date',
|
|
62
|
+
attributes: [],
|
|
63
|
+
dimension: null,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'dispatcher_id',
|
|
67
|
+
type: 'int',
|
|
68
|
+
attributes: [],
|
|
69
|
+
dimension: null,
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
updated_at: '2023-08-21T16:48:52.981201+00:00',
|
|
73
|
+
materializations: [],
|
|
74
|
+
parents: [],
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
node_revision_id: 2,
|
|
78
|
+
node_id: 2,
|
|
79
|
+
type: 'dimension',
|
|
80
|
+
name: 'default.repair_order',
|
|
81
|
+
display_name: 'Repair Orders',
|
|
82
|
+
version: 'v2.0',
|
|
83
|
+
status: 'valid',
|
|
84
|
+
mode: 'published',
|
|
85
|
+
catalog: {
|
|
86
|
+
id: 1,
|
|
87
|
+
uuid: '0fc18295-e1a2-4c3c-b72a-894725c12488',
|
|
88
|
+
created_at: '2023-08-21T16:48:51.146121+00:00',
|
|
89
|
+
updated_at: '2023-08-21T16:48:51.146122+00:00',
|
|
90
|
+
extra_params: {},
|
|
91
|
+
name: 'warehouse',
|
|
92
|
+
},
|
|
93
|
+
description: 'Repair order dimension',
|
|
94
|
+
query:
|
|
95
|
+
'SELECT repair_order_id, municipality_id, hard_hat_id, ' +
|
|
96
|
+
'dispatcher_id FROM default.repair_orders',
|
|
97
|
+
availability: null,
|
|
98
|
+
columns: [
|
|
99
|
+
{
|
|
100
|
+
name: 'repair_order_id',
|
|
101
|
+
type: 'int',
|
|
102
|
+
attributes: [],
|
|
103
|
+
dimension: {
|
|
104
|
+
name: 'default.repair_order',
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'municipality_id',
|
|
109
|
+
type: 'int',
|
|
110
|
+
attributes: [],
|
|
111
|
+
dimension: null,
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: 'hard_hat_id',
|
|
115
|
+
type: 'int',
|
|
116
|
+
attributes: [],
|
|
117
|
+
dimension: null,
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: 'dispatcher_id',
|
|
121
|
+
type: 'int',
|
|
122
|
+
attributes: [],
|
|
123
|
+
dimension: null,
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
updated_at: '2023-08-21T16:48:52.981201+00:00',
|
|
127
|
+
materializations: [],
|
|
128
|
+
parents: [],
|
|
129
|
+
},
|
|
130
|
+
];
|
|
131
|
+
|
|
132
|
+
beforeEach(() => {
|
|
133
|
+
// Reset the mocks before each test
|
|
134
|
+
mockDjClient.DataJunctionAPI.revisions.mockReset();
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('renders revision diff', async () => {
|
|
138
|
+
mockDjClient.DataJunctionAPI.revisions.mockReturnValue(
|
|
139
|
+
mockNodesWithDimension,
|
|
140
|
+
);
|
|
141
|
+
const element = (
|
|
142
|
+
<DJClientContext.Provider value={mockDjClient}>
|
|
143
|
+
<RevisionDiff />
|
|
144
|
+
</DJClientContext.Provider>
|
|
145
|
+
);
|
|
146
|
+
const { container } = render(
|
|
147
|
+
<MemoryRouter
|
|
148
|
+
initialEntries={['/nodes/default.repair_orders_cube/revisions/v2.0']}
|
|
149
|
+
>
|
|
150
|
+
<Routes>
|
|
151
|
+
<Route path="nodes/:name/revisions/:revision" element={element} />
|
|
152
|
+
</Routes>
|
|
153
|
+
</MemoryRouter>,
|
|
154
|
+
);
|
|
155
|
+
await waitFor(() => {
|
|
156
|
+
expect(mockDjClient.DataJunctionAPI.revisions).toHaveBeenCalledWith(
|
|
157
|
+
'default.repair_orders_cube',
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
const diffViews = screen.getAllByRole('gridcell', 'DiffView');
|
|
161
|
+
diffViews.map(diffView => expect(diffView).toBeInTheDocument());
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
});
|
|
@@ -1,105 +1,5 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
|
-
exports[`<NodePage /> renders the NodeHistory tab correctly 1`] = `
|
|
4
|
-
<table
|
|
5
|
-
aria-label="Revisions"
|
|
6
|
-
class="card-inner-table table"
|
|
7
|
-
>
|
|
8
|
-
<thead
|
|
9
|
-
class="fs-7 fw-bold text-gray-400 border-bottom-0"
|
|
10
|
-
>
|
|
11
|
-
<tr>
|
|
12
|
-
<th
|
|
13
|
-
class="text-start"
|
|
14
|
-
>
|
|
15
|
-
Version
|
|
16
|
-
</th>
|
|
17
|
-
<th>
|
|
18
|
-
Display Name
|
|
19
|
-
</th>
|
|
20
|
-
<th>
|
|
21
|
-
Description
|
|
22
|
-
</th>
|
|
23
|
-
<th>
|
|
24
|
-
Query
|
|
25
|
-
</th>
|
|
26
|
-
<th>
|
|
27
|
-
Tags
|
|
28
|
-
</th>
|
|
29
|
-
</tr>
|
|
30
|
-
</thead>
|
|
31
|
-
<tbody>
|
|
32
|
-
<tr>
|
|
33
|
-
<td
|
|
34
|
-
class="text-start"
|
|
35
|
-
>
|
|
36
|
-
<span
|
|
37
|
-
class="badge node_type__source"
|
|
38
|
-
>
|
|
39
|
-
v1.0
|
|
40
|
-
</span>
|
|
41
|
-
</td>
|
|
42
|
-
<td>
|
|
43
|
-
Default: Avg Repair Price
|
|
44
|
-
</td>
|
|
45
|
-
<td>
|
|
46
|
-
Average repair price
|
|
47
|
-
</td>
|
|
48
|
-
<td>
|
|
49
|
-
<pre
|
|
50
|
-
style="display: block; overflow-x: auto; padding: 2rem; background: rgb(238, 238, 238); color: black;"
|
|
51
|
-
>
|
|
52
|
-
<code
|
|
53
|
-
class="language-sql"
|
|
54
|
-
style="white-space: pre-wrap;"
|
|
55
|
-
>
|
|
56
|
-
<span>
|
|
57
|
-
<span
|
|
58
|
-
style="color: rgb(0, 153, 153);"
|
|
59
|
-
>
|
|
60
|
-
SELECT
|
|
61
|
-
</span>
|
|
62
|
-
<span>
|
|
63
|
-
|
|
64
|
-
</span>
|
|
65
|
-
<span
|
|
66
|
-
class="hljs-built_in"
|
|
67
|
-
>
|
|
68
|
-
avg
|
|
69
|
-
</span>
|
|
70
|
-
<span>
|
|
71
|
-
(price) default_DOT_avg_repair_price
|
|
72
|
-
|
|
73
|
-
</span>
|
|
74
|
-
</span>
|
|
75
|
-
<span>
|
|
76
|
-
<span>
|
|
77
|
-
|
|
78
|
-
</span>
|
|
79
|
-
<span
|
|
80
|
-
style="color: rgb(0, 153, 153);"
|
|
81
|
-
>
|
|
82
|
-
FROM
|
|
83
|
-
</span>
|
|
84
|
-
<span>
|
|
85
|
-
default.repair_order_details
|
|
86
|
-
|
|
87
|
-
</span>
|
|
88
|
-
</span>
|
|
89
|
-
<span>
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
</span>
|
|
93
|
-
<span />
|
|
94
|
-
</code>
|
|
95
|
-
</pre>
|
|
96
|
-
</td>
|
|
97
|
-
<td />
|
|
98
|
-
</tr>
|
|
99
|
-
</tbody>
|
|
100
|
-
</table>
|
|
101
|
-
`;
|
|
102
|
-
|
|
103
3
|
exports[`<NodePage /> renders the NodeInfo tab correctly for a metric node 1`] = `
|
|
104
4
|
HTMLCollection [
|
|
105
5
|
<code
|
|
@@ -58,6 +58,7 @@ export function NodePage() {
|
|
|
58
58
|
data.required_dimensions = metric.required_dimensions;
|
|
59
59
|
data.upstream_node = metric.upstream_node;
|
|
60
60
|
data.expression = metric.expression;
|
|
61
|
+
data.incompatible_druid_functions = metric.incompatible_druid_functions;
|
|
61
62
|
}
|
|
62
63
|
if (data.type === 'cube') {
|
|
63
64
|
const cube = await djClient.cube(name);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import QueryBuilder from 'react-querybuilder';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
|
|
4
|
+
export function QueryRunner() {
|
|
5
|
+
const [fields, setFields] = useState([]);
|
|
6
|
+
const [filters, setFilters] = useState({
|
|
7
|
+
combinator: 'and',
|
|
8
|
+
rules: [],
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<>
|
|
13
|
+
<h4>Test Query</h4>
|
|
14
|
+
<label>Add Filters</label>
|
|
15
|
+
<QueryBuilder
|
|
16
|
+
fields={fields}
|
|
17
|
+
query={filters}
|
|
18
|
+
onQueryChange={q => setFilters(q)}
|
|
19
|
+
/>
|
|
20
|
+
<span
|
|
21
|
+
className="button-3 execute-button"
|
|
22
|
+
// onClick={getData}
|
|
23
|
+
role="button"
|
|
24
|
+
aria-label="RunQuery"
|
|
25
|
+
aria-hidden="false"
|
|
26
|
+
>
|
|
27
|
+
{'Run Query'}
|
|
28
|
+
</span>
|
|
29
|
+
</>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
@@ -613,6 +613,51 @@ export const DataJunctionAPI = {
|
|
|
613
613
|
);
|
|
614
614
|
return { status: response.status, json: await response.json() };
|
|
615
615
|
},
|
|
616
|
+
|
|
617
|
+
addComplexDimensionLink: async function (
|
|
618
|
+
nodeName,
|
|
619
|
+
dimensionNode,
|
|
620
|
+
joinOn,
|
|
621
|
+
joinType = null,
|
|
622
|
+
joinCardinality = null,
|
|
623
|
+
role = null,
|
|
624
|
+
) {
|
|
625
|
+
const response = await fetch(`${DJ_URL}/nodes/${nodeName}/link`, {
|
|
626
|
+
method: 'POST',
|
|
627
|
+
headers: {
|
|
628
|
+
'Content-Type': 'application/json',
|
|
629
|
+
},
|
|
630
|
+
body: JSON.stringify({
|
|
631
|
+
dimensionNode: dimensionNode,
|
|
632
|
+
joinType: joinType,
|
|
633
|
+
joinOn: joinOn,
|
|
634
|
+
joinCardinality: joinCardinality,
|
|
635
|
+
role: role,
|
|
636
|
+
}),
|
|
637
|
+
credentials: 'include',
|
|
638
|
+
});
|
|
639
|
+
return { status: response.status, json: await response.json() };
|
|
640
|
+
},
|
|
641
|
+
|
|
642
|
+
removeComplexDimensionLink: async function (
|
|
643
|
+
nodeName,
|
|
644
|
+
dimensionNode,
|
|
645
|
+
role = null,
|
|
646
|
+
) {
|
|
647
|
+
const response = await fetch(`${DJ_URL}/nodes/${nodeName}/link`, {
|
|
648
|
+
method: 'DELETE',
|
|
649
|
+
headers: {
|
|
650
|
+
'Content-Type': 'application/json',
|
|
651
|
+
},
|
|
652
|
+
body: JSON.stringify({
|
|
653
|
+
dimensionNode: dimensionNode,
|
|
654
|
+
role: role,
|
|
655
|
+
}),
|
|
656
|
+
credentials: 'include',
|
|
657
|
+
});
|
|
658
|
+
return { status: response.status, json: await response.json() };
|
|
659
|
+
},
|
|
660
|
+
|
|
616
661
|
deactivate: async function (nodeName) {
|
|
617
662
|
const response = await fetch(`${DJ_URL}/nodes/${nodeName}`, {
|
|
618
663
|
method: 'DELETE',
|
|
@@ -34,6 +34,22 @@ describe('DataJunctionAPI', () => {
|
|
|
34
34
|
});
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
+
it('calls catalogs correctly', async () => {
|
|
38
|
+
fetch.mockResponseOnce(JSON.stringify({}));
|
|
39
|
+
await DataJunctionAPI.catalogs();
|
|
40
|
+
expect(fetch).toHaveBeenCalledWith(`${DJ_URL}/catalogs`, {
|
|
41
|
+
credentials: 'include',
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('calls engines correctly', async () => {
|
|
46
|
+
fetch.mockResponseOnce(JSON.stringify({}));
|
|
47
|
+
await DataJunctionAPI.engines();
|
|
48
|
+
expect(fetch).toHaveBeenCalledWith(`${DJ_URL}/engines`, {
|
|
49
|
+
credentials: 'include',
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
37
53
|
it('calls node correctly', async () => {
|
|
38
54
|
fetch.mockResponseOnce(JSON.stringify(mocks.mockMetricNode));
|
|
39
55
|
const nodeData = await DataJunctionAPI.node(mocks.mockMetricNode.name);
|
|
@@ -49,6 +65,57 @@ describe('DataJunctionAPI', () => {
|
|
|
49
65
|
expect(nodeData.primary_key).toEqual([]);
|
|
50
66
|
});
|
|
51
67
|
|
|
68
|
+
it('calls nodeDetails correctly', async () => {
|
|
69
|
+
fetch.mockResponseOnce(JSON.stringify([mocks.mockMetricNode]));
|
|
70
|
+
const nodeData = await DataJunctionAPI.nodeDetails();
|
|
71
|
+
expect(fetch).toHaveBeenCalledWith(`${DJ_URL}/nodes/details/`, {
|
|
72
|
+
credentials: 'include',
|
|
73
|
+
});
|
|
74
|
+
expect(nodeData).toEqual([mocks.mockMetricNode]);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('calls validate correctly', async () => {
|
|
78
|
+
fetch.mockResponseOnce(JSON.stringify([mocks.mockMetricNode]));
|
|
79
|
+
await DataJunctionAPI.validateNode(
|
|
80
|
+
'metric',
|
|
81
|
+
'default.num_repair_orders',
|
|
82
|
+
'aa',
|
|
83
|
+
'desc',
|
|
84
|
+
'select 1',
|
|
85
|
+
);
|
|
86
|
+
expect(fetch).toHaveBeenCalledWith(`${DJ_URL}/nodes/validate`, {
|
|
87
|
+
credentials: 'include',
|
|
88
|
+
body: JSON.stringify({
|
|
89
|
+
name: 'default.num_repair_orders',
|
|
90
|
+
display_name: 'aa',
|
|
91
|
+
description: 'desc',
|
|
92
|
+
query: 'select 1',
|
|
93
|
+
type: 'metric',
|
|
94
|
+
mode: 'published',
|
|
95
|
+
}),
|
|
96
|
+
|
|
97
|
+
headers: {
|
|
98
|
+
'Content-Type': 'application/json',
|
|
99
|
+
},
|
|
100
|
+
method: 'POST',
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('calls registerTable correctly', async () => {
|
|
105
|
+
fetch.mockResponseOnce(JSON.stringify([mocks.mockMetricNode]));
|
|
106
|
+
await DataJunctionAPI.registerTable('default', 'xyz', 'abc');
|
|
107
|
+
expect(fetch).toHaveBeenCalledWith(
|
|
108
|
+
`${DJ_URL}/register/table/default/xyz/abc`,
|
|
109
|
+
{
|
|
110
|
+
credentials: 'include',
|
|
111
|
+
headers: {
|
|
112
|
+
'Content-Type': 'application/json',
|
|
113
|
+
},
|
|
114
|
+
method: 'POST',
|
|
115
|
+
},
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
|
|
52
119
|
it('node with errors are handled', async () => {
|
|
53
120
|
const mockNotFound = { message: 'node not found' };
|
|
54
121
|
fetch.mockResponseOnce(JSON.stringify(mockNotFound));
|
|
@@ -656,6 +723,46 @@ describe('DataJunctionAPI', () => {
|
|
|
656
723
|
);
|
|
657
724
|
});
|
|
658
725
|
|
|
726
|
+
it('calls add and remove complex dimension link correctly', async () => {
|
|
727
|
+
const nodeName = 'default.transform1';
|
|
728
|
+
const dimensionNode = 'default.dimension1';
|
|
729
|
+
const joinOn = 'blah';
|
|
730
|
+
fetch.mockResponseOnce(JSON.stringify({}));
|
|
731
|
+
await DataJunctionAPI.removeComplexDimensionLink(nodeName, dimensionNode);
|
|
732
|
+
expect(fetch).toHaveBeenCalledWith(`${DJ_URL}/nodes/${nodeName}/link`, {
|
|
733
|
+
credentials: 'include',
|
|
734
|
+
headers: {
|
|
735
|
+
'Content-Type': 'application/json',
|
|
736
|
+
},
|
|
737
|
+
body: JSON.stringify({
|
|
738
|
+
dimensionNode: dimensionNode,
|
|
739
|
+
role: null,
|
|
740
|
+
}),
|
|
741
|
+
method: 'DELETE',
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
fetch.mockResponseOnce(JSON.stringify({}));
|
|
745
|
+
await DataJunctionAPI.addComplexDimensionLink(
|
|
746
|
+
nodeName,
|
|
747
|
+
dimensionNode,
|
|
748
|
+
joinOn,
|
|
749
|
+
);
|
|
750
|
+
expect(fetch).toHaveBeenCalledWith(`${DJ_URL}/nodes/${nodeName}/link`, {
|
|
751
|
+
credentials: 'include',
|
|
752
|
+
headers: {
|
|
753
|
+
'Content-Type': 'application/json',
|
|
754
|
+
},
|
|
755
|
+
body: JSON.stringify({
|
|
756
|
+
dimensionNode: dimensionNode,
|
|
757
|
+
joinType: null,
|
|
758
|
+
joinOn: joinOn,
|
|
759
|
+
joinCardinality: null,
|
|
760
|
+
role: null,
|
|
761
|
+
}),
|
|
762
|
+
method: 'POST',
|
|
763
|
+
});
|
|
764
|
+
});
|
|
765
|
+
|
|
659
766
|
it('calls deactivate correctly', async () => {
|
|
660
767
|
const nodeName = 'default.transform1';
|
|
661
768
|
fetch.mockResponseOnce(JSON.stringify({}));
|
package/src/index.tsx
CHANGED
package/src/mocks/mockNodes.jsx
CHANGED
|
@@ -103,6 +103,7 @@ export const mocks = {
|
|
|
103
103
|
created_at: '2023-08-21T16:48:56.841631+00:00',
|
|
104
104
|
tags: [{ name: 'purpose', display_name: 'Purpose' }],
|
|
105
105
|
dimension_links: [],
|
|
106
|
+
incompatible_druid_functions: ['IF'],
|
|
106
107
|
dimensions: [
|
|
107
108
|
{
|
|
108
109
|
value: 'default.date_dim.dateint',
|
|
@@ -408,6 +409,53 @@ export const mocks = {
|
|
|
408
409
|
},
|
|
409
410
|
created_at: '2023-08-21T16:48:56.950482+00:00',
|
|
410
411
|
},
|
|
412
|
+
{
|
|
413
|
+
id: 7,
|
|
414
|
+
entity_type: 'backfill',
|
|
415
|
+
entity_name: 'default.avg_repair_price',
|
|
416
|
+
node: 'default.avg_repair_price',
|
|
417
|
+
activity_type: 'create',
|
|
418
|
+
user: null,
|
|
419
|
+
pre: { status: 'valid' },
|
|
420
|
+
post: { status: 'invalid' },
|
|
421
|
+
details: {
|
|
422
|
+
materialization: 'druid_metrics_cube__incremental_time__xyz',
|
|
423
|
+
partition: {
|
|
424
|
+
column_name: 'xyz.abc',
|
|
425
|
+
values: null,
|
|
426
|
+
range: ['20240201', '20240301'],
|
|
427
|
+
},
|
|
428
|
+
},
|
|
429
|
+
created_at: '2023-08-21T16:48:56.950482+00:00',
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
id: 8,
|
|
433
|
+
entity_type: 'node',
|
|
434
|
+
entity_name: 'default.avg_repair_price',
|
|
435
|
+
node: 'default.avg_repair_price',
|
|
436
|
+
activity_type: 'tag',
|
|
437
|
+
user: null,
|
|
438
|
+
pre: {},
|
|
439
|
+
post: {},
|
|
440
|
+
details: {
|
|
441
|
+
tags: ['a', 'b'],
|
|
442
|
+
},
|
|
443
|
+
created_at: '2023-08-21T16:48:56.950482+00:00',
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
id: 9,
|
|
447
|
+
entity_type: 'link',
|
|
448
|
+
entity_name: 'default.avg_repair_price',
|
|
449
|
+
node: 'default.avg_repair_price',
|
|
450
|
+
activity_type: 'create',
|
|
451
|
+
user: null,
|
|
452
|
+
pre: {},
|
|
453
|
+
post: {},
|
|
454
|
+
details: {
|
|
455
|
+
dimension: 'abcde',
|
|
456
|
+
},
|
|
457
|
+
created_at: '2023-08-21T16:48:56.950482+00:00',
|
|
458
|
+
},
|
|
411
459
|
],
|
|
412
460
|
nodeMaterializations: [
|
|
413
461
|
{
|
package/src/styles/index.css
CHANGED
|
@@ -1113,3 +1113,92 @@ pre {
|
|
|
1113
1113
|
font-size: 100%;
|
|
1114
1114
|
margin-bottom: 5px;
|
|
1115
1115
|
}
|
|
1116
|
+
|
|
1117
|
+
.history {
|
|
1118
|
+
padding: 20px;
|
|
1119
|
+
list-style: none;
|
|
1120
|
+
border-top-left-radius: 6px;
|
|
1121
|
+
border-top-right-radius: 6px;
|
|
1122
|
+
border-bottom-width: 1px;
|
|
1123
|
+
border-bottom-style: solid;
|
|
1124
|
+
border-color: #748f7c75;
|
|
1125
|
+
display: grid;
|
|
1126
|
+
|
|
1127
|
+
position: relative;
|
|
1128
|
+
min-height: 2rem;
|
|
1129
|
+
font-size: 14px;
|
|
1130
|
+
grid-template-rows: repeat(3, auto);
|
|
1131
|
+
grid-template-areas:
|
|
1132
|
+
'description description details'
|
|
1133
|
+
'description description details'
|
|
1134
|
+
'metadata metadata details';
|
|
1135
|
+
grid-template-columns: min-content minmax(30%, 1fr);
|
|
1136
|
+
gap: 4px;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
.history-border {
|
|
1140
|
+
display: block;
|
|
1141
|
+
list-style-type: disc;
|
|
1142
|
+
padding-inline-start: 0;
|
|
1143
|
+
unicode-bidi: isolate;
|
|
1144
|
+
border-radius: 6px !important;
|
|
1145
|
+
border: 1px solid #748f7c75;
|
|
1146
|
+
margin-block-start: 1em;
|
|
1147
|
+
margin-block-end: 1em;
|
|
1148
|
+
margin-inline-start: 0;
|
|
1149
|
+
margin-inline-end: 0;
|
|
1150
|
+
}
|
|
1151
|
+
.history-left {
|
|
1152
|
+
grid-area: description;
|
|
1153
|
+
-webkit-box-flex: 2;
|
|
1154
|
+
flex-grow: 2;
|
|
1155
|
+
display: inline;
|
|
1156
|
+
font-size: 16px;
|
|
1157
|
+
}
|
|
1158
|
+
.history-small {
|
|
1159
|
+
display: flex;
|
|
1160
|
+
flex-direction: row;
|
|
1161
|
+
-webkit-box-align: center;
|
|
1162
|
+
align-items: center;
|
|
1163
|
+
gap: 5px;
|
|
1164
|
+
padding-right: 8px;
|
|
1165
|
+
-webkit-box-flex: 1;
|
|
1166
|
+
flex-grow: 1;
|
|
1167
|
+
overflow: hidden;
|
|
1168
|
+
grid-area: metadata;
|
|
1169
|
+
font-size: 12px;
|
|
1170
|
+
}
|
|
1171
|
+
.history-right {
|
|
1172
|
+
display: flex;
|
|
1173
|
+
flex-flow: wrap;
|
|
1174
|
+
padding-top: 10px;
|
|
1175
|
+
gap: 19px;
|
|
1176
|
+
grid-area: details;
|
|
1177
|
+
-webkit-box-flex: 2;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
.version {
|
|
1181
|
+
color: #055d20;
|
|
1182
|
+
font-weight: bold;
|
|
1183
|
+
font-size: 13px;
|
|
1184
|
+
border: solid #055d20 1px;
|
|
1185
|
+
background-color: #ccf7e545;
|
|
1186
|
+
margin: 0.25rem;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
.highlight-svg:hover {
|
|
1190
|
+
filter: invert(56%) sepia(68%) saturate(4415%) hue-rotate(162deg)
|
|
1191
|
+
brightness(96%) contrast(101%);
|
|
1192
|
+
text-decoration: none;
|
|
1193
|
+
}
|
|
1194
|
+
.no-change {
|
|
1195
|
+
padding: 10px;
|
|
1196
|
+
display: inline-block;
|
|
1197
|
+
margin-top: -25px;
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
.no-change-banner {
|
|
1201
|
+
color: #055d20;
|
|
1202
|
+
text-transform: uppercase;
|
|
1203
|
+
padding-left: 10px;
|
|
1204
|
+
}
|
|
@@ -254,6 +254,15 @@ form {
|
|
|
254
254
|
}
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
+
.warning {
|
|
258
|
+
background-color: rgb(253, 248, 242);
|
|
259
|
+
color: rgb(190, 105, 37);
|
|
260
|
+
svg {
|
|
261
|
+
filter: invert(16%) sepia(68%) saturate(2827%) hue-rotate(344deg)
|
|
262
|
+
brightness(96%) contrast(100%);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
257
266
|
.SourceCreationInput {
|
|
258
267
|
margin: 0.5rem 0;
|
|
259
268
|
display: inline-grid;
|