@truedat/dd 4.40.1 → 4.40.4

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,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.40.2] 2022-03-14
4
+
5
+ ### Added
6
+
7
+ - [TD-4500] Support for data structures with multiple domain_ids
8
+
3
9
  ## [4.40.1] 2022-03-08
4
10
 
5
11
  ### Changed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/dd",
3
- "version": "4.40.1",
3
+ "version": "4.40.4",
4
4
  "description": "Truedat Web Data Dictionary",
5
5
  "sideEffects": false,
6
6
  "jsnext:main": "src/index.js",
@@ -34,7 +34,7 @@
34
34
  "@testing-library/jest-dom": "^5.14.1",
35
35
  "@testing-library/react": "^12.0.0",
36
36
  "@testing-library/user-event": "^13.2.1",
37
- "@truedat/test": "4.39.0",
37
+ "@truedat/test": "4.40.4",
38
38
  "babel-jest": "^27.0.6",
39
39
  "babel-plugin-dynamic-import-node": "^2.3.3",
40
40
  "babel-plugin-lodash": "^3.3.4",
@@ -84,9 +84,9 @@
84
84
  ]
85
85
  },
86
86
  "dependencies": {
87
- "@truedat/auth": "4.40.1",
88
- "@truedat/core": "4.40.1",
89
- "@truedat/df": "4.40.1",
87
+ "@truedat/auth": "4.40.4",
88
+ "@truedat/core": "4.40.4",
89
+ "@truedat/df": "4.40.4",
90
90
  "lodash": "^4.17.21",
91
91
  "path-to-regexp": "^1.7.0",
92
92
  "prop-types": "^15.7.2",
@@ -107,5 +107,5 @@
107
107
  "react-dom": ">= 16.8.6 < 17",
108
108
  "semantic-ui-react": ">= 0.88.2 < 2.1"
109
109
  },
110
- "gitHead": "58b35b48833fbed1602d1070853e6c805bcc48f1"
110
+ "gitHead": "e9f62f91507d810f91963967a5f3afa20100c1b9"
111
111
  }
@@ -8,24 +8,25 @@ import { useIntl } from "react-intl";
8
8
  import { connect } from "react-redux";
9
9
  import { updateStructure } from "../routines";
10
10
 
11
- export const EditDomainForm = ({ title, updateStructure, structure }) => {
11
+ export const EditDomainForm = ({
12
+ saving,
13
+ title,
14
+ updateStructure,
15
+ structure,
16
+ }) => {
12
17
  const { formatMessage } = useIntl();
13
- const [domainId, setDomainId] = useState(null);
14
- const [with_inheritance, set_with_inheritance] = useState(true);
18
+ const [domainIds, setDomainIds] = useState(structure?.domain_ids || []);
19
+ const [inherit, setInherit] = useState(true);
15
20
 
16
21
  const onSubmit = () => {
17
- const data_structure = {
18
- id: structure.id,
19
- domain_id: domainId,
20
- with_inheritance,
21
- };
22
+ const data_structure = { id: structure.id, domain_ids: domainIds };
22
23
  const redirect = linkTo.STRUCTURE_NOTES(data_structure);
23
24
 
24
- updateStructure({ data_structure, redirect });
25
+ updateStructure({ data_structure, inherit, redirect });
25
26
  };
26
27
 
27
28
  const handleDomainSelected = (e, { value }) => {
28
- setDomainId(value);
29
+ setDomainIds(value);
29
30
  };
30
31
 
31
32
  return (
@@ -33,27 +34,33 @@ export const EditDomainForm = ({ title, updateStructure, structure }) => {
33
34
  <Header as="h2" content={title} />
34
35
  <DomainDropdownSelector
35
36
  clearable={false}
37
+ multiple={true}
36
38
  onChange={handleDomainSelected}
37
39
  name="domain"
38
- value={domainId || structure?.domain_id}
40
+ value={domainIds}
39
41
  />
40
42
 
41
43
  <Checkbox
42
44
  label={formatMessage({
43
- id: "structureDomain.actions.update.with_inheritance",
45
+ id: "structureDomain.actions.update.inherit",
44
46
  })}
45
- checked={with_inheritance}
47
+ checked={inherit}
46
48
  onChange={(e) => {
47
- set_with_inheritance(!with_inheritance);
49
+ setInherit(!inherit);
48
50
  e.preventDefault();
49
51
  }}
50
52
  />
51
53
 
52
- <Form onSubmit={onSubmit}>
54
+ <Form onSubmit={saving ? null : onSubmit}>
53
55
  <div className="actions">
54
56
  <Button
55
57
  type="submit"
56
- disabled={!Boolean(domainId) || domainId == structure?.domain_id}
58
+ loading={saving}
59
+ disabled={
60
+ saving ||
61
+ _.isEmpty(domainIds) ||
62
+ domainIds == [structure?.domain_ids]
63
+ }
57
64
  primary
58
65
  content={formatMessage({ id: "structureDomain.actions.update" })}
59
66
  />
@@ -67,10 +74,12 @@ EditDomainForm.propTypes = {
67
74
  structure: PropTypes.object,
68
75
  updateStructure: PropTypes.func,
69
76
  title: PropTypes.string,
77
+ saving: PropTypes.bool,
70
78
  };
71
79
 
72
80
  const mapStateToProps = (state) => ({
73
- structure: _.pick(["id", "domain_id"])(state.structure),
81
+ structure: _.pick(["id", "domain_ids"])(state.structure),
82
+ saving: state.structureUpdating,
74
83
  });
75
84
 
76
85
  export default connect(mapStateToProps, { updateStructure })(EditDomainForm);
@@ -5,7 +5,7 @@ import { Button, Icon, Popup } from "semantic-ui-react";
5
5
  import PropTypes from "prop-types";
6
6
  import EditDomainForm from "./EditDomainForm";
7
7
 
8
- export const EditDomainPopup = ({ userPermissions, saving }) => {
8
+ export const EditDomainPopup = ({ userPermissions, saving, text }) => {
9
9
  const { formatMessage } = useIntl();
10
10
  const [open, setOpen] = useState(false);
11
11
 
@@ -19,8 +19,11 @@ export class StructureConfidentialButton extends React.Component {
19
19
  const {
20
20
  structure: { id, confidential },
21
21
  } = this.props;
22
- const data_structure = { id, confidential: !confidential };
23
- this.props.updateStructure({ data_structure });
22
+ const data_structure = {
23
+ id,
24
+ confidential: !confidential,
25
+ };
26
+ this.props.updateStructure({ data_structure, inherit: true });
24
27
  };
25
28
 
26
29
  render() {
@@ -18,15 +18,15 @@ describe("<EditDomainForm />", () => {
18
18
 
19
19
  const props = {
20
20
  title: "title",
21
- saving: true,
22
21
  updateStructure,
23
- structure: structure,
22
+ structure,
24
23
  };
24
+
25
25
  const messages = {
26
26
  en: {
27
27
  "structure.edit_domain.title": "Edit domain",
28
28
  "structureDomain.actions.update": "Update",
29
- "structureDomain.actions.update.with_inheritance": "Apply on children",
29
+ "structureDomain.actions.update.inherit": "Apply on children",
30
30
  "domain.selector.label": "Domain",
31
31
  "domain.selector.placeholder": "Select a domain...",
32
32
  },
@@ -82,7 +82,8 @@ describe("<EditDomainForm />", () => {
82
82
  });
83
83
  expect(updateStructure).toHaveBeenCalledWith(
84
84
  expect.objectContaining({
85
- data_structure: { domain_id: 1, id: 42, with_inheritance: true },
85
+ data_structure: { domain_ids: [1], id: 42 },
86
+ inherit: true,
86
87
  redirect: "/structures/42/notes",
87
88
  })
88
89
  );
@@ -111,7 +112,39 @@ describe("<EditDomainForm />", () => {
111
112
  });
112
113
  expect(updateStructure).toHaveBeenCalledWith(
113
114
  expect.objectContaining({
114
- data_structure: { domain_id: 1, id: 42, with_inheritance: false },
115
+ data_structure: { domain_ids: [1], id: 42 },
116
+ inherit: false,
117
+ redirect: "/structures/42/notes",
118
+ })
119
+ );
120
+ });
121
+
122
+ it("send selected multiple domain ids when button clicked", async () => {
123
+ const { getByRole } = render(<EditDomainForm {...props} />, {
124
+ state: { domains },
125
+ messages,
126
+ });
127
+
128
+ const button = getByRole("button", { name: /update/i });
129
+ const checkbox = getByRole("checkbox");
130
+ const optionOne = getByRole("option", { name: /Domain 1/i });
131
+ const optionTwo = getByRole("option", { name: /Domain 2/i });
132
+
133
+ expect(button).toBeDisabled();
134
+ expect(checkbox).toBeChecked();
135
+ userEvent.click(optionTwo);
136
+ userEvent.click(optionOne);
137
+ await waitFor(() => {
138
+ expect(button).not.toBeDisabled();
139
+ });
140
+ userEvent.click(button);
141
+ await waitFor(() => {
142
+ expect(updateStructure.mock.calls.length).toBe(1);
143
+ });
144
+ expect(updateStructure).toHaveBeenCalledWith(
145
+ expect.objectContaining({
146
+ data_structure: { domain_ids: [2, 1], id: 42 },
147
+ inherit: true,
115
148
  redirect: "/structures/42/notes",
116
149
  })
117
150
  );
@@ -22,7 +22,7 @@ exports[`<EditDomainForm /> matches the latest snapshot 1`] = `
22
22
  >
23
23
  <div
24
24
  aria-expanded="false"
25
- class="ui fluid search selection dropdown"
25
+ class="ui fluid multiple search selection dropdown"
26
26
  name="domain"
27
27
  role="combobox"
28
28
  >
@@ -34,6 +34,9 @@ exports[`<EditDomainForm /> matches the latest snapshot 1`] = `
34
34
  type="text"
35
35
  value=""
36
36
  />
37
+ <span
38
+ class="sizer"
39
+ />
37
40
  <div
38
41
  aria-atomic="true"
39
42
  aria-live="polite"
@@ -47,6 +50,7 @@ exports[`<EditDomainForm /> matches the latest snapshot 1`] = `
47
50
  class="dropdown icon"
48
51
  />
49
52
  <div
53
+ aria-multiselectable="true"
50
54
  class="menu transition"
51
55
  role="listbox"
52
56
  >
@@ -162,6 +162,7 @@ exports[`<StructureSummary /> renders custom grant label when grant provided 1`]
162
162
  <div
163
163
  class="description"
164
164
  >
165
+
165
166
  <button
166
167
  class="ui basic icon button"
167
168
  style="box-shadow: none;"
@@ -310,6 +311,7 @@ exports[`<StructureSummary /> renders label when grant provided 1`] = `
310
311
  <div
311
312
  class="description"
312
313
  >
314
+
313
315
  <button
314
316
  class="ui basic icon button"
315
317
  style="box-shadow: none;"
@@ -314,7 +314,7 @@ export default {
314
314
  "structure.version.inserted_at": "Imported {when}",
315
315
  "structure.version.version": "Version {version}",
316
316
  "structureDomain.actions.update": "Update",
317
- "structureDomain.actions.update.with_inheritance": "Apply on children",
317
+ "structureDomain.actions.update.inherit": "Apply on children",
318
318
  "structureSelector.union.criteria": "Union criteria",
319
319
  "structureTagForm.props.name": "Name",
320
320
  "structureTags.actions.create": "Create Structure Tag",
@@ -318,7 +318,7 @@ export default {
318
318
  "structure.version.inserted_at": "Importada {when}",
319
319
  "structure.version.version": "Versión {version}",
320
320
  "structureDomain.actions.update": "Actualizar",
321
- "structureDomain.actions.update.with_inheritance": "Aplicar en hijos",
321
+ "structureDomain.actions.update.inherit": "Aplicar en hijos",
322
322
  "structureSelector.union.criteria": "Criterio de unión",
323
323
  "structureTagForm.props.name": "Nombre",
324
324
  "structureTags.actions.create": "Crear Etiqueta de Estructura",
@@ -428,7 +428,7 @@ export default {
428
428
  "structures.props.system": "Sistema",
429
429
  "structures.props.type": "Tipo",
430
430
  "structures.relation.new.header":
431
- "Vas a vincular este campo a un término del glosário",
431
+ "Vas a vincular este campo a un término del glosario",
432
432
  "structures.retrieved.results": "{count} elementos encontrados",
433
433
  "structures.search.placeholder": "Buscar estructuras...",
434
434
  "structures.searching": "Buscando Estructuras...",
@@ -23,7 +23,7 @@ describe("reducers: structure", () => {
23
23
  const type = "table";
24
24
  const group = "kong";
25
25
  const system = { id: 1, name: "king" };
26
- const domain = { id: 1, name: "Domain" };
26
+ const domains = [{ id: 1, name: "Domain" }];
27
27
  const metadata = { foo: "bar" };
28
28
  const grant = { id: 1, detail: { foo: "bar" } };
29
29
  const siblings = [{ id: 1, name: "foo" }];
@@ -32,7 +32,7 @@ describe("reducers: structure", () => {
32
32
  inserted_at: "foo",
33
33
  updated_at: "foo",
34
34
  confidential: false,
35
- domain,
35
+ domains,
36
36
  };
37
37
  const data = {
38
38
  data_structure,
@@ -9,8 +9,8 @@ const structureFields = (fn) =>
9
9
  _.pick([
10
10
  "confidential",
11
11
  "latest_note",
12
- "domain_id",
13
- "domain",
12
+ "domain_ids",
13
+ "domains",
14
14
  "external_id",
15
15
  "id",
16
16
  "inserted_at",
@@ -35,8 +35,9 @@ describe("sagas: updateStructureSaga", () => {
35
35
  const url = compile(API_DATA_STRUCTURE)({ id });
36
36
  const data_structure = { id, description, lopd };
37
37
  const redirect = "foo";
38
- const payload = { data_structure, redirect };
39
- const requestData = { data_structure: { description, lopd } };
38
+ const inherit = false;
39
+ const payload = { data_structure, redirect, inherit };
40
+ const requestData = { data_structure: { description, lopd }, inherit };
40
41
  const successData = { ...data_structure, redirect };
41
42
 
42
43
  it("should put a success action when a response is returned", () => {
@@ -7,9 +7,12 @@ import { API_DATA_STRUCTURE } from "../api";
7
7
 
8
8
  export function* updateStructureSaga({ payload }) {
9
9
  try {
10
- const { data_structure, redirect } = payload;
10
+ const { data_structure, inherit, redirect } = payload;
11
11
  const url = compile(API_DATA_STRUCTURE)(data_structure);
12
- const requestData = { data_structure: _.omit(["id"])(data_structure) };
12
+ const requestData = {
13
+ data_structure: _.omit(["id"])(data_structure),
14
+ inherit,
15
+ };
13
16
  yield put(updateStructure.request());
14
17
  const { data } = yield call(apiJsonPatch, url, requestData, JSON_OPTS);
15
18
  const successPayload = redirect ? { ...data, redirect } : data;
@@ -3,18 +3,17 @@ import React from "react";
3
3
  import { createSelector } from "reselect";
4
4
  import EditDomainPopup from "../components/EditDomainPopup";
5
5
 
6
- const domainDecorator = (domain) => (
6
+ const domainDecorator = (domainNames) => (
7
7
  <>
8
- {domain}
8
+ {domainNames}
9
9
  <EditDomainPopup />
10
10
  </>
11
11
  );
12
- false;
13
12
 
14
13
  export const defaultStructureProperties = [
15
14
  {
16
15
  name: "domain",
17
- fieldSelector: _.path("domain.name"),
16
+ fieldSelector: _.flow(_.propOr([], "domains"), _.map("name"), _.join(", ")),
18
17
  fieldDecorator: domainDecorator,
19
18
  },
20
19
  { name: "group" },