@truedat/core 4.56.8 → 4.58.0

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.58.0] 2022-11-15
4
+
5
+ ### Added
6
+
7
+ - [TD-3919] Add concept subscopes submenus
8
+
9
+ ## [4.56.9] 2022-11-12
10
+
11
+ ### Added
12
+
13
+ - [TD-5161] Get specific domain_ids have been indluded for the selector
14
+
3
15
  ## [4.56.3] 2022-11-24
4
16
 
5
17
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/core",
3
- "version": "4.56.8",
3
+ "version": "4.58.0",
4
4
  "description": "Truedat Web Core",
5
5
  "sideEffects": false,
6
6
  "jsnext:main": "src/index.js",
@@ -35,7 +35,7 @@
35
35
  "@testing-library/jest-dom": "^5.16.5",
36
36
  "@testing-library/react": "^12.0.0",
37
37
  "@testing-library/user-event": "^13.2.1",
38
- "@truedat/test": "4.56.8",
38
+ "@truedat/test": "4.58.0",
39
39
  "babel-jest": "^28.1.0",
40
40
  "babel-plugin-dynamic-import-node": "^2.3.3",
41
41
  "babel-plugin-lodash": "^3.3.4",
@@ -115,5 +115,5 @@
115
115
  "react-dom": ">= 16.8.6 < 17",
116
116
  "semantic-ui-react": ">= 2.0.3 < 2.2"
117
117
  },
118
- "gitHead": "9bf266eb26e4af0b774560d5a88b0f22325495e0"
118
+ "gitHead": "3987557a127b4e999021e0d7179ad7a6375bfe01"
119
119
  }
@@ -1,8 +1,8 @@
1
1
  import { gql } from "@apollo/client";
2
2
 
3
3
  export const DOMAINS_QUERY = gql`
4
- query DomainsQuery($action: String!, $domainActions: [String!]) {
5
- domains(action: $action) {
4
+ query DomainsQuery($action: String!, $domainActions: [String!], $ids: [ID]) {
5
+ domains(action: $action, ids: $ids) {
6
6
  id
7
7
  externalId
8
8
  name
@@ -12,6 +12,7 @@ export const DomainSelector = ({
12
12
  action,
13
13
  multiple,
14
14
  domainActions,
15
+ domainIds,
15
16
  onLoad,
16
17
  value,
17
18
  ...props
@@ -22,11 +23,13 @@ export const DomainSelector = ({
22
23
  variables: {
23
24
  action: action || "viewDomain",
24
25
  domainActions,
26
+ ids: domainIds,
25
27
  },
26
28
  onCompleted: onLoad,
27
29
  });
28
30
  if (error) return null;
29
31
  if (loading) return null;
32
+
30
33
  const options = _.flow(
31
34
  _.propOr([], "domains"),
32
35
  _.sortBy(accentInsensitivePathOrder("name")),
@@ -53,6 +56,7 @@ DomainSelector.propTypes = {
53
56
  action: PropTypes.string,
54
57
  multiple: PropTypes.bool,
55
58
  domainActions: PropTypes.array,
59
+ domainIds: PropTypes.array,
56
60
  onLoad: PropTypes.func,
57
61
  value: PropTypes.oneOfType([
58
62
  PropTypes.array,
@@ -1,30 +1,69 @@
1
+ import _ from "lodash/fp";
1
2
  import React from "react";
3
+ import TemplatesLoader from "@truedat/df/templates/components/TemplatesLoader";
4
+ import { connect } from "react-redux";
5
+ import PropTypes from "prop-types";
6
+ import { makeGetSubscopes } from "@truedat/df/selectors/subscopedTemplates";
7
+ import { linkTo } from "@truedat/core/routes";
2
8
  import { useAuthorized } from "../hooks";
3
9
  import { CONCEPTS, CONCEPTS_PENDING } from "../routes";
4
10
  import Submenu from "./Submenu";
5
11
 
6
- const items = [
12
+ const items = (bgSubscopes = []) => [
7
13
  {
8
14
  name: "concepts",
9
15
  routes: [CONCEPTS],
10
- groups: ["business_glossary_view"]
16
+ groups: ["business_glossary_view"],
11
17
  },
18
+ ...bgSubscopes,
12
19
  {
13
20
  name: "concepts_management",
14
21
  routes: [CONCEPTS_PENDING],
15
- groups: ["business_glossary_management"]
16
- }
22
+ groups: ["business_glossary_management"],
23
+ },
17
24
  ];
18
25
 
19
- export const GlossaryMenu = () => {
26
+ const subscopeItems = _.flow(
27
+ _.map((bgSubscope) => ({
28
+ name: bgSubscope,
29
+ routes: [linkTo.CONCEPTS_SUBSCOPED({ subscope: bgSubscope })],
30
+ groups: ["business_glossary_view"],
31
+ })),
32
+ _.orderBy(["name"], ["asc"])
33
+ );
34
+
35
+ export const GlossaryMenu = ({ bgSubscopes }) => {
20
36
  const authorized = useAuthorized([
21
37
  "business_glossary_view",
22
- "business_glossary_management"
38
+ "business_glossary_management",
23
39
  ]);
24
40
 
25
41
  return authorized ? (
26
- <Submenu items={items} icon="tags" name="glossary" />
42
+ // Use TemplatesLoader without scope, so that templates are saved in the
43
+ // "allTemplates" reducer, and thus do not collide with other
44
+ // <TemplatesLoader scope="..."> that collect templates in the "templates"
45
+ // reducer.
46
+ <>
47
+ <TemplatesLoader />
48
+ <Submenu
49
+ items={items(subscopeItems(bgSubscopes))}
50
+ icon="tags"
51
+ name="glossary"
52
+ />
53
+ </>
27
54
  ) : null;
28
55
  };
29
56
 
30
- export default GlossaryMenu;
57
+ GlossaryMenu.propTypes = {
58
+ bgSubscopes: PropTypes.array,
59
+ };
60
+
61
+ const makeMapStateToProps = () => {
62
+ const getSubscopes = makeGetSubscopes("bg");
63
+ const mapStateToProps = (state, props) => ({
64
+ bgSubscopes: getSubscopes(state, props),
65
+ });
66
+ return mapStateToProps;
67
+ };
68
+
69
+ export default connect(makeMapStateToProps)(GlossaryMenu);
@@ -81,6 +81,7 @@ export const Submenu = ({ items, icon, name, sidebarVisible }) => {
81
81
  );
82
82
  } else {
83
83
  const className = active ? "active" : null;
84
+
84
85
  const trigger = (
85
86
  <Link to={primaryRoute} className="ui">
86
87
  <Icon size="large" name={icon} />
@@ -2,59 +2,24 @@ import React from "react";
2
2
  import { waitFor } from "@testing-library/react";
3
3
  import userEvent from "@testing-library/user-event";
4
4
  import { render } from "@truedat/test/render";
5
- import { DOMAINS_QUERY } from "../../api/queries";
5
+ import { domainsMock } from "@truedat/test/mocks";
6
6
  import DomainSelector from "../DomainSelector";
7
7
 
8
8
  const action = "manageTags";
9
+ const variables = { action: action };
9
10
 
10
- const domainsMock = {
11
- request: { query: DOMAINS_QUERY, variables: { action } },
12
- result: {
13
- data: {
14
- domains: [
15
- {
16
- __typename: "Domain",
17
- id: "1",
18
- name: "foo",
19
- externalId: "A",
20
- parentId: null,
21
- actions: [],
22
- },
23
- {
24
- __typename: "Domain",
25
- id: "2",
26
- name: "bar",
27
- externalId: "B",
28
- parentId: "1",
29
- actions: [],
30
- },
31
- {
32
- __typename: "Domain",
33
- id: "3",
34
- name: "baz",
35
- externalId: "C",
36
- parentId: "2",
37
- actions: [],
38
- },
39
- {
40
- __typename: "Domain",
41
- id: "4",
42
- name: "xyzzy",
43
- externalId: "D",
44
- parentId: "99",
45
- actions: [],
46
- },
47
- ],
48
- },
49
- },
50
- };
51
-
52
- const renderOpts = { mocks: [domainsMock] };
11
+ const renderOpts = { mocks: [domainsMock(variables)] };
53
12
 
54
13
  describe("<DomainSelector />", () => {
55
- it("matches latest snapshot", () => {
14
+ it("matches latest snapshot", async () => {
56
15
  const props = { action, onChange: jest.fn() };
57
- const { container } = render(<DomainSelector {...props} />, renderOpts);
16
+ const { container, queryByText } = render(
17
+ <DomainSelector {...props} />,
18
+ renderOpts
19
+ );
20
+ await waitFor(() => {
21
+ expect(queryByText(/fooDomain/)).toBeInTheDocument();
22
+ });
58
23
  expect(container).toMatchSnapshot();
59
24
  });
60
25
 
@@ -1,16 +1,80 @@
1
1
  import React from "react";
2
- import { shallow } from "enzyme";
3
- import { GlossaryMenu } from "../GlossaryMenu";
2
+ import { render } from "@truedat/test/render";
3
+ import GlossaryMenu from "../GlossaryMenu";
4
4
 
5
5
  jest.mock("../../hooks", () => ({
6
6
  useActiveRoutes: jest.fn(() => true),
7
7
  useAuthorized: jest.fn(() => true),
8
- useAuthorizedItems: jest.fn(() => true)
8
+ useAuthorizedItems: jest.fn((items) => items),
9
9
  }));
10
10
 
11
+ const messages = {
12
+ en: {
13
+ "sidemenu.concepts": "sidemenu.concepts",
14
+ "sidemenu.concepts_management": "sidemenu.concepts_management",
15
+ },
16
+ };
17
+
18
+ const renderOpts = {
19
+ messages,
20
+ state: {
21
+ allTemplates: [
22
+ {
23
+ content: [],
24
+ id: 7,
25
+ label: "Término",
26
+ name: "termino",
27
+ scope: "bg",
28
+ subscope: null,
29
+ },
30
+ {
31
+ content: [],
32
+ id: 2,
33
+ label: "Métrica",
34
+ name: "metrica",
35
+ scope: "bg",
36
+ subscope: null,
37
+ },
38
+ {
39
+ content: [],
40
+ id: 3,
41
+ label: "Dimensión",
42
+ name: "dimension",
43
+ scope: "bg",
44
+ subscope: null,
45
+ },
46
+ {
47
+ content: [],
48
+ id: 53,
49
+ label: "subscope1",
50
+ name: "subscope1",
51
+ scope: "bg",
52
+ subscope: "subscope1",
53
+ },
54
+ {
55
+ content: [],
56
+ id: 54,
57
+ label: "subscope2",
58
+ name: "subscope2",
59
+ scope: "bg",
60
+ subscope: "subscope2",
61
+ },
62
+ ],
63
+ },
64
+ };
65
+
11
66
  describe("<GlossaryMenu />", () => {
12
- it("matches the latest snapshot", () => {
13
- const wrapper = shallow(<GlossaryMenu />);
14
- expect(wrapper).toMatchSnapshot();
67
+ it("matches the latest snapshot, finds fixed and subscopes submenus", () => {
68
+ const { container, queryByRole } = render(<GlossaryMenu />, renderOpts);
69
+
70
+ expect(container).toMatchSnapshot();
71
+ expect(
72
+ queryByRole("option", { name: "sidemenu.concepts" })
73
+ ).toBeInTheDocument();
74
+ expect(
75
+ queryByRole("option", { name: "sidemenu.concepts_management" })
76
+ ).toBeInTheDocument();
77
+ expect(queryByRole("option", { name: "subscope1" })).toBeInTheDocument();
78
+ expect(queryByRole("option", { name: "subscope2" })).toBeInTheDocument();
15
79
  });
16
80
  });
@@ -1,3 +1,89 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`<DomainSelector /> matches latest snapshot 1`] = `<div />`;
3
+ exports[`<DomainSelector /> matches latest snapshot 1`] = `
4
+ <div>
5
+ <div
6
+ class="field"
7
+ >
8
+ <div
9
+ aria-expanded="false"
10
+ aria-multiselectable="false"
11
+ class="ui floating dropdown"
12
+ role="listbox"
13
+ tabindex="0"
14
+ >
15
+ <label>
16
+ Select a domain...
17
+ </label>
18
+ <i
19
+ aria-hidden="true"
20
+ class="dropdown icon"
21
+ />
22
+ <div
23
+ class="menu transition"
24
+ >
25
+ <div
26
+ class="ui left icon input search"
27
+ >
28
+ <input
29
+ type="text"
30
+ />
31
+ <i
32
+ aria-hidden="true"
33
+ class="search icon"
34
+ />
35
+ </div>
36
+ <div
37
+ class="scrolling menu transition"
38
+ >
39
+ <div
40
+ aria-selected="false"
41
+ class="item"
42
+ role="option"
43
+ >
44
+ <div
45
+ style="margin-left: 0px;"
46
+ >
47
+ <i
48
+ aria-hidden="true"
49
+ class="plus icon"
50
+ />
51
+ barDomain
52
+ </div>
53
+ </div>
54
+ <div
55
+ aria-selected="false"
56
+ class="item"
57
+ role="option"
58
+ >
59
+ <div
60
+ style="margin-left: 0px;"
61
+ >
62
+ <i
63
+ aria-hidden="true"
64
+ class="icon"
65
+ />
66
+ bazDomain
67
+ </div>
68
+ </div>
69
+ <div
70
+ aria-selected="false"
71
+ class="item"
72
+ role="option"
73
+ >
74
+ <div
75
+ style="margin-left: 0px;"
76
+ >
77
+ <i
78
+ aria-hidden="true"
79
+ class="icon"
80
+ />
81
+ fooDomain
82
+ </div>
83
+ </div>
84
+ </div>
85
+ </div>
86
+ </div>
87
+ </div>
88
+ </div>
89
+ `;
@@ -1,30 +1,90 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`<GlossaryMenu /> matches the latest snapshot 1`] = `
4
- <Connect(Submenu)
5
- icon="tags"
6
- items={
7
- Array [
8
- Object {
9
- "groups": Array [
10
- "business_glossary_view",
11
- ],
12
- "name": "concepts",
13
- "routes": Array [
14
- "/concepts",
15
- ],
16
- },
17
- Object {
18
- "groups": Array [
19
- "business_glossary_management",
20
- ],
21
- "name": "concepts_management",
22
- "routes": Array [
23
- "/pendingConcepts",
24
- ],
25
- },
26
- ]
27
- }
28
- name="glossary"
29
- />
3
+ exports[`<GlossaryMenu /> matches the latest snapshot, finds fixed and subscopes submenus 1`] = `
4
+ <div>
5
+ <div
6
+ class="active"
7
+ >
8
+ <div
9
+ aria-expanded="false"
10
+ class="ui item dropdown active"
11
+ role="listbox"
12
+ tabindex="0"
13
+ >
14
+ <a
15
+ class="ui"
16
+ href="/concepts"
17
+ >
18
+ <i
19
+ aria-hidden="true"
20
+ class="tags large icon"
21
+ />
22
+ </a>
23
+ <div
24
+ class="menu transition"
25
+ >
26
+ <div
27
+ class="header selectable"
28
+ >
29
+ glossary
30
+ </div>
31
+ <div
32
+ class="divider"
33
+ />
34
+ <a
35
+ aria-checked="true"
36
+ class="active item"
37
+ href="/concepts"
38
+ name="concepts"
39
+ role="option"
40
+ >
41
+ <span
42
+ class="text"
43
+ >
44
+ sidemenu.concepts
45
+ </span>
46
+ </a>
47
+ <a
48
+ aria-checked="true"
49
+ class="active item"
50
+ href="/subscopedConcepts/subscope1"
51
+ name="subscope1"
52
+ role="option"
53
+ >
54
+ <span
55
+ class="text"
56
+ >
57
+ subscope1
58
+ </span>
59
+ </a>
60
+ <a
61
+ aria-checked="true"
62
+ class="active item"
63
+ href="/subscopedConcepts/subscope2"
64
+ name="subscope2"
65
+ role="option"
66
+ >
67
+ <span
68
+ class="text"
69
+ >
70
+ subscope2
71
+ </span>
72
+ </a>
73
+ <a
74
+ aria-checked="true"
75
+ class="active item"
76
+ href="/pendingConcepts"
77
+ name="concepts_management"
78
+ role="option"
79
+ >
80
+ <span
81
+ class="text"
82
+ >
83
+ sidemenu.concepts_management
84
+ </span>
85
+ </a>
86
+ </div>
87
+ </div>
88
+ </div>
89
+ </div>
30
90
  `;
@@ -82,7 +82,7 @@ export default {
82
82
  "sidemenu.admin": "Administration",
83
83
  "sidemenu.catalog": "Catalog",
84
84
  "sidemenu.concepts_management": "Drafts",
85
- "sidemenu.concepts": "Concepts",
85
+ "sidemenu.concepts": "Glossary",
86
86
  "sidemenu.configurations": "Configuration",
87
87
  "sidemenu.dashboard": "Dashboard",
88
88
  "sidemenu.executions": "My Executions",
@@ -85,7 +85,7 @@ export default {
85
85
  "sidemenu.admin": "Administración",
86
86
  "sidemenu.catalog": "Catálogo",
87
87
  "sidemenu.concepts_management": "Borradores",
88
- "sidemenu.concepts": "Conceptos",
88
+ "sidemenu.concepts": "Glosario",
89
89
  "sidemenu.configurations": "Configuración",
90
90
  "sidemenu.dashboard": "Dashboard",
91
91
  "sidemenu.executions": "Mis ejecuciones",
package/src/routes.js CHANGED
@@ -6,6 +6,7 @@ export const CONCEPTS = "/concepts";
6
6
  export const CONCEPTS_BULK_UPDATE = "/concepts/bulk_update";
7
7
  export const CONCEPTS_NEW = "/concepts/new";
8
8
  export const CONCEPTS_PENDING = "/pendingConcepts";
9
+ export const CONCEPTS_SUBSCOPED = "/subscopedConcepts/:subscope";
9
10
  export const CONCEPT_ARCHIVE =
10
11
  "/concepts/:business_concept_id/versions/:id/archive";
11
12
  export const CONCEPT_EDIT = "/concepts/:business_concept_id/versions/:id/edit";
@@ -210,6 +211,7 @@ const routes = {
210
211
  CONCEPTS_BULK_UPDATE,
211
212
  CONCEPTS_NEW,
212
213
  CONCEPTS_PENDING,
214
+ CONCEPTS_SUBSCOPED,
213
215
  CONCEPT_ARCHIVE,
214
216
  CONCEPT_EDIT,
215
217
  CONCEPT_EVENTS,