@truedat/dd 4.40.12 → 4.41.0

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 (26) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/package.json +6 -6
  3. package/src/api.js +3 -0
  4. package/src/components/DictionaryRoutes.js +17 -1
  5. package/src/components/PendingStructureNoteRow.js +45 -0
  6. package/src/components/PendingStructureNotes.js +149 -0
  7. package/src/components/PendingStructureNotesTable.js +73 -0
  8. package/src/components/StructuresDomainsUploadOption.js +52 -0
  9. package/src/components/StructuresOptions.js +4 -0
  10. package/src/components/__tests__/PendingStructureNoteRow.spec.js +48 -0
  11. package/src/components/__tests__/PendingStructureNotes.spec.js +102 -0
  12. package/src/components/__tests__/PendingStructureNotesTable.spec.js +83 -0
  13. package/src/components/__tests__/StructuresOptions.spec.js +6 -1
  14. package/src/components/__tests__/__snapshots__/DictionaryRoutes.spec.js.snap +4 -0
  15. package/src/components/__tests__/__snapshots__/PendingStructureNoteRow.spec.js.snap +35 -0
  16. package/src/components/__tests__/__snapshots__/PendingStructureNotes.spec.js.snap +126 -0
  17. package/src/components/__tests__/__snapshots__/PendingStructureNotesTable.spec.js.snap +123 -0
  18. package/src/components/__tests__/__snapshots__/StructuresOptions.spec.js.snap +14 -0
  19. package/src/messages/en.js +27 -0
  20. package/src/messages/es.js +30 -0
  21. package/src/reducers/__tests__/ddMessage.spec.js +76 -0
  22. package/src/reducers/ddMessage.js +51 -8
  23. package/src/routines.js +1 -0
  24. package/src/sagas/__tests__/uploadStructuresDomains.spec.js +81 -0
  25. package/src/sagas/index.js +3 -0
  26. package/src/sagas/uploadStructuresDomains.js +35 -0
@@ -0,0 +1,83 @@
1
+ import React from "react";
2
+ import { waitFor } from "@testing-library/react";
3
+ import { render } from "@truedat/test/render";
4
+ import PendingStructureNotesTable from "../PendingStructureNotesTable";
5
+
6
+ const renderOpts = {
7
+ messages: {
8
+ en: {
9
+ "pendingStructureNotes.search.results.empty": "Empty",
10
+ "pendingStructureNotes.props.structure": "Structure",
11
+ "pendingStructureNotes.props.status": "Status",
12
+ "pendingStructureNotes.props.system": "System",
13
+ "pendingStructureNotes.props.domains": "Domains",
14
+ "structure.notes.status.draft": "Draft",
15
+ "structure.notes.status.rejected": "Rejected",
16
+ "pendingStructureNotes.props.path": "Path",
17
+ },
18
+ },
19
+ };
20
+
21
+ const props = {
22
+ loading: false,
23
+ structureNotes: [
24
+ {
25
+ id: "7207",
26
+ status: "draft",
27
+ data_structure: {
28
+ current_version: {
29
+ name: "bar",
30
+ path: ["bar rute"],
31
+ },
32
+ domains: [{ name: "bar domain" }],
33
+ system: { name: "bar system" },
34
+ },
35
+ },
36
+ {
37
+ id: "665214",
38
+ status: "rejected",
39
+ data_structure: {
40
+ current_version: {
41
+ name: "foo",
42
+ path: ["foo rute", "other route"],
43
+ },
44
+ domains: [{ name: "foo domain 1" }, { name: "foo domain 2" }],
45
+ system: { name: "foo system" },
46
+ },
47
+ },
48
+ ],
49
+ };
50
+
51
+ describe("<PendingStructureNotesTable />", () => {
52
+ it("matches the latest snapshot", async () => {
53
+ const { container, queryByText } = render(
54
+ <PendingStructureNotesTable {...props} />,
55
+ renderOpts
56
+ );
57
+ expect(container).toMatchSnapshot();
58
+
59
+ await waitFor(() => {
60
+ expect(queryByText(/Draft/)).toBeTruthy();
61
+ });
62
+
63
+ await waitFor(() => {
64
+ expect(queryByText(/Rejected/)).toBeTruthy();
65
+ });
66
+ });
67
+
68
+ it("matches when StructureNotes are empty and not loading", async () => {
69
+ const props = {
70
+ loading: false,
71
+ structureNotes: [],
72
+ };
73
+
74
+ const { container, queryByText } = render(
75
+ <PendingStructureNotesTable {...props} />,
76
+ renderOpts
77
+ );
78
+ expect(container).toMatchSnapshot();
79
+ await waitFor(() => {
80
+ expect(queryByText(/Empty/)).toBeTruthy();
81
+ });
82
+ });
83
+ });
@@ -10,7 +10,12 @@ const renderOpts = {
10
10
  };
11
11
 
12
12
  describe("<StructuresOptions />", () => {
13
- const props = { bulkUpload: {}, bulkUpdate: {}, autoPublish: {} };
13
+ const props = {
14
+ bulkUpload: {},
15
+ bulkUpdate: {},
16
+ bulkUploadDomains: {},
17
+ autoPublish: {},
18
+ };
14
19
 
15
20
  it("matches the latest snapshot", async () => {
16
21
  const { container } = render(<StructuresOptions {...props} />, renderOpts);
@@ -21,6 +21,10 @@ exports[`<DictionaryRoutes /> matches the latest snapshot 1`] = `
21
21
  path="/structure_types"
22
22
  render={[Function]}
23
23
  />
24
+ <Route
25
+ path="/structure_notes"
26
+ render={[Function]}
27
+ />
24
28
  <Route
25
29
  path="/profileGroups/:id"
26
30
  render={[Function]}
@@ -0,0 +1,35 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`<PendingStructureNoteRow /> matches the latest snapshot 1`] = `
4
+ <div>
5
+ <tr
6
+ class=""
7
+ >
8
+ <td
9
+ class=""
10
+ >
11
+ bar
12
+ </td>
13
+ <td
14
+ class=""
15
+ >
16
+ Draft
17
+ </td>
18
+ <td
19
+ class=""
20
+ >
21
+ bar system
22
+ </td>
23
+ <td
24
+ class=""
25
+ >
26
+ bar domain
27
+ </td>
28
+ <td
29
+ class=""
30
+ >
31
+ bar rute
32
+ </td>
33
+ </tr>
34
+ </div>
35
+ `;
@@ -0,0 +1,126 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`<PendingStructureNotes /> matches the latest snapshot 1`] = `
4
+ <div>
5
+ <div
6
+ class="ui segment"
7
+ style="display: none;"
8
+ >
9
+ <h2
10
+ class="ui header"
11
+ >
12
+ <i
13
+ aria-hidden="true"
14
+ class="sticky note outline circular icon"
15
+ />
16
+ <div
17
+ class="content"
18
+ >
19
+ Header
20
+ <div
21
+ class="sub header"
22
+ >
23
+ Sub header
24
+ </div>
25
+ </div>
26
+ </h2>
27
+ <form
28
+ class="ui form"
29
+ >
30
+ <h5
31
+ class="ui header"
32
+ >
33
+ Filters
34
+ </h5>
35
+ <div
36
+ class="field subscriptions-checkbox-filters"
37
+ >
38
+ <label>
39
+ Status
40
+ </label>
41
+ <div
42
+ class="ui checked checkbox"
43
+ >
44
+ <input
45
+ checked=""
46
+ class="hidden"
47
+ readonly=""
48
+ tabindex="0"
49
+ type="checkbox"
50
+ value=""
51
+ />
52
+ <label>
53
+ Empty
54
+ </label>
55
+ </div>
56
+ <div
57
+ class="ui checked checkbox"
58
+ >
59
+ <input
60
+ checked=""
61
+ class="hidden"
62
+ readonly=""
63
+ tabindex="0"
64
+ type="checkbox"
65
+ value=""
66
+ />
67
+ <label>
68
+ Draft
69
+ </label>
70
+ </div>
71
+ <div
72
+ class="ui checked checkbox"
73
+ >
74
+ <input
75
+ checked=""
76
+ class="hidden"
77
+ readonly=""
78
+ tabindex="0"
79
+ type="checkbox"
80
+ value=""
81
+ />
82
+ <label>
83
+ Rejected
84
+ </label>
85
+ </div>
86
+ </div>
87
+ <div
88
+ class="field"
89
+ >
90
+ <label>
91
+ System
92
+ </label>
93
+ <div
94
+ aria-expanded="false"
95
+ aria-multiselectable="true"
96
+ class="ui multiple selection dropdown"
97
+ role="listbox"
98
+ tabindex="0"
99
+ >
100
+ <i
101
+ aria-hidden="true"
102
+ class="dropdown icon"
103
+ />
104
+ <div
105
+ class="menu transition"
106
+ >
107
+ <div
108
+ aria-checked="false"
109
+ aria-selected="true"
110
+ class="selected item"
111
+ role="option"
112
+ style="pointer-events: all;"
113
+ >
114
+ <span
115
+ class="text"
116
+ >
117
+ some system
118
+ </span>
119
+ </div>
120
+ </div>
121
+ </div>
122
+ </div>
123
+ </form>
124
+ </div>
125
+ </div>
126
+ `;
@@ -0,0 +1,123 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`<PendingStructureNotesTable /> matches the latest snapshot 1`] = `
4
+ <div>
5
+ <table
6
+ class="ui selectable table"
7
+ >
8
+ <thead
9
+ class=""
10
+ >
11
+ <tr
12
+ class=""
13
+ >
14
+ <th
15
+ class=""
16
+ >
17
+ Structure
18
+ </th>
19
+ <th
20
+ class=""
21
+ >
22
+ Status
23
+ </th>
24
+ <th
25
+ class=""
26
+ >
27
+ System
28
+ </th>
29
+ <th
30
+ class=""
31
+ >
32
+ Domains
33
+ </th>
34
+ <th
35
+ class=""
36
+ >
37
+ Path
38
+ </th>
39
+ </tr>
40
+ </thead>
41
+ <tbody
42
+ class=""
43
+ >
44
+ <tr
45
+ class=""
46
+ >
47
+ <td
48
+ class=""
49
+ >
50
+ bar
51
+ </td>
52
+ <td
53
+ class=""
54
+ >
55
+ Draft
56
+ </td>
57
+ <td
58
+ class=""
59
+ >
60
+ bar system
61
+ </td>
62
+ <td
63
+ class=""
64
+ >
65
+ bar domain
66
+ </td>
67
+ <td
68
+ class=""
69
+ >
70
+ bar rute
71
+ </td>
72
+ </tr>
73
+ <tr
74
+ class=""
75
+ >
76
+ <td
77
+ class=""
78
+ >
79
+ foo
80
+ </td>
81
+ <td
82
+ class=""
83
+ >
84
+ Rejected
85
+ </td>
86
+ <td
87
+ class=""
88
+ >
89
+ foo system
90
+ </td>
91
+ <td
92
+ class=""
93
+ >
94
+ foo domain 1, foo domain 2
95
+ </td>
96
+ <td
97
+ class=""
98
+ >
99
+ foo rute &gt; other route
100
+ </td>
101
+ </tr>
102
+ </tbody>
103
+ </table>
104
+ </div>
105
+ `;
106
+
107
+ exports[`<PendingStructureNotesTable /> matches when StructureNotes are empty and not loading 1`] = `
108
+ <div>
109
+ <h4
110
+ class="ui header"
111
+ >
112
+ <i
113
+ aria-hidden="true"
114
+ class="search icon"
115
+ />
116
+ <div
117
+ class="content"
118
+ >
119
+ Empty
120
+ </div>
121
+ </h4>
122
+ </div>
123
+ `;
@@ -68,6 +68,20 @@ exports[`<StructuresOptions /> matches the latest snapshot 1`] = `
68
68
  Upload structure notes
69
69
  </span>
70
70
  </div>
71
+ <div
72
+ class="item"
73
+ role="option"
74
+ >
75
+ <i
76
+ aria-hidden="true"
77
+ class="upload icon"
78
+ />
79
+ <span
80
+ class="text"
81
+ >
82
+ Update structure domains
83
+ </span>
84
+ </div>
71
85
  <div
72
86
  class="divider"
73
87
  />
@@ -150,6 +150,15 @@ export default {
150
150
  "navigation.lineage.view": "View in Data Catalog",
151
151
  "navigation.profile.executions": "Executions",
152
152
  "navigation.profile.executions.detail": "Detail",
153
+ "pendingStructureNotes.header": "Pending Notes",
154
+ "pendingStructureNotes.subheader": "Structure notes pending some action",
155
+ "pendingStructureNotes.props.structure": "Data Structure",
156
+ "pendingStructureNotes.props.status": "Status",
157
+ "pendingStructureNotes.props.system": "System",
158
+ "pendingStructureNotes.props.domains": "Domains",
159
+ "pendingStructureNotes.props.path": "Path",
160
+ "pendingStructureNotes.search.results.empty": "No structure notes found",
161
+ "pendingStructureNotes.filters": "Filters",
153
162
  "profile.completed.content": "{count} profiles completed.",
154
163
  "profile.completed.header": "Profiles completed.",
155
164
  "profile.pending.content":
@@ -362,9 +371,13 @@ export default {
362
371
  "structures.actions.new_system": "New system",
363
372
  "structures.actions.upload": "Upload file",
364
373
  "structures.actions.upload.confirmation.content": "Notes",
374
+ "structures.actions.uploadDomains.confirmation.content": "Structure domains",
365
375
  "structures.actions.upload.confirmation.header":
366
376
  "Upload notes file of structures",
377
+ "structures.actions.uploadDomains.confirmation.header":
378
+ "Upload structures domains file",
367
379
  "structures.actions.upload.tooltip": "Upload structure notes",
380
+ "structures.actions.uploadDomains.tooltip": "Update structure domains",
368
381
  "structures.bulkUpdate.crumbs.top": "Bulk update",
369
382
  "structures.bulkUpdate.success.content":
370
383
  "Updated {count} structures successfully",
@@ -382,12 +395,25 @@ export default {
382
395
  "Bulk update completed. Loaded {count_ids} errors {count_errors}",
383
396
  "structures.bulkUpdateStructures.success.errors":
384
397
  "Error in external id {externalId}, message: {message}",
398
+ "structures.bulkUploadStructuresDomains.success.errors.domain: not_exist":
399
+ "Error in line {row}, in external id {externalId}, domain does not exist",
400
+ "structures.bulkUploadStructuresDomains.success.errors.update_domain: forbbiden":
401
+ "Error in line {row}, in external id {externalId}, update forbbiden",
402
+ "structures.bulkUploadStructuresDomains.success.errors.domain_ids: must be a non-empty list":
403
+ "Error in line {row}, in external id {externalId}, domain_ids must be a non-empty list",
404
+ "structures.bulkUploadStructuresDomains.success.errors.structure: not_exist":
405
+ "Error in line {row}, in external id {externalId}, data structure does not exist",
385
406
  "structures.bulkUploadStructures.success.errors":
386
407
  "Error in line {row}, in external id {externalId}, message: {message}",
408
+ "structures.bulkUploadStructuresDomains.success.errors":
409
+ "Error in line {row}, in external id {externalId}, message: {message}",
387
410
  "structures.bulkUpdateStructures.success.unchanged":
388
411
  "{unchanged} structures remained unchanged.",
389
412
  "structures.bulkUpdateStructures.success.updated":
390
413
  "Updated {changed} structures successfully.",
414
+ "structures.bulkUploadStructuresDomains.success.header":
415
+ "Bulk update completed. Loaded {count_ids} errors {count_errors}",
416
+
391
417
  "structures.crumbs.top": "Structures",
392
418
  "structures.edit.bulk.confirmation.content":
393
419
  "{structures_count} structures will be updated. Are you sure?",
@@ -436,6 +462,7 @@ export default {
436
462
  "structures.uploadStructures.failed.external_id_not_exist":
437
463
  "Invalid External Id",
438
464
  "structures.uploadStructures.failed.header": "Upload Failed!",
465
+ "structures.uploadStructuresDomains.failed.header": "Upload Failed!",
439
466
  "structures.uploadStructures.failed.invalid_file_format":
440
467
  "Invalid file format",
441
468
  "structures.uploadStructures.failed.note.df_content.default":
@@ -153,6 +153,16 @@ export default {
153
153
  "navigation.lineage.view": "Ver detalle",
154
154
  "navigation.profile.executions": "Ejecuciones",
155
155
  "navigation.profile.executions.detail": "Detalle",
156
+ "pendingStructureNotes.header": "Notas pendientes",
157
+ "pendingStructureNotes.subheader":
158
+ "Notas de estructuras pendientes de acción",
159
+ "pendingStructureNotes.props.structure": "Estructura",
160
+ "pendingStructureNotes.props.status": "Estado",
161
+ "pendingStructureNotes.props.system": "Sistema",
162
+ "pendingStructureNotes.props.domains": "Dominios",
163
+ "pendingStructureNotes.props.path": "Ruta",
164
+ "pendingStructureNotes.search.results.empty": "Ninguna nota encontrada",
165
+ "pendingStructureNotes.filters": "Filtros",
156
166
  "profile.completed.content": "Se han ejecutado {count} perfilados.",
157
167
  "profile.completed.header": "Ejecuciones finalizadas",
158
168
  "profile.pending.content":
@@ -365,9 +375,15 @@ export default {
365
375
  "structures.actions.new_system": "Nuevo sistema",
366
376
  "structures.actions.upload": "Subir fichero",
367
377
  "structures.actions.upload.confirmation.content": "Notas",
378
+ "structures.actions.uploadDomains.confirmation.content":
379
+ "Dominios de estructuras",
368
380
  "structures.actions.upload.confirmation.header":
369
381
  "Subir fichero de notas de estructuras",
382
+ "structures.actions.uploadDomains.confirmation.header":
383
+ "Subir fichero de dominios de estructuras",
370
384
  "structures.actions.upload.tooltip": "Subir notas de estructuras",
385
+ "structures.actions.uploadDomains.tooltip":
386
+ "Actualizar dominios de estructuras",
371
387
  "structures.bulkUpdate.crumbs.top": "Actualización masiva",
372
388
  "structures.bulkUpdate.success.content":
373
389
  "Se han actualizado {count} estructuras",
@@ -385,12 +401,24 @@ export default {
385
401
  "¡Actualización finalizada! subidos {count_ids} errores {count_errors}",
386
402
  "structures.bulkUpdateStructures.success.errors":
387
403
  "Error en external id {externalId}, mensaje: {message}",
404
+ "structures.bulkUploadStructuresDomains.success.errors.domain: not_exist":
405
+ "Error en linea {row}, en external id {externalId}, el dominio no existe",
406
+ "structures.bulkUploadStructuresDomains.success.errors.structure: not_exist":
407
+ "Error en linea {row}, en external id {externalId}, la estructura no existe",
408
+ "structures.bulkUploadStructuresDomains.success.errors.update_domain: forbbiden":
409
+ "Error en linea {row}, en external id {externalId}, no tiene permisos para actualizar",
410
+ "structures.bulkUploadStructuresDomains.success.errors.domain_ids: must be a non-empty list":
411
+ "Error en linea {row}, en external id {externalId}, domain_ids no puede ser una lista vacia",
388
412
  "structures.bulkUploadStructures.success.errors":
389
413
  "Error en linea {row}, en external id {externalId} mensaje: {message}",
414
+ "structures.bulkUploadStructuresDomains.success.errors":
415
+ "Error en linea {row}, en external id {externalId} mensaje: {message}",
390
416
  "structures.bulkUpdateStructures.success.unchanged":
391
417
  "{unchanged} se han mantenido sin cambios.",
392
418
  "structures.bulkUpdateStructures.success.updated":
393
419
  "Se han actualizado {changed} estructuras.",
420
+ "structures.bulkUploadStructuresDomains.success.header":
421
+ "¡Actualización finalizada! subidos {count_ids} errores {count_errors}",
394
422
  "structures.crumbs.top": "Estructuras",
395
423
  "structures.edit.bulk.confirmation.content":
396
424
  "Se van a actualizar {structures_count} estructuras. ¿Estás seguro?",
@@ -443,6 +471,8 @@ export default {
443
471
  "External Id Inválido",
444
472
  "structures.uploadStructures.failed.header":
445
473
  "Error al subir el fichero. El contenido no se ha actualizado",
474
+ "structures.uploadStructuresDomains.failed.header":
475
+ "Error al subir el fichero. El contenido no se ha actualizado",
446
476
  "structures.uploadStructures.failed.invalid_file_format":
447
477
  "Formato de fichero inválido",
448
478
  "structures.uploadStructures.failed.note.df_content.default":
@@ -0,0 +1,76 @@
1
+ import { uploadStructuresDomains } from "../../routines";
2
+ import { ddMessage } from "..";
3
+
4
+ const fooState = { foo: "bar" };
5
+
6
+ describe("reducers: ddMessage", () => {
7
+ const initialState = null;
8
+
9
+ it("should provide the initial state", () => {
10
+ expect(ddMessage(undefined, {})).toEqual(initialState);
11
+ });
12
+
13
+ it("should handle the uploadStructuresDomains.SUCCESS action returning some errored rows", () => {
14
+ const ddMsg = ddMessage(fooState, {
15
+ type: uploadStructuresDomains.SUCCESS,
16
+ payload: {
17
+ data: {
18
+ errors: [
19
+ {
20
+ external_id: "postgres://Postgres-Test/postgres/public/city/city_id",
21
+ message: {
22
+ external_domain_ids: ["must exist: UEUEUEU"],
23
+ },
24
+ row: 3,
25
+ },
26
+ {
27
+ external_id:
28
+ "postgres://Postgres-Test/postgres/public/city/city_name",
29
+ message: {
30
+ external_domain_ids: ["must exist: NANDAKA, JAJAJA"],
31
+ },
32
+ row: 4,
33
+ },
34
+ ],
35
+ ids: [5375339],
36
+ },
37
+ },
38
+ });
39
+
40
+ expect(ddMsg).toMatchObject({
41
+ error: false,
42
+ header: "structures.bulkUploadStructuresDomains.success.header",
43
+ icon: "check",
44
+ color: "orange",
45
+ fields: { count_errors: 2, count_ids: 1}
46
+ });
47
+ const { messages: errors } = ddMsg;
48
+ expect(errors.length).toEqual(2);
49
+ });
50
+
51
+ it("should handle the uploadStructuresDomains.FAILURE action", () => {
52
+ const ddMsg = ddMessage(fooState, {
53
+ type: uploadStructuresDomains.FAILURE,
54
+ payload: {
55
+ status: 422,
56
+ data: {
57
+ error: {
58
+ message:
59
+ "invalid_headers, must be: external_id, domain_external_ids",
60
+ },
61
+ },
62
+ },
63
+ });
64
+
65
+ expect(ddMsg).toMatchObject({
66
+ error: true,
67
+ header: "structures.uploadStructuresDomains.failed.header",
68
+ icon: "attention",
69
+ content: "invalid_headers, must be: external_id, domain_external_ids",
70
+ });
71
+ });
72
+
73
+
74
+
75
+
76
+ });