datajunction-ui 0.0.1-rc.24 → 0.0.1-rc.26
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/.env +1 -0
- package/package.json +3 -2
- package/src/app/components/Tab.jsx +0 -1
- package/src/app/constants.js +2 -2
- package/src/app/icons/LoadingIcon.jsx +14 -0
- package/src/app/index.tsx +11 -1
- package/src/app/pages/AddEditNodePage/__tests__/AddEditNodePageFormFailed.test.jsx +28 -2
- package/src/app/pages/AddEditNodePage/__tests__/AddEditNodePageFormSuccess.test.jsx +44 -9
- package/src/app/pages/AddEditNodePage/__tests__/__snapshots__/AddEditNodePageFormFailed.test.jsx.snap +1 -0
- package/src/app/pages/AddEditNodePage/__tests__/__snapshots__/AddEditNodePageFormSuccess.test.jsx.snap +0 -50
- package/src/app/pages/AddEditNodePage/__tests__/index.test.jsx +2 -0
- package/src/app/pages/AddEditNodePage/index.jsx +60 -6
- package/src/app/pages/AddEditTagPage/Loadable.jsx +16 -0
- package/src/app/pages/AddEditTagPage/__tests__/AddEditTagPage.test.jsx +107 -0
- package/src/app/pages/AddEditTagPage/index.jsx +132 -0
- package/src/app/pages/LoginPage/LoginForm.jsx +124 -0
- package/src/app/pages/LoginPage/SignupForm.jsx +156 -0
- package/src/app/pages/LoginPage/__tests__/index.test.jsx +34 -2
- package/src/app/pages/LoginPage/index.jsx +9 -82
- package/src/app/pages/NamespacePage/index.jsx +5 -0
- package/src/app/pages/NodePage/AddBackfillPopover.jsx +166 -0
- package/src/app/pages/NodePage/AddMaterializationPopover.jsx +161 -0
- package/src/app/pages/NodePage/EditColumnPopover.jsx +1 -1
- package/src/app/pages/NodePage/LinkDimensionPopover.jsx +0 -1
- package/src/app/pages/NodePage/NodeColumnTab.jsx +102 -25
- package/src/app/pages/NodePage/NodeInfoTab.jsx +33 -23
- package/src/app/pages/NodePage/NodeMaterializationTab.jsx +158 -99
- package/src/app/pages/NodePage/PartitionColumnPopover.jsx +153 -0
- package/src/app/pages/NodePage/__tests__/AddBackfillPopover.test.jsx +47 -0
- package/src/app/pages/NodePage/__tests__/NodePage.test.jsx +47 -17
- package/src/app/pages/NodePage/__tests__/__snapshots__/NodePage.test.jsx.snap +101 -100
- package/src/app/pages/RegisterTablePage/__tests__/__snapshots__/RegisterTablePage.test.jsx.snap +1 -0
- package/src/app/pages/Root/index.tsx +1 -1
- package/src/app/pages/TagPage/Loadable.jsx +16 -0
- package/src/app/pages/TagPage/__tests__/TagPage.test.jsx +70 -0
- package/src/app/pages/TagPage/index.jsx +79 -0
- package/src/app/services/DJService.js +166 -1
- package/src/app/services/__tests__/DJService.test.jsx +196 -1
- package/src/mocks/mockNodes.jsx +64 -31
- package/src/styles/dag.css +4 -0
- package/src/styles/index.css +89 -1
- package/src/styles/loading.css +34 -0
- package/src/styles/login.css +17 -3
- package/src/utils/form.jsx +2 -2
|
@@ -104,9 +104,6 @@ exports[`<NodePage /> renders the NodeMaterialization tab with materializations
|
|
|
104
104
|
<th
|
|
105
105
|
class="text-start"
|
|
106
106
|
>
|
|
107
|
-
Name
|
|
108
|
-
</th>
|
|
109
|
-
<th>
|
|
110
107
|
Schedule
|
|
111
108
|
</th>
|
|
112
109
|
<th>
|
|
@@ -131,11 +128,22 @@ exports[`<NodePage /> renders the NodeMaterialization tab with materializations
|
|
|
131
128
|
<td
|
|
132
129
|
class="text-start node_name"
|
|
133
130
|
>
|
|
134
|
-
<
|
|
135
|
-
|
|
131
|
+
<span
|
|
132
|
+
class="badge cron"
|
|
136
133
|
>
|
|
137
|
-
|
|
138
|
-
</
|
|
134
|
+
0 * * * *
|
|
135
|
+
</span>
|
|
136
|
+
<div
|
|
137
|
+
class="cron-description"
|
|
138
|
+
>
|
|
139
|
+
Every hour
|
|
140
|
+
|
|
141
|
+
</div>
|
|
142
|
+
</td>
|
|
143
|
+
<td>
|
|
144
|
+
spark
|
|
145
|
+
<br />
|
|
146
|
+
2.4.4
|
|
139
147
|
<button
|
|
140
148
|
aria-label="code-button"
|
|
141
149
|
class="code-button"
|
|
@@ -222,79 +230,7 @@ exports[`<NodePage /> renders the NodeMaterialization tab with materializations
|
|
|
222
230
|
</pre>
|
|
223
231
|
</div>
|
|
224
232
|
</td>
|
|
225
|
-
<td
|
|
226
|
-
<span
|
|
227
|
-
class="badge cron"
|
|
228
|
-
>
|
|
229
|
-
0 * * * *
|
|
230
|
-
</span>
|
|
231
|
-
<div
|
|
232
|
-
class="cron-description"
|
|
233
|
-
>
|
|
234
|
-
Every hour
|
|
235
|
-
|
|
236
|
-
</div>
|
|
237
|
-
</td>
|
|
238
|
-
<td>
|
|
239
|
-
spark
|
|
240
|
-
<br />
|
|
241
|
-
2.4.4
|
|
242
|
-
</td>
|
|
243
|
-
<td>
|
|
244
|
-
<div
|
|
245
|
-
class="partition__full"
|
|
246
|
-
>
|
|
247
|
-
<div
|
|
248
|
-
class="partition__header"
|
|
249
|
-
>
|
|
250
|
-
country
|
|
251
|
-
</div>
|
|
252
|
-
<div
|
|
253
|
-
class="partition__body"
|
|
254
|
-
>
|
|
255
|
-
<span
|
|
256
|
-
class="badge partition_value"
|
|
257
|
-
>
|
|
258
|
-
DE
|
|
259
|
-
</span>
|
|
260
|
-
<span
|
|
261
|
-
class="badge partition_value"
|
|
262
|
-
>
|
|
263
|
-
MY
|
|
264
|
-
</span>
|
|
265
|
-
</div>
|
|
266
|
-
</div>
|
|
267
|
-
<div
|
|
268
|
-
class="partition__full"
|
|
269
|
-
>
|
|
270
|
-
<div
|
|
271
|
-
class="partition__header"
|
|
272
|
-
>
|
|
273
|
-
contractor_id
|
|
274
|
-
</div>
|
|
275
|
-
<div
|
|
276
|
-
class="partition__body"
|
|
277
|
-
>
|
|
278
|
-
<div>
|
|
279
|
-
<span
|
|
280
|
-
class="badge partition_value"
|
|
281
|
-
>
|
|
282
|
-
<span
|
|
283
|
-
class="badge partition_value"
|
|
284
|
-
>
|
|
285
|
-
1
|
|
286
|
-
</span>
|
|
287
|
-
to
|
|
288
|
-
<span
|
|
289
|
-
class="badge partition_value"
|
|
290
|
-
>
|
|
291
|
-
10
|
|
292
|
-
</span>
|
|
293
|
-
</span>
|
|
294
|
-
</div>
|
|
295
|
-
</div>
|
|
296
|
-
</div>
|
|
297
|
-
</td>
|
|
233
|
+
<td />
|
|
298
234
|
<td>
|
|
299
235
|
<div
|
|
300
236
|
class="table__full"
|
|
@@ -356,35 +292,100 @@ exports[`<NodePage /> renders the NodeMaterialization tab with materializations
|
|
|
356
292
|
</div>
|
|
357
293
|
</td>
|
|
358
294
|
<td>
|
|
359
|
-
<
|
|
360
|
-
class="
|
|
295
|
+
<a
|
|
296
|
+
class="partitionLink"
|
|
361
297
|
>
|
|
362
298
|
<div
|
|
363
|
-
class="
|
|
299
|
+
class="partition__full"
|
|
364
300
|
>
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
301
|
+
<div
|
|
302
|
+
class="partition__header"
|
|
303
|
+
/>
|
|
304
|
+
<div
|
|
305
|
+
class="partition__body"
|
|
306
|
+
>
|
|
371
307
|
<span
|
|
372
308
|
class="badge partition_value"
|
|
373
309
|
>
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
class="badge partition_value"
|
|
382
|
-
>
|
|
383
|
-
20020101
|
|
384
|
-
</span>
|
|
310
|
+
20230101
|
|
311
|
+
</span>
|
|
312
|
+
to
|
|
313
|
+
<span
|
|
314
|
+
class="badge partition_value"
|
|
315
|
+
>
|
|
316
|
+
20230102
|
|
385
317
|
</span>
|
|
386
318
|
</div>
|
|
387
319
|
</div>
|
|
320
|
+
</a>
|
|
321
|
+
<button
|
|
322
|
+
aria-label="AddBackfill"
|
|
323
|
+
class="edit_button"
|
|
324
|
+
tabindex="0"
|
|
325
|
+
>
|
|
326
|
+
<span
|
|
327
|
+
class="add_node"
|
|
328
|
+
>
|
|
329
|
+
+ Add Backfill
|
|
330
|
+
</span>
|
|
331
|
+
</button>
|
|
332
|
+
<div
|
|
333
|
+
class="fade modal-backdrop in"
|
|
334
|
+
style="display: none;"
|
|
335
|
+
/>
|
|
336
|
+
<div
|
|
337
|
+
aria-label="client-code"
|
|
338
|
+
class="centerPopover"
|
|
339
|
+
role="dialog"
|
|
340
|
+
style="display: none; width: 50%;"
|
|
341
|
+
>
|
|
342
|
+
<form
|
|
343
|
+
action="#"
|
|
344
|
+
>
|
|
345
|
+
<h2>
|
|
346
|
+
Run Backfill
|
|
347
|
+
</h2>
|
|
348
|
+
<span
|
|
349
|
+
data-testid="edit-partition"
|
|
350
|
+
>
|
|
351
|
+
<label
|
|
352
|
+
for="engine"
|
|
353
|
+
style="padding-bottom: 1rem;"
|
|
354
|
+
>
|
|
355
|
+
Engine
|
|
356
|
+
</label>
|
|
357
|
+
<select
|
|
358
|
+
disabled=""
|
|
359
|
+
id="engine"
|
|
360
|
+
name="engine"
|
|
361
|
+
>
|
|
362
|
+
<option
|
|
363
|
+
value="spark"
|
|
364
|
+
>
|
|
365
|
+
spark
|
|
366
|
+
|
|
367
|
+
2.4.4
|
|
368
|
+
</option>
|
|
369
|
+
</select>
|
|
370
|
+
</span>
|
|
371
|
+
<br />
|
|
372
|
+
<br />
|
|
373
|
+
<label
|
|
374
|
+
for="partition"
|
|
375
|
+
style="padding-bottom: 1rem;"
|
|
376
|
+
>
|
|
377
|
+
Partition Range
|
|
378
|
+
</label>
|
|
379
|
+
<br />
|
|
380
|
+
<button
|
|
381
|
+
aria-hidden="false"
|
|
382
|
+
aria-label="SaveEditColumn"
|
|
383
|
+
class="add_node"
|
|
384
|
+
type="submit"
|
|
385
|
+
>
|
|
386
|
+
Save
|
|
387
|
+
</button>
|
|
388
|
+
</form>
|
|
388
389
|
</div>
|
|
389
390
|
</td>
|
|
390
391
|
<td>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asynchronously loads the component for the Node page
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as React from 'react';
|
|
6
|
+
import { lazyLoad } from '../../../utils/loadable';
|
|
7
|
+
|
|
8
|
+
export const TagPage = () => {
|
|
9
|
+
return lazyLoad(
|
|
10
|
+
() => import('./index'),
|
|
11
|
+
module => module.TagPage,
|
|
12
|
+
{
|
|
13
|
+
fallback: <div></div>,
|
|
14
|
+
},
|
|
15
|
+
)();
|
|
16
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { screen, waitFor } from '@testing-library/react';
|
|
3
|
+
import fetchMock from 'jest-fetch-mock';
|
|
4
|
+
import { render } from '../../../../setupTests';
|
|
5
|
+
import { MemoryRouter, Route, Routes } from 'react-router-dom';
|
|
6
|
+
import DJClientContext from '../../../providers/djclient';
|
|
7
|
+
import { TagPage } from '../index';
|
|
8
|
+
|
|
9
|
+
describe('<TagPage />', () => {
|
|
10
|
+
const initializeMockDJClient = () => {
|
|
11
|
+
return {
|
|
12
|
+
DataJunctionAPI: {
|
|
13
|
+
getTag: jest.fn(),
|
|
14
|
+
listNodesForTag: jest.fn(),
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const mockDjClient = initializeMockDJClient();
|
|
20
|
+
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
fetchMock.resetMocks();
|
|
23
|
+
jest.clearAllMocks();
|
|
24
|
+
window.scrollTo = jest.fn();
|
|
25
|
+
|
|
26
|
+
mockDjClient.DataJunctionAPI.getTag.mockReturnValue({
|
|
27
|
+
name: 'domains.com',
|
|
28
|
+
tag_type: 'domains',
|
|
29
|
+
description: 'Top-level domain .com',
|
|
30
|
+
});
|
|
31
|
+
mockDjClient.DataJunctionAPI.listNodesForTag.mockReturnValue([
|
|
32
|
+
{
|
|
33
|
+
name: 'random.node_a',
|
|
34
|
+
type: 'metric',
|
|
35
|
+
display_name: 'Node A',
|
|
36
|
+
},
|
|
37
|
+
]);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const renderTagsPage = element => {
|
|
41
|
+
return render(
|
|
42
|
+
<MemoryRouter initialEntries={['/tags/:name']}>
|
|
43
|
+
<Routes>
|
|
44
|
+
<Route path="tags/:name" element={element} />
|
|
45
|
+
</Routes>
|
|
46
|
+
</MemoryRouter>,
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const testElement = djClient => {
|
|
51
|
+
return (
|
|
52
|
+
<DJClientContext.Provider value={djClient}>
|
|
53
|
+
<TagPage />
|
|
54
|
+
</DJClientContext.Provider>
|
|
55
|
+
);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
it('renders the tag page correctly', async () => {
|
|
59
|
+
const element = testElement(mockDjClient);
|
|
60
|
+
renderTagsPage(element);
|
|
61
|
+
await waitFor(() => {
|
|
62
|
+
expect(mockDjClient.DataJunctionAPI.getTag).toHaveBeenCalledTimes(1);
|
|
63
|
+
expect(
|
|
64
|
+
mockDjClient.DataJunctionAPI.listNodesForTag,
|
|
65
|
+
).toHaveBeenCalledTimes(1);
|
|
66
|
+
});
|
|
67
|
+
expect(screen.getByText('Nodes')).toBeInTheDocument();
|
|
68
|
+
expect(screen.getByText('Node A')).toBeInTheDocument();
|
|
69
|
+
}, 60000);
|
|
70
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* For a given tag, displays nodes tagged with it
|
|
3
|
+
*/
|
|
4
|
+
import NamespaceHeader from '../../components/NamespaceHeader';
|
|
5
|
+
import React, { useContext, useEffect, useState } from 'react';
|
|
6
|
+
import 'styles/node-creation.scss';
|
|
7
|
+
import DJClientContext from '../../providers/djclient';
|
|
8
|
+
import { useParams } from 'react-router-dom';
|
|
9
|
+
|
|
10
|
+
export function TagPage() {
|
|
11
|
+
const [nodes, setNodes] = useState([]);
|
|
12
|
+
const [tag, setTag] = useState([]);
|
|
13
|
+
|
|
14
|
+
const { name } = useParams();
|
|
15
|
+
|
|
16
|
+
const djClient = useContext(DJClientContext).DataJunctionAPI;
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
const fetchData = async () => {
|
|
19
|
+
const data = await djClient.listNodesForTag(name);
|
|
20
|
+
const tagData = await djClient.getTag(name);
|
|
21
|
+
setNodes(data);
|
|
22
|
+
setTag(tagData);
|
|
23
|
+
};
|
|
24
|
+
fetchData().catch(console.error);
|
|
25
|
+
}, [djClient, name]);
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<div className="mid">
|
|
29
|
+
<NamespaceHeader namespace="" />
|
|
30
|
+
<div className="card">
|
|
31
|
+
<div className="card-header">
|
|
32
|
+
<h3
|
|
33
|
+
className="card-title align-items-start flex-column"
|
|
34
|
+
style={{ display: 'inline-block' }}
|
|
35
|
+
>
|
|
36
|
+
Tag
|
|
37
|
+
</h3>
|
|
38
|
+
<div>
|
|
39
|
+
<div style={{ marginBottom: '1.5rem' }}>
|
|
40
|
+
<h6 className="mb-0 w-100">Display Name</h6>
|
|
41
|
+
<p className="mb-0 opacity-75">{tag.display_name}</p>
|
|
42
|
+
</div>
|
|
43
|
+
<div style={{ marginBottom: '1.5rem' }}>
|
|
44
|
+
<h6 className="mb-0 w-100">Name</h6>
|
|
45
|
+
<p className="mb-0 opacity-75">{name}</p>
|
|
46
|
+
</div>
|
|
47
|
+
<div style={{ marginBottom: '1.5rem' }}>
|
|
48
|
+
<h6 className="mb-0 w-100">Tag Type</h6>
|
|
49
|
+
<p className="mb-0 opacity-75">{tag.tag_type}</p>
|
|
50
|
+
</div>
|
|
51
|
+
<div style={{ marginBottom: '1.5rem' }}>
|
|
52
|
+
<h6 className="mb-0 w-100">Description</h6>
|
|
53
|
+
<p className="mb-0 opacity-75">{tag.description}</p>
|
|
54
|
+
</div>
|
|
55
|
+
<div style={{ marginBottom: '1.5rem' }}>
|
|
56
|
+
<h6 className="mb-0 w-100">Nodes</h6>
|
|
57
|
+
<div className={`list-group-item`}>
|
|
58
|
+
{nodes?.map(node => (
|
|
59
|
+
<div
|
|
60
|
+
className="button-3 cube-element"
|
|
61
|
+
key={node.name}
|
|
62
|
+
role="cell"
|
|
63
|
+
aria-label="CubeElement"
|
|
64
|
+
aria-hidden="false"
|
|
65
|
+
>
|
|
66
|
+
<a href={`/nodes/${node.name}`}>{node.display_name}</a>
|
|
67
|
+
<span className={`badge node_type__${node.type}`}>
|
|
68
|
+
{node.type}
|
|
69
|
+
</span>
|
|
70
|
+
</div>
|
|
71
|
+
))}
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
@@ -12,7 +12,7 @@ export const DataJunctionAPI = {
|
|
|
12
12
|
},
|
|
13
13
|
|
|
14
14
|
logout: async function () {
|
|
15
|
-
await await fetch(`${DJ_URL}/
|
|
15
|
+
await await fetch(`${DJ_URL}/logout/`, {
|
|
16
16
|
credentials: 'include',
|
|
17
17
|
method: 'POST',
|
|
18
18
|
});
|
|
@@ -26,6 +26,14 @@ export const DataJunctionAPI = {
|
|
|
26
26
|
).json();
|
|
27
27
|
},
|
|
28
28
|
|
|
29
|
+
engines: async function () {
|
|
30
|
+
return await (
|
|
31
|
+
await fetch(`${DJ_URL}/engines`, {
|
|
32
|
+
credentials: 'include',
|
|
33
|
+
})
|
|
34
|
+
).json();
|
|
35
|
+
},
|
|
36
|
+
|
|
29
37
|
node: async function (name) {
|
|
30
38
|
const data = await (
|
|
31
39
|
await fetch(`${DJ_URL}/nodes/${name}/`, {
|
|
@@ -497,4 +505,161 @@ export const DataJunctionAPI = {
|
|
|
497
505
|
});
|
|
498
506
|
return { status: response.status, json: await response.json() };
|
|
499
507
|
},
|
|
508
|
+
listTags: async function () {
|
|
509
|
+
const response = await fetch(`${DJ_URL}/tags`, {
|
|
510
|
+
method: 'GET',
|
|
511
|
+
headers: {
|
|
512
|
+
'Content-Type': 'application/json',
|
|
513
|
+
},
|
|
514
|
+
credentials: 'include',
|
|
515
|
+
});
|
|
516
|
+
return await response.json();
|
|
517
|
+
},
|
|
518
|
+
getTag: async function (tagName) {
|
|
519
|
+
const response = await fetch(`${DJ_URL}/tags/${tagName}`, {
|
|
520
|
+
method: 'GET',
|
|
521
|
+
headers: {
|
|
522
|
+
'Content-Type': 'application/json',
|
|
523
|
+
},
|
|
524
|
+
credentials: 'include',
|
|
525
|
+
});
|
|
526
|
+
return await response.json();
|
|
527
|
+
},
|
|
528
|
+
listNodesForTag: async function (tagName) {
|
|
529
|
+
const response = await fetch(`${DJ_URL}/tags/${tagName}/nodes`, {
|
|
530
|
+
method: 'GET',
|
|
531
|
+
headers: {
|
|
532
|
+
'Content-Type': 'application/json',
|
|
533
|
+
},
|
|
534
|
+
credentials: 'include',
|
|
535
|
+
});
|
|
536
|
+
return await response.json();
|
|
537
|
+
},
|
|
538
|
+
tagsNode: async function (nodeName, tagNames) {
|
|
539
|
+
const url = tagNames
|
|
540
|
+
.map(value => `tag_names=${encodeURIComponent(value)}`)
|
|
541
|
+
.join('&');
|
|
542
|
+
const response = await fetch(`${DJ_URL}/nodes/${nodeName}/tags?${url}`, {
|
|
543
|
+
method: 'POST',
|
|
544
|
+
headers: {
|
|
545
|
+
'Content-Type': 'application/json',
|
|
546
|
+
},
|
|
547
|
+
credentials: 'include',
|
|
548
|
+
});
|
|
549
|
+
return { status: response.status, json: await response.json() };
|
|
550
|
+
},
|
|
551
|
+
addTag: async function (name, displayName, tagType, description) {
|
|
552
|
+
const response = await fetch(`${DJ_URL}/tags`, {
|
|
553
|
+
method: 'POST',
|
|
554
|
+
headers: {
|
|
555
|
+
'Content-Type': 'application/json',
|
|
556
|
+
},
|
|
557
|
+
body: JSON.stringify({
|
|
558
|
+
name: name,
|
|
559
|
+
display_name: displayName,
|
|
560
|
+
tag_type: tagType,
|
|
561
|
+
description: description,
|
|
562
|
+
}),
|
|
563
|
+
credentials: 'include',
|
|
564
|
+
});
|
|
565
|
+
return { status: response.status, json: await response.json() };
|
|
566
|
+
},
|
|
567
|
+
editTag: async function (name, description, displayName) {
|
|
568
|
+
const updates = {};
|
|
569
|
+
if (description) {
|
|
570
|
+
updates.description = description;
|
|
571
|
+
}
|
|
572
|
+
if (displayName) {
|
|
573
|
+
updates.display_name = displayName;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
const response = await fetch(`${DJ_URL}/tags/${name}`, {
|
|
577
|
+
method: 'PATCH',
|
|
578
|
+
headers: {
|
|
579
|
+
'Content-Type': 'application/json',
|
|
580
|
+
},
|
|
581
|
+
body: JSON.stringify(updates),
|
|
582
|
+
credentials: 'include',
|
|
583
|
+
});
|
|
584
|
+
return { status: response.status, json: await response.json() };
|
|
585
|
+
},
|
|
586
|
+
setPartition: async function (
|
|
587
|
+
nodeName,
|
|
588
|
+
columnName,
|
|
589
|
+
partitionType,
|
|
590
|
+
format,
|
|
591
|
+
granularity,
|
|
592
|
+
) {
|
|
593
|
+
const body = {
|
|
594
|
+
type_: partitionType,
|
|
595
|
+
};
|
|
596
|
+
if (format) {
|
|
597
|
+
body.format = format;
|
|
598
|
+
}
|
|
599
|
+
if (granularity) {
|
|
600
|
+
body.granularity = granularity;
|
|
601
|
+
}
|
|
602
|
+
const response = await fetch(
|
|
603
|
+
`${DJ_URL}/nodes/${nodeName}/columns/${columnName}/partition`,
|
|
604
|
+
{
|
|
605
|
+
method: 'POST',
|
|
606
|
+
headers: {
|
|
607
|
+
'Content-Type': 'application/json',
|
|
608
|
+
},
|
|
609
|
+
body: JSON.stringify(body),
|
|
610
|
+
credentials: 'include',
|
|
611
|
+
},
|
|
612
|
+
);
|
|
613
|
+
return { status: response.status, json: await response.json() };
|
|
614
|
+
},
|
|
615
|
+
materialize: async function (
|
|
616
|
+
nodeName,
|
|
617
|
+
engineName,
|
|
618
|
+
engineVersion,
|
|
619
|
+
schedule,
|
|
620
|
+
config,
|
|
621
|
+
) {
|
|
622
|
+
const response = await fetch(
|
|
623
|
+
`${DJ_URL}/nodes/${nodeName}/materialization`,
|
|
624
|
+
{
|
|
625
|
+
method: 'POST',
|
|
626
|
+
headers: {
|
|
627
|
+
'Content-Type': 'application/json',
|
|
628
|
+
},
|
|
629
|
+
body: JSON.stringify({
|
|
630
|
+
engine: {
|
|
631
|
+
name: engineName,
|
|
632
|
+
version: engineVersion,
|
|
633
|
+
},
|
|
634
|
+
schedule: schedule,
|
|
635
|
+
config: JSON.parse(config),
|
|
636
|
+
}),
|
|
637
|
+
credentials: 'include',
|
|
638
|
+
},
|
|
639
|
+
);
|
|
640
|
+
return { status: response.status, json: await response.json() };
|
|
641
|
+
},
|
|
642
|
+
runBackfill: async function (
|
|
643
|
+
nodeName,
|
|
644
|
+
materializationName,
|
|
645
|
+
partitionColumn,
|
|
646
|
+
from,
|
|
647
|
+
to,
|
|
648
|
+
) {
|
|
649
|
+
const response = await fetch(
|
|
650
|
+
`${DJ_URL}/nodes/${nodeName}/materializations/${materializationName}/backfill`,
|
|
651
|
+
{
|
|
652
|
+
method: 'POST',
|
|
653
|
+
headers: {
|
|
654
|
+
'Content-Type': 'application/json',
|
|
655
|
+
},
|
|
656
|
+
body: JSON.stringify({
|
|
657
|
+
column_name: partitionColumn,
|
|
658
|
+
range: [from, to],
|
|
659
|
+
}),
|
|
660
|
+
credentials: 'include',
|
|
661
|
+
},
|
|
662
|
+
);
|
|
663
|
+
return { status: response.status, json: await response.json() };
|
|
664
|
+
},
|
|
500
665
|
};
|