datajunction-ui 0.0.1-a108 → 0.0.1-a110

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.
Files changed (29) hide show
  1. package/package.json +3 -2
  2. package/src/app/icons/AlertIcon.jsx +1 -0
  3. package/src/app/icons/InvalidIcon.jsx +5 -3
  4. package/src/app/icons/NodeIcon.jsx +49 -0
  5. package/src/app/icons/ValidIcon.jsx +5 -3
  6. package/src/app/index.tsx +6 -0
  7. package/src/app/pages/CubeBuilderPage/DimensionsSelect.jsx +8 -10
  8. package/src/app/pages/CubeBuilderPage/MetricsSelect.jsx +6 -8
  9. package/src/app/pages/CubeBuilderPage/__tests__/index.test.jsx +39 -71
  10. package/src/app/pages/CubeBuilderPage/index.jsx +31 -7
  11. package/src/app/pages/OverviewPage/ByStatusPanel.jsx +69 -0
  12. package/src/app/pages/OverviewPage/DimensionNodeUsagePanel.jsx +48 -0
  13. package/src/app/pages/OverviewPage/GovernanceWarningsPanel.jsx +107 -0
  14. package/src/app/pages/OverviewPage/Loadable.jsx +16 -0
  15. package/src/app/pages/OverviewPage/NodesByTypePanel.jsx +63 -0
  16. package/src/app/pages/OverviewPage/OverviewPanel.jsx +94 -0
  17. package/src/app/pages/OverviewPage/TrendsPanel.jsx +66 -0
  18. package/src/app/pages/OverviewPage/__tests__/ByStatusPanel.test.jsx +36 -0
  19. package/src/app/pages/OverviewPage/__tests__/DimensionNodeUsagePanel.test.jsx +76 -0
  20. package/src/app/pages/OverviewPage/__tests__/GovernanceWarningsPanel.test.jsx +77 -0
  21. package/src/app/pages/OverviewPage/__tests__/NodesByTypePanel.test.jsx +86 -0
  22. package/src/app/pages/OverviewPage/__tests__/OverviewPanel.test.jsx +78 -0
  23. package/src/app/pages/OverviewPage/__tests__/TrendsPanel.test.jsx +120 -0
  24. package/src/app/pages/OverviewPage/__tests__/index.test.jsx +54 -0
  25. package/src/app/pages/OverviewPage/index.jsx +22 -0
  26. package/src/app/pages/RegisterTablePage/__tests__/__snapshots__/RegisterTablePage.test.jsx.snap +3 -2
  27. package/src/app/services/DJService.js +175 -0
  28. package/src/app/services/__tests__/DJService.test.jsx +364 -0
  29. package/src/styles/overview.css +72 -0
@@ -1138,4 +1138,368 @@ describe('DataJunctionAPI', () => {
1138
1138
  },
1139
1139
  );
1140
1140
  });
1141
+
1142
+ it('calls node_counts_by_type correctly', async () => {
1143
+ fetch.mockResponseOnce(
1144
+ JSON.stringify([
1145
+ [
1146
+ {
1147
+ value: 'cube',
1148
+ col: 'system.dj.node_type.type',
1149
+ },
1150
+ {
1151
+ value: 226,
1152
+ col: 'system.dj.number_of_nodes',
1153
+ },
1154
+ ],
1155
+ [
1156
+ {
1157
+ value: 'dimension',
1158
+ col: 'system.dj.node_type.type',
1159
+ },
1160
+ {
1161
+ value: 241,
1162
+ col: 'system.dj.number_of_nodes',
1163
+ },
1164
+ ],
1165
+ [
1166
+ {
1167
+ value: 'metric',
1168
+ col: 'system.dj.node_type.type',
1169
+ },
1170
+ {
1171
+ value: 2853,
1172
+ col: 'system.dj.number_of_nodes',
1173
+ },
1174
+ ],
1175
+ [
1176
+ {
1177
+ value: 'source',
1178
+ col: 'system.dj.node_type.type',
1179
+ },
1180
+ {
1181
+ value: 540,
1182
+ col: 'system.dj.number_of_nodes',
1183
+ },
1184
+ ],
1185
+ [
1186
+ {
1187
+ value: 'transform',
1188
+ col: 'system.dj.node_type.type',
1189
+ },
1190
+ {
1191
+ value: 663,
1192
+ col: 'system.dj.number_of_nodes',
1193
+ },
1194
+ ],
1195
+ ]),
1196
+ );
1197
+ const results = await DataJunctionAPI.system.node_counts_by_type();
1198
+ expect(fetch).toHaveBeenCalledWith(
1199
+ `${DJ_URL}/system/data/system.dj.number_of_nodes?dimensions=system.dj.node_type.type&filters=system.dj.is_active.active_id%3Dtrue&orderby=system.dj.node_type.type`,
1200
+ {
1201
+ credentials: 'include',
1202
+ },
1203
+ );
1204
+ expect(results).toEqual([
1205
+ { name: 'cube', value: 226 },
1206
+ { name: 'dimension', value: 241 },
1207
+ { name: 'metric', value: 2853 },
1208
+ { name: 'source', value: 540 },
1209
+ { name: 'transform', value: 663 },
1210
+ ]);
1211
+ });
1212
+
1213
+ it('calls node_counts_by_active correctly', async () => {
1214
+ fetch.mockResponseOnce(
1215
+ JSON.stringify([
1216
+ [
1217
+ {
1218
+ value: false,
1219
+ col: 'system.dj.is_active.active_id',
1220
+ },
1221
+ {
1222
+ value: 3136,
1223
+ col: 'system.dj.number_of_nodes',
1224
+ },
1225
+ ],
1226
+ [
1227
+ {
1228
+ value: true,
1229
+ col: 'system.dj.is_active.active_id',
1230
+ },
1231
+ {
1232
+ value: 4523,
1233
+ col: 'system.dj.number_of_nodes',
1234
+ },
1235
+ ],
1236
+ ]),
1237
+ );
1238
+ const results = await DataJunctionAPI.system.node_counts_by_active();
1239
+ expect(fetch).toHaveBeenCalledWith(
1240
+ `${DJ_URL}/system/data/system.dj.number_of_nodes?dimensions=system.dj.is_active.active_id`,
1241
+ {
1242
+ credentials: 'include',
1243
+ },
1244
+ );
1245
+ expect(results).toEqual([
1246
+ { name: 'false', value: 3136 },
1247
+ { name: 'true', value: 4523 },
1248
+ ]);
1249
+ });
1250
+
1251
+ it('calls node_counts_by_status correctly', async () => {
1252
+ fetch.mockResponseOnce(
1253
+ JSON.stringify([
1254
+ [
1255
+ {
1256
+ value: 'VALID',
1257
+ col: 'system.dj.nodes.status',
1258
+ },
1259
+ {
1260
+ value: 4333,
1261
+ col: 'system.dj.number_of_nodes',
1262
+ },
1263
+ ],
1264
+ [
1265
+ {
1266
+ value: 'INVALID',
1267
+ col: 'system.dj.nodes.status',
1268
+ },
1269
+ {
1270
+ value: 190,
1271
+ col: 'system.dj.number_of_nodes',
1272
+ },
1273
+ ],
1274
+ ]),
1275
+ );
1276
+ const results = await DataJunctionAPI.system.node_counts_by_status();
1277
+ expect(fetch).toHaveBeenCalledWith(
1278
+ `${DJ_URL}/system/data/system.dj.number_of_nodes?dimensions=system.dj.nodes.status&filters=system.dj.is_active.active_id%3Dtrue&orderby=system.dj.nodes.status`,
1279
+ {
1280
+ credentials: 'include',
1281
+ },
1282
+ );
1283
+ expect(results).toEqual([
1284
+ { name: 'VALID', value: 4333 },
1285
+ { name: 'INVALID', value: 190 },
1286
+ ]);
1287
+ });
1288
+
1289
+ it('calls nodes_without_description correctly', async () => {
1290
+ fetch.mockResponseOnce(
1291
+ JSON.stringify([
1292
+ [
1293
+ {
1294
+ value: 'cube',
1295
+ col: 'system.dj.node_type.type',
1296
+ },
1297
+ {
1298
+ value: 0.1,
1299
+ col: 'system.dj.node_without_description',
1300
+ },
1301
+ ],
1302
+ [
1303
+ {
1304
+ value: 'dimension',
1305
+ col: 'system.dj.node_type.type',
1306
+ },
1307
+ {
1308
+ value: 0.2,
1309
+ col: 'system.dj.node_without_description',
1310
+ },
1311
+ ],
1312
+ [
1313
+ {
1314
+ value: 'metric',
1315
+ col: 'system.dj.node_type.type',
1316
+ },
1317
+ {
1318
+ value: 0.3,
1319
+ col: 'system.dj.node_without_description',
1320
+ },
1321
+ ],
1322
+ [
1323
+ {
1324
+ value: 'source',
1325
+ col: 'system.dj.node_type.type',
1326
+ },
1327
+ {
1328
+ value: 0.4,
1329
+ col: 'system.dj.node_without_description',
1330
+ },
1331
+ ],
1332
+ [
1333
+ {
1334
+ value: 'transform',
1335
+ col: 'system.dj.node_type.type',
1336
+ },
1337
+ {
1338
+ value: 0.5,
1339
+ col: 'system.dj.node_without_description',
1340
+ },
1341
+ ],
1342
+ ]),
1343
+ );
1344
+ const results = await DataJunctionAPI.system.nodes_without_description();
1345
+ expect(fetch).toHaveBeenCalledWith(
1346
+ `${DJ_URL}/system/data/system.dj.node_without_description?dimensions=system.dj.node_type.type&filters=system.dj.is_active.active_id%3Dtrue&orderby=system.dj.node_type.type`,
1347
+ {
1348
+ credentials: 'include',
1349
+ },
1350
+ );
1351
+ expect(results).toEqual([
1352
+ { name: 'cube', value: 0.1 },
1353
+ { name: 'dimension', value: 0.2 },
1354
+ { name: 'metric', value: 0.3 },
1355
+ { name: 'source', value: 0.4 },
1356
+ { name: 'transform', value: 0.5 },
1357
+ ]);
1358
+ });
1359
+ it('calls node_trends correctly', async () => {
1360
+ fetch.mockResponseOnce(
1361
+ JSON.stringify([
1362
+ [
1363
+ {
1364
+ value: 20250630,
1365
+ col: 'system.dj.nodes.created_at_week',
1366
+ },
1367
+ {
1368
+ value: 'metric',
1369
+ col: 'system.dj.node_type.type',
1370
+ },
1371
+ {
1372
+ value: 42,
1373
+ col: 'system.dj.number_of_nodes',
1374
+ },
1375
+ ],
1376
+ [
1377
+ {
1378
+ value: 20250707,
1379
+ col: 'system.dj.nodes.created_at_week',
1380
+ },
1381
+ {
1382
+ value: 'dimension',
1383
+ col: 'system.dj.node_type.type',
1384
+ },
1385
+ {
1386
+ value: 21,
1387
+ col: 'system.dj.number_of_nodes',
1388
+ },
1389
+ ],
1390
+ [
1391
+ {
1392
+ value: 20250707,
1393
+ col: 'system.dj.nodes.created_at_week',
1394
+ },
1395
+ {
1396
+ value: 'metric',
1397
+ col: 'system.dj.node_type.type',
1398
+ },
1399
+ {
1400
+ value: 9,
1401
+ col: 'system.dj.number_of_nodes',
1402
+ },
1403
+ ],
1404
+ [
1405
+ {
1406
+ value: 20250714,
1407
+ col: 'system.dj.nodes.created_at_week',
1408
+ },
1409
+ {
1410
+ value: 'metric',
1411
+ col: 'system.dj.node_type.type',
1412
+ },
1413
+ {
1414
+ value: 3,
1415
+ col: 'system.dj.number_of_nodes',
1416
+ },
1417
+ ],
1418
+ [
1419
+ {
1420
+ value: 20250714,
1421
+ col: 'system.dj.nodes.created_at_week',
1422
+ },
1423
+ {
1424
+ value: 'dimension',
1425
+ col: 'system.dj.node_type.type',
1426
+ },
1427
+ {
1428
+ value: 7,
1429
+ col: 'system.dj.number_of_nodes',
1430
+ },
1431
+ ],
1432
+ ]),
1433
+ );
1434
+ const results = await DataJunctionAPI.system.node_trends();
1435
+ expect(fetch).toHaveBeenCalledWith(
1436
+ `${DJ_URL}/system/data/system.dj.number_of_nodes?dimensions=system.dj.nodes.created_at_week&dimensions=system.dj.node_type.type&filters=system.dj.nodes.created_at_week>=20240101&orderby=system.dj.nodes.created_at_week`,
1437
+ {
1438
+ credentials: 'include',
1439
+ },
1440
+ );
1441
+ expect(results).toEqual([
1442
+ { date: 20250630, metric: 42 },
1443
+ { date: 20250707, dimension: 21, metric: 9 },
1444
+ { date: 20250714, dimension: 7, metric: 3 },
1445
+ ]);
1446
+ });
1447
+
1448
+ it('calls materialization_counts_by_type correctly', async () => {
1449
+ fetch.mockResponseOnce(
1450
+ JSON.stringify([
1451
+ [
1452
+ {
1453
+ value: 'cube',
1454
+ col: 'system.dj.node_type.type',
1455
+ },
1456
+ {
1457
+ value: 76,
1458
+ col: 'system.dj.number_of_materializations',
1459
+ },
1460
+ ],
1461
+ [
1462
+ {
1463
+ value: 'dimension',
1464
+ col: 'system.dj.node_type.type',
1465
+ },
1466
+ {
1467
+ value: 3,
1468
+ col: 'system.dj.number_of_materializations',
1469
+ },
1470
+ ],
1471
+ [
1472
+ {
1473
+ value: 'transform',
1474
+ col: 'system.dj.node_type.type',
1475
+ },
1476
+ {
1477
+ value: 9,
1478
+ col: 'system.dj.number_of_materializations',
1479
+ },
1480
+ ],
1481
+ ]),
1482
+ );
1483
+ const results =
1484
+ await DataJunctionAPI.system.materialization_counts_by_type();
1485
+ expect(fetch).toHaveBeenCalledWith(
1486
+ `${DJ_URL}/system/data/system.dj.number_of_materializations?dimensions=system.dj.node_type.type&filters=system.dj.is_active.active_id%3Dtrue&orderby=system.dj.node_type.type`,
1487
+ {
1488
+ credentials: 'include',
1489
+ },
1490
+ );
1491
+ expect(results).toEqual([
1492
+ { name: 'cube', value: 76 },
1493
+ { name: 'dimension', value: 3 },
1494
+ { name: 'transform', value: 9 },
1495
+ ]);
1496
+ });
1497
+
1498
+ it('calls system.dimensions correctly', async () => {
1499
+ fetch.mockResponseOnce(JSON.stringify([]));
1500
+ const results = await DataJunctionAPI.system.dimensions();
1501
+ expect(fetch).toHaveBeenCalledWith(`${DJ_URL}/system/dimensions`, {
1502
+ credentials: 'include',
1503
+ });
1504
+ });
1141
1505
  });
@@ -0,0 +1,72 @@
1
+ /* Overview page css */
2
+
3
+ .chart-container {
4
+ display: flex;
5
+ flex-wrap: wrap;
6
+ gap: 2em;
7
+ margin: 2em 2em;
8
+ }
9
+
10
+ .chart-box {
11
+ display: flex;
12
+ flex-grow: 1;
13
+ flex-direction: column;
14
+ flex: 1 1 300px;
15
+ min-width: 300px;
16
+ max-width: fit-content;
17
+ border: 1px solid #ddd;
18
+ border-radius: 12px;
19
+ background-color: #fff;
20
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
21
+ padding: calc(1.3rem);
22
+ }
23
+
24
+ .chart-title {
25
+ padding-bottom: 10px;
26
+ font-size: calc(1.3rem);
27
+ font-weight: 400;
28
+ margin: 0;
29
+ text-align: center;
30
+ color: rgb(110, 110, 110);
31
+ font-family: Roboto, Helvetica, Arial, sans-serif;
32
+ line-height: 1.235;
33
+ letter-spacing: 0.00735em;
34
+ overflow: hidden;
35
+ text-overflow: ellipsis;
36
+ white-space: nowrap;
37
+ }
38
+
39
+ .vert-box {
40
+ display: flex;
41
+ padding: 1em 1em;
42
+ font-size: 18px;
43
+ align-items: center;
44
+ flex-direction: column;
45
+ }
46
+ .vert-box span {
47
+ opacity: 0.6;
48
+ font-size: 13px;
49
+ }
50
+
51
+ .horiz-box {
52
+ width: 100%;
53
+ display: flex;
54
+ flex-wrap: wrap;
55
+ }
56
+ .horiz-box-value {
57
+ margin: 0 12px;
58
+ font-size: 20px;
59
+ text-align: left;
60
+ }
61
+ .horiz-box-label {
62
+ font-size: smaller;
63
+ padding: 5px 12px;
64
+ }
65
+
66
+ .jss316 {
67
+ display: inline-block;
68
+ padding: 0.2em;
69
+ font-size: 18px;
70
+ align-items: center;
71
+ flex-direction: column;
72
+ }