@truedat/bg 6.6.5 → 6.7.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/bg",
3
- "version": "6.6.5",
3
+ "version": "6.7.0",
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": "6.6.5",
37
+ "@truedat/test": "6.7.0",
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": "6.6.5",
90
- "@truedat/df": "6.6.5",
91
- "@truedat/lm": "6.6.5",
89
+ "@truedat/core": "6.7.0",
90
+ "@truedat/df": "6.7.0",
91
+ "@truedat/lm": "6.7.0",
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": "875dcb0716cc64d30974106dc64c861d4306fcd6"
114
+ "gitHead": "6a4284b126a917e396160f1b36c03ca0faf6bac5"
115
115
  }
@@ -14,7 +14,7 @@ const missingRequiredFields = (concept, content) => {
14
14
  _.flatMap(({ fields }) =>
15
15
  _.filter((field) => {
16
16
  const name = field?.name;
17
- const value = _.prop(name)(content);
17
+ const value = _.prop("value")(_.prop(name)(content));
18
18
  return (
19
19
  !_.isNumber(value) &&
20
20
  isRequired(field, content) &&
@@ -40,10 +40,12 @@ export const Completeness = ({
40
40
  id="concepts.props.completeness"
41
41
  defaultMessage="Completeness"
42
42
  />{" "}
43
- <FormattedMessage
44
- id={`i18n.messages.locale.${lang}`}
45
- defaultMessage={langLocalName}
46
- />
43
+ {langLocalName ? (
44
+ <FormattedMessage
45
+ id={`i18n.messages.locale.${lang}`}
46
+ defaultMessage={langLocalName}
47
+ />
48
+ ) : null}
47
49
  </Header>
48
50
  <>{}</>
49
51
  <Progress
@@ -26,17 +26,17 @@ const ConceptCreate = ({ conceptActionLoading, conceptAction }) => {
26
26
  useEffect(() => {
27
27
  const templateFields = splitTranslatableFields(template);
28
28
 
29
- setTranslatableKeys(_.keys(templateFields.translatable));
30
- setNoTranslatableKeys(_.keys(templateFields.noTranslatable));
29
+ const translatableFields = _.keys(templateFields.translatable);
30
+ const noTranslatableFields = _.keys(templateFields.noTranslatable);
31
+
32
+ setTranslatableKeys(translatableFields);
33
+ setNoTranslatableKeys(noTranslatableFields);
31
34
 
32
35
  const updateI18nConcept = _.flow(
33
36
  _.map((langContent) => ({
34
37
  ...langContent,
35
38
  content: langContent.is_default
36
- ? {
37
- ...templateFields.translatable,
38
- ...templateFields.noTranslatable,
39
- }
39
+ ? { ...langContent.content }
40
40
  : { ...templateFields.translatable },
41
41
  })),
42
42
  _.keyBy("lang")
@@ -10,68 +10,34 @@ import {
10
10
  formatLocales,
11
11
  } from "@truedat/core/services/i18nContent";
12
12
  import { useTemplate } from "@truedat/core/hooks";
13
-
14
13
  import { conceptAction } from "../routines";
15
-
16
14
  import ConceptForms from "./ConceptForms";
17
15
  const actionKey = "update";
18
16
 
19
17
  export const ConceptEdit = ({
20
18
  concept,
19
+ content,
21
20
  loading,
21
+ locales,
22
+ localesLoading,
22
23
  template,
23
24
  action,
24
25
  conceptAction,
25
26
  processedContent,
26
27
  }) => {
27
- const { content: propContent, name: propName, domain } = concept;
28
- const { locales, loading: localesLoading } = useLocales(false);
29
- const [i18nConcept, setI18nConcept] = useState({});
30
-
31
- if (_.isNil(propContent)) {
32
- return null;
33
- }
34
-
35
- if (_.isEmpty(i18nConcept)) {
36
- const i18n_content = concept.i18n_content || {};
37
-
38
- const { translatable: translatableFields } =
39
- splitTranslatableFields(template);
40
-
41
- const i18nConceptInit = _.flow(
42
- _.filter(({ is_enabled }) => is_enabled),
43
- _.map(({ id, lang, is_default, is_required }) => {
44
- const contentLang = _.get(lang)(i18n_content);
45
-
46
- const langContent = is_default
47
- ? propContent
48
- : { ...translatableFields, ...contentLang?.content };
49
- const langName = is_default ? propName : contentLang?.name || "";
50
-
51
- return {
52
- id,
53
- lang,
54
- is_default,
55
- is_required,
56
- name: langName,
57
- content: langContent,
58
- };
59
- }),
60
- _.keyBy("lang")
61
- )(locales);
62
-
63
- setI18nConcept(i18nConceptInit);
64
- }
28
+ const { domain } = concept;
29
+
30
+ const [i18nConcept, setI18nConcept] = useState(content);
65
31
 
66
32
  const templateFields = splitTranslatableFields(template);
67
33
 
68
34
  const translatableKeys = _.keys(templateFields.translatable);
69
35
  const noTranslatableKeys = _.keys(templateFields.noTranslatable);
70
36
  const langs = formatLocales(locales);
71
- const defaultContent = _.flow(_.find("is_default"))(i18nConcept);
72
37
 
73
38
  const handleSubmit = (e) => {
74
39
  e.preventDefault();
40
+ const defaultContent = _.flow(_.find("is_default"))(i18nConcept);
75
41
 
76
42
  const i18nSendConcept = _.flow(
77
43
  _.omit(defaultContent.lang),
@@ -129,8 +95,9 @@ ConceptEdit.propTypes = {
129
95
  export const ConceptEditLoader = (props) => {
130
96
  const templateName = _.prop("templateName")(props);
131
97
  const concept = _.prop("concept")(props);
132
- const { domain } = concept;
98
+ const { content: propContent, name: propName, domain } = concept;
133
99
 
100
+ const { locales, loading: localesLoading } = useLocales(false);
134
101
  const { data, loading: templateLoading } = useTemplate({
135
102
  name: templateName,
136
103
  domainIds: [domain.id],
@@ -139,11 +106,39 @@ export const ConceptEditLoader = (props) => {
139
106
  const template = _.prop("template")(data);
140
107
  const processedContent = applyTemplate(template);
141
108
 
109
+ const i18nContent = _.flow(
110
+ _.filter(({ is_enabled }) => is_enabled),
111
+ _.map(({ id, lang, is_default, is_required }) => {
112
+ const contentLang = _.get(lang)(concept.i18n_content || {});
113
+
114
+ const langContent = is_default
115
+ ? propContent
116
+ : {
117
+ ...splitTranslatableFields(template).translatable,
118
+ ...contentLang?.content,
119
+ };
120
+ const langName = is_default ? propName : contentLang?.name || "";
121
+
122
+ return {
123
+ id,
124
+ lang,
125
+ is_default,
126
+ is_required,
127
+ name: langName,
128
+ content: langContent,
129
+ };
130
+ }),
131
+ _.keyBy("lang")
132
+ )(locales);
133
+
142
134
  return (
143
135
  <ConceptEdit
144
136
  templateLoading={templateLoading}
137
+ localesLoading={localesLoading}
145
138
  processedContent={processedContent}
139
+ content={i18nContent}
146
140
  template={template}
141
+ locales={locales}
147
142
  {...props}
148
143
  />
149
144
  );
@@ -79,8 +79,15 @@ const ConceptForm = ({
79
79
  onChangeConceptContent(concept.lang, content);
80
80
 
81
81
  const applySuggestions = (suggestions) => {
82
+ const suggestionContent = _.flow(
83
+ Object.entries,
84
+ _.reduce(
85
+ (acc, [key, value]) => _.set(key, { value, origin: "ai" })(acc),
86
+ {}
87
+ )
88
+ )(suggestions);
82
89
  onChangeConceptContent(concept.lang, {
83
- content: { ...concept?.content, ...suggestions },
90
+ content: { ...concept?.content, ...suggestionContent },
84
91
  });
85
92
  };
86
93
 
@@ -165,7 +172,7 @@ ConceptForm.propTypes = {
165
172
  onChangeTemplate: PropTypes.func,
166
173
  onChangeConceptContent: PropTypes.func,
167
174
  actionKey: PropTypes.string,
168
- conceptActionLoading: PropTypes.string,
175
+ loading: PropTypes.bool,
169
176
  };
170
177
 
171
178
  export default ConceptForm;
@@ -101,7 +101,7 @@ describe("<ConceptEdit />", () => {
101
101
  applyTemplate: jest.fn(),
102
102
  };
103
103
  it("matches the latest snapshot", async () => {
104
- const { container, queryByText, debug } = render(
104
+ const { container, queryByText } = render(
105
105
  <Suspense fallback={null}>
106
106
  <ConceptEdit {...props} />
107
107
  </Suspense>,
@@ -1,7 +1,22 @@
1
1
  import React from "react";
2
- import { shallow } from "enzyme";
2
+ import { render } from "@truedat/test/render";
3
3
  import { ConceptCompleteness } from "../ConceptCompleteness";
4
4
 
5
+ jest.mock("@truedat/core/hooks", () => ({
6
+ useLocales: jest.fn(() => ({
7
+ loading: false,
8
+ locales: [
9
+ {
10
+ lang: "es",
11
+ id: 1,
12
+ is_default: true,
13
+ is_required: true,
14
+ is_enabled: true,
15
+ },
16
+ ],
17
+ })),
18
+ }));
19
+
5
20
  describe("<ConceptCompleteness />", () => {
6
21
  const props = {
7
22
  concept: {
@@ -10,21 +25,21 @@ describe("<ConceptCompleteness />", () => {
10
25
  content: [
11
26
  {
12
27
  fields: [
13
- { cardinality: "?", name: "field1" },
14
- { cardinality: "1", name: "field2" },
15
- { cardinality: "1", name: "field3" }
16
- ]
17
- }
18
- ]
28
+ { cardinality: "?", name: "field1", label: "label1" },
29
+ { cardinality: "1", name: "field2", label: "label2" },
30
+ { cardinality: "1", name: "field3", label: "label3" },
31
+ ],
32
+ },
33
+ ],
19
34
  },
20
35
  content: {
21
- field3: "value"
22
- }
23
- }
36
+ field3: { value: "value", origin: "user" },
37
+ },
38
+ },
24
39
  };
25
40
 
26
41
  it("matches the latest snapshot", () => {
27
- const wrapper = shallow(<ConceptCompleteness {...props} />);
28
- expect(wrapper).toMatchSnapshot();
42
+ const { container } = render(<ConceptCompleteness {...props} />);
43
+ expect(container).toMatchSnapshot();
29
44
  });
30
45
  });
@@ -1,7 +1,26 @@
1
- import React, { Suspense } from "react";
1
+ import React from "react";
2
2
  import { render } from "@truedat/test/render";
3
3
  import { ConceptDetails } from "../ConceptDetails";
4
4
 
5
+ jest.mock("@truedat/core/hooks", () => ({
6
+ useLocales: jest.fn(() => ({
7
+ loading: false,
8
+ locales: [
9
+ {
10
+ lang: "en",
11
+ id: 1,
12
+ is_default: true,
13
+ is_required: true,
14
+ is_enabled: true,
15
+ },
16
+ ],
17
+ })),
18
+ }));
19
+
20
+ const renderOpts = {
21
+ fallback: <div>Loading</div>,
22
+ };
23
+
5
24
  describe("<ConceptDetails />", () => {
6
25
  const props = {
7
26
  concept: {
@@ -9,17 +28,27 @@ describe("<ConceptDetails />", () => {
9
28
  type: "type",
10
29
  status: "draft",
11
30
  template: {
12
- content: [{ name: "field", value: "value1" }],
31
+ content: [
32
+ {
33
+ name: "foo_group",
34
+ fields: [
35
+ { name: "field", label: "field_label", values: ["value1"] },
36
+ ],
37
+ },
38
+ ],
39
+ },
40
+ content: {
41
+ field: { value: "value1", origin: "user" },
13
42
  },
14
43
  },
15
44
  };
16
45
 
17
- it("matches the latest snapshot", () => {
18
- const { container } = render(
19
- <Suspense fallback={null}>
20
- <ConceptDetails {...props} />
21
- </Suspense>
22
- );
46
+ it("matches the latest snapshot", async () => {
47
+ const { container, findByText } = render(<ConceptDetails {...props} />, {
48
+ ...renderOpts,
49
+ });
50
+
51
+ await findByText("field_label");
23
52
  expect(container).toMatchSnapshot();
24
53
  });
25
54
  });
@@ -86,7 +86,10 @@ describe("<ConceptsBulkUpdate />", () => {
86
86
  await waitFor(() => {
87
87
  expect(dispatch).toHaveBeenLastCalledWith(
88
88
  bulkUpdate({
89
- updateAttributes: { content: { field1: "abc123456" }, domain_id: 1 },
89
+ updateAttributes: {
90
+ content: { field1: { value: "abc123456", origin: "user" } },
91
+ domain_id: 1,
92
+ },
90
93
  searchParams: {},
91
94
  })
92
95
  );
@@ -80,10 +80,10 @@ exports[`<ConceptEdit /> matches the latest snapshot 1`] = `
80
80
  <div
81
81
  aria-atomic="true"
82
82
  aria-live="polite"
83
- class="divider text"
83
+ class="divider default text"
84
84
  role="alert"
85
85
  >
86
- xyz_user
86
+ Select one...
87
87
  </div>
88
88
  <i
89
89
  aria-hidden="true"
@@ -96,8 +96,8 @@ exports[`<ConceptEdit /> matches the latest snapshot 1`] = `
96
96
  >
97
97
  <div
98
98
  aria-checked="false"
99
- aria-selected="false"
100
- class="item"
99
+ aria-selected="true"
100
+ class="selected item"
101
101
  role="option"
102
102
  style="pointer-events: all;"
103
103
  >
@@ -121,9 +121,9 @@ exports[`<ConceptEdit /> matches the latest snapshot 1`] = `
121
121
  </span>
122
122
  </div>
123
123
  <div
124
- aria-checked="true"
125
- aria-selected="true"
126
- class="active selected item"
124
+ aria-checked="false"
125
+ aria-selected="false"
126
+ class="item"
127
127
  role="option"
128
128
  style="pointer-events: all;"
129
129
  >
@@ -1,7 +1,51 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`<ConceptCompleteness /> matches the latest snapshot 1`] = `
4
- <Segment
5
- className="completeness"
6
- />
4
+ <div>
5
+ <div
6
+ class="ui segment completeness"
7
+ >
8
+ <h3
9
+ class="ui dividing header"
10
+ >
11
+ Completeness
12
+
13
+ </h3>
14
+ <div
15
+ class="ui warning progress"
16
+ data-percent="50"
17
+ >
18
+ <div
19
+ class="bar"
20
+ style="width: 50%;"
21
+ >
22
+ <div
23
+ class="progress"
24
+ >
25
+ 50%
26
+ </div>
27
+ </div>
28
+ </div>
29
+ <h4
30
+ class="ui dividing header"
31
+ >
32
+ Missing required fields
33
+ </h4>
34
+ <div
35
+ class="ui list"
36
+ role="list"
37
+ >
38
+ <div
39
+ class="item"
40
+ role="listitem"
41
+ >
42
+ <i
43
+ aria-hidden="true"
44
+ class="grey right angle fitted icon"
45
+ />
46
+ label2
47
+ </div>
48
+ </div>
49
+ </div>
50
+ </div>
7
51
  `;
@@ -4,7 +4,39 @@ exports[`<ConceptDetails /> matches the latest snapshot 1`] = `
4
4
  <div>
5
5
  <div
6
6
  class="ui bottom attached segment"
7
- style="display: none;"
8
- />
7
+ style=""
8
+ >
9
+ <div
10
+ class="ui horizontal divider"
11
+ >
12
+ <h3>
13
+ foo_group
14
+ </h3>
15
+ </div>
16
+ <div
17
+ class="ui big very relaxed list"
18
+ role="list"
19
+ >
20
+ <div
21
+ class="item"
22
+ role="listitem"
23
+ >
24
+ <div
25
+ class="header dynamic-field-header"
26
+ >
27
+ field_label
28
+ </div>
29
+ <div
30
+ class="description"
31
+ >
32
+ <div
33
+ class="default-value"
34
+ >
35
+ value1
36
+ </div>
37
+ </div>
38
+ </div>
39
+ </div>
40
+ </div>
9
41
  </div>
10
42
  `;