datajunction-ui 0.0.1-rc.25 → 0.0.1-rc.27

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.
@@ -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
- <a
135
- href="http://fake.url/job"
131
+ <span
132
+ class="badge cron"
136
133
  >
137
- country_birth_date_contractor_id_379232101
138
- </a>
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
- <div
360
- class="partition__full"
295
+ <a
296
+ class="partitionLink"
361
297
  >
362
298
  <div
363
- class="partition__header"
299
+ class="partition__full"
364
300
  >
365
- birth_date
366
- </div>
367
- <div
368
- class="partition__body"
369
- >
370
- <div>
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
- <span
375
- class="badge partition_value"
376
- >
377
- 20010101
378
- </span>
379
- to
380
- <span
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>
@@ -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}/`, {
@@ -575,4 +583,83 @@ export const DataJunctionAPI = {
575
583
  });
576
584
  return { status: response.status, json: await response.json() };
577
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
+ },
578
665
  };
@@ -607,6 +607,18 @@ describe('DataJunctionAPI', () => {
607
607
  );
608
608
  });
609
609
 
610
+ it('calls addNamespace correctly', async () => {
611
+ fetch.mockResponseOnce(JSON.stringify({}));
612
+ await DataJunctionAPI.addNamespace('test');
613
+ expect(fetch).toHaveBeenCalledWith(`${DJ_URL}/namespaces/test`, {
614
+ credentials: 'include',
615
+ headers: {
616
+ 'Content-Type': 'application/json',
617
+ },
618
+ method: 'POST',
619
+ });
620
+ });
621
+
610
622
  it('calls listTags correctly', async () => {
611
623
  fetch.mockResponseOnce(JSON.stringify(mocks.tags));
612
624
  const res = await DataJunctionAPI.listTags();
@@ -689,4 +701,104 @@ describe('DataJunctionAPI', () => {
689
701
  method: 'POST',
690
702
  });
691
703
  });
704
+
705
+ it('calls editTag correctly', async () => {
706
+ fetch.mockResponseOnce(JSON.stringify({}));
707
+ await DataJunctionAPI.editTag(
708
+ 'report.financials',
709
+ 'Financial reports',
710
+ 'Financial Reports',
711
+ );
712
+ expect(fetch).toHaveBeenCalledWith(`${DJ_URL}/tags/report.financials`, {
713
+ credentials: 'include',
714
+ headers: {
715
+ 'Content-Type': 'application/json',
716
+ },
717
+ body: JSON.stringify({
718
+ description: 'Financial reports',
719
+ display_name: 'Financial Reports',
720
+ }),
721
+ method: 'PATCH',
722
+ });
723
+ });
724
+
725
+ it('calls setPartition correctly', async () => {
726
+ fetch.mockResponseOnce(JSON.stringify({}));
727
+ await DataJunctionAPI.setPartition(
728
+ 'default.hard_hat',
729
+ 'hire_date',
730
+ 'temporal',
731
+ 'yyyyMMdd',
732
+ 'day',
733
+ );
734
+ expect(fetch).toHaveBeenCalledWith(
735
+ `${DJ_URL}/nodes/default.hard_hat/columns/hire_date/partition`,
736
+ {
737
+ credentials: 'include',
738
+ headers: {
739
+ 'Content-Type': 'application/json',
740
+ },
741
+ body: JSON.stringify({
742
+ type_: 'temporal',
743
+ format: 'yyyyMMdd',
744
+ granularity: 'day',
745
+ }),
746
+ method: 'POST',
747
+ },
748
+ );
749
+ });
750
+
751
+ it('calls materialize correctly', async () => {
752
+ fetch.mockResponseOnce(JSON.stringify({}));
753
+ await DataJunctionAPI.materialize(
754
+ 'default.hard_hat',
755
+ 'spark',
756
+ '3.3',
757
+ '@daily',
758
+ '{}',
759
+ );
760
+ expect(fetch).toHaveBeenCalledWith(
761
+ `${DJ_URL}/nodes/default.hard_hat/materialization`,
762
+ {
763
+ credentials: 'include',
764
+ headers: {
765
+ 'Content-Type': 'application/json',
766
+ },
767
+ body: JSON.stringify({
768
+ engine: {
769
+ name: 'spark',
770
+ version: '3.3',
771
+ },
772
+ schedule: '@daily',
773
+ config: {},
774
+ }),
775
+ method: 'POST',
776
+ },
777
+ );
778
+ });
779
+
780
+ it('calls runBackfill correctly', async () => {
781
+ fetch.mockResponseOnce(JSON.stringify({}));
782
+ await DataJunctionAPI.runBackfill(
783
+ 'default.hard_hat',
784
+ 'spark',
785
+ 'hire_date',
786
+ '20230101',
787
+ '20230202',
788
+ );
789
+ expect(fetch).toHaveBeenCalledWith(
790
+ `${DJ_URL}/nodes/default.hard_hat/materializations/spark/backfill`,
791
+ {
792
+ credentials: 'include',
793
+ headers: {
794
+ 'Content-Type': 'application/json',
795
+ },
796
+ body: JSON.stringify({
797
+ column_name: 'hire_date',
798
+ range: ['20230101', '20230202'],
799
+ }),
800
+ method: 'POST',
801
+ },
802
+ );
803
+ });
692
804
  });
@@ -30,6 +30,7 @@ export const mocks = {
30
30
  display_name: 'Default DOT num repair orders',
31
31
  attributes: [],
32
32
  dimension: null,
33
+ partition: null,
33
34
  },
34
35
  ],
35
36
  primary_key: ['repair_order_id', 'country'],
@@ -247,6 +248,7 @@ export const mocks = {
247
248
  display_name: 'Default DOT avg repair price',
248
249
  attributes: [],
249
250
  dimension: null,
251
+ partition: null,
250
252
  },
251
253
  ],
252
254
  metricNodeHistory: [
@@ -338,32 +340,19 @@ export const mocks = {
338
340
  ],
339
341
  nodeMaterializations: [
340
342
  {
343
+ backfills: [
344
+ {
345
+ spec: {
346
+ column_name: 'default_DOT_hard_hat_DOT_hire_date',
347
+ values: null,
348
+ range: ['20230101', '20230102'],
349
+ },
350
+ urls: [],
351
+ },
352
+ ],
341
353
  name: 'country_birth_date_contractor_id_379232101',
342
354
  engine: { name: 'spark', version: '2.4.4', uri: null, dialect: 'spark' },
343
355
  config: {
344
- partitions: [
345
- {
346
- name: 'country',
347
- values: ['DE', 'MY'],
348
- range: null,
349
- expression: null,
350
- type_: 'categorical',
351
- },
352
- {
353
- name: 'birth_date',
354
- values: null,
355
- range: [20010101, 20020101],
356
- expression: null,
357
- type_: 'temporal',
358
- },
359
- {
360
- name: 'contractor_id',
361
- values: null,
362
- range: [1, 10],
363
- expression: null,
364
- type_: 'categorical',
365
- },
366
- ],
367
356
  spark: {},
368
357
  query:
369
358
  "SELECT default_DOT_hard_hats.address,\n\tdefault_DOT_hard_hats.birth_date,\n\tdefault_DOT_hard_hats.city,\n\tdefault_DOT_hard_hats.contractor_id,\n\tdefault_DOT_hard_hats.country,\n\tdefault_DOT_hard_hats.first_name,\n\tdefault_DOT_hard_hats.hard_hat_id,\n\tdefault_DOT_hard_hats.hire_date,\n\tdefault_DOT_hard_hats.last_name,\n\tdefault_DOT_hard_hats.manager,\n\tdefault_DOT_hard_hats.postal_code,\n\tdefault_DOT_hard_hats.state,\n\tdefault_DOT_hard_hats.title \n FROM roads.hard_hats AS default_DOT_hard_hats \n WHERE default_DOT_hard_hats.country IN ('DE', 'MY') AND default_DOT_hard_hats.contractor_id BETWEEN 1 AND 10\n\n",
@@ -1235,66 +1224,66 @@ export const mocks = {
1235
1224
  },
1236
1225
  },
1237
1226
  {
1238
- "name": "hire_date",
1239
- "type": "date",
1240
- "attributes": [],
1241
- "dimension": {
1242
- "name": "default.date_dim"
1227
+ name: 'hire_date',
1228
+ type: 'date',
1229
+ attributes: [],
1230
+ dimension: {
1231
+ name: 'default.date_dim',
1243
1232
  },
1244
- "display_name": "Hire Date"
1233
+ display_name: 'Hire Date',
1245
1234
  },
1246
1235
  {
1247
- "name": "address",
1248
- "type": "string",
1249
- "attributes": [],
1250
- "dimension": null,
1251
- "display_name": "Address"
1236
+ name: 'address',
1237
+ type: 'string',
1238
+ attributes: [],
1239
+ dimension: null,
1240
+ display_name: 'Address',
1252
1241
  },
1253
1242
  {
1254
- "name": "city",
1255
- "type": "string",
1256
- "attributes": [],
1257
- "dimension": null,
1258
- "display_name": "City"
1243
+ name: 'city',
1244
+ type: 'string',
1245
+ attributes: [],
1246
+ dimension: null,
1247
+ display_name: 'City',
1259
1248
  },
1260
1249
  {
1261
- "name": "state",
1262
- "type": "string",
1263
- "attributes": [],
1264
- "dimension": {
1265
- "name": "default.us_state"
1250
+ name: 'state',
1251
+ type: 'string',
1252
+ attributes: [],
1253
+ dimension: {
1254
+ name: 'default.us_state',
1266
1255
  },
1267
- "display_name": "State"
1256
+ display_name: 'State',
1268
1257
  },
1269
1258
  {
1270
- "name": "postal_code",
1271
- "type": "string",
1272
- "attributes": [],
1273
- "dimension": null,
1274
- "display_name": "Postal Code"
1259
+ name: 'postal_code',
1260
+ type: 'string',
1261
+ attributes: [],
1262
+ dimension: null,
1263
+ display_name: 'Postal Code',
1275
1264
  },
1276
1265
  {
1277
- "name": "country",
1278
- "type": "string",
1279
- "attributes": [],
1280
- "dimension": null,
1281
- "display_name": "Country"
1266
+ name: 'country',
1267
+ type: 'string',
1268
+ attributes: [],
1269
+ dimension: null,
1270
+ display_name: 'Country',
1282
1271
  },
1283
1272
  {
1284
- "name": "manager",
1285
- "type": "int",
1286
- "attributes": [],
1287
- "dimension": null,
1288
- "display_name": "Manager"
1273
+ name: 'manager',
1274
+ type: 'int',
1275
+ attributes: [],
1276
+ dimension: null,
1277
+ display_name: 'Manager',
1289
1278
  },
1290
1279
  {
1291
- "name": "contractor_id",
1292
- "type": "int",
1293
- "attributes": [],
1294
- "dimension": null,
1295
- "display_name": "Contractor Id"
1296
- }
1297
- ],
1280
+ name: 'contractor_id',
1281
+ type: 'int',
1282
+ attributes: [],
1283
+ dimension: null,
1284
+ display_name: 'Contractor Id',
1285
+ },
1286
+ ],
1298
1287
  created_at: '2023-08-21T16:48:55.594537+00:00',
1299
1288
  tags: [],
1300
1289
  },
@@ -97,6 +97,10 @@
97
97
  rgba(0, 0, 0, 0.06) 0px 2px 4px -1px;
98
98
  }
99
99
 
100
+ .partition__full:hover {
101
+ border: solid #195039 0.025em;
102
+ }
103
+
100
104
  .partition__header,
101
105
  .partition__body,
102
106
  .partition__full,