@truedat/df 7.12.5 → 7.12.7
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 +4 -4
- package/src/components/DynamicFieldValue.js +1 -1
- package/src/components/DynamicFormViewer.js +4 -3
- package/src/components/DynamicFormWithTranslations.js +3 -3
- package/src/components/EditableDynamicFieldValue.js +1 -1
- package/src/components/FieldViewerValue.js +44 -3
- package/src/components/__tests__/FieldViewerValue.spec.js +10 -6
- package/src/components/__tests__/__snapshots__/FieldViewerValue.spec.js.snap +53 -0
- package/src/components/widgets/DynamicField.js +6 -62
- package/src/components/widgets/DynamicTableField.js +150 -0
- package/src/components/widgets/FieldByWidget.js +63 -0
- package/src/components/widgets/StandardDropdown.js +2 -2
- package/src/components/widgets/StringField.js +2 -1
- package/src/components/widgets/__tests__/DynamicField.spec.js +10 -1
- package/src/components/widgets/__tests__/DynamicTableField.spec.js +257 -0
- package/src/components/widgets/__tests__/__snapshots__/DynamicField.spec.js.snap +97 -0
- package/src/components/widgets/__tests__/__snapshots__/DynamicTableField.spec.js.snap +114 -0
- package/src/templates/components/templateForm/ActiveGroupForm.js +5 -16
- package/src/templates/components/templateForm/FieldDefinition.js +158 -0
- package/src/templates/components/templateForm/FieldForm.js +32 -135
- package/src/templates/components/templateForm/TableValuesForm.js +258 -0
- package/src/templates/components/templateForm/TemplateForm.js +43 -26
- package/src/templates/components/templateForm/ValuesConfiguration.js +67 -0
- package/src/templates/components/templateForm/ValuesField.js +60 -96
- package/src/templates/components/templateForm/ValuesListForm.js +1 -3
- package/src/templates/components/templateForm/__tests__/FieldDefinition.spec.js +227 -0
- package/src/templates/components/templateForm/__tests__/TableValuesForm.spec.js +215 -0
- package/src/templates/components/templateForm/__tests__/ValuesField.spec.js +28 -83
- package/src/templates/components/templateForm/__tests__/__snapshots__/ActiveGroupForm.spec.js.snap +17 -0
- package/src/templates/components/templateForm/__tests__/__snapshots__/FieldDefinition.spec.js.snap +443 -0
- package/src/templates/components/templateForm/__tests__/__snapshots__/FieldForm.spec.js.snap +51 -0
- package/src/templates/components/templateForm/__tests__/__snapshots__/TemplateForm.spec.js.snap +17 -0
- package/src/templates/components/templateForm/__tests__/__snapshots__/ValuesField.spec.js.snap +61 -387
- package/src/templates/components/templateForm/contentValidation.js +22 -3
- package/src/templates/components/templateForm/valueDefinitions.js +16 -2
- package/src/templates/components/templateForm/widgetDefinitions.js +28 -2
- package/src/templates/utils/__tests__/validateContent.spec.js +6 -6
- package/src/templates/utils/applyTemplate.js +72 -23
- package/src/templates/utils/filterValues.js +3 -3
- package/src/templates/utils/parseFieldOptions.js +73 -58
- package/src/templates/utils/parseGroups.js +47 -48
- package/src/templates/utils/validateContent.js +70 -25
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
+
import { useIntl } from "react-intl";
|
|
3
|
+
|
|
4
|
+
export const getCardinalityOptions = (widget) => {
|
|
5
|
+
const { formatMessage } = useIntl();
|
|
2
6
|
|
|
3
|
-
export const getCardinalityOptions = (formatMessage) => (widget) => {
|
|
4
7
|
const cardinalities = _.flow([
|
|
5
8
|
_.find({ value: widget }),
|
|
6
9
|
_.prop("cardinalities"),
|
|
@@ -12,7 +15,9 @@ export const getCardinalityOptions = (formatMessage) => (widget) => {
|
|
|
12
15
|
}))(cardinalities);
|
|
13
16
|
};
|
|
14
17
|
|
|
15
|
-
export const getTypeOptions = (
|
|
18
|
+
export const getTypeOptions = (widget) => {
|
|
19
|
+
const { formatMessage } = useIntl();
|
|
20
|
+
|
|
16
21
|
const types = _.flow([_.find({ value: widget }), _.prop("types")])(WIDGETS);
|
|
17
22
|
return _.map((type) => ({
|
|
18
23
|
key: type,
|
|
@@ -111,6 +116,14 @@ export const WIDGETS = [
|
|
|
111
116
|
cardinalities: ["*"],
|
|
112
117
|
types: ["table"],
|
|
113
118
|
},
|
|
119
|
+
{
|
|
120
|
+
key: "dynamic_table",
|
|
121
|
+
value: "dynamic_table",
|
|
122
|
+
text: "Dynamic Table",
|
|
123
|
+
icon: "table",
|
|
124
|
+
cardinalities: ["*"],
|
|
125
|
+
types: ["dynamic_table"],
|
|
126
|
+
},
|
|
114
127
|
{
|
|
115
128
|
key: "password",
|
|
116
129
|
value: "password",
|
|
@@ -152,3 +165,16 @@ export const WIDGETS = [
|
|
|
152
165
|
types: ["datetime"],
|
|
153
166
|
},
|
|
154
167
|
];
|
|
168
|
+
|
|
169
|
+
export const defaultFieldDefinition = {
|
|
170
|
+
name: "new_field",
|
|
171
|
+
label: "New Field",
|
|
172
|
+
widget: "string",
|
|
173
|
+
cardinality: "?",
|
|
174
|
+
type: "string",
|
|
175
|
+
default: {
|
|
176
|
+
value: "",
|
|
177
|
+
origin: "default",
|
|
178
|
+
},
|
|
179
|
+
values: null,
|
|
180
|
+
};
|
|
@@ -62,7 +62,7 @@ const templateMultCondVisibility = {
|
|
|
62
62
|
describe("utils: validateContent", () => {
|
|
63
63
|
describe("validateRequired", () => {
|
|
64
64
|
it("should return an empty array on valid content", () => {
|
|
65
|
-
const content = { req: "foo" };
|
|
65
|
+
const content = { req: { value: "foo" } };
|
|
66
66
|
const result = validateContent(template)(content);
|
|
67
67
|
expect(result).toEqual([]);
|
|
68
68
|
});
|
|
@@ -77,12 +77,12 @@ describe("utils: validateContent", () => {
|
|
|
77
77
|
]);
|
|
78
78
|
});
|
|
79
79
|
it("should return empty array on valid multiple field", () => {
|
|
80
|
-
const content = { req: ["value"] };
|
|
80
|
+
const content = { req: { value: ["value"] } };
|
|
81
81
|
const result = validateContent(templateMultiple)(content);
|
|
82
82
|
expect(result).toEqual([]);
|
|
83
83
|
});
|
|
84
84
|
it("should return error on empty required multiple field", () => {
|
|
85
|
-
const content = { req: [] };
|
|
85
|
+
const content = { req: { value: [] } };
|
|
86
86
|
const result = validateContent(templateMultiple)(content);
|
|
87
87
|
expect(result).toEqual([
|
|
88
88
|
{
|
|
@@ -92,12 +92,12 @@ describe("utils: validateContent", () => {
|
|
|
92
92
|
]);
|
|
93
93
|
});
|
|
94
94
|
it("should return empty array on hidden required field", () => {
|
|
95
|
-
const content = { depend: "no" };
|
|
95
|
+
const content = { depend: { value: "no" } };
|
|
96
96
|
const result = validateContent(templateCondVisibility)(content);
|
|
97
97
|
expect(result).toEqual([]);
|
|
98
98
|
});
|
|
99
99
|
it("should return error on conditionaly shown required field", () => {
|
|
100
|
-
const content = { depend: "yes" };
|
|
100
|
+
const content = { depend: { value: "yes" } };
|
|
101
101
|
const result = validateContent(templateCondVisibility)(content);
|
|
102
102
|
expect(result).toEqual([
|
|
103
103
|
{
|
|
@@ -107,7 +107,7 @@ describe("utils: validateContent", () => {
|
|
|
107
107
|
]);
|
|
108
108
|
});
|
|
109
109
|
it("should return error on multiple conditionaly shown required field", () => {
|
|
110
|
-
const content = { depend: "maybe" };
|
|
110
|
+
const content = { depend: { value: "maybe" } };
|
|
111
111
|
const result = validateContent(templateMultCondVisibility)(content);
|
|
112
112
|
expect(result).toEqual([
|
|
113
113
|
{
|
|
@@ -17,33 +17,82 @@ const isInformed = _.flow(
|
|
|
17
17
|
(value) => !value
|
|
18
18
|
);
|
|
19
19
|
|
|
20
|
+
const applyTableFields = (templateContent, content, domainId) => {
|
|
21
|
+
const tableFields = _.filter((field) => field.type === "dynamic_table")(templateContent);
|
|
22
|
+
return _.reduce((content, field) => {
|
|
23
|
+
const fieldName = field.name;
|
|
24
|
+
const contentValues = _.pathOr([], `${fieldName}.value`)(content)
|
|
25
|
+
|
|
26
|
+
if (!_.isEmpty(contentValues)) {
|
|
27
|
+
const tableColumns = field.values.table_columns;
|
|
28
|
+
const updatedContentValues = _.map((contentValue) => _.flow(
|
|
29
|
+
filterFields(tableColumns),
|
|
30
|
+
filterValues(tableColumns),
|
|
31
|
+
filterDepends(tableColumns),
|
|
32
|
+
filterSwitches(tableColumns),
|
|
33
|
+
(content) => filterDomains(tableColumns)(content, domainId),
|
|
34
|
+
(content) => applyDefaults(tableColumns)(content, domainId),
|
|
35
|
+
)(contentValue))(contentValues);
|
|
36
|
+
|
|
37
|
+
return _.set(`${fieldName}.value`, updatedContentValues)(content);
|
|
38
|
+
} else {
|
|
39
|
+
return content
|
|
40
|
+
}
|
|
41
|
+
}, content)(tableFields)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const applyTableFieldsWithoutDefaults = (templateContent, content, domainId) => {
|
|
45
|
+
const tableFields = _.filter((field) => field.type === "dynamic_table")(templateContent);
|
|
46
|
+
return _.reduce((content, field) => {
|
|
47
|
+
const fieldName = field.name;
|
|
48
|
+
const contentValues = _.pathOr([], `${fieldName}.value`)(content)
|
|
49
|
+
|
|
50
|
+
if (!_.isEmpty(contentValues)) {
|
|
51
|
+
const tableColumns = field.values.table_columns;
|
|
52
|
+
const updatedContentValues = _.map((contentValue) => _.flow(
|
|
53
|
+
filterFields(tableColumns),
|
|
54
|
+
filterValues(tableColumns),
|
|
55
|
+
filterDepends(tableColumns),
|
|
56
|
+
filterSwitches(tableColumns),
|
|
57
|
+
(content) => filterDomains(tableColumns)(content, domainId),
|
|
58
|
+
(content) => applyDefaults(tableColumns)(content, domainId),
|
|
59
|
+
)(contentValue))(contentValues);
|
|
60
|
+
|
|
61
|
+
return _.set(`${fieldName}.value`, updatedContentValues)(content);
|
|
62
|
+
} else {
|
|
63
|
+
return content
|
|
64
|
+
}
|
|
65
|
+
}, content)(tableFields)
|
|
66
|
+
}
|
|
20
67
|
export const applyTemplate =
|
|
21
68
|
(template) =>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
69
|
+
(content, domainId = null) => {
|
|
70
|
+
const templateContent = flattenFields(template);
|
|
71
|
+
return _.flow(
|
|
72
|
+
filterFields(templateContent),
|
|
73
|
+
filterValues(templateContent),
|
|
74
|
+
filterDepends(templateContent),
|
|
75
|
+
filterSwitches(templateContent),
|
|
76
|
+
(content) => filterDomains(templateContent)(content, domainId),
|
|
77
|
+
(content) => applyDefaults(templateContent)(content, domainId),
|
|
78
|
+
_.pickBy((value) => isInformed(value.value)),
|
|
79
|
+
(content) => applyTableFields(templateContent, content, domainId)
|
|
80
|
+
)(content);
|
|
81
|
+
};
|
|
34
82
|
|
|
35
83
|
export const applyTemplateWithoutDefaults =
|
|
36
84
|
(template) =>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
85
|
+
(content, domainId = null) => {
|
|
86
|
+
const templateContent = flattenFields(template);
|
|
87
|
+
return _.flow(
|
|
88
|
+
filterFields(templateContent),
|
|
89
|
+
filterValues(templateContent),
|
|
90
|
+
filterDepends(templateContent),
|
|
91
|
+
filterSwitches(templateContent),
|
|
92
|
+
(content) => filterDomains(templateContent)(content, domainId),
|
|
93
|
+
_.pickBy((value) => isInformed(value.value)),
|
|
94
|
+
(content) => applyTableFieldsWithoutDefaults(templateContent, content, domainId)
|
|
95
|
+
)(content);
|
|
96
|
+
};
|
|
48
97
|
|
|
49
98
|
export default applyTemplate;
|
|
@@ -34,9 +34,9 @@ export const filterValues = (templateContent) => {
|
|
|
34
34
|
_.has(key)(vv)
|
|
35
35
|
? _.isArray(value.value)
|
|
36
36
|
? _.set(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
"value",
|
|
38
|
+
_.filter((v) => _.includes(v)(_.prop(key)(vv)))(value.value)
|
|
39
|
+
)(value)
|
|
40
40
|
: _.includes(value.value)(_.prop(key)(vv))
|
|
41
41
|
? value
|
|
42
42
|
: { ...value, value: null }
|
|
@@ -7,66 +7,81 @@ const makeOptions = (formatMessage, label) =>
|
|
|
7
7
|
text: formatMessage({ id: `fields.${label}.${v}`, defaultMessage: v }),
|
|
8
8
|
}));
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const value = _.prop(field?.name)(content);
|
|
13
|
-
if (!field?.values) return { ...field, value };
|
|
10
|
+
const doParseFieldOptions = (formatMessage, content, selectedDomain, field) => {
|
|
11
|
+
const value = _.prop(field?.name)(content);
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
13
|
+
if (!field?.values) return { ...field, value };
|
|
14
|
+
if (field?.type == "dynamic_table" && _.has("values.table_columns")(field)) {
|
|
15
|
+
const tableColumns = _.flow(
|
|
16
|
+
_.propOr([], "values.table_columns"),
|
|
17
|
+
_.map((field) =>
|
|
18
|
+
doParseFieldOptions(formatMessage, content, selectedDomain, field),
|
|
19
|
+
),
|
|
20
|
+
)(field);
|
|
21
|
+
return {
|
|
22
|
+
...field,
|
|
23
|
+
value,
|
|
24
|
+
values: { ...field?.values, table_columns: tableColumns },
|
|
25
25
|
};
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
}
|
|
27
|
+
const translateValues = _.flow(
|
|
28
|
+
makeOptions(formatMessage, field?.label),
|
|
29
|
+
_.sortBy(accentInsensitivePathOrder("text")),
|
|
30
|
+
);
|
|
31
|
+
const parseSwitch = (values) => {
|
|
32
|
+
const switchOn = _.prop("switch.on")(values);
|
|
33
|
+
const switchedValues = _.prop(`switch.values.${content[switchOn].value}`)(
|
|
34
|
+
values,
|
|
34
35
|
);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
_.
|
|
57
|
-
|
|
36
|
+
return translateValues(switchedValues);
|
|
37
|
+
};
|
|
38
|
+
const parseFixed = _.flow(_.get("fixed"), translateValues);
|
|
39
|
+
const parseRoleUsers = _.flow(
|
|
40
|
+
_.get("processed_users"),
|
|
41
|
+
_.cond([
|
|
42
|
+
[_.isArray, _.identity],
|
|
43
|
+
[_.stubTrue, _.constant([])],
|
|
44
|
+
]),
|
|
45
|
+
translateValues,
|
|
46
|
+
);
|
|
47
|
+
const parseRoleGroups = (values) =>
|
|
48
|
+
_.concat(
|
|
49
|
+
_.flow(
|
|
50
|
+
_.get("processed_users"),
|
|
51
|
+
_.map((name) => ({
|
|
52
|
+
value: `user:${name}`,
|
|
53
|
+
text: name,
|
|
54
|
+
icon: "user",
|
|
55
|
+
})),
|
|
56
|
+
)(values),
|
|
57
|
+
_.flow(
|
|
58
|
+
_.get("processed_groups"),
|
|
59
|
+
_.map((name) => ({
|
|
60
|
+
value: `group:${name}`,
|
|
61
|
+
text: name,
|
|
62
|
+
icon: "group",
|
|
63
|
+
})),
|
|
64
|
+
)(values),
|
|
58
65
|
);
|
|
66
|
+
const parseDomain = _.flow(
|
|
67
|
+
_.get("domain"),
|
|
68
|
+
_.propOr([], _.toString(selectedDomain?.id)),
|
|
69
|
+
translateValues,
|
|
70
|
+
);
|
|
59
71
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
const parsedValues = _.flow(
|
|
73
|
+
_.get("values"),
|
|
74
|
+
_.cond([
|
|
75
|
+
[_.has("switch"), parseSwitch],
|
|
76
|
+
[_.has("fixed"), parseFixed],
|
|
77
|
+
[_.has("fixed_tuple"), _.get("fixed_tuple")],
|
|
78
|
+
[_.has("role_users"), parseRoleUsers],
|
|
79
|
+
[_.has("role_groups"), parseRoleGroups],
|
|
80
|
+
[_.has("domain"), parseDomain],
|
|
81
|
+
]),
|
|
82
|
+
)(field);
|
|
83
|
+
return { ...field, value, parsedValues };
|
|
84
|
+
};
|
|
85
|
+
export const parseFieldOptions =
|
|
86
|
+
(formatMessage) => (content, selectedDomain) => (field) =>
|
|
87
|
+
doParseFieldOptions(formatMessage, content, selectedDomain, field);
|
|
@@ -31,61 +31,60 @@ export const parseGroups =
|
|
|
31
31
|
(hasDependentKeys(field) && checkDependency(field, content))) &&
|
|
32
32
|
(!(field.values && "switch" in field.values) ||
|
|
33
33
|
_.prop(`${_.prop("values.switch.on")(field)}.value`)(content) in
|
|
34
|
-
|
|
34
|
+
_.prop("values.switch.values")(field)),
|
|
35
35
|
),
|
|
36
36
|
_.map(parseFieldOptions(formatMessage)(content, selectedDomain)),
|
|
37
37
|
_.map(enrichRequired(content)),
|
|
38
|
-
_.map(enrichIsSecret(_.get("is_secret")(group)))
|
|
38
|
+
_.map(enrichIsSecret(_.get("is_secret")(group))),
|
|
39
39
|
)(group);
|
|
40
40
|
return { ...group, fields };
|
|
41
41
|
}),
|
|
42
|
-
_.filter(({ fields }) => _.negate(_.isEmpty)(fields))
|
|
42
|
+
_.filter(({ fields }) => _.negate(_.isEmpty)(fields)),
|
|
43
43
|
)(template);
|
|
44
44
|
|
|
45
45
|
export const parseGroupsWithLangs =
|
|
46
46
|
(formatMessage) =>
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
};
|
|
47
|
+
(template, i18nContent, fieldsToOmit, selectedDomain, requiredLangs = []) => {
|
|
48
|
+
return _.flow(
|
|
49
|
+
_.getOr([], "content"),
|
|
50
|
+
_.map((group) => {
|
|
51
|
+
const langs = _.flow(
|
|
52
|
+
_.toPairs,
|
|
53
|
+
_.map(([lang, langContent]) => {
|
|
54
|
+
const fields = _.flow(
|
|
55
|
+
_.get("fields"),
|
|
56
|
+
_.reject((field) => _.includes(fieldsToOmit)(field?.name)),
|
|
57
|
+
_.filter((field) => {
|
|
58
|
+
return (
|
|
59
|
+
(!("depends" in field) ||
|
|
60
|
+
(hasDependentKeys(field) &&
|
|
61
|
+
checkDependency(field, langContent))) &&
|
|
62
|
+
(!(field.values && "switch" in field.values) ||
|
|
63
|
+
_.prop(`${_.prop("values.switch.on")(field)}.value`)(
|
|
64
|
+
langContent,
|
|
65
|
+
) in _.prop("values.switch.values")(field))
|
|
66
|
+
);
|
|
67
|
+
}),
|
|
68
|
+
_.map(
|
|
69
|
+
_.flow(
|
|
70
|
+
parseFieldOptions(formatMessage)(langContent, selectedDomain),
|
|
71
|
+
(field) => requiredLangs.includes(lang)
|
|
72
|
+
? enrichRequired(langContent)(field)
|
|
73
|
+
: { ...field, required: false }
|
|
74
|
+
,
|
|
75
|
+
enrichIsSecret(_.get("is_secret")(group)),
|
|
76
|
+
),
|
|
77
|
+
),
|
|
78
|
+
)(group);
|
|
79
|
+
return [lang, fields];
|
|
80
|
+
}),
|
|
81
|
+
_.fromPairs,
|
|
82
|
+
)(i18nContent);
|
|
83
|
+
return {
|
|
84
|
+
name: group.name,
|
|
85
|
+
langs,
|
|
86
|
+
};
|
|
87
|
+
}),
|
|
88
|
+
_.filter(({ langs }) => _.some((fields) => !_.isEmpty(fields))(langs)),
|
|
89
|
+
)(template);
|
|
90
|
+
};
|
|
@@ -3,42 +3,75 @@ import { flattenFields } from "./flattenFields";
|
|
|
3
3
|
|
|
4
4
|
const fieldIsHiddenVerifier =
|
|
5
5
|
(content) =>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
({ depends }) => {
|
|
7
|
+
if (!depends) return false;
|
|
8
|
+
const { on, to_be } = depends;
|
|
9
|
+
const dependentValue = content[on]?.value;
|
|
10
|
+
return _.isArray(dependentValue)
|
|
11
|
+
? !_.some((d) => to_be.includes(d))(dependentValue)
|
|
12
|
+
: !to_be.includes(dependentValue);
|
|
13
|
+
};
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
const isTableRequired = (field, content) => {
|
|
16
|
+
if (field?.type === "dynamic_table" && _.has("values.table_columns")(field)) {
|
|
17
|
+
const rowValues = _.pathOr([], `${field?.name}.value`)(content);
|
|
18
|
+
|
|
19
|
+
if (_.isEmpty(rowValues)) return false;
|
|
20
|
+
|
|
21
|
+
return _.flow(
|
|
22
|
+
_.pathOr([], "values.table_columns"),
|
|
23
|
+
_.any((nestedField) => _.includes(nestedField?.cardinality)(["1", "+"])))
|
|
24
|
+
(field);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const validateTemplateContent = (schema, content) => {
|
|
16
31
|
const fieldIsHidden = fieldIsHiddenVerifier(content);
|
|
17
|
-
const templateContent = _.
|
|
18
|
-
flattenFields,
|
|
19
|
-
_.reject(fieldIsHidden)
|
|
20
|
-
)(template);
|
|
32
|
+
const templateContent = _.reject(fieldIsHidden)(schema);
|
|
21
33
|
return _.flow(validateRequired(templateContent), _.head)([[], content]);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const validateContent = (template) => (content) => {
|
|
37
|
+
const schema = flattenFields(template);
|
|
38
|
+
return validateTemplateContent(schema, content);
|
|
22
39
|
};
|
|
23
40
|
|
|
24
|
-
const isEmptyValue = (value) => !_.isNumber(value) && _.isEmpty(value);
|
|
41
|
+
const isEmptyValue = (value) => _.isNil(value) || (!_.isNumber(value) && _.isEmpty(value));
|
|
42
|
+
|
|
43
|
+
const isEmptyField = (field, content) => {
|
|
44
|
+
if (field?.type === "dynamic_table" && _.has("values.table_columns")(field)) {
|
|
45
|
+
const tableColumns = _.pathOr([], "values.table_columns")(field);
|
|
46
|
+
const rowValues = _.pathOr([], `${field?.name}.value`)(content);
|
|
47
|
+
|
|
48
|
+
if (_.isEmpty(rowValues)) return true;
|
|
49
|
+
|
|
50
|
+
const requiredErrors = _.flow(
|
|
51
|
+
_.map((row) => _.flow(validateRequired(tableColumns), _.head)([[], row])),
|
|
52
|
+
_.flatten,
|
|
53
|
+
)(rowValues);
|
|
54
|
+
|
|
55
|
+
return !_.isEmpty(requiredErrors);
|
|
56
|
+
}
|
|
57
|
+
return isEmptyValue(content?.[field?.name]?.value);
|
|
58
|
+
}
|
|
25
59
|
|
|
26
60
|
export const validateRequired =
|
|
27
61
|
(templateContent) =>
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
};
|
|
62
|
+
([validations, content]) => {
|
|
63
|
+
const newValidations = _.flow([
|
|
64
|
+
_.filter((field) => isRequired(field, content)),
|
|
65
|
+
_.filter((field) => isEmptyField(field, content)),
|
|
66
|
+
_.map((field) => ({ error: "missing required", field: field?.name })),
|
|
67
|
+
])(templateContent);
|
|
68
|
+
return [[...validations, ...newValidations], content];
|
|
69
|
+
};
|
|
37
70
|
|
|
38
71
|
export const dependentRequired = (field, content) => {
|
|
39
72
|
if (_.has("mandatory")(field)) {
|
|
40
73
|
const on = field?.mandatory?.on;
|
|
41
|
-
const dependent = content[on];
|
|
74
|
+
const dependent = content[on]?.value;
|
|
42
75
|
const target = field?.mandatory?.to_be || [];
|
|
43
76
|
if (_.isArray(dependent)) {
|
|
44
77
|
return !_.isEmpty(_.intersection(dependent)(target));
|
|
@@ -50,11 +83,23 @@ export const dependentRequired = (field, content) => {
|
|
|
50
83
|
};
|
|
51
84
|
|
|
52
85
|
export const isRequired = (field, content) =>
|
|
53
|
-
_.includes(field?.cardinality)(["1", "+"]) ||
|
|
86
|
+
_.includes(field?.cardinality)(["1", "+"]) || isTableRequired(field, content) ||
|
|
54
87
|
dependentRequired(field, content);
|
|
55
88
|
|
|
56
89
|
export const enrichRequired = (content) => (field) => {
|
|
57
90
|
const required = isRequired(field, content);
|
|
91
|
+
if (field?.type === "dynamic_table" && _.has("values.table_columns")(field)) {
|
|
92
|
+
const tableColumns = _.flow(
|
|
93
|
+
_.propOr([], "values.table_columns"),
|
|
94
|
+
_.map((field) => enrichRequired({})(field)))
|
|
95
|
+
(field);
|
|
96
|
+
|
|
97
|
+
return _.flow(
|
|
98
|
+
_.set("values.table_columns", tableColumns),
|
|
99
|
+
_.set("required", required))
|
|
100
|
+
(field);
|
|
101
|
+
}
|
|
102
|
+
|
|
58
103
|
return { ...field, required };
|
|
59
104
|
};
|
|
60
105
|
|