@truedat/dd 7.2.4 → 7.2.6

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 (34) hide show
  1. package/package.json +6 -6
  2. package/src/api.js +4 -2
  3. package/src/components/StructuresDownloadOption.js +23 -20
  4. package/src/components/StructuresEditableDownloadOption.js +23 -21
  5. package/src/components/StructuresOptions.js +27 -24
  6. package/src/components/StructuresUploadEventsTable.js +3 -2
  7. package/src/components/StructuresUploadOption.js +18 -23
  8. package/src/components/StructuresView.js +1 -1
  9. package/src/components/__tests__/StructuresDownloadOption.spec.js +12 -12
  10. package/src/components/__tests__/StructuresEditableDownloadOption.spec.js +8 -8
  11. package/src/components/__tests__/StructuresUploadEventsTable.spec.js +2 -2
  12. package/src/components/__tests__/StructuresUploadOption.spec.js +2 -5
  13. package/src/components/__tests__/__snapshots__/StructuresDownloadOption.spec.js.snap +2 -1
  14. package/src/components/__tests__/__snapshots__/StructuresEditableDownloadOption.spec.js.snap +2 -7
  15. package/src/components/__tests__/__snapshots__/StructuresOptions.spec.js.snap +3 -0
  16. package/src/components/__tests__/__snapshots__/StructuresUploadOption.spec.js.snap +2 -0
  17. package/src/hooks/useStructures.js +34 -1
  18. package/src/reducers/__tests__/structuresUploadEvents.spec.js +2 -2
  19. package/src/reducers/index.js +0 -6
  20. package/src/routines.js +0 -4
  21. package/src/sagas/__tests__/fetchStructuresUploadEvents.spec.js +2 -2
  22. package/src/sagas/index.js +0 -9
  23. package/src/reducers/__tests__/structuresDownloading.spec.js +0 -26
  24. package/src/reducers/__tests__/structuresEditableDownloading.spec.js +0 -32
  25. package/src/reducers/__tests__/uploadingStructuresFile.spec.js +0 -40
  26. package/src/reducers/structuresDownloading.js +0 -14
  27. package/src/reducers/structuresEditableDownloading.js +0 -14
  28. package/src/reducers/uploadingStructuresFile.js +0 -18
  29. package/src/sagas/__tests__/downloadEditableStructures.spec.js +0 -81
  30. package/src/sagas/__tests__/downloadStructures.spec.js +0 -82
  31. package/src/sagas/__tests__/uploadStructures.spec.js +0 -70
  32. package/src/sagas/downloadEditableStructures.js +0 -51
  33. package/src/sagas/downloadStructures.js +0 -51
  34. package/src/sagas/uploadStructures.js +0 -33
@@ -2,11 +2,19 @@ import _ from "lodash/fp";
2
2
  import { compile } from "path-to-regexp";
3
3
  import useSWR from "swr";
4
4
  import useSWRMutations from "swr/mutation";
5
- import { apiJson, apiJsonPost } from "@truedat/core/services/api";
5
+ import FileSaver from "file-saver";
6
+ import {
7
+ apiJson,
8
+ apiJsonPost,
9
+ JSON_OPTS,
10
+ UPLOAD_JSON_OPTS,
11
+ } from "@truedat/core/services/api";
6
12
  import {
7
13
  API_SYSTEM_STRUCTURES,
8
14
  API_DATA_STRUCTURES_SEARCH,
9
15
  API_DATA_STRUCTURE_FILTERS_SEARCH,
16
+ API_DATA_STRUCTURES_XLSX_DOWNLOAD,
17
+ API_DATA_STRUCTURES_XLSX_UPLOAD,
10
18
  } from "../api";
11
19
 
12
20
  const toApiPath = compile(API_SYSTEM_STRUCTURES);
@@ -25,6 +33,15 @@ const asQueryParams = (queryParams) => {
25
33
  return _.isEmpty(stringifyQueryParams) ? "" : `?${stringifyQueryParams}`;
26
34
  };
27
35
 
36
+ function saveFile({ data, headers }) {
37
+ const contentDisposition = headers["content-disposition"];
38
+ const regex = /filename=(.+)$/;
39
+ const match = regex.exec(contentDisposition);
40
+ const fileName = match ? match[1] : "structures.xlsx";
41
+
42
+ FileSaver.saveAs(data, fileName);
43
+ }
44
+
28
45
  export const useStructures = (args) => {
29
46
  const url = toApiPath({ id: args.systemId });
30
47
  const requestData = () => apiJson(`${url}${asQueryParams(args)}`);
@@ -55,3 +72,19 @@ export const useDataStructureSearch = () => {
55
72
  return apiJsonPost(url, arg);
56
73
  });
57
74
  };
75
+
76
+ export const useDataStructureDownload = () => {
77
+ return useSWRMutations(API_DATA_STRUCTURES_XLSX_DOWNLOAD, (url, { arg }) => {
78
+ return apiJsonPost(url, arg, { ...JSON_OPTS, responseType: "blob" }).then(
79
+ ({ data, headers }) => {
80
+ saveFile({ data, headers });
81
+ }
82
+ );
83
+ });
84
+ };
85
+
86
+ export const useDataStructureUpload = () => {
87
+ return useSWRMutations(API_DATA_STRUCTURES_XLSX_UPLOAD, (url, { arg }) => {
88
+ return apiJsonPost(url, arg, UPLOAD_JSON_OPTS);
89
+ });
90
+ };
@@ -13,7 +13,7 @@ describe("reducers: structuresUploadEvents", () => {
13
13
  it("should handle the fetchStructuresUploadEvents.SUCCESS action", () => {
14
14
  const someEvents = [
15
15
  {
16
- csv_hash: "99E400B91D164F8F0A39F400CA323C8F",
16
+ hash: "99E400B91D164F8F0A39F400CA323C8F",
17
17
  inserted_at: "2022-04-23T15:53:24.638484Z",
18
18
  message: null,
19
19
  response: {},
@@ -22,7 +22,7 @@ describe("reducers: structuresUploadEvents", () => {
22
22
  user_id: 467,
23
23
  },
24
24
  {
25
- csv_hash: "47D90FDF1AD967BD7DBBDAE28664278E",
25
+ hash: "47D90FDF1AD967BD7DBBDAE28664278E",
26
26
  inserted_at: "2022-04-23T15:14:48.770275Z",
27
27
  message: null,
28
28
  response: {},
@@ -58,8 +58,6 @@ import { structureQuery } from "./structureQuery";
58
58
  import { structureRedirect } from "./structureRedirect";
59
59
  import { structures } from "./structures";
60
60
  import { structuresAliasNameMode } from "./structuresAliasNameMode";
61
- import { structuresDownloading } from "./structuresDownloading";
62
- import { structuresEditableDownloading } from "./structuresEditableDownloading";
63
61
  import { structureSiblings } from "./structureSiblings";
64
62
  import { structuresSiblings } from "./structureSiblings";
65
63
  import { structuresUploadEvents } from "./structuresUploadEvents";
@@ -80,7 +78,6 @@ import { systemsLoading } from "./systemsLoading";
80
78
  import { systemStructures } from "./systemStructures";
81
79
  import { systemStructuresLoading } from "./systemStructuresLoading";
82
80
  import { tagSaving } from "./tagSaving";
83
- import { uploadingStructuresFile } from "./uploadingStructuresFile";
84
81
  import { userPermissions } from "./userPermissions";
85
82
  import { userSearchFilters } from "./userSearchFilters";
86
83
 
@@ -145,8 +142,6 @@ export {
145
142
  structureRedirect,
146
143
  structures,
147
144
  structuresAliasNameMode,
148
- structuresDownloading,
149
- structuresEditableDownloading,
150
145
  structuresFields,
151
146
  structureSiblings,
152
147
  structuresSiblings,
@@ -169,7 +164,6 @@ export {
169
164
  systemStructures,
170
165
  systemStructuresLoading,
171
166
  tagSaving,
172
- uploadingStructuresFile,
173
167
  userPermissions,
174
168
  userSearchFilters,
175
169
  };
package/src/routines.js CHANGED
@@ -72,14 +72,10 @@ export const deleteUserSearchFilter = createRoutine(
72
72
  );
73
73
  export const doStructureNoteAction = createRoutine("DO_STRUCTURE_NOTE_ACTION");
74
74
  export const downloadCsvGraph = createRoutine("DOWNLOAD_CSV_GRAPH");
75
- export const downloadEditableStructures = createRoutine(
76
- "DOWNLOAD_EDITABLE_STRUCTURES"
77
- );
78
75
  export const downloadGrants = createRoutine("DOWNLOAD_GRANTS");
79
76
  export const downloadReferenceDataset = createRoutine(
80
77
  "DOWNLOAD_REFERENCE_DATASET"
81
78
  );
82
- export const downloadStructures = createRoutine("DOWNLOAD_STRUCTURES");
83
79
  export const excludeNode = createRoutine("EXCLUDE_NODE");
84
80
  export const fetchGrant = createRoutine("FETCH_GRANT");
85
81
  export const fetchGrantFilters = createRoutine("FETCH_GRANT_FILTERS");
@@ -35,10 +35,10 @@ describe("sagas: fetchStructuresUploadEventsSaga", () => {
35
35
  const url = API_STRUCTURES_UPLOAD_EVENTS;
36
36
  const data = [
37
37
  {
38
- csv_hash: "99E400B91D164F8F0A39F400CA323C8F",
38
+ hash: "99E400B91D164F8F0A39F400CA323C8F",
39
39
  },
40
40
  {
41
- csv_hash: "47D90FDF1AD967BD7DBBDAE28664278E",
41
+ hash: "47D90FDF1AD967BD7DBBDAE28664278E",
42
42
  },
43
43
  ];
44
44
 
@@ -18,10 +18,8 @@ import { deleteTagRequestSaga } from "./deleteTag";
18
18
  import { deleteUserSearchFilterRequestSaga } from "./deleteUserSearchFilter";
19
19
  import { doStructureNoteActionRequestSaga } from "./doStructureNoteAction";
20
20
  import { downloadCsvGraphRequestSaga } from "./downloadCsvGraph";
21
- import { downloadEditableStructuresRequestSaga } from "./downloadEditableStructures";
22
21
  import { downloadGrantsRequestSaga } from "./downloadGrants";
23
22
  import { downloadReferenceDatasetRequestSaga } from "./downloadReferenceDataset";
24
- import { downloadStructuresRequestSaga } from "./downloadStructures";
25
23
  import { fetchGrantFiltersRequestSaga } from "./fetchGrantFilters";
26
24
  import { fetchGrantRequestsFiltersRequestSaga } from "./fetchGrantRequestsFilters";
27
25
  import { fetchGrantRequestRequestSaga } from "./fetchGrantRequest";
@@ -54,7 +52,6 @@ import { updateStructureRequestSaga } from "./updateStructure";
54
52
  import { updateStructureTypeRequestSaga } from "./updateStructureType";
55
53
  import { updateSystemRequestSaga } from "./updateSystem";
56
54
  import { uploadStructuresDomainsRequestSaga } from "./uploadStructuresDomains";
57
- import { uploadStructuresRequestSaga } from "./uploadStructures";
58
55
  import { updateTagRequestSaga } from "./updateTag";
59
56
  import { upsertCatalogViewConfigRequestSaga } from "./upsertCatalogViewConfig";
60
57
 
@@ -79,10 +76,8 @@ export {
79
76
  deleteUserSearchFilterRequestSaga,
80
77
  doStructureNoteActionRequestSaga,
81
78
  downloadCsvGraphRequestSaga,
82
- downloadEditableStructuresRequestSaga,
83
79
  downloadGrantsRequestSaga,
84
80
  downloadReferenceDatasetRequestSaga,
85
- downloadStructuresRequestSaga,
86
81
  fetchGrantFiltersRequestSaga,
87
82
  fetchGrantRequestRequestSaga,
88
83
  fetchGrantRequestsFiltersRequestSaga,
@@ -115,7 +110,6 @@ export {
115
110
  updateStructureTypeRequestSaga,
116
111
  updateSystemRequestSaga,
117
112
  uploadStructuresDomainsRequestSaga,
118
- uploadStructuresRequestSaga,
119
113
  updateTagRequestSaga,
120
114
  upsertCatalogViewConfigRequestSaga,
121
115
  };
@@ -141,10 +135,8 @@ export default [
141
135
  deleteUserSearchFilterRequestSaga(),
142
136
  doStructureNoteActionRequestSaga(),
143
137
  downloadCsvGraphRequestSaga(),
144
- downloadEditableStructuresRequestSaga(),
145
138
  downloadGrantsRequestSaga(),
146
139
  downloadReferenceDatasetRequestSaga(),
147
- downloadStructuresRequestSaga(),
148
140
  fetchGrantFiltersRequestSaga(),
149
141
  fetchGrantRequestRequestSaga(),
150
142
  fetchGrantRequestsRequestSaga(),
@@ -178,6 +170,5 @@ export default [
178
170
  updateStructureTypeRequestSaga(),
179
171
  updateSystemRequestSaga(),
180
172
  uploadStructuresDomainsRequestSaga(),
181
- uploadStructuresRequestSaga(),
182
173
  upsertCatalogViewConfigRequestSaga(),
183
174
  ];
@@ -1,26 +0,0 @@
1
- import { downloadStructures } from "../../routines";
2
- import { structuresDownloading } from "..";
3
-
4
- const fooState = { foo: "bar" };
5
-
6
- describe("reducers: structuresDownloading", () => {
7
- it("should provide the initial state", () => {
8
- expect(structuresDownloading(undefined, {})).toBe(false);
9
- });
10
-
11
- it("should be true after receiving the downloadStructures.TRIGGER action", () => {
12
- expect(
13
- structuresDownloading(fooState, { type: downloadStructures.TRIGGER })
14
- ).toBe(true);
15
- });
16
-
17
- it("should be false after receiving the downloadStructures.FULFILL action", () => {
18
- expect(
19
- structuresDownloading(fooState, { type: downloadStructures.FULFILL })
20
- ).toBe(false);
21
- });
22
-
23
- it("should ignore unhandled actions", () => {
24
- expect(structuresDownloading(fooState, { type: "FOO" })).toBe(fooState);
25
- });
26
- });
@@ -1,32 +0,0 @@
1
- import { downloadEditableStructures } from "../../routines";
2
- import { structuresEditableDownloading } from "..";
3
-
4
- const fooState = { foo: "bar" };
5
-
6
- describe("reducers: structuresEditableDownloading", () => {
7
- it("should provide the initial state", () => {
8
- expect(structuresEditableDownloading(undefined, {})).toBe(false);
9
- });
10
-
11
- it("should be true after receiving the downloadEditableStructures.TRIGGER action", () => {
12
- expect(
13
- structuresEditableDownloading(fooState, {
14
- type: downloadEditableStructures.TRIGGER,
15
- })
16
- ).toBe(true);
17
- });
18
-
19
- it("should be false after receiving the downloadEditableStructures.FULFILL action", () => {
20
- expect(
21
- structuresEditableDownloading(fooState, {
22
- type: downloadEditableStructures.FULFILL,
23
- })
24
- ).toBe(false);
25
- });
26
-
27
- it("should ignore unhandled actions", () => {
28
- expect(structuresEditableDownloading(fooState, { type: "FOO" })).toBe(
29
- fooState
30
- );
31
- });
32
- });
@@ -1,40 +0,0 @@
1
- import { uploadStructures } from "../../routines";
2
- import { uploadingStructuresFile } from "..";
3
-
4
- const fooState = { foo: "bar" };
5
-
6
- describe("reducers: system", () => {
7
- const initialState = false;
8
-
9
- it("should provide the initial state", () => {
10
- expect(uploadingStructuresFile(undefined, {})).toEqual(initialState);
11
- });
12
-
13
- it("should handle the uploadStructures.TRIGGER action", () => {
14
- expect(
15
- uploadingStructuresFile(fooState, {
16
- type: uploadStructures.TRIGGER
17
- })
18
- ).toBe(true);
19
- });
20
-
21
- it("should handle the uploadStructures.TRIGGER action", () => {
22
- expect(
23
- uploadingStructuresFile(fooState, {
24
- type: uploadStructures.REQUEST
25
- })
26
- ).toBe(true);
27
- });
28
-
29
- it("should handle the uploadStructures.TRIGGER action", () => {
30
- expect(
31
- uploadingStructuresFile(fooState, {
32
- type: uploadStructures.FULFILL
33
- })
34
- ).toBe(false);
35
- });
36
-
37
- it("should ignore unknown actions", () => {
38
- expect(uploadingStructuresFile(fooState, { type: "FOO" })).toBe(fooState);
39
- });
40
- });
@@ -1,14 +0,0 @@
1
- import { downloadStructures } from "../routines";
2
-
3
- const structuresDownloading = (state = false, { type }) => {
4
- switch (type) {
5
- case downloadStructures.TRIGGER:
6
- return true;
7
- case downloadStructures.FULFILL:
8
- return false;
9
- default:
10
- return state;
11
- }
12
- };
13
-
14
- export { structuresDownloading };
@@ -1,14 +0,0 @@
1
- import { downloadEditableStructures } from "../routines";
2
-
3
- const structuresEditableDownloading = (state = false, { type }) => {
4
- switch (type) {
5
- case downloadEditableStructures.TRIGGER:
6
- return true;
7
- case downloadEditableStructures.FULFILL:
8
- return false;
9
- default:
10
- return state;
11
- }
12
- };
13
-
14
- export { structuresEditableDownloading };
@@ -1,18 +0,0 @@
1
- import { uploadStructures } from "../routines";
2
-
3
- const initialState = false;
4
-
5
- export const uploadingStructuresFile = (state = initialState, { type }) => {
6
- switch (type) {
7
- case uploadStructures.TRIGGER:
8
- return true;
9
- case uploadStructures.REQUEST:
10
- return true;
11
- case uploadStructures.FULFILL:
12
- return false;
13
- default:
14
- return state;
15
- }
16
- };
17
-
18
- export default uploadingStructuresFile;
@@ -1,81 +0,0 @@
1
- import { testSaga } from "redux-saga-test-plan";
2
- import { apiJsonPost, JSON_OPTS } from "@truedat/core/services/api";
3
- import {
4
- downloadEditableStructuresRequestSaga,
5
- downloadEditableStructuresSaga,
6
- saveFile,
7
- } from "../downloadEditableStructures";
8
- import { downloadEditableStructures } from "../../routines";
9
- import { API_DATA_STRUCTURES_EDITABLE_CSV } from "../../api";
10
-
11
- describe("sagas: downloadEditableStructuresRequestSaga", () => {
12
- it("should invoke downloadEditableStructuresSaga on downloadEditableStructures.TRIGGER", () => {
13
- expect(() => {
14
- testSaga(downloadEditableStructuresRequestSaga)
15
- .next()
16
- .takeLatest(
17
- downloadEditableStructures.TRIGGER,
18
- downloadEditableStructuresSaga
19
- )
20
- .finish()
21
- .isDone();
22
- }).not.toThrow();
23
- });
24
-
25
- it("should throw exception if an unhandled action is received", () => {
26
- expect(() => {
27
- testSaga(downloadEditableStructuresRequestSaga)
28
- .next()
29
- .takeLatest("FOO", downloadEditableStructuresRequestSaga);
30
- }).toThrow();
31
- });
32
- });
33
-
34
- describe("sagas: downloadEditableStructuresSaga", () => {
35
- const lang = "es";
36
- const query = { filters: {} };
37
- const payload = { lang, searchParams: query };
38
- const body = {
39
- structure_url_schema: "http://localhost/structures/:id",
40
- ...query,
41
- lang,
42
- };
43
- const data = "SOME CSV DATA";
44
-
45
- it("should put a success action when a response is returned", () => {
46
- expect(() => {
47
- testSaga(downloadEditableStructuresSaga, { payload })
48
- .next()
49
- .put(downloadEditableStructures.request(body))
50
- .next()
51
- .call(apiJsonPost, API_DATA_STRUCTURES_EDITABLE_CSV, body, JSON_OPTS)
52
- .next({ data })
53
- .call(saveFile, data)
54
- .next()
55
- .put(downloadEditableStructures.success(data))
56
- .next()
57
- .put(downloadEditableStructures.fulfill())
58
- .next()
59
- .isDone();
60
- }).not.toThrow();
61
- });
62
-
63
- it("should put a failure action when the call returns an error", () => {
64
- const message = "Request failed";
65
- const error = { message };
66
-
67
- expect(() => {
68
- testSaga(downloadEditableStructuresSaga, { payload })
69
- .next()
70
- .put(downloadEditableStructures.request(body))
71
- .next()
72
- .call(apiJsonPost, API_DATA_STRUCTURES_EDITABLE_CSV, body, JSON_OPTS)
73
- .throw(error)
74
- .put(downloadEditableStructures.failure(message))
75
- .next()
76
- .put(downloadEditableStructures.fulfill())
77
- .next()
78
- .isDone();
79
- }).not.toThrow();
80
- });
81
- });
@@ -1,82 +0,0 @@
1
- import { testSaga } from "redux-saga-test-plan";
2
- import { apiJsonPost, JSON_OPTS } from "@truedat/core/services/api";
3
- import {
4
- downloadStructuresRequestSaga,
5
- downloadStructuresSaga,
6
- saveFile,
7
- } from "../downloadStructures";
8
- import { downloadStructures } from "../../routines";
9
- import { API_DATA_STRUCTURES_CSV } from "../../api";
10
-
11
- describe("sagas: downloadStructuresRequestSaga", () => {
12
- it("should invoke downloadStructuresSaga on downloadStructures.TRIGGER", () => {
13
- expect(() => {
14
- testSaga(downloadStructuresRequestSaga)
15
- .next()
16
- .takeLatest(downloadStructures.TRIGGER, downloadStructuresSaga)
17
- .finish()
18
- .isDone();
19
- }).not.toThrow();
20
- });
21
-
22
- it("should throw exception if an unhandled action is received", () => {
23
- expect(() => {
24
- testSaga(downloadStructuresRequestSaga)
25
- .next()
26
- .takeLatest("FOO", downloadStructuresRequestSaga);
27
- }).toThrow();
28
- });
29
- });
30
-
31
- describe("sagas: downloadStructuresSaga", () => {
32
- const headerLabels = { name: "Name" };
33
- const lang = "es";
34
- const query = { filters: {} };
35
- const payload = { headerLabels, lang: lang, searchParams: query };
36
-
37
- const data = "SOME CSV DATA";
38
-
39
- const body = {
40
- header_labels: headerLabels,
41
- lang: lang,
42
- structure_url_schema: "http://localhost/structures/:id",
43
- ...query,
44
- };
45
-
46
- it("should put a success action when a response is returned", () => {
47
- expect(() => {
48
- testSaga(downloadStructuresSaga, { payload })
49
- .next()
50
- .put(downloadStructures.request(body))
51
- .next()
52
- .call(apiJsonPost, API_DATA_STRUCTURES_CSV, body, JSON_OPTS)
53
- .next({ data })
54
- .call(saveFile, data)
55
- .next()
56
- .put(downloadStructures.success(data))
57
- .next()
58
- .put(downloadStructures.fulfill())
59
- .next()
60
- .isDone();
61
- }).not.toThrow();
62
- });
63
-
64
- it("should put a failure action when the call returns an error", () => {
65
- const message = "Request failed";
66
- const error = { message };
67
-
68
- expect(() => {
69
- testSaga(downloadStructuresSaga, { payload })
70
- .next()
71
- .put(downloadStructures.request(body))
72
- .next()
73
- .call(apiJsonPost, API_DATA_STRUCTURES_CSV, body, JSON_OPTS)
74
- .throw(error)
75
- .put(downloadStructures.failure(message))
76
- .next()
77
- .put(downloadStructures.fulfill())
78
- .next()
79
- .isDone();
80
- }).not.toThrow();
81
- });
82
- });
@@ -1,70 +0,0 @@
1
- import { testSaga } from "redux-saga-test-plan";
2
- import { apiJsonPost, UPLOAD_JSON_OPTS } from "@truedat/core/services/api";
3
- import {
4
- uploadStructuresRequestSaga,
5
- uploadStructuresSaga,
6
- } from "../uploadStructures";
7
- import { uploadStructures } from "../../routines";
8
- import { API_STRUCTURES_UPLOAD } from "../../api";
9
-
10
- describe("sagas: uploadStructuresRequestSaga", () => {
11
- it("should invoke uploadStructuresSaga on trigger", () => {
12
- expect(() => {
13
- testSaga(uploadStructuresRequestSaga)
14
- .next()
15
- .takeLatest(uploadStructures.TRIGGER, uploadStructuresSaga)
16
- .finish()
17
- .isDone();
18
- }).not.toThrow();
19
- });
20
-
21
- it("should throw exception if an unhandled action is received", () => {
22
- expect(() => {
23
- testSaga(uploadStructuresRequestSaga)
24
- .next()
25
- .takeLatest("FOO", uploadStructuresSaga);
26
- }).toThrow();
27
- });
28
- });
29
-
30
- describe("sagas: uploadStructuresSaga", () => {
31
- const lang = "es";
32
- const body = new FormData();
33
- const payload = { data: body, lang };
34
- const status = "JUST_STARTED";
35
- const data = { message: [1, 2] };
36
- it("should put a success action when a response is returned", () => {
37
- expect(() => {
38
- testSaga(uploadStructuresSaga, { payload })
39
- .next()
40
- .put(uploadStructures.request())
41
- .next()
42
- .call(apiJsonPost, API_STRUCTURES_UPLOAD, body, UPLOAD_JSON_OPTS)
43
- .next({ status, data })
44
- .put(uploadStructures.success({ status, data }))
45
- .next()
46
- .put(uploadStructures.fulfill())
47
- .next()
48
- .isDone();
49
- }).not.toThrow();
50
- });
51
-
52
- it("should put a failure action when the call returns an error", () => {
53
- const message = "Request failed";
54
- const error = { message };
55
-
56
- expect(() => {
57
- testSaga(uploadStructuresSaga, { payload })
58
- .next()
59
- .put(uploadStructures.request())
60
- .next()
61
- .call(apiJsonPost, API_STRUCTURES_UPLOAD, body, UPLOAD_JSON_OPTS)
62
- .throw(error)
63
- .put(uploadStructures.failure(message))
64
- .next()
65
- .put(uploadStructures.fulfill())
66
- .next()
67
- .isDone();
68
- }).not.toThrow();
69
- });
70
- });
@@ -1,51 +0,0 @@
1
- import _ from "lodash/fp";
2
- import FileSaver from "file-saver";
3
- import { call, put, takeLatest } from "redux-saga/effects";
4
- import { apiJsonPost, JSON_OPTS } from "@truedat/core/services/api";
5
- import { STRUCTURE } from "@truedat/core/routes";
6
- import { downloadEditableStructures } from "../routines";
7
- import { API_DATA_STRUCTURES_EDITABLE_CSV } from "../api";
8
-
9
- export function saveFile(data) {
10
- if (!_.isEmpty(data)) {
11
- const blob = new Blob([String.fromCharCode(0xfeff), data], {
12
- type: "text/csv;charset=utf-8",
13
- });
14
- FileSaver.saveAs(blob, "structures.csv");
15
- }
16
- }
17
-
18
- export function* downloadEditableStructuresSaga({ payload }) {
19
- const lang = _.propOr("en", "lang")(payload);
20
- try {
21
- const query = _.prop("searchParams")(payload);
22
- const body = {
23
- structure_url_schema: getStructureUrlSchema(),
24
- lang,
25
- ...query,
26
- };
27
- const url = API_DATA_STRUCTURES_EDITABLE_CSV;
28
- yield put(downloadEditableStructures.request(body));
29
- const { data } = yield call(apiJsonPost, url, body, JSON_OPTS);
30
- yield call(saveFile, data);
31
- yield put(downloadEditableStructures.success(data));
32
- } catch (error) {
33
- if (error.response) {
34
- const { status, data } = error.response;
35
- yield put(downloadEditableStructures.failure({ status, data }));
36
- } else {
37
- yield put(downloadEditableStructures.failure(error.message));
38
- }
39
- } finally {
40
- yield put(downloadEditableStructures.fulfill());
41
- }
42
- }
43
-
44
- export function* downloadEditableStructuresRequestSaga() {
45
- yield takeLatest(
46
- downloadEditableStructures.TRIGGER,
47
- downloadEditableStructuresSaga
48
- );
49
- }
50
-
51
- const getStructureUrlSchema = () => window.location.origin + STRUCTURE;
@@ -1,51 +0,0 @@
1
- import _ from "lodash/fp";
2
- import FileSaver from "file-saver";
3
- import { call, put, takeLatest } from "redux-saga/effects";
4
- import { apiJsonPost, JSON_OPTS } from "@truedat/core/services/api";
5
- import { STRUCTURE } from "@truedat/core/routes";
6
- import { downloadStructures } from "../routines";
7
- import { API_DATA_STRUCTURES_CSV } from "../api";
8
-
9
- export function saveFile(data) {
10
- if (!_.isEmpty(data)) {
11
- const blob = new Blob([String.fromCharCode(0xfeff), data], {
12
- type: "text/csv;charset=utf-8",
13
- });
14
- FileSaver.saveAs(blob, "structures.csv");
15
- }
16
- }
17
-
18
- export function* downloadStructuresSaga({ payload }) {
19
- try {
20
- const headerLabels = _.propOr({}, "headerLabels")(payload);
21
- const lang = _.propOr("en", "lang")(payload);
22
- const query = _.prop("searchParams")(payload);
23
-
24
- const body = {
25
- header_labels: headerLabels,
26
- structure_url_schema: getStructureUrlSchema(),
27
- lang,
28
- ...query,
29
- };
30
- const url = API_DATA_STRUCTURES_CSV;
31
- yield put(downloadStructures.request(body));
32
- const { data } = yield call(apiJsonPost, url, body, JSON_OPTS);
33
- yield call(saveFile, data);
34
- yield put(downloadStructures.success(data));
35
- } catch (error) {
36
- if (error.response) {
37
- const { status, data } = error.response;
38
- yield put(downloadStructures.failure({ status, data }));
39
- } else {
40
- yield put(downloadStructures.failure(error.message));
41
- }
42
- } finally {
43
- yield put(downloadStructures.fulfill());
44
- }
45
- }
46
-
47
- export function* downloadStructuresRequestSaga() {
48
- yield takeLatest(downloadStructures.TRIGGER, downloadStructuresSaga);
49
- }
50
-
51
- const getStructureUrlSchema = () => window.location.origin + STRUCTURE;