@truedat/dd 4.32.1 → 4.33.3
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 +12 -0
- package/package.json +6 -6
- package/src/api.js +4 -0
- package/src/components/DictionaryRoutes.js +21 -3
- package/src/components/StructureTypesLoader.js +4 -2
- package/src/components/{StructuresDownloadButton.js → StructuresDownloadOption.js} +23 -26
- package/src/components/StructuresEditableDownloadOption.js +57 -0
- package/src/components/StructuresOptions.js +41 -0
- package/src/components/StructuresUpdateOption.js +46 -0
- package/src/components/{StructuresUploadButton.js → StructuresUploadOption.js} +17 -22
- package/src/components/StructuresView.js +6 -10
- package/src/components/SystemCreateOption.js +23 -0
- package/src/components/__tests__/StructuresDownloadOption.spec.js +45 -0
- package/src/components/__tests__/StructuresEditableDownloadOption.spec.js +39 -0
- package/src/components/__tests__/StructuresUpdateOption.spec.js +36 -0
- package/src/components/__tests__/StructuresUploadOption.spec.js +41 -0
- package/src/components/__tests__/SystemCreateOption.spec.js +22 -0
- package/src/components/__tests__/__snapshots__/StructuresDownloadOption.spec.js.snap +24 -0
- package/src/components/__tests__/__snapshots__/StructuresEditableDownloadOption.spec.js.snap +24 -0
- package/src/components/__tests__/__snapshots__/StructuresUpdateOption.spec.js.snap +19 -0
- package/src/components/__tests__/__snapshots__/StructuresUploadOption.spec.js.snap +39 -0
- package/src/components/__tests__/__snapshots__/StructuresView.spec.js.snap +2 -6
- package/src/components/__tests__/__snapshots__/SystemCreateOption.spec.js.snap +21 -0
- package/src/components/index.js +0 -2
- package/src/messages/en.js +7 -2
- package/src/messages/es.js +8 -3
- package/src/reducers/__tests__/structuresEditableDownloading.spec.js +32 -0
- package/src/reducers/index.js +2 -0
- package/src/reducers/structuresEditableDownloading.js +14 -0
- package/src/routines.js +3 -0
- package/src/sagas/__tests__/downloadEditableStructures.spec.js +80 -0
- package/src/sagas/downloadEditableStructures.js +43 -0
- package/src/sagas/fetchStructureTypes.js +5 -3
- package/src/sagas/index.js +3 -0
- package/src/selectors/__tests__/__snapshots__/getGrantsColumns.spec.js.snap +2 -2
- package/src/selectors/__tests__/getTabVisibility.spec.js +3 -6
- package/src/selectors/getTabVisibility.js +3 -12
- package/src/components/SystemCreateButton.js +0 -27
- package/src/components/__tests__/StructuresDownloadButton.spec.js +0 -26
- package/src/components/__tests__/StructuresUpdateButton.spec.js +0 -27
- package/src/components/__tests__/StructuresUploadButton.spec.js +0 -28
- package/src/components/__tests__/SystemCreateButton.spec.js +0 -14
- package/src/components/__tests__/__snapshots__/StructuresDownloadButton.spec.js.snap +0 -33
- package/src/components/__tests__/__snapshots__/StructuresUpdateButton.spec.js.snap +0 -44
- package/src/components/__tests__/__snapshots__/StructuresUploadButton.spec.js.snap +0 -515
- package/src/components/__tests__/__snapshots__/SystemCreateButton.spec.js.snap +0 -32
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// only admin user
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { render } from "@truedat/test/render";
|
|
4
|
+
import { StructuresUploadOption } from "../StructuresUploadOption";
|
|
5
|
+
|
|
6
|
+
describe("<StructuresUploadOption />", () => {
|
|
7
|
+
const renderOpts = {
|
|
8
|
+
messages: {
|
|
9
|
+
en: {
|
|
10
|
+
"uploadModal.accept.publish": "publish",
|
|
11
|
+
"structures.actions.upload.tooltip": "tooltip",
|
|
12
|
+
"structures.actions.upload.confirmation.header": "header",
|
|
13
|
+
"structures.actions.upload.confirmation.content": "content",
|
|
14
|
+
"uploadModal.accept.publish": "publish",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
it("matches the latest snapshot", () => {
|
|
20
|
+
const props = {
|
|
21
|
+
uploadStructures: jest.fn(),
|
|
22
|
+
};
|
|
23
|
+
const { container } = render(
|
|
24
|
+
<StructuresUploadOption {...props} />,
|
|
25
|
+
renderOpts
|
|
26
|
+
);
|
|
27
|
+
expect(container).toMatchSnapshot();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("matches the latest snapshot with auto publish", () => {
|
|
31
|
+
const props = {
|
|
32
|
+
uploadStructures: jest.fn(),
|
|
33
|
+
canAutoPublish: true,
|
|
34
|
+
};
|
|
35
|
+
const { container } = render(
|
|
36
|
+
<StructuresUploadOption {...props} />,
|
|
37
|
+
renderOpts
|
|
38
|
+
);
|
|
39
|
+
expect(container).toMatchSnapshot();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import { SystemCreateOption } from "../SystemCreateOption";
|
|
4
|
+
|
|
5
|
+
jest.mock("@truedat/core/hooks", () => ({
|
|
6
|
+
useAuthorized: jest.fn(() => true),
|
|
7
|
+
}));
|
|
8
|
+
|
|
9
|
+
describe("<SystemCreateOption />", () => {
|
|
10
|
+
const renderOpts = {
|
|
11
|
+
messages: {
|
|
12
|
+
en: {
|
|
13
|
+
"structures.actions.new_system": "new system",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
it("matches the latest snapshot", () => {
|
|
19
|
+
const { container } = render(<SystemCreateOption />, renderOpts);
|
|
20
|
+
expect(container).toMatchSnapshot();
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<StructuresDownloadOption /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
aria-disabled="true"
|
|
7
|
+
class="disabled item"
|
|
8
|
+
role="option"
|
|
9
|
+
>
|
|
10
|
+
<i
|
|
11
|
+
aria-hidden="true"
|
|
12
|
+
class="download icon"
|
|
13
|
+
/>
|
|
14
|
+
<span>
|
|
15
|
+
tooltip
|
|
16
|
+
</span>
|
|
17
|
+
<p
|
|
18
|
+
class="menu-item-description"
|
|
19
|
+
>
|
|
20
|
+
popup
|
|
21
|
+
</p>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
`;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<StructuresEditableDownloadOption /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
aria-disabled="true"
|
|
7
|
+
class="disabled item"
|
|
8
|
+
role="option"
|
|
9
|
+
>
|
|
10
|
+
<i
|
|
11
|
+
aria-hidden="true"
|
|
12
|
+
class="download icon"
|
|
13
|
+
/>
|
|
14
|
+
<span>
|
|
15
|
+
tooltip
|
|
16
|
+
</span>
|
|
17
|
+
<p
|
|
18
|
+
class="menu-item-description"
|
|
19
|
+
>
|
|
20
|
+
popup
|
|
21
|
+
</p>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
`;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<StructuresUpdateOption /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<a
|
|
6
|
+
class="item"
|
|
7
|
+
href="/structures/bulk_update"
|
|
8
|
+
role="option"
|
|
9
|
+
>
|
|
10
|
+
<i
|
|
11
|
+
aria-hidden="true"
|
|
12
|
+
class="refresh icon"
|
|
13
|
+
/>
|
|
14
|
+
<span>
|
|
15
|
+
update
|
|
16
|
+
</span>
|
|
17
|
+
</a>
|
|
18
|
+
</div>
|
|
19
|
+
`;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<StructuresUploadOption /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="item"
|
|
7
|
+
role="option"
|
|
8
|
+
>
|
|
9
|
+
<i
|
|
10
|
+
aria-hidden="true"
|
|
11
|
+
class="upload icon"
|
|
12
|
+
/>
|
|
13
|
+
<span
|
|
14
|
+
class="text"
|
|
15
|
+
>
|
|
16
|
+
tooltip
|
|
17
|
+
</span>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
exports[`<StructuresUploadOption /> matches the latest snapshot with auto publish 1`] = `
|
|
23
|
+
<div>
|
|
24
|
+
<div
|
|
25
|
+
class="item"
|
|
26
|
+
role="option"
|
|
27
|
+
>
|
|
28
|
+
<i
|
|
29
|
+
aria-hidden="true"
|
|
30
|
+
class="upload icon"
|
|
31
|
+
/>
|
|
32
|
+
<span
|
|
33
|
+
class="text"
|
|
34
|
+
>
|
|
35
|
+
tooltip
|
|
36
|
+
</span>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
`;
|
|
@@ -6,13 +6,9 @@ exports[`<StructuresView /> matches the latest snapshot 1`] = `
|
|
|
6
6
|
<Divider
|
|
7
7
|
hidden={true}
|
|
8
8
|
/>
|
|
9
|
-
<
|
|
10
|
-
<Connect(StructuresUpdateButton)
|
|
11
|
-
canAutoPublish={false}
|
|
12
|
-
/>
|
|
13
|
-
<Connect(StructuresDownloadButton) />
|
|
14
|
-
<Connect(StructuresUploadButton)
|
|
9
|
+
<StructuresOptions
|
|
15
10
|
canAutoPublish={false}
|
|
11
|
+
canBulkUpload={true}
|
|
16
12
|
/>
|
|
17
13
|
<Connect(StructuresSearch) />
|
|
18
14
|
<injectIntl(Connect(SelectedFilters)) />
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<SystemCreateOption /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<a
|
|
6
|
+
class="item"
|
|
7
|
+
href="/systems/new"
|
|
8
|
+
role="option"
|
|
9
|
+
>
|
|
10
|
+
<i
|
|
11
|
+
aria-hidden="true"
|
|
12
|
+
class="plus square outline icon"
|
|
13
|
+
/>
|
|
14
|
+
<span
|
|
15
|
+
class="text"
|
|
16
|
+
>
|
|
17
|
+
new system
|
|
18
|
+
</span>
|
|
19
|
+
</a>
|
|
20
|
+
</div>
|
|
21
|
+
`;
|
package/src/components/index.js
CHANGED
|
@@ -45,7 +45,6 @@ import StructuresRoutes from "./StructuresRoutes";
|
|
|
45
45
|
import StructuresSearch from "./StructuresSearch";
|
|
46
46
|
import StructuresSearchResults from "./StructuresSearchResults";
|
|
47
47
|
import StructuresTable from "./StructuresTable";
|
|
48
|
-
import StructuresUpdateButton from "./StructuresUpdateButton";
|
|
49
48
|
import StructuresView from "./StructuresView";
|
|
50
49
|
import SystemForm from "./SystemForm";
|
|
51
50
|
import SystemStructures from "./SystemStructures";
|
|
@@ -103,7 +102,6 @@ export {
|
|
|
103
102
|
StructuresSearch,
|
|
104
103
|
StructuresSearchResults,
|
|
105
104
|
StructuresTable,
|
|
106
|
-
StructuresUpdateButton,
|
|
107
105
|
StructuresView,
|
|
108
106
|
SystemForm,
|
|
109
107
|
SystemStructures,
|
package/src/messages/en.js
CHANGED
|
@@ -329,15 +329,18 @@ export default {
|
|
|
329
329
|
"structures.actions.bulk_update": "Update",
|
|
330
330
|
"structures.actions.bulk_update.popup":
|
|
331
331
|
"You should select only one type in filters",
|
|
332
|
+
"structures.actions.editableDownload.tooltip":
|
|
333
|
+
"Download editable structures metadata",
|
|
332
334
|
"structures.actions.download.popup":
|
|
333
335
|
"You should select some filter or doing a search",
|
|
334
336
|
"structures.actions.download.tooltip": "Download structures metadata",
|
|
335
337
|
"structures.actions.edit_system": "Edit system",
|
|
336
338
|
"structures.actions.new_system": "New system",
|
|
337
339
|
"structures.actions.upload": "Upload file",
|
|
340
|
+
"structures.actions.upload.confirmation.content": "Notes",
|
|
338
341
|
"structures.actions.upload.confirmation.header":
|
|
339
|
-
"Upload
|
|
340
|
-
"structures.actions.upload.tooltip": "Upload
|
|
342
|
+
"Upload notes file of structures",
|
|
343
|
+
"structures.actions.upload.tooltip": "Upload structure notes",
|
|
341
344
|
"structures.bulkUpdate.crumbs.top": "Bulk update",
|
|
342
345
|
"structures.bulkUpdate.success.content":
|
|
343
346
|
"Updated {count} structures successfully",
|
|
@@ -395,6 +398,8 @@ export default {
|
|
|
395
398
|
"structures.uploadStructures.failed.default": "Error in row {row}",
|
|
396
399
|
"structures.uploadStructures.failed.df_content.invalid_content":
|
|
397
400
|
"Invalid content in row {row}",
|
|
401
|
+
"structures.uploadStructures.failed.external_id_not_exist":
|
|
402
|
+
"Invalid External Id",
|
|
398
403
|
"structures.uploadStructures.failed.header": "Upload Failed!",
|
|
399
404
|
"structures.uploadStructures.failed.invalid_file_format":
|
|
400
405
|
"Invalid file format",
|
package/src/messages/es.js
CHANGED
|
@@ -328,18 +328,21 @@ export default {
|
|
|
328
328
|
"structureVersion.inserted_at.header": "Insertada",
|
|
329
329
|
"structureVersion.updated_at.header": "Actualizada",
|
|
330
330
|
"structureVersion.version.header": "Versión",
|
|
331
|
-
"structures.actions.bulk_update": "Actualizar",
|
|
331
|
+
"structures.actions.bulk_update": "Actualizar masivamente",
|
|
332
332
|
"structures.actions.bulk_update.popup":
|
|
333
333
|
"Seleccione un único tipo existente en los filtros",
|
|
334
|
+
"structures.actions.editableDownload.tooltip":
|
|
335
|
+
"Descarga de metadata editable de estructuras",
|
|
334
336
|
"structures.actions.download.popup":
|
|
335
337
|
"Seleccione algún filtro o realice una búsqueda",
|
|
336
338
|
"structures.actions.download.tooltip": "Descarga de metadata de estructuras",
|
|
337
339
|
"structures.actions.edit_system": "Editar sistema",
|
|
338
340
|
"structures.actions.new_system": "Nuevo sistema",
|
|
339
341
|
"structures.actions.upload": "Subir fichero",
|
|
342
|
+
"structures.actions.upload.confirmation.content": "Notas",
|
|
340
343
|
"structures.actions.upload.confirmation.header":
|
|
341
|
-
"Subir fichero de
|
|
342
|
-
"structures.actions.upload.tooltip": "Subir
|
|
344
|
+
"Subir fichero de notas de estructuras",
|
|
345
|
+
"structures.actions.upload.tooltip": "Subir notas de estructuras",
|
|
343
346
|
"structures.bulkUpdate.crumbs.top": "Actualización masiva",
|
|
344
347
|
"structures.bulkUpdate.success.content":
|
|
345
348
|
"Se han actualizado {count} estructuras",
|
|
@@ -401,6 +404,8 @@ export default {
|
|
|
401
404
|
"structures.uploadStructures.failed.default": "Error en fila {row}",
|
|
402
405
|
"structures.uploadStructures.failed.df_content.invalid_content":
|
|
403
406
|
"Contenido inválido en fila {row}",
|
|
407
|
+
"structures.uploadStructures.failed.external_id_not_exist":
|
|
408
|
+
"External Id Inválido",
|
|
404
409
|
"structures.uploadStructures.failed.header":
|
|
405
410
|
"Error al subir el fichero. El contenido no se ha actualizado",
|
|
406
411
|
"structures.uploadStructures.failed.invalid_file_format":
|
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
});
|
package/src/reducers/index.js
CHANGED
|
@@ -74,6 +74,7 @@ import { structureUserFilters } from "./structureUserFilters";
|
|
|
74
74
|
import { structureVersion } from "./structureVersion";
|
|
75
75
|
import { structureVersions } from "./structureVersions";
|
|
76
76
|
import { structures } from "./structures";
|
|
77
|
+
import { structuresEditableDownloading } from "./structuresEditableDownloading";
|
|
77
78
|
import { structuresDownloading } from "./structuresDownloading";
|
|
78
79
|
import { structuresLoading } from "./structuresLoading";
|
|
79
80
|
import { structuresPageSize } from "./structuresPageSize";
|
|
@@ -168,6 +169,7 @@ export {
|
|
|
168
169
|
structureVersion,
|
|
169
170
|
structureVersions,
|
|
170
171
|
structures,
|
|
172
|
+
structuresEditableDownloading,
|
|
171
173
|
structuresDownloading,
|
|
172
174
|
structuresFields,
|
|
173
175
|
structuresLoading,
|
|
@@ -0,0 +1,14 @@
|
|
|
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 };
|
package/src/routines.js
CHANGED
|
@@ -57,6 +57,9 @@ export const deleteStructureUserFilter = createRoutine(
|
|
|
57
57
|
);
|
|
58
58
|
export const doStructureNoteAction = createRoutine("DO_STRUCTURE_NOTE_ACTION");
|
|
59
59
|
export const downloadCsvGraph = createRoutine("DOWNLOAD_CSV_GRAPH");
|
|
60
|
+
export const downloadEditableStructures = createRoutine(
|
|
61
|
+
"DOWNLOAD_EDITABLE_STRUCTURES"
|
|
62
|
+
);
|
|
60
63
|
export const downloadGrants = createRoutine("DOWNLOAD_GRANTS");
|
|
61
64
|
export const downloadStructures = createRoutine("DOWNLOAD_STRUCTURES");
|
|
62
65
|
export const excludeNode = createRoutine("EXCLUDE_NODE");
|
|
@@ -0,0 +1,80 @@
|
|
|
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
|
+
import { getPreviousStructureQuery } from "../../selectors";
|
|
11
|
+
|
|
12
|
+
describe("sagas: downloadEditableStructuresRequestSaga", () => {
|
|
13
|
+
it("should invoke downloadEditableStructuresSaga on downloadEditableStructures.TRIGGER", () => {
|
|
14
|
+
expect(() => {
|
|
15
|
+
testSaga(downloadEditableStructuresRequestSaga)
|
|
16
|
+
.next()
|
|
17
|
+
.takeLatest(
|
|
18
|
+
downloadEditableStructures.TRIGGER,
|
|
19
|
+
downloadEditableStructuresSaga
|
|
20
|
+
)
|
|
21
|
+
.finish()
|
|
22
|
+
.isDone();
|
|
23
|
+
}).not.toThrow();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("should throw exception if an unhandled action is received", () => {
|
|
27
|
+
expect(() => {
|
|
28
|
+
testSaga(downloadEditableStructuresRequestSaga)
|
|
29
|
+
.next()
|
|
30
|
+
.takeLatest("FOO", downloadEditableStructuresRequestSaga);
|
|
31
|
+
}).toThrow();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("sagas: downloadEditableStructuresSaga", () => {
|
|
36
|
+
const query = { filters: {} };
|
|
37
|
+
const body = query;
|
|
38
|
+
const data = "SOME CSV DATA";
|
|
39
|
+
|
|
40
|
+
it("should put a success action when a response is returned", () => {
|
|
41
|
+
expect(() => {
|
|
42
|
+
testSaga(downloadEditableStructuresSaga)
|
|
43
|
+
.next()
|
|
44
|
+
.select(getPreviousStructureQuery)
|
|
45
|
+
.next(query)
|
|
46
|
+
.put(downloadEditableStructures.request(body))
|
|
47
|
+
.next()
|
|
48
|
+
.call(apiJsonPost, API_DATA_STRUCTURES_EDITABLE_CSV, body, JSON_OPTS)
|
|
49
|
+
.next({ data })
|
|
50
|
+
.call(saveFile, data)
|
|
51
|
+
.next()
|
|
52
|
+
.put(downloadEditableStructures.success(data))
|
|
53
|
+
.next()
|
|
54
|
+
.put(downloadEditableStructures.fulfill())
|
|
55
|
+
.next()
|
|
56
|
+
.isDone();
|
|
57
|
+
}).not.toThrow();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("should put a failure action when the call returns an error", () => {
|
|
61
|
+
const message = "Request failed";
|
|
62
|
+
const error = { message };
|
|
63
|
+
|
|
64
|
+
expect(() => {
|
|
65
|
+
testSaga(downloadEditableStructuresSaga)
|
|
66
|
+
.next()
|
|
67
|
+
.select(getPreviousStructureQuery)
|
|
68
|
+
.next(query)
|
|
69
|
+
.put(downloadEditableStructures.request(body))
|
|
70
|
+
.next()
|
|
71
|
+
.call(apiJsonPost, API_DATA_STRUCTURES_EDITABLE_CSV, body, JSON_OPTS)
|
|
72
|
+
.throw(error)
|
|
73
|
+
.put(downloadEditableStructures.failure(message))
|
|
74
|
+
.next()
|
|
75
|
+
.put(downloadEditableStructures.fulfill())
|
|
76
|
+
.next()
|
|
77
|
+
.isDone();
|
|
78
|
+
}).not.toThrow();
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import FileSaver from "file-saver";
|
|
3
|
+
import { call, put, select, takeLatest } from "redux-saga/effects";
|
|
4
|
+
import { apiJsonPost, JSON_OPTS } from "@truedat/core/services/api";
|
|
5
|
+
import { downloadEditableStructures } from "../routines";
|
|
6
|
+
import { getPreviousStructureQuery } from "../selectors";
|
|
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() {
|
|
19
|
+
try {
|
|
20
|
+
const body = yield select(getPreviousStructureQuery);
|
|
21
|
+
const url = API_DATA_STRUCTURES_EDITABLE_CSV;
|
|
22
|
+
yield put(downloadEditableStructures.request(body));
|
|
23
|
+
const { data } = yield call(apiJsonPost, url, body, JSON_OPTS);
|
|
24
|
+
yield call(saveFile, data);
|
|
25
|
+
yield put(downloadEditableStructures.success(data));
|
|
26
|
+
} catch (error) {
|
|
27
|
+
if (error.response) {
|
|
28
|
+
const { status, data } = error.response;
|
|
29
|
+
yield put(downloadEditableStructures.failure({ status, data }));
|
|
30
|
+
} else {
|
|
31
|
+
yield put(downloadEditableStructures.failure(error.message));
|
|
32
|
+
}
|
|
33
|
+
} finally {
|
|
34
|
+
yield put(downloadEditableStructures.fulfill());
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function* downloadEditableStructuresRequestSaga() {
|
|
39
|
+
yield takeLatest(
|
|
40
|
+
downloadEditableStructures.TRIGGER,
|
|
41
|
+
downloadEditableStructuresSaga
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { call, put, takeLatest } from "redux-saga/effects";
|
|
2
2
|
import { apiJson, JSON_OPTS } from "@truedat/core/services/api";
|
|
3
3
|
import { fetchStructureTypes } from "../routines";
|
|
4
|
-
import { API_STRUCTURE_TYPES } from "../api";
|
|
4
|
+
import { API_STRUCTURE_TYPES, API_STRUCTURE_TYPES_LITE } from "../api";
|
|
5
5
|
|
|
6
|
-
export function* fetchStructureTypesSaga() {
|
|
6
|
+
export function* fetchStructureTypesSaga({ payload }) {
|
|
7
7
|
try {
|
|
8
|
+
const { liteRequest } = payload;
|
|
8
9
|
yield put(fetchStructureTypes.request());
|
|
9
|
-
const
|
|
10
|
+
const url = liteRequest ? API_STRUCTURE_TYPES_LITE : API_STRUCTURE_TYPES;
|
|
11
|
+
const { data } = yield call(apiJson, url, JSON_OPTS);
|
|
10
12
|
yield put(fetchStructureTypes.success(data));
|
|
11
13
|
} catch (error) {
|
|
12
14
|
if (error.response) {
|
package/src/sagas/index.js
CHANGED
|
@@ -12,6 +12,7 @@ import { deleteStructureUserFilterRequestSaga } from "./deleteStructureUserFilte
|
|
|
12
12
|
import { doStructureNoteActionRequestSaga } from "./doStructureNoteAction";
|
|
13
13
|
import { downloadCsvGraphRequestSaga } from "./downloadCsvGraph";
|
|
14
14
|
import { downloadGrantsRequestSaga } from "./downloadGrants";
|
|
15
|
+
import { downloadEditableStructuresRequestSaga } from "./downloadEditableStructures";
|
|
15
16
|
import { downloadStructuresRequestSaga } from "./downloadStructures";
|
|
16
17
|
import { fetchGrantFiltersRequestSaga } from "./fetchGrantFilters";
|
|
17
18
|
import { fetchGrantsRequestSaga } from "./fetchGrants";
|
|
@@ -60,6 +61,7 @@ export {
|
|
|
60
61
|
doStructureNoteActionRequestSaga,
|
|
61
62
|
downloadCsvGraphRequestSaga,
|
|
62
63
|
downloadGrantsRequestSaga,
|
|
64
|
+
downloadEditableStructuresRequestSaga,
|
|
63
65
|
downloadStructuresRequestSaga,
|
|
64
66
|
fetchGrantFiltersRequestSaga,
|
|
65
67
|
fetchGrantsRequestSaga,
|
|
@@ -109,6 +111,7 @@ export default [
|
|
|
109
111
|
doStructureNoteActionRequestSaga(),
|
|
110
112
|
downloadCsvGraphRequestSaga(),
|
|
111
113
|
downloadGrantsRequestSaga(),
|
|
114
|
+
downloadEditableStructuresRequestSaga(),
|
|
112
115
|
downloadStructuresRequestSaga(),
|
|
113
116
|
fetchGrantFiltersRequestSaga(),
|
|
114
117
|
fetchGrantsRequestSaga(),
|
|
@@ -11,7 +11,7 @@ exports[`EndDateDecorator matches the latest snapshot 1`] = `
|
|
|
11
11
|
<time
|
|
12
12
|
datetime="1589727661000"
|
|
13
13
|
>
|
|
14
|
-
|
|
14
|
+
2 years ago
|
|
15
15
|
</time>
|
|
16
16
|
</div>
|
|
17
17
|
</div>
|
|
@@ -85,7 +85,7 @@ exports[`StartDateDecorator matches the latest snapshot 1`] = `
|
|
|
85
85
|
<time
|
|
86
86
|
datetime="1589727661000"
|
|
87
87
|
>
|
|
88
|
-
|
|
88
|
+
2 years ago
|
|
89
89
|
</time>
|
|
90
90
|
</div>
|
|
91
91
|
</div>
|
|
@@ -83,10 +83,9 @@ describe("selectors: getTabVisibility", () => {
|
|
|
83
83
|
});
|
|
84
84
|
});
|
|
85
85
|
|
|
86
|
-
it("should include notes if
|
|
87
|
-
const structure = { type: "foo" };
|
|
88
|
-
const templates = [{ name: "foo" }];
|
|
89
|
-
const structureTypes = [{ name: "foo", template: { id: 1, name: "n" } }];
|
|
86
|
+
it("should include notes if template_id is in structure_note", () => {
|
|
87
|
+
const structure = { type: "foo", data_structure_type: { template_id: 1 } };
|
|
88
|
+
const templates = [{ name: "foo", id: 1 }];
|
|
90
89
|
expect(getTabVisibility({ templatesLoading: true })).toMatchObject({
|
|
91
90
|
notes: false,
|
|
92
91
|
});
|
|
@@ -94,8 +93,6 @@ describe("selectors: getTabVisibility", () => {
|
|
|
94
93
|
getTabVisibility({
|
|
95
94
|
structure,
|
|
96
95
|
templates,
|
|
97
|
-
structureTypes,
|
|
98
|
-
structureTypesLoading: false,
|
|
99
96
|
})
|
|
100
97
|
).toMatchObject({
|
|
101
98
|
notes: true,
|
|
@@ -24,25 +24,16 @@ const linksTabVisible = (state) => {
|
|
|
24
24
|
return conceptCount > 0 || !_.isEmpty(structureLinks);
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
const notesTabVisible = ({
|
|
28
|
-
templatesLoading,
|
|
29
|
-
templates,
|
|
30
|
-
structure,
|
|
31
|
-
structureTypes,
|
|
32
|
-
structureTypesLoading,
|
|
33
|
-
}) =>
|
|
27
|
+
const notesTabVisible = ({ templatesLoading, templates, structure }) =>
|
|
34
28
|
!templatesLoading &&
|
|
35
29
|
notEmpty(templates) &&
|
|
36
30
|
_.has("type")(structure) &&
|
|
37
|
-
!structureTypesLoading &&
|
|
38
|
-
notEmpty(structureTypes) &&
|
|
39
31
|
_.flow(
|
|
40
32
|
_.find({
|
|
41
|
-
|
|
33
|
+
id: _.propOr(null, "data_structure_type.template_id")(structure),
|
|
42
34
|
}),
|
|
43
|
-
_.get("template"),
|
|
44
35
|
_.negate(_.isNil)
|
|
45
|
-
)(
|
|
36
|
+
)(templates);
|
|
46
37
|
|
|
47
38
|
const versionsTabVisible = notEmptyPath("structureVersions");
|
|
48
39
|
const rulesTabVisible = notEmptyPath("ruleImplementations");
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { Button } from "semantic-ui-react";
|
|
3
|
-
import { Link } from "react-router-dom";
|
|
4
|
-
import { FormattedMessage } from "react-intl";
|
|
5
|
-
import { useAuthorized } from "@truedat/core/hooks";
|
|
6
|
-
import { SYSTEM_NEW } from "@truedat/core/routes";
|
|
7
|
-
|
|
8
|
-
export const SystemCreateButton = () => {
|
|
9
|
-
const authorized = useAuthorized();
|
|
10
|
-
return authorized ? (
|
|
11
|
-
<span className="button-update">
|
|
12
|
-
<Button
|
|
13
|
-
secondary
|
|
14
|
-
as={Link}
|
|
15
|
-
to={SYSTEM_NEW}
|
|
16
|
-
content={
|
|
17
|
-
<FormattedMessage
|
|
18
|
-
id="structures.actions.new_system"
|
|
19
|
-
defaultMessage="new_system"
|
|
20
|
-
/>
|
|
21
|
-
}
|
|
22
|
-
/>
|
|
23
|
-
</span>
|
|
24
|
-
) : null;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export default SystemCreateButton;
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { shallow } from "enzyme";
|
|
3
|
-
import { intl } from "@truedat/test/intl-stub";
|
|
4
|
-
import { StructuresDownloadButton } from "../StructuresDownloadButton";
|
|
5
|
-
|
|
6
|
-
// workaround for enzyme issue with React.useContext
|
|
7
|
-
// see https://github.com/airbnb/enzyme/issues/2176#issuecomment-532361526
|
|
8
|
-
jest.spyOn(React, "useContext").mockImplementation(() => intl);
|
|
9
|
-
|
|
10
|
-
describe("<StructuresDownloadButton />", () => {
|
|
11
|
-
const downloadStructures = jest.fn();
|
|
12
|
-
const structuresLoading = false;
|
|
13
|
-
|
|
14
|
-
it("matches the latest snapshot", () => {
|
|
15
|
-
const props = { downloadStructures, structuresLoading };
|
|
16
|
-
const wrapper = shallow(<StructuresDownloadButton {...props} />);
|
|
17
|
-
expect(wrapper).toMatchSnapshot();
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it("is disabled if there are no structures to be downloaded", () => {
|
|
21
|
-
const props = { downloadStructures, structuresLoading, structures: [] };
|
|
22
|
-
const wrapper = shallow(<StructuresDownloadButton {...props} />);
|
|
23
|
-
wrapper.find("Popup").props().content;
|
|
24
|
-
expect(wrapper.find({ disabled: false }).length).toBe(1);
|
|
25
|
-
});
|
|
26
|
-
});
|