@truedat/bg 7.5.0 → 7.5.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": "7.5.0",
3
+ "version": "7.5.1",
4
4
  "description": "Truedat Web Business Glossary",
5
5
  "sideEffects": false,
6
6
  "jsnext:main": "src/index.js",
@@ -34,7 +34,7 @@
34
34
  "@testing-library/jest-dom": "^5.16.5",
35
35
  "@testing-library/react": "^12.0.0",
36
36
  "@testing-library/user-event": "^13.2.1",
37
- "@truedat/test": "7.5.0",
37
+ "@truedat/test": "7.5.1",
38
38
  "babel-jest": "^28.1.0",
39
39
  "babel-plugin-dynamic-import-node": "^2.3.3",
40
40
  "babel-plugin-lodash": "^3.3.4",
@@ -86,9 +86,9 @@
86
86
  ]
87
87
  },
88
88
  "dependencies": {
89
- "@truedat/core": "7.5.0",
90
- "@truedat/df": "7.5.0",
91
- "@truedat/lm": "7.5.0",
89
+ "@truedat/core": "7.5.1",
90
+ "@truedat/df": "7.5.1",
91
+ "@truedat/lm": "7.5.1",
92
92
  "decode-uri-component": "^0.2.2",
93
93
  "file-saver": "^2.0.5",
94
94
  "moment": "^2.29.4",
@@ -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": "c6088400f5b3724b8b358e9c4893096005fe4e42"
114
+ "gitHead": "dd78383f466a9151664396b76163d13c0a5c641c"
115
115
  }
@@ -10,6 +10,8 @@ const API_BUSINESS_CONCEPT_VERSIONS_SEARCH =
10
10
  const API_BUSINESS_CONCEPT_VERSIONS_UPLOAD =
11
11
  "/api/business_concept_versions/upload";
12
12
  const API_CONCEPT_ARCHIVE = "/api/business_concepts/:id/versions";
13
+ const API_CONCEPT_LINKS_DOWNLOAD =
14
+ "/api/business_concept_versions/links/download";
13
15
  const API_CONCEPT_FILTERS = "/api/business_concept_filters/search";
14
16
  const API_CONCEPT_SHARED_DOMAINS = "/api/business_concepts/:id/shared_domains";
15
17
  const API_BUSINESS_CONCEPT_BULK_UPDATE =
@@ -27,6 +29,7 @@ export {
27
29
  API_BUSINESS_CONCEPT_VERSIONS_SEARCH,
28
30
  API_BUSINESS_CONCEPT_VERSIONS_UPLOAD,
29
31
  API_CONCEPT_ARCHIVE,
32
+ API_CONCEPT_LINKS_DOWNLOAD,
30
33
  API_CONCEPT_FILTERS,
31
34
  API_CONCEPT_SHARED_DOMAINS,
32
35
  API_BUSINESS_CONCEPT_BULK_UPDATE,
@@ -1,13 +1,24 @@
1
1
  import useSWR from "swr";
2
2
  import useSWRMutations from "swr/mutation";
3
- import { apiJson, apiJsonPost } from "@truedat/core/services/api";
3
+ import FileSaver from "file-saver";
4
+ import { apiJson, apiJsonPost, JSON_OPTS } from "@truedat/core/services/api";
4
5
 
5
6
  import {
6
7
  API_CONCEPT_FILTERS,
8
+ API_CONCEPT_LINKS_DOWNLOAD,
7
9
  API_BUSINESS_CONCEPT_VERSIONS_SEARCH,
8
10
  API_BUSINESS_CONCEPT_VERSIONS_ACTIONS,
9
11
  } from "../api";
10
12
 
13
+ function saveFile({ data, headers }) {
14
+ const contentDisposition = headers["content-disposition"];
15
+ const regex = /filename=(.+)$/;
16
+ const match = regex.exec(contentDisposition);
17
+ const fileName = match ? match[1] : "links.xlsx";
18
+
19
+ FileSaver.saveAs(data, fileName);
20
+ }
21
+
11
22
  export const useConceptFilters = () => {
12
23
  return useSWRMutations(API_CONCEPT_FILTERS, (url, { arg }) =>
13
24
  apiJsonPost(url, arg)
@@ -32,3 +43,13 @@ export const useConceptVersionsActions = () => {
32
43
  mutate,
33
44
  };
34
45
  };
46
+
47
+ export const useConceptLinksDownload = () => {
48
+ return useSWRMutations(API_CONCEPT_LINKS_DOWNLOAD, (url, { arg }) => {
49
+ return apiJsonPost(url, arg, { ...JSON_OPTS, responseType: "blob" }).then(
50
+ ({ data, headers }) => {
51
+ saveFile({ data, headers });
52
+ }
53
+ );
54
+ });
55
+ };
@@ -2,8 +2,15 @@ import _ from "lodash/fp";
2
2
  import React from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import { connect } from "react-redux";
5
- import { Table, Message, Label, Icon, Segment } from "semantic-ui-react";
6
- import { FormattedMessage } from "react-intl";
5
+ import {
6
+ Button,
7
+ Table,
8
+ Message,
9
+ Label,
10
+ Icon,
11
+ Segment,
12
+ } from "semantic-ui-react";
13
+ import { FormattedMessage, useIntl } from "react-intl";
7
14
  import SearchWidget from "@truedat/core/search/SearchWidget";
8
15
  import {
9
16
  SearchContextProvider,
@@ -14,6 +21,7 @@ import { mapStatusColor } from "../../constants/mappings";
14
21
  import { translations } from "../../utils/filterOptions";
15
22
 
16
23
  import {
24
+ useConceptLinksDownload,
17
25
  useConceptVersionsSearch,
18
26
  useConceptFilters,
19
27
  } from "../../hooks/useConcepts";
@@ -78,8 +86,12 @@ export function ConceptSelectorContent({
78
86
  showTitle = true,
79
87
  links,
80
88
  }) {
81
- const { searchData } = useSearchContext();
89
+ const { searchData, filterParams: searchParams } = useSearchContext();
90
+ const { trigger: triggerDownload, isMutating: downloading } =
91
+ useConceptLinksDownload();
92
+ const { formatMessage } = useIntl();
82
93
  const concepts = searchData?.data;
94
+ const conceptsActions = _.propOr({}, "_actions")(searchData);
83
95
 
84
96
  const selectedConceptIsFiltered = !_.reduce(
85
97
  (acc, c) => (selectedConcept && c.id == selectedConcept.id) || acc,
@@ -103,6 +115,18 @@ export function ConceptSelectorContent({
103
115
  </label>
104
116
  )}
105
117
  <Segment>
118
+ {conceptsActions?.downloadLinks && (
119
+ <Button
120
+ icon="download"
121
+ floated="right"
122
+ secondary
123
+ loading={downloading}
124
+ onClick={() => triggerDownload(searchParams)}
125
+ data-tooltip={formatMessage({
126
+ id: "concepts.actions.downloadLinks.tooltip",
127
+ })}
128
+ />
129
+ )}
106
130
  <SearchWidget />
107
131
  {!_.isEmpty(concepts) || selectedConcept ? (
108
132
  <Table selectable size="small">
@@ -25,6 +25,7 @@ const data = {
25
25
  last_change_at: "2020-01-01T00:00:00.000Z",
26
26
  },
27
27
  ],
28
+ _actions: { downloadLinks: {} },
28
29
  };
29
30
 
30
31
  const filterData = {
@@ -91,6 +92,11 @@ describe("<ConceptSelector />", () => {
91
92
  await waitFor(() => {
92
93
  expect(container.querySelector(".loading")).toBeNull();
93
94
  });
95
+ expect(
96
+ container.querySelector(
97
+ 'button[data-tooltip="concepts.actions.downloadLinks.tooltip"]'
98
+ )
99
+ ).toBeInTheDocument();
94
100
  expect(container).toMatchSnapshot();
95
101
  });
96
102
 
@@ -8,6 +8,15 @@ exports[`<ConceptSelector /> matches the latest snapshot 1`] = `
8
8
  <div
9
9
  class="ui segment"
10
10
  >
11
+ <button
12
+ class="ui icon secondary right floated button"
13
+ data-tooltip="concepts.actions.downloadLinks.tooltip"
14
+ >
15
+ <i
16
+ aria-hidden="true"
17
+ class="download icon"
18
+ />
19
+ </button>
11
20
  <div
12
21
  class="ui action left icon input"
13
22
  >