@truedat/bg 5.19.0 → 5.19.2
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/package.json +2 -2
- package/src/concepts/api.js +4 -1
- package/src/concepts/components/ConceptsActions.js +2 -17
- package/src/concepts/components/__tests__/ConceptsActions.spec.js +18 -9
- package/src/concepts/components/__tests__/__snapshots__/ConceptsActions.spec.js.snap +27 -31
- package/src/concepts/sagas/__tests__/downloadConcepts.spec.js +16 -9
- package/src/concepts/sagas/downloadConcepts.js +14 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/bg",
|
|
3
|
-
"version": "5.19.
|
|
3
|
+
"version": "5.19.2",
|
|
4
4
|
"description": "Truedat Web Business Glossary",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -111,5 +111,5 @@
|
|
|
111
111
|
"react-dom": ">= 16.8.6 < 17",
|
|
112
112
|
"semantic-ui-react": ">= 2.0.3 < 2.2"
|
|
113
113
|
},
|
|
114
|
-
"gitHead": "
|
|
114
|
+
"gitHead": "a260407696f2b53d1d7a857c1d9d4aa707a99bd1"
|
|
115
115
|
}
|
package/src/concepts/api.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const API_BUSINESS_CONCEPT_VERSION =
|
|
2
2
|
"/api/business_concepts/:business_concept_id/versions/:id";
|
|
3
3
|
const API_BUSINESS_CONCEPT_VERSIONS_CSV = "/api/business_concept_versions/csv";
|
|
4
|
+
const API_BUSINESS_CONCEPT_VERSIONS_XLSX =
|
|
5
|
+
"/api/business_concept_versions/xlsx";
|
|
4
6
|
const API_BUSINESS_CONCEPT_VERSIONS_SEARCH =
|
|
5
7
|
"/api/business_concept_versions/search";
|
|
6
8
|
const API_BUSINESS_CONCEPT_VERSIONS_UPLOAD =
|
|
@@ -20,6 +22,7 @@ const API_BUSINESS_CONCEPT_SET_CONFIDENTIAL =
|
|
|
20
22
|
export {
|
|
21
23
|
API_BUSINESS_CONCEPT_VERSION,
|
|
22
24
|
API_BUSINESS_CONCEPT_VERSIONS_CSV,
|
|
25
|
+
API_BUSINESS_CONCEPT_VERSIONS_XLSX,
|
|
23
26
|
API_BUSINESS_CONCEPT_VERSIONS_SEARCH,
|
|
24
27
|
API_BUSINESS_CONCEPT_VERSIONS_UPLOAD,
|
|
25
28
|
API_CONCEPT_ARCHIVE,
|
|
@@ -29,5 +32,5 @@ export {
|
|
|
29
32
|
API_CONCEPT_USER_FILTERS,
|
|
30
33
|
API_GET_CONCEPT_USER_FILTERS,
|
|
31
34
|
API_BUSINESS_CONCEPT_BULK_UPDATE,
|
|
32
|
-
API_BUSINESS_CONCEPT_SET_CONFIDENTIAL
|
|
35
|
+
API_BUSINESS_CONCEPT_SET_CONFIDENTIAL,
|
|
33
36
|
};
|
|
@@ -10,18 +10,6 @@ import { downloadConcepts, uploadConcepts } from "../routines";
|
|
|
10
10
|
import ConceptsUpdateButton from "./ConceptsUpdateButton";
|
|
11
11
|
import ConceptsUploadButton from "./ConceptsUploadButton";
|
|
12
12
|
|
|
13
|
-
const staticLabels = [
|
|
14
|
-
"template",
|
|
15
|
-
"name",
|
|
16
|
-
"domain",
|
|
17
|
-
"status",
|
|
18
|
-
"description",
|
|
19
|
-
"link_to_concept",
|
|
20
|
-
"completeness",
|
|
21
|
-
"inserted_at",
|
|
22
|
-
"last_change_at",
|
|
23
|
-
];
|
|
24
|
-
|
|
25
13
|
export const ConceptsActions = ({
|
|
26
14
|
create,
|
|
27
15
|
createUrl,
|
|
@@ -32,10 +20,7 @@ export const ConceptsActions = ({
|
|
|
32
20
|
update,
|
|
33
21
|
}) => {
|
|
34
22
|
const { formatMessage, locale } = useIntl();
|
|
35
|
-
|
|
36
|
-
_.map((l) => [l, formatMessage({ id: `concepts.props.${l}` })]),
|
|
37
|
-
_.fromPairs
|
|
38
|
-
)(staticLabels);
|
|
23
|
+
|
|
39
24
|
return hidden ? null : (
|
|
40
25
|
<div>
|
|
41
26
|
{create && createUrl ? (
|
|
@@ -51,7 +36,7 @@ export const ConceptsActions = ({
|
|
|
51
36
|
floated="right"
|
|
52
37
|
secondary
|
|
53
38
|
icon="download"
|
|
54
|
-
onClick={() => downloadConcepts({
|
|
39
|
+
onClick={() => downloadConcepts({ lang: locale })}
|
|
55
40
|
loading={conceptsDownloading}
|
|
56
41
|
data-tooltip={formatMessage({
|
|
57
42
|
id: "concepts.actions.download.tooltip",
|
|
@@ -1,23 +1,32 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
3
|
-
import { intl } from "@truedat/test/intl-stub";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
4
3
|
import { ConceptsActions } from "../ConceptsActions";
|
|
5
4
|
|
|
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
5
|
describe("<ConceptsActions />", () => {
|
|
11
6
|
const props = {
|
|
12
7
|
createUrl: "/url/to/create/concept",
|
|
13
8
|
conceptActionsLoaded: true,
|
|
14
9
|
conceptsDownloading: true,
|
|
15
10
|
create: true,
|
|
16
|
-
upload: true
|
|
11
|
+
upload: true,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const renderOpts = {
|
|
15
|
+
messages: {
|
|
16
|
+
en: {
|
|
17
|
+
"concepts.actions.create": "Create",
|
|
18
|
+
"concepts.actions.download.tooltip": "Download",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
state: {
|
|
22
|
+
uploadConceptsFile: {
|
|
23
|
+
loading: false,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
17
26
|
};
|
|
18
27
|
|
|
19
28
|
it("matches the latest snapshot", () => {
|
|
20
|
-
const
|
|
21
|
-
expect(
|
|
29
|
+
const { container } = render(<ConceptsActions {...props} />, renderOpts);
|
|
30
|
+
expect(container).toMatchSnapshot();
|
|
22
31
|
});
|
|
23
32
|
});
|
|
@@ -2,36 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`<ConceptsActions /> matches the latest snapshot 1`] = `
|
|
4
4
|
<div>
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
secondary={true}
|
|
33
|
-
/>
|
|
34
|
-
<Connect(ConceptsUploadButton) />
|
|
35
|
-
<Connect(ConceptsUpdateButton) />
|
|
5
|
+
<div>
|
|
6
|
+
<a
|
|
7
|
+
class="ui primary right floated button"
|
|
8
|
+
href="/url/to/create/concept"
|
|
9
|
+
role="button"
|
|
10
|
+
>
|
|
11
|
+
Create
|
|
12
|
+
</a>
|
|
13
|
+
<button
|
|
14
|
+
class="ui icon loading secondary right floated button"
|
|
15
|
+
data-tooltip="Download"
|
|
16
|
+
>
|
|
17
|
+
<i
|
|
18
|
+
aria-hidden="true"
|
|
19
|
+
class="download icon"
|
|
20
|
+
/>
|
|
21
|
+
</button>
|
|
22
|
+
<button
|
|
23
|
+
class="ui icon secondary right floated button"
|
|
24
|
+
data-tooltip="concepts.actions.upload.tooltip"
|
|
25
|
+
>
|
|
26
|
+
<i
|
|
27
|
+
aria-hidden="true"
|
|
28
|
+
class="upload icon"
|
|
29
|
+
/>
|
|
30
|
+
</button>
|
|
31
|
+
</div>
|
|
36
32
|
</div>
|
|
37
33
|
`;
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
saveFile,
|
|
7
7
|
} from "../downloadConcepts";
|
|
8
8
|
import { downloadConcepts } from "../../routines";
|
|
9
|
-
import {
|
|
9
|
+
import { API_BUSINESS_CONCEPT_VERSIONS_XLSX } from "../../api";
|
|
10
10
|
import { getPreviousConceptQuery } from "../../selectors";
|
|
11
11
|
|
|
12
12
|
describe("sagas: downloadConceptsRequestSaga", () => {
|
|
@@ -30,15 +30,16 @@ describe("sagas: downloadConceptsRequestSaga", () => {
|
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
describe("sagas: downloadConceptsSaga", () => {
|
|
33
|
-
const headerLabels = { name: "Name" };
|
|
34
33
|
const lang = "es";
|
|
35
|
-
const payload = {
|
|
34
|
+
const payload = { lang: lang };
|
|
36
35
|
|
|
37
36
|
const conceptQuery = { filters: {} };
|
|
38
|
-
const data = "SOME
|
|
37
|
+
const data = new Blob(["SOME XLS DATA BINARY"]);
|
|
38
|
+
const headers = {
|
|
39
|
+
"content-disposition": "attachment; filename=test.xlsx",
|
|
40
|
+
};
|
|
39
41
|
|
|
40
42
|
const body = {
|
|
41
|
-
header_labels: headerLabels,
|
|
42
43
|
lang: lang,
|
|
43
44
|
concept_url_schema:
|
|
44
45
|
"http://localhost/concepts/:business_concept_id/versions/:id",
|
|
@@ -53,9 +54,12 @@ describe("sagas: downloadConceptsSaga", () => {
|
|
|
53
54
|
.next(conceptQuery)
|
|
54
55
|
.put(downloadConcepts.request(body))
|
|
55
56
|
.next()
|
|
56
|
-
.call(apiJsonPost,
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
.call(apiJsonPost, API_BUSINESS_CONCEPT_VERSIONS_XLSX, body, {
|
|
58
|
+
...JSON_OPTS,
|
|
59
|
+
responseType: "blob",
|
|
60
|
+
})
|
|
61
|
+
.next({ data, headers })
|
|
62
|
+
.call(saveFile, { data, headers })
|
|
59
63
|
.next()
|
|
60
64
|
.put(downloadConcepts.success(data))
|
|
61
65
|
.next()
|
|
@@ -76,7 +80,10 @@ describe("sagas: downloadConceptsSaga", () => {
|
|
|
76
80
|
.next(conceptQuery)
|
|
77
81
|
.put(downloadConcepts.request(body))
|
|
78
82
|
.next()
|
|
79
|
-
.call(apiJsonPost,
|
|
83
|
+
.call(apiJsonPost, API_BUSINESS_CONCEPT_VERSIONS_XLSX, body, {
|
|
84
|
+
...JSON_OPTS,
|
|
85
|
+
responseType: "blob",
|
|
86
|
+
})
|
|
80
87
|
.throw(error)
|
|
81
88
|
.put(downloadConcepts.failure(message))
|
|
82
89
|
.next()
|
|
@@ -5,31 +5,34 @@ import { apiJsonPost, JSON_OPTS } from "@truedat/core/services/api";
|
|
|
5
5
|
import { CONCEPT_VERSION } from "@truedat/core/routes";
|
|
6
6
|
import { downloadConcepts } from "../routines";
|
|
7
7
|
import { getPreviousConceptQuery } from "../selectors";
|
|
8
|
-
import {
|
|
8
|
+
import { API_BUSINESS_CONCEPT_VERSIONS_XLSX } from "../api";
|
|
9
9
|
|
|
10
|
-
export function saveFile(data) {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
export function saveFile({ data, headers }) {
|
|
11
|
+
const contentDisposition = headers["content-disposition"];
|
|
12
|
+
const regex = /filename=(.+)$/;
|
|
13
|
+
const match = regex.exec(contentDisposition);
|
|
14
|
+
const fileName = match ? match[1] : "concepts.xlsx";
|
|
15
|
+
|
|
16
|
+
FileSaver.saveAs(data, fileName);
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export function* downloadConceptsSaga({ payload }) {
|
|
18
20
|
try {
|
|
19
|
-
const headerLabels = _.propOr({}, "headerLabels")(payload);
|
|
20
21
|
const lang = _.propOr("es", "lang")(payload);
|
|
21
22
|
const query = yield select(getPreviousConceptQuery);
|
|
22
23
|
const conceptUrlSchema = window.location.origin + CONCEPT_VERSION;
|
|
23
24
|
const body = {
|
|
24
|
-
header_labels: headerLabels,
|
|
25
25
|
concept_url_schema: conceptUrlSchema,
|
|
26
26
|
lang,
|
|
27
27
|
...query,
|
|
28
28
|
};
|
|
29
|
-
const url =
|
|
29
|
+
const url = API_BUSINESS_CONCEPT_VERSIONS_XLSX;
|
|
30
30
|
yield put(downloadConcepts.request(body));
|
|
31
|
-
const { data } = yield call(apiJsonPost, url, body,
|
|
32
|
-
|
|
31
|
+
const { data, headers } = yield call(apiJsonPost, url, body, {
|
|
32
|
+
...JSON_OPTS,
|
|
33
|
+
responseType: "blob",
|
|
34
|
+
});
|
|
35
|
+
yield call(saveFile, { data, headers });
|
|
33
36
|
yield put(downloadConcepts.success(data));
|
|
34
37
|
} catch (error) {
|
|
35
38
|
if (error.response) {
|