@truedat/bg 5.19.0 → 5.19.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/bg",
3
- "version": "5.19.0",
3
+ "version": "5.19.1",
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": "df3fcd6655456c3468259d79762800c3c417147d"
114
+ "gitHead": "4bee2c4335315835fa62f4c8115036439eb86fb5"
115
115
  }
@@ -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
- const headerLabels = _.flow(
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({ headerLabels, lang: locale })}
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 { shallow } from "enzyme";
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 wrapper = shallow(<ConceptsActions {...props} />);
21
- expect(wrapper).toMatchSnapshot();
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
- <Button
6
- as={
7
- {
8
- "$$typeof": Symbol(react.forward_ref),
9
- "displayName": "Link",
10
- "propTypes": {
11
- "innerRef": [Function],
12
- "onClick": [Function],
13
- "replace": [Function],
14
- "target": [Function],
15
- "to": [Function],
16
- },
17
- "render": [Function],
18
- }
19
- }
20
- content="concepts.actions.create"
21
- floated="right"
22
- primary={true}
23
- to="/url/to/create/concept"
24
- />
25
- <Button
26
- as="button"
27
- data-tooltip="concepts.actions.download.tooltip"
28
- floated="right"
29
- icon="download"
30
- loading={true}
31
- onClick={[Function]}
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 { API_BUSINESS_CONCEPT_VERSIONS_CSV } from "../../api";
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 = { headerLabels, lang: lang };
34
+ const payload = { lang: lang };
36
35
 
37
36
  const conceptQuery = { filters: {} };
38
- const data = "SOME CSV DATA";
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, API_BUSINESS_CONCEPT_VERSIONS_CSV, body, JSON_OPTS)
57
- .next({ data })
58
- .call(saveFile, data)
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, API_BUSINESS_CONCEPT_VERSIONS_CSV, body, JSON_OPTS)
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 { API_BUSINESS_CONCEPT_VERSIONS_CSV } from "../api";
8
+ import { API_BUSINESS_CONCEPT_VERSIONS_XLSX } from "../api";
9
9
 
10
- export function saveFile(data) {
11
- const blob = new Blob([String.fromCharCode(0xfeff), data], {
12
- type: "text/csv;charset=utf-8",
13
- });
14
- FileSaver.saveAs(blob, "concepts.csv");
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 = API_BUSINESS_CONCEPT_VERSIONS_CSV;
29
+ const url = API_BUSINESS_CONCEPT_VERSIONS_XLSX;
30
30
  yield put(downloadConcepts.request(body));
31
- const { data } = yield call(apiJsonPost, url, body, JSON_OPTS);
32
- yield call(saveFile, data);
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) {