datajunction-ui 0.0.21 → 0.0.23-dev2
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 +11 -4
- package/src/app/components/NotificationBell.tsx +11 -5
- package/src/app/components/UserMenu.tsx +3 -11
- package/src/app/components/__tests__/NotificationBell.test.tsx +17 -6
- package/src/app/components/__tests__/UserMenu.test.tsx +10 -3
- package/src/app/index.tsx +92 -85
- package/src/app/pages/AddEditNodePage/OwnersField.jsx +2 -3
- package/src/app/pages/NamespacePage/index.jsx +2 -4
- package/src/app/pages/NodePage/ClientCodePopover.jsx +27 -5
- package/src/app/pages/NodePage/NodeDependenciesTab.jsx +47 -45
- package/src/app/pages/NodePage/NodeInfoTab.jsx +73 -15
- package/src/app/pages/NodePage/__tests__/NodeDependenciesTab.test.jsx +13 -7
- package/src/app/pages/NodePage/__tests__/NodePage.test.jsx +23 -13
- package/src/app/pages/NodePage/index.jsx +14 -19
- package/src/app/pages/SettingsPage/__tests__/index.test.jsx +4 -1
- package/src/app/pages/SettingsPage/index.jsx +6 -6
- package/src/app/providers/UserProvider.tsx +78 -0
- package/src/app/services/DJService.js +43 -0
- package/src/app/services/__tests__/DJService.test.jsx +76 -0
- package/src/styles/nav-bar.css +1 -1
- package/webpack.config.js +3 -1
|
@@ -690,6 +690,49 @@ export const DataJunctionAPI = {
|
|
|
690
690
|
).json();
|
|
691
691
|
},
|
|
692
692
|
|
|
693
|
+
// GraphQL-based upstream/downstream queries - more efficient as they only fetch needed fields
|
|
694
|
+
upstreamsGQL: async function (nodeNames) {
|
|
695
|
+
const names = Array.isArray(nodeNames) ? nodeNames : [nodeNames];
|
|
696
|
+
const query = `
|
|
697
|
+
query GetUpstreamNodes($nodeNames: [String!]!) {
|
|
698
|
+
upstreamNodes(nodeNames: $nodeNames) {
|
|
699
|
+
name
|
|
700
|
+
type
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
`;
|
|
704
|
+
const results = await (
|
|
705
|
+
await fetch(DJ_GQL, {
|
|
706
|
+
method: 'POST',
|
|
707
|
+
headers: { 'Content-Type': 'application/json' },
|
|
708
|
+
credentials: 'include',
|
|
709
|
+
body: JSON.stringify({ query, variables: { nodeNames: names } }),
|
|
710
|
+
})
|
|
711
|
+
).json();
|
|
712
|
+
return results.data?.upstreamNodes || [];
|
|
713
|
+
},
|
|
714
|
+
|
|
715
|
+
downstreamsGQL: async function (nodeNames) {
|
|
716
|
+
const names = Array.isArray(nodeNames) ? nodeNames : [nodeNames];
|
|
717
|
+
const query = `
|
|
718
|
+
query GetDownstreamNodes($nodeNames: [String!]!) {
|
|
719
|
+
downstreamNodes(nodeNames: $nodeNames) {
|
|
720
|
+
name
|
|
721
|
+
type
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
`;
|
|
725
|
+
const results = await (
|
|
726
|
+
await fetch(DJ_GQL, {
|
|
727
|
+
method: 'POST',
|
|
728
|
+
headers: { 'Content-Type': 'application/json' },
|
|
729
|
+
credentials: 'include',
|
|
730
|
+
body: JSON.stringify({ query, variables: { nodeNames: names } }),
|
|
731
|
+
})
|
|
732
|
+
).json();
|
|
733
|
+
return results.data?.downstreamNodes || [];
|
|
734
|
+
},
|
|
735
|
+
|
|
693
736
|
node_dag: async function (name) {
|
|
694
737
|
return await (
|
|
695
738
|
await fetch(`${DJ_URL}/nodes/${name}/dag/`, {
|
|
@@ -324,6 +324,82 @@ describe('DataJunctionAPI', () => {
|
|
|
324
324
|
);
|
|
325
325
|
});
|
|
326
326
|
|
|
327
|
+
it('calls upstreamsGQL correctly with single node', async () => {
|
|
328
|
+
const nodeName = 'sampleNode';
|
|
329
|
+
fetch.mockResponseOnce(
|
|
330
|
+
JSON.stringify({
|
|
331
|
+
data: { upstreamNodes: [{ name: 'upstream1', type: 'SOURCE' }] },
|
|
332
|
+
}),
|
|
333
|
+
);
|
|
334
|
+
const result = await DataJunctionAPI.upstreamsGQL(nodeName);
|
|
335
|
+
expect(fetch).toHaveBeenCalledWith(
|
|
336
|
+
`${DJ_URL}/graphql`,
|
|
337
|
+
expect.objectContaining({
|
|
338
|
+
method: 'POST',
|
|
339
|
+
credentials: 'include',
|
|
340
|
+
headers: { 'Content-Type': 'application/json' },
|
|
341
|
+
}),
|
|
342
|
+
);
|
|
343
|
+
expect(result).toEqual([{ name: 'upstream1', type: 'SOURCE' }]);
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
it('calls upstreamsGQL correctly with multiple nodes', async () => {
|
|
347
|
+
const nodeNames = ['node1', 'node2'];
|
|
348
|
+
fetch.mockResponseOnce(
|
|
349
|
+
JSON.stringify({
|
|
350
|
+
data: {
|
|
351
|
+
upstreamNodes: [
|
|
352
|
+
{ name: 'upstream1', type: 'SOURCE' },
|
|
353
|
+
{ name: 'upstream2', type: 'TRANSFORM' },
|
|
354
|
+
],
|
|
355
|
+
},
|
|
356
|
+
}),
|
|
357
|
+
);
|
|
358
|
+
const result = await DataJunctionAPI.upstreamsGQL(nodeNames);
|
|
359
|
+
expect(result).toEqual([
|
|
360
|
+
{ name: 'upstream1', type: 'SOURCE' },
|
|
361
|
+
{ name: 'upstream2', type: 'TRANSFORM' },
|
|
362
|
+
]);
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
it('calls downstreamsGQL correctly with single node', async () => {
|
|
366
|
+
const nodeName = 'sampleNode';
|
|
367
|
+
fetch.mockResponseOnce(
|
|
368
|
+
JSON.stringify({
|
|
369
|
+
data: { downstreamNodes: [{ name: 'downstream1', type: 'METRIC' }] },
|
|
370
|
+
}),
|
|
371
|
+
);
|
|
372
|
+
const result = await DataJunctionAPI.downstreamsGQL(nodeName);
|
|
373
|
+
expect(fetch).toHaveBeenCalledWith(
|
|
374
|
+
`${DJ_URL}/graphql`,
|
|
375
|
+
expect.objectContaining({
|
|
376
|
+
method: 'POST',
|
|
377
|
+
credentials: 'include',
|
|
378
|
+
headers: { 'Content-Type': 'application/json' },
|
|
379
|
+
}),
|
|
380
|
+
);
|
|
381
|
+
expect(result).toEqual([{ name: 'downstream1', type: 'METRIC' }]);
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
it('calls downstreamsGQL correctly with multiple nodes', async () => {
|
|
385
|
+
const nodeNames = ['node1', 'node2'];
|
|
386
|
+
fetch.mockResponseOnce(
|
|
387
|
+
JSON.stringify({
|
|
388
|
+
data: {
|
|
389
|
+
downstreamNodes: [
|
|
390
|
+
{ name: 'downstream1', type: 'METRIC' },
|
|
391
|
+
{ name: 'downstream2', type: 'CUBE' },
|
|
392
|
+
],
|
|
393
|
+
},
|
|
394
|
+
}),
|
|
395
|
+
);
|
|
396
|
+
const result = await DataJunctionAPI.downstreamsGQL(nodeNames);
|
|
397
|
+
expect(result).toEqual([
|
|
398
|
+
{ name: 'downstream1', type: 'METRIC' },
|
|
399
|
+
{ name: 'downstream2', type: 'CUBE' },
|
|
400
|
+
]);
|
|
401
|
+
});
|
|
402
|
+
|
|
327
403
|
it('calls node_dag correctly', async () => {
|
|
328
404
|
const nodeName = 'sampleNode';
|
|
329
405
|
fetch.mockResponseOnce(JSON.stringify({}));
|
package/src/styles/nav-bar.css
CHANGED
package/webpack.config.js
CHANGED
|
@@ -10,6 +10,8 @@ var babelOptions = {
|
|
|
10
10
|
presets: ['@babel/preset-react'],
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
+
const isProduction = process.env.NODE_ENV === 'production';
|
|
14
|
+
|
|
13
15
|
module.exports = {
|
|
14
16
|
cache: true,
|
|
15
17
|
entry: {
|
|
@@ -17,7 +19,7 @@ module.exports = {
|
|
|
17
19
|
vendor: ['events', 'react', 'react-dom'],
|
|
18
20
|
},
|
|
19
21
|
target: 'web',
|
|
20
|
-
mode: 'development',
|
|
22
|
+
mode: isProduction ? 'production' : 'development',
|
|
21
23
|
stats: 'minimal',
|
|
22
24
|
output: {
|
|
23
25
|
path: path.resolve(__dirname, './dist'),
|