@truedat/dd 4.40.14 → 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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.41.0] 2022-03-25
4
+
5
+ ### Added
6
+
7
+ - [TD-4535] Structures domains CSV upload bulk update
8
+
3
9
  ## [4.40.14] 2022-03-22
4
10
 
5
11
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/dd",
3
- "version": "4.40.14",
3
+ "version": "4.41.0",
4
4
  "description": "Truedat Web Data Dictionary",
5
5
  "sideEffects": false,
6
6
  "jsnext:main": "src/index.js",
@@ -34,7 +34,7 @@
34
34
  "@testing-library/jest-dom": "^5.14.1",
35
35
  "@testing-library/react": "^12.0.0",
36
36
  "@testing-library/user-event": "^13.2.1",
37
- "@truedat/test": "4.40.14",
37
+ "@truedat/test": "4.41.0",
38
38
  "babel-jest": "^27.0.6",
39
39
  "babel-plugin-dynamic-import-node": "^2.3.3",
40
40
  "babel-plugin-lodash": "^3.3.4",
@@ -84,9 +84,9 @@
84
84
  ]
85
85
  },
86
86
  "dependencies": {
87
- "@truedat/auth": "4.40.14",
88
- "@truedat/core": "4.40.14",
89
- "@truedat/df": "4.40.14",
87
+ "@truedat/auth": "4.41.0",
88
+ "@truedat/core": "4.41.0",
89
+ "@truedat/df": "4.41.0",
90
90
  "lodash": "^4.17.21",
91
91
  "path-to-regexp": "^1.7.0",
92
92
  "prop-types": "^15.7.2",
@@ -107,5 +107,5 @@
107
107
  "react-dom": ">= 16.8.6 < 17",
108
108
  "semantic-ui-react": ">= 0.88.2 < 2.1"
109
109
  },
110
- "gitHead": "11d6d5749f624fd3db6005f79f0df6ce05bc7793"
110
+ "gitHead": "f4d8bc5e536b847c7b562a84bfa70955a93166ea"
111
111
  }
package/src/api.js CHANGED
@@ -31,6 +31,8 @@ const API_STRUCTURE_TAG = "/api/data_structure_tags/:id";
31
31
  const API_STRUCTURE_TAGS = "/api/data_structure_tags";
32
32
  const API_STRUCTURE_TYPE = "/api/data_structure_types/:id";
33
33
  const API_STRUCTURE_TYPES = "/api/data_structure_types";
34
+ const API_STRUCTURES_DOMAINS_UPLOAD =
35
+ "/api/data_structures/bulk_upload_domains";
34
36
  const API_STRUCTURES_TAG = "/api/data_structures/:data_structure_id/tags/:id";
35
37
  const API_STRUCTURES_TAGS = "/api/data_structures/:data_structure_id/tags";
36
38
  const API_USER_SEARCH_FILTERS = "/api/user_search_filters";
@@ -79,6 +81,7 @@ export {
79
81
  API_USER_SEARCH_FILTERS,
80
82
  API_USER_SEARCH_FILTER,
81
83
  API_GET_USER_SEARCH_FILTERS,
84
+ API_STRUCTURES_DOMAINS_UPLOAD,
82
85
  API_STRUCTURES_TAG,
83
86
  API_STRUCTURES_TAGS,
84
87
  API_STRUCTURES_UPLOAD,
@@ -0,0 +1,52 @@
1
+ import React from "react";
2
+ import PropTypes from "prop-types";
3
+ import { connect } from "react-redux";
4
+ import { Dropdown } from "semantic-ui-react";
5
+ import { useIntl } from "react-intl";
6
+ import { UploadModal } from "@truedat/core/components";
7
+ import { uploadStructuresDomains } from "../routines";
8
+
9
+ export const StructuresDomainsUploadOption = ({
10
+ uploadStructuresDomains,
11
+ loading,
12
+ }) => {
13
+ const { formatMessage } = useIntl();
14
+
15
+ return (
16
+ <UploadModal
17
+ icon="upload"
18
+ trigger={
19
+ <Dropdown.Item
20
+ icon="upload"
21
+ text={formatMessage({ id: "structures.actions.uploadDomains.tooltip" })}
22
+ disabled={loading}
23
+ />
24
+ }
25
+ header={formatMessage({
26
+ id: "structures.actions.uploadDomains.confirmation.header",
27
+ })}
28
+ content={formatMessage({
29
+ id: "structures.actions.uploadDomains.confirmation.content",
30
+ })}
31
+ param={"structures_domains"}
32
+ handleSubmit={(data) =>
33
+ uploadStructuresDomains({
34
+ data,
35
+ })
36
+ }
37
+ />
38
+ );
39
+ };
40
+
41
+ StructuresDomainsUploadOption.propTypes = {
42
+ uploadStructuresDomains: PropTypes.func,
43
+ loading: PropTypes.bool,
44
+ };
45
+
46
+ const mapStateToProps = ({ uploadingStructuresDomainsFile }) => ({
47
+ loading: uploadingStructuresDomainsFile,
48
+ });
49
+
50
+ export default connect(mapStateToProps, { uploadStructuresDomains })(
51
+ StructuresDomainsUploadOption
52
+ );
@@ -6,10 +6,12 @@ import StructuresDownloadOption from "./StructuresDownloadOption";
6
6
  import StructuresEditableDownloadOption from "./StructuresEditableDownloadOption";
7
7
  import StructuresUpdateOption from "./StructuresUpdateOption";
8
8
  import StructuresUploadOption from "./StructuresUploadOption";
9
+ import StructuresDomainsUploadOption from "./StructuresDomainsUploadOption";
9
10
 
10
11
  export const StructuresOptions = ({
11
12
  autoPublish,
12
13
  bulkUpload,
14
+ bulkUploadDomains,
13
15
  hasFilterApplied,
14
16
  }) => (
15
17
  <Dropdown
@@ -26,6 +28,7 @@ export const StructuresOptions = ({
26
28
  {bulkUpload ? (
27
29
  <StructuresUploadOption canAutoPublish={!!autoPublish} />
28
30
  ) : null}
31
+ {bulkUploadDomains ? <StructuresDomainsUploadOption /> : null}
29
32
  <Dropdown.Divider />
30
33
  <StructuresUpdateOption />
31
34
  </Dropdown.Menu>
@@ -35,6 +38,7 @@ export const StructuresOptions = ({
35
38
  StructuresOptions.propTypes = {
36
39
  autoPublish: PropTypes.object,
37
40
  bulkUpload: PropTypes.object,
41
+ bulkUploadDomains: PropTypes.object,
38
42
  hasFilterApplied: PropTypes.bool,
39
43
  };
40
44
 
@@ -13,6 +13,7 @@ const renderOpts = {
13
13
  "pendingStructureNotes.props.domains": "Domains",
14
14
  "structure.notes.status.draft": "Draft",
15
15
  "structure.notes.status.rejected": "Rejected",
16
+ "pendingStructureNotes.props.path": "Path",
16
17
  },
17
18
  },
18
19
  };
@@ -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);
@@ -34,7 +34,7 @@ exports[`<PendingStructureNotesTable /> matches the latest snapshot 1`] = `
34
34
  <th
35
35
  class=""
36
36
  >
37
- pendingStructureNotes.props.path
37
+ Path
38
38
  </th>
39
39
  </tr>
40
40
  </thead>
@@ -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
  />
@@ -371,9 +371,13 @@ export default {
371
371
  "structures.actions.new_system": "New system",
372
372
  "structures.actions.upload": "Upload file",
373
373
  "structures.actions.upload.confirmation.content": "Notes",
374
+ "structures.actions.uploadDomains.confirmation.content": "Structure domains",
374
375
  "structures.actions.upload.confirmation.header":
375
376
  "Upload notes file of structures",
377
+ "structures.actions.uploadDomains.confirmation.header":
378
+ "Upload structures domains file",
376
379
  "structures.actions.upload.tooltip": "Upload structure notes",
380
+ "structures.actions.uploadDomains.tooltip": "Update structure domains",
377
381
  "structures.bulkUpdate.crumbs.top": "Bulk update",
378
382
  "structures.bulkUpdate.success.content":
379
383
  "Updated {count} structures successfully",
@@ -391,12 +395,25 @@ export default {
391
395
  "Bulk update completed. Loaded {count_ids} errors {count_errors}",
392
396
  "structures.bulkUpdateStructures.success.errors":
393
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",
394
406
  "structures.bulkUploadStructures.success.errors":
395
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}",
396
410
  "structures.bulkUpdateStructures.success.unchanged":
397
411
  "{unchanged} structures remained unchanged.",
398
412
  "structures.bulkUpdateStructures.success.updated":
399
413
  "Updated {changed} structures successfully.",
414
+ "structures.bulkUploadStructuresDomains.success.header":
415
+ "Bulk update completed. Loaded {count_ids} errors {count_errors}",
416
+
400
417
  "structures.crumbs.top": "Structures",
401
418
  "structures.edit.bulk.confirmation.content":
402
419
  "{structures_count} structures will be updated. Are you sure?",
@@ -445,6 +462,7 @@ export default {
445
462
  "structures.uploadStructures.failed.external_id_not_exist":
446
463
  "Invalid External Id",
447
464
  "structures.uploadStructures.failed.header": "Upload Failed!",
465
+ "structures.uploadStructuresDomains.failed.header": "Upload Failed!",
448
466
  "structures.uploadStructures.failed.invalid_file_format":
449
467
  "Invalid file format",
450
468
  "structures.uploadStructures.failed.note.df_content.default":
@@ -375,9 +375,15 @@ export default {
375
375
  "structures.actions.new_system": "Nuevo sistema",
376
376
  "structures.actions.upload": "Subir fichero",
377
377
  "structures.actions.upload.confirmation.content": "Notas",
378
+ "structures.actions.uploadDomains.confirmation.content":
379
+ "Dominios de estructuras",
378
380
  "structures.actions.upload.confirmation.header":
379
381
  "Subir fichero de notas de estructuras",
382
+ "structures.actions.uploadDomains.confirmation.header":
383
+ "Subir fichero de dominios de estructuras",
380
384
  "structures.actions.upload.tooltip": "Subir notas de estructuras",
385
+ "structures.actions.uploadDomains.tooltip":
386
+ "Actualizar dominios de estructuras",
381
387
  "structures.bulkUpdate.crumbs.top": "Actualización masiva",
382
388
  "structures.bulkUpdate.success.content":
383
389
  "Se han actualizado {count} estructuras",
@@ -395,12 +401,24 @@ export default {
395
401
  "¡Actualización finalizada! subidos {count_ids} errores {count_errors}",
396
402
  "structures.bulkUpdateStructures.success.errors":
397
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",
398
412
  "structures.bulkUploadStructures.success.errors":
399
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}",
400
416
  "structures.bulkUpdateStructures.success.unchanged":
401
417
  "{unchanged} se han mantenido sin cambios.",
402
418
  "structures.bulkUpdateStructures.success.updated":
403
419
  "Se han actualizado {changed} estructuras.",
420
+ "structures.bulkUploadStructuresDomains.success.header":
421
+ "¡Actualización finalizada! subidos {count_ids} errores {count_errors}",
404
422
  "structures.crumbs.top": "Estructuras",
405
423
  "structures.edit.bulk.confirmation.content":
406
424
  "Se van a actualizar {structures_count} estructuras. ¿Estás seguro?",
@@ -453,6 +471,8 @@ export default {
453
471
  "External Id Inválido",
454
472
  "structures.uploadStructures.failed.header":
455
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",
456
476
  "structures.uploadStructures.failed.invalid_file_format":
457
477
  "Formato de fichero inválido",
458
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
+ });
@@ -4,6 +4,7 @@ import {
4
4
  bulkUpdateStructures,
5
5
  uploadStructures,
6
6
  updateStructureType,
7
+ uploadStructuresDomains,
7
8
  } from "../routines";
8
9
 
9
10
  const initialState = null;
@@ -18,10 +19,7 @@ const ddMessage = (state = initialState, { type, payload }) => {
18
19
  ? _.flow(
19
20
  _.propOr([], "errors"),
20
21
  _.map((error) => ({
21
- id:
22
- type == bulkUpdateStructures.SUCCESS
23
- ? `structures.bulkUpdateStructures.failed.note.${error.message}`
24
- : `structures.uploadStructures.failed.note.${error.message}`,
22
+ id: `structures.bulkUpdateStructures.failed.note.${error.message}`,
25
23
  fields: {
26
24
  row: error.row,
27
25
  id: error.id,
@@ -29,10 +27,7 @@ const ddMessage = (state = initialState, { type, payload }) => {
29
27
  externalId: error.external_id,
30
28
  message: error.message,
31
29
  },
32
- defaultMessage:
33
- type == bulkUpdateStructures.SUCCESS
34
- ? "structures.bulkUpdateStructures.success.errors"
35
- : "structures.bulkUploadStructures.success.errors",
30
+ defaultMessage: "structures.bulkUploadStructures.success.errors",
36
31
  }))
37
32
  )(payload.data)
38
33
  : "";
@@ -51,6 +46,54 @@ const ddMessage = (state = initialState, { type, payload }) => {
51
46
  initialMaxListItems: 5,
52
47
  };
53
48
  }
49
+
50
+ case uploadStructuresDomains.SUCCESS: {
51
+ const messagesImp = _.has("errors")(payload.data)
52
+ ? _.flow(
53
+ _.propOr([], "errors"),
54
+ _.map((error) => {
55
+ const errorMessage = Object.entries(error.message)
56
+ .map(([field, messages]) => `${field}: ${messages.join(", ")}`)
57
+ .join(" | ");
58
+ return {
59
+ id: `structures.bulkUploadStructuresDomains.success.errors.${errorMessage}`,
60
+ fields: {
61
+ row: error.row,
62
+ id: error.id,
63
+ field: error.field,
64
+ externalId: error.external_id,
65
+ message: errorMessage,
66
+ },
67
+ };
68
+ })
69
+ )(payload.data)
70
+ : "";
71
+ return {
72
+ error: false,
73
+ header: "structures.bulkUploadStructuresDomains.success.header",
74
+ icon: "check",
75
+ color: payload.data.errors.length >= 1 ? "orange" : "green",
76
+ text: "",
77
+ messages: messagesImp,
78
+ fields: {
79
+ count_ids: payload.data.ids.length,
80
+ count_errors: payload.data.errors.length,
81
+ },
82
+ downloadable: true,
83
+ initialMaxListItems: 5,
84
+ };
85
+ }
86
+
87
+ case uploadStructuresDomains.FAILURE:
88
+ return payload.status !== 422
89
+ ? state
90
+ : {
91
+ error: true,
92
+ header: "structures.uploadStructuresDomains.failed.header",
93
+ icon: "attention",
94
+ content: payload?.data?.error?.message,
95
+ };
96
+
54
97
  case updateStructureType.SUCCESS:
55
98
  return {
56
99
  error: false,
package/src/routines.js CHANGED
@@ -132,6 +132,7 @@ export const updateStructureTag = createRoutine("UPDATE_STRUCTURE_TAG");
132
132
  export const updateStructureType = createRoutine("UPDATE_STRUCTURE_TYPE");
133
133
  export const updateSystem = createRoutine("UPDATE_SYSTEM");
134
134
  export const uploadStructures = createRoutine("UPLOAD_STRUCTURES");
135
+ export const uploadStructuresDomains = createRoutine("UPLOAD_STRUCTURES_DOMAINS");
135
136
  export const addGrantRequestToCart = createRoutine("ADD_GRANT_REQUEST_TO_CART");
136
137
  export const removeGrantRequestFromCart = createRoutine(
137
138
  "REMOVE_GRANT_REQUEST_FROM_CART"
@@ -0,0 +1,81 @@
1
+ import { testSaga } from "redux-saga-test-plan";
2
+ import { apiJsonPost, UPLOAD_JSON_OPTS } from "@truedat/core/services/api";
3
+ import {
4
+ uploadStructuresDomainsRequestSaga,
5
+ uploadStructuresDomainsSaga,
6
+ } from "../uploadStructuresDomains";
7
+ import { uploadStructuresDomains } from "../../routines";
8
+ import { API_STRUCTURES_DOMAINS_UPLOAD } from "../../api";
9
+
10
+ describe("sagas: uploadStructuresDomainsRequestSaga", () => {
11
+ it("should invoke uploadStructuresDomainsSaga on trigger", () => {
12
+ expect(() => {
13
+ testSaga(uploadStructuresDomainsRequestSaga)
14
+ .next()
15
+ .takeLatest(
16
+ uploadStructuresDomains.TRIGGER,
17
+ uploadStructuresDomainsSaga
18
+ )
19
+ .finish()
20
+ .isDone();
21
+ }).not.toThrow();
22
+ });
23
+
24
+ it("should throw exception if an unhandled action is received", () => {
25
+ expect(() => {
26
+ testSaga(uploadStructuresDomainsRequestSaga)
27
+ .next()
28
+ .takeLatest("FOO", uploadStructuresDomainsSaga);
29
+ }).toThrow();
30
+ });
31
+ });
32
+
33
+ describe("sagas: uploadStructuresDomainsSaga", () => {
34
+ const body = { structures_domains: "content" };
35
+ const payload = { data: body };
36
+ const data = { message: [1, 2] };
37
+ it("should put a success action when a response is returned", () => {
38
+ expect(() => {
39
+ testSaga(uploadStructuresDomainsSaga, { payload })
40
+ .next()
41
+ .put(uploadStructuresDomains.request())
42
+ .next()
43
+ .call(
44
+ apiJsonPost,
45
+ API_STRUCTURES_DOMAINS_UPLOAD,
46
+ body,
47
+ UPLOAD_JSON_OPTS
48
+ )
49
+ .next({ data })
50
+ .put(uploadStructuresDomains.success({ data }))
51
+ .next()
52
+ .put(uploadStructuresDomains.fulfill())
53
+ .next()
54
+ .isDone();
55
+ }).not.toThrow();
56
+ });
57
+
58
+ it("should put a failure action when the call returns an error", () => {
59
+ const message = "Request failed";
60
+ const error = { message };
61
+
62
+ expect(() => {
63
+ testSaga(uploadStructuresDomainsSaga, { payload })
64
+ .next()
65
+ .put(uploadStructuresDomains.request())
66
+ .next()
67
+ .call(
68
+ apiJsonPost,
69
+ API_STRUCTURES_DOMAINS_UPLOAD,
70
+ body,
71
+ UPLOAD_JSON_OPTS
72
+ )
73
+ .throw(error)
74
+ .put(uploadStructuresDomains.failure(message))
75
+ .next()
76
+ .put(uploadStructuresDomains.fulfill())
77
+ .next()
78
+ .isDone();
79
+ }).not.toThrow();
80
+ });
81
+ });
@@ -46,6 +46,7 @@ import { updateStructureTagRequestSaga } from "./updateStructureTag";
46
46
  import { updateStructureTypeRequestSaga } from "./updateStructureType";
47
47
  import { updateSystemRequestSaga } from "./updateSystem";
48
48
  import { uploadStructuresRequestSaga } from "./uploadStructures";
49
+ import { uploadStructuresDomainsRequestSaga } from "./uploadStructuresDomains";
49
50
  import { operateGrantRequestToCartRequestSaga } from "./operateGrantRequestCart";
50
51
 
51
52
  export {
@@ -97,6 +98,7 @@ export {
97
98
  updateStructureTypeRequestSaga,
98
99
  updateSystemRequestSaga,
99
100
  uploadStructuresRequestSaga,
101
+ uploadStructuresDomainsRequestSaga,
100
102
  operateGrantRequestToCartRequestSaga,
101
103
  };
102
104
 
@@ -149,5 +151,6 @@ export default [
149
151
  updateStructureTypeRequestSaga(),
150
152
  updateSystemRequestSaga(),
151
153
  uploadStructuresRequestSaga(),
154
+ uploadStructuresDomainsRequestSaga(),
152
155
  operateGrantRequestToCartRequestSaga(),
153
156
  ];
@@ -0,0 +1,35 @@
1
+ import { call, put, takeLatest } from "redux-saga/effects";
2
+ import { apiJsonPost, UPLOAD_JSON_OPTS } from "@truedat/core/services/api";
3
+ import { uploadStructuresDomains } from "../routines";
4
+ import { API_STRUCTURES_DOMAINS_UPLOAD } from "../api";
5
+
6
+ export function* uploadStructuresDomainsSaga({ payload }) {
7
+ try {
8
+ const { data: body } = payload;
9
+ yield put(uploadStructuresDomains.request());
10
+ const { data } = yield call(
11
+ apiJsonPost,
12
+ API_STRUCTURES_DOMAINS_UPLOAD,
13
+ body,
14
+ UPLOAD_JSON_OPTS
15
+ );
16
+
17
+ yield put(uploadStructuresDomains.success({ data }));
18
+ } catch (error) {
19
+ if (error.response) {
20
+ const { status, data } = error.response;
21
+ yield put(uploadStructuresDomains.failure({ status, data }));
22
+ } else {
23
+ yield put(uploadStructuresDomains.failure(error.message));
24
+ }
25
+ } finally {
26
+ yield put(uploadStructuresDomains.fulfill());
27
+ }
28
+ }
29
+
30
+ export function* uploadStructuresDomainsRequestSaga() {
31
+ yield takeLatest(
32
+ uploadStructuresDomains.TRIGGER,
33
+ uploadStructuresDomainsSaga
34
+ );
35
+ }