@truedat/df 4.28.1 → 4.28.5

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.28.2] 2021-09-14
4
+
5
+ ### Added
6
+
7
+ - [TD-3971] Template mandatory dependent field
8
+
3
9
  ## [4.27.6] 2021-09-02
4
10
 
5
11
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/df",
3
- "version": "4.28.1",
3
+ "version": "4.28.5",
4
4
  "description": "Truedat Web Data Quality Module",
5
5
  "sideEffects": false,
6
6
  "jsnext:main": "src/index.js",
@@ -30,7 +30,7 @@
30
30
  "@babel/plugin-transform-modules-commonjs": "^7.15.0",
31
31
  "@babel/preset-env": "^7.15.0",
32
32
  "@babel/preset-react": "^7.14.5",
33
- "@truedat/test": "4.28.1",
33
+ "@truedat/test": "4.28.5",
34
34
  "babel-jest": "^27.0.6",
35
35
  "babel-plugin-dynamic-import-node": "^2.3.3",
36
36
  "babel-plugin-lodash": "^3.3.4",
@@ -80,8 +80,8 @@
80
80
  ]
81
81
  },
82
82
  "dependencies": {
83
- "@truedat/auth": "4.28.1",
84
- "@truedat/core": "4.28.1",
83
+ "@truedat/auth": "4.28.5",
84
+ "@truedat/core": "4.28.5",
85
85
  "axios": "^0.19.2",
86
86
  "path-to-regexp": "^1.7.0",
87
87
  "prop-types": "^15.7.2",
@@ -100,5 +100,5 @@
100
100
  "react-dom": ">= 16.8.6 < 17",
101
101
  "semantic-ui-react": ">= 0.88.2 < 2.1"
102
102
  },
103
- "gitHead": "6ff590df29781cbbbdbd8719a394649d758330c4"
103
+ "gitHead": "e004c6a673d6824a4807e4378b6e5c83e947c992"
104
104
  }
@@ -3,8 +3,8 @@ import React from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import { connect } from "react-redux";
5
5
  import { makeGetApplyTemplate, makeGetTemplate } from "../selectors";
6
+ import { enrichRequired } from "../utils";
6
7
  import FieldGroupSegment from "./FieldGroupSegment";
7
-
8
8
  const hasDependentKeys = (field) =>
9
9
  !_.isNil(_.path("depends.to_be")(field)) &&
10
10
  !_.isNil(_.path("depends.on")(field));
@@ -82,12 +82,14 @@ export const DynamicForm = ({
82
82
  (!(field.values && "switch" in field.values) ||
83
83
  content[field.values.switch.on] in field.values.switch.values)
84
84
  ),
85
- _.map(parseValues)
85
+ _.map(parseValues),
86
+ _.map((field) => enrichRequired(field, content))
86
87
  )(group.fields);
87
88
  return { ...group, fields };
88
89
  }),
89
90
  _.filter(({ fields }) => _.negate(_.isEmpty)(fields))
90
91
  )(template.content);
92
+
91
93
  return (
92
94
  <>
93
95
  {parsedGroups.map(({ name, fields }, i) => {
@@ -8,6 +8,7 @@ exports[`<DynamicForm /> matches snapshot for default field 1`] = `
8
8
  Object {
9
9
  "name": "test",
10
10
  "parsed_values": undefined,
11
+ "required": false,
11
12
  "value": undefined,
12
13
  },
13
14
  ]
@@ -34,6 +35,7 @@ exports[`<DynamicForm /> matches snapshot for role_users values 1`] = `
34
35
  "value": "user1",
35
36
  },
36
37
  ],
38
+ "required": false,
37
39
  "value": undefined,
38
40
  "values": Object {
39
41
  "processed_users": Array [
@@ -72,7 +72,7 @@ export const DynamicField = ({
72
72
  <Form.Field>
73
73
  <label>
74
74
  {label}
75
- {_.includes(cardinality)(["1", "+"]) && (
75
+ {fieldProps?.required && (
76
76
  <span
77
77
  style={{
78
78
  color: "#D95C5C",
@@ -98,7 +98,7 @@ export const DynamicField = ({
98
98
  hideOnScroll
99
99
  />
100
100
  )}
101
- {_.includes(cardinality)(["1", "+"]) && isNullOrEmpty(value) ? (
101
+ {fieldProps?.required && isNullOrEmpty(value) ? (
102
102
  <Label pointing="left">
103
103
  <FormattedMessage id="template.form.validation.empty_required" />
104
104
  </Label>
@@ -18,6 +18,9 @@ export default {
18
18
  "template.field.depends.to_be": "Source Value",
19
19
  "template.field.description": "Description",
20
20
  "template.field.label": "Label",
21
+ "template.field.mandatory.depends": "Mandatory depending on",
22
+ "template.field.mandatory.depends.on": "Depending on",
23
+ "template.field.mandatory.depends.to_be": "Depending value",
21
24
  "template.field.name": "Name",
22
25
  "template.field.subscribable": "Subscribable",
23
26
  "template.field.switch_values": "Dependent List",
@@ -17,6 +17,9 @@ export default {
17
17
  "template.field.depends.on": "Campo origen",
18
18
  "template.field.depends.to_be": "Valor origen",
19
19
  "template.field.description": "Descripción",
20
+ "template.field.mandatory.depends": "Obligatorio dependiente de",
21
+ "template.field.mandatory.depends.on": "Depende de",
22
+ "template.field.mandatory.depends.to_be": "Valor dependiente",
20
23
  "template.field.label": "Label",
21
24
  "template.field.name": "Nombre",
22
25
  "template.field.subscribable": "Suscribible",
@@ -3,13 +3,12 @@ import React, { useState } from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import {
5
5
  Accordion,
6
- Checkbox,
7
6
  Form,
8
7
  Button,
9
8
  Label,
10
9
  Confirm,
11
10
  Input,
12
- Icon
11
+ Icon,
13
12
  } from "semantic-ui-react";
14
13
  import { useIntl } from "react-intl";
15
14
  import { dropAt, swap } from "@truedat/core/services/arrays";
@@ -19,7 +18,7 @@ export const ActiveGroupForm = ({
19
18
  activeGroup,
20
19
  content,
21
20
  setActiveGroup,
22
- onChange
21
+ onChange,
23
22
  }) => {
24
23
  const [activeField, setActiveField] = useState();
25
24
  const [confirmDelete, setConfirmDelete] = useState(null);
@@ -30,21 +29,21 @@ export const ActiveGroupForm = ({
30
29
 
31
30
  const allFields = _.flow([
32
31
  _.map("fields"),
33
- _.reduce((acc, f) => [...acc, ...f], [])
32
+ _.reduce((acc, f) => [...acc, ...f], []),
34
33
  ])(content);
35
34
 
36
35
  const dependencies = _.groupBy("depends.on")(allFields);
37
36
  const groupFieldsName = _.map("name")(fields);
38
37
 
39
38
  const disabledDelete = _.flow(
40
- _.map(fieldName => _.prop(fieldName)(dependencies)),
39
+ _.map((fieldName) => _.prop(fieldName)(dependencies)),
41
40
  _.reject(_.isNil),
42
41
  _.flatten,
43
42
  _.reject(({ name }) => _.includes(name)(groupFieldsName)),
44
43
  _.negate(_.isEmpty)
45
44
  )(groupFieldsName);
46
45
 
47
- const moveGroup = direction => {
46
+ const moveGroup = (direction) => {
48
47
  const newIndex = direction == "up" ? activeGroup - 1 : activeGroup + 1;
49
48
  const value = swap(activeGroup, newIndex)(content);
50
49
  onChange(null, { name: "content", value });
@@ -59,14 +58,14 @@ export const ActiveGroupForm = ({
59
58
  cardinality: "?",
60
59
  type: "string",
61
60
  default: "",
62
- values: null
61
+ values: null,
63
62
  };
64
63
  const name = `${groupNamePrefix}.fields`;
65
64
  onChange(null, { name, value: [...fields, newField] });
66
65
  };
67
66
 
68
67
  const onSelectField = (e, { index }) =>
69
- setActiveField(x => (x == index ? null : index));
68
+ setActiveField((x) => (x == index ? null : index));
70
69
 
71
70
  const handleMoveField = (idx, direction) => {
72
71
  const newIndex = direction == "up" ? idx - 1 : idx + 1;
@@ -104,28 +103,28 @@ export const ActiveGroupForm = ({
104
103
  icon: "arrow up",
105
104
  disabled: activeGroup === 0,
106
105
  type: "button",
107
- onClick: () => moveGroup("up")
106
+ onClick: () => moveGroup("up"),
108
107
  },
109
108
  {
110
109
  key: "down",
111
110
  icon: "arrow down",
112
111
  disabled: activeGroup === content.length - 1,
113
112
  type: "button",
114
- onClick: () => moveGroup("down")
113
+ onClick: () => moveGroup("down"),
115
114
  },
116
115
  {
117
116
  key: "delete",
118
117
  icon: "trash alternate outline",
119
118
  disabled: disabledDelete,
120
119
  type: "button",
121
- onClick: () => setConfirmDelete({ type: "group" })
120
+ onClick: () => setConfirmDelete({ type: "group" }),
122
121
  },
123
122
  {
124
123
  key: "add_field",
125
124
  content: formatMessage({ id: "template.form.group.newField" }),
126
125
  type: "button",
127
- onClick: handleAddField
128
- }
126
+ onClick: handleAddField,
127
+ },
129
128
  ]}
130
129
  />
131
130
  <Form.Field
@@ -138,8 +137,8 @@ export const ActiveGroupForm = ({
138
137
  errors &&
139
138
  errors.nameDuplicated && {
140
139
  content: formatMessage({
141
- id: "template.form.validation.name_duplicated"
142
- })
140
+ id: "template.form.validation.name_duplicated",
141
+ }),
143
142
  }
144
143
  }
145
144
  />
@@ -160,11 +159,11 @@ export const ActiveGroupForm = ({
160
159
  {field.label}
161
160
  </Label>
162
161
  {!_.isEmpty(_.prop(field.name)(dependencies)) &&
163
- _.map(d => <Label key={i}>{d.name}</Label>)(
162
+ _.map((d) => <Label key={i}>{d.name}</Label>)(
164
163
  _.prop(field.name)(dependencies)
165
164
  )}
166
165
  </>
167
- )
166
+ ),
168
167
  },
169
168
  active: activeField === i,
170
169
  onTitleClick: onSelectField,
@@ -182,8 +181,8 @@ export const ActiveGroupForm = ({
182
181
  onMove={handleMoveField}
183
182
  onDelete={() => setConfirmDelete({ type: "field", idx: i })}
184
183
  />
185
- )
186
- }
184
+ ),
185
+ },
187
186
  }))(fields)}
188
187
  />
189
188
  {!_.isEmpty(confirmDelete) && (
@@ -192,7 +191,7 @@ export const ActiveGroupForm = ({
192
191
  cancelButton={formatMessage({ id: "confirmation.no" })}
193
192
  confirmButton={formatMessage({ id: "confirmation.yes" })}
194
193
  content={formatMessage({
195
- id: `template.form.delete.${confirmDelete.type}`
194
+ id: `template.form.delete.${confirmDelete.type}`,
196
195
  })}
197
196
  onCancel={() => setConfirmDelete(null)}
198
197
  onConfirm={handleDelete}
@@ -206,8 +205,7 @@ ActiveGroupForm.propTypes = {
206
205
  activeGroup: PropTypes.number.isRequired,
207
206
  setActiveGroup: PropTypes.func.isRequired,
208
207
  content: PropTypes.array.isRequired,
209
- allowSecretOption: PropTypes.bool,
210
- onChange: PropTypes.func.isRequired
208
+ onChange: PropTypes.func.isRequired,
211
209
  };
212
210
 
213
211
  export default ActiveGroupForm;
@@ -1,23 +1,25 @@
1
1
  import _ from "lodash/fp";
2
2
  import React from "react";
3
+ import PropTypes from "prop-types";
3
4
  import { useIntl } from "react-intl";
4
- import { Form } from "semantic-ui-react";
5
+ import DependentFormField from "./DependentFormField";
5
6
 
6
- const nilOrEmpty = value => _.isEmpty(value) || _.isNil(value);
7
+ const nilOrEmpty = (value) => _.isEmpty(value) || _.isNil(value);
7
8
  const fieldsToOptions = (fields, fieldName) =>
8
9
  _.flow(
9
10
  _.filter(
10
- f => !nilOrEmpty(_.pathOr([], "values.fixed")(f)) && f.name !== fieldName
11
+ (f) =>
12
+ !nilOrEmpty(_.pathOr([], "values.fixed")(f)) && f.name !== fieldName
11
13
  ),
12
- _.map(f => ({ text: f.label, value: f.name }))
14
+ _.map((f) => ({ text: f.label, value: f.name }))
13
15
  )(fields);
14
16
  const valuesToOptions = (fields, value) =>
15
17
  value !== ""
16
18
  ? _.flow(
17
- _.find(f => f.name === value),
19
+ _.find((f) => f.name === value),
18
20
  _.propOr([], "values.fixed"),
19
- _.filter(v => !_.isNil(v)),
20
- _.map(v => ({ text: v, value: v }))
21
+ _.filter((v) => !_.isNil(v)),
22
+ _.map((v) => ({ text: v, value: v }))
21
23
  )(fields)
22
24
  : [];
23
25
 
@@ -25,44 +27,39 @@ const ConditionalFieldForm = ({
25
27
  allFields,
26
28
  fieldNamePrefix,
27
29
  field,
28
- onChange
30
+ onChange,
29
31
  }) => {
30
32
  const { formatMessage } = useIntl();
31
33
  const { name, depends } = field;
32
34
  const optionFields = fieldsToOptions(allFields, name);
33
35
  const optionValues = valuesToOptions(allFields, _.propOr("", "on")(depends));
36
+ const handleChange = (e, { name, value }) => {
37
+ if (_.includes("depends.on")(name) && !_.isEmpty(depends?.to_be))
38
+ onChange(e, { name: `${fieldNamePrefix}.depends.to_be`, value: [] });
39
+
40
+ onChange(e, { name, value });
41
+ };
34
42
  return (
35
- <Form.Field>
36
- <label>{formatMessage({ id: "template.field.depends" })}</label>
37
- <Form.Group size="small" widths="equal">
38
- <Form.Dropdown
39
- name={`${fieldNamePrefix}.depends.on`}
40
- fluid
41
- selection
42
- clearable
43
- placeholder={formatMessage({ id: "template.field.depends.on" })}
44
- value={_.propOr("", "on")(depends)}
45
- onChange={onChange}
46
- options={optionFields}
47
- disabled={_.isEmpty(optionFields)}
48
- search
49
- />
50
- <Form.Dropdown
51
- name={`${fieldNamePrefix}.depends.to_be`}
52
- size="small"
53
- fluid
54
- selection
55
- placeholder={formatMessage({ id: "template.field.depends.to_be" })}
56
- value={_.propOr([], "to_be")(depends)}
57
- onChange={onChange}
58
- options={optionValues}
59
- multiple
60
- disabled={_.isEmpty(optionValues)}
61
- search
62
- />
63
- </Form.Group>
64
- </Form.Field>
43
+ <DependentFormField
44
+ label={formatMessage({ id: "template.field.depends" })}
45
+ fieldName={`${fieldNamePrefix}.depends.on`}
46
+ fieldOptions={optionFields}
47
+ fieldPlaceholder={formatMessage({ id: "template.field.depends.on" })}
48
+ fieldValue={_.propOr("", "on")(depends)}
49
+ onChange={handleChange}
50
+ value={_.propOr([], "to_be")(depends)}
51
+ valueName={`${fieldNamePrefix}.depends.to_be`}
52
+ valueOptions={optionValues}
53
+ valuePlaceholder={formatMessage({ id: "template.field.depends.to_be" })}
54
+ />
65
55
  );
66
56
  };
67
57
 
58
+ ConditionalFieldForm.propTypes = {
59
+ allFields: PropTypes.array,
60
+ fieldNamePrefix: PropTypes.string,
61
+ field: PropTypes.object,
62
+ onChange: PropTypes.func,
63
+ };
64
+
68
65
  export default ConditionalFieldForm;
@@ -0,0 +1,68 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import PropTypes from "prop-types";
4
+ import { Form } from "semantic-ui-react";
5
+
6
+ export const DependentFormField = ({
7
+ label,
8
+ fieldName,
9
+ fieldOptions,
10
+ fieldPlaceholder,
11
+ fieldValue,
12
+ onChange,
13
+ value,
14
+ valueName,
15
+ valueOptions,
16
+ valuePlaceholder,
17
+ }) => (
18
+ <Form.Field>
19
+ <label>{label}</label>
20
+ <Form.Group size="small" widths="equal">
21
+ <Form.Field>
22
+ <Form.Dropdown
23
+ clearable
24
+ disabled={_.isEmpty(fieldOptions)}
25
+ fluid
26
+ name={fieldName}
27
+ onChange={onChange}
28
+ options={fieldOptions}
29
+ placeholder={fieldPlaceholder}
30
+ search
31
+ selection
32
+ size="small"
33
+ value={fieldValue || ""}
34
+ />
35
+ </Form.Field>
36
+ <Form.Field>
37
+ <Form.Dropdown
38
+ clearable
39
+ disabled={_.isEmpty(valueOptions)}
40
+ fluid
41
+ name={valueName}
42
+ onChange={onChange}
43
+ options={valueOptions}
44
+ placeholder={valuePlaceholder}
45
+ multiple
46
+ search
47
+ selection
48
+ value={value || []}
49
+ />
50
+ </Form.Field>
51
+ </Form.Group>
52
+ </Form.Field>
53
+ );
54
+
55
+ DependentFormField.propTypes = {
56
+ label: PropTypes.string,
57
+ fieldOptions: PropTypes.array,
58
+ fieldPlaceholder: PropTypes.string,
59
+ fieldName: PropTypes.string,
60
+ fieldValue: PropTypes.string,
61
+ onChange: PropTypes.func,
62
+ value: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
63
+ valueName: PropTypes.string,
64
+ valueOptions: PropTypes.array,
65
+ valuePlaceholder: PropTypes.string,
66
+ };
67
+
68
+ export default DependentFormField;