@truedat/df 7.4.4 → 7.5.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 +5 -5
- package/src/messages/en.js +4 -0
- package/src/messages/es.js +5 -1
- package/src/styles/template.less +12 -0
- package/src/templates/components/__tests__/Template.spec.js +25 -9
- package/src/templates/components/__tests__/__snapshots__/Template.spec.js.snap +364 -5
- package/src/templates/components/templateForm/ActiveGroupForm.js +16 -2
- package/src/templates/components/templateForm/ConditionalFieldForm.js +28 -4
- package/src/templates/components/templateForm/DependentDomain.js +27 -1
- package/src/templates/components/templateForm/DependentFormField.js +1 -1
- package/src/templates/components/templateForm/FieldForm.js +33 -5
- package/src/templates/components/templateForm/HierarchiesList.js +0 -1
- package/src/templates/components/templateForm/MandatoryConditional.js +28 -5
- package/src/templates/components/templateForm/SwitchListForm.js +48 -2
- package/src/templates/components/templateForm/TemplateForm.js +58 -11
- package/src/templates/components/templateForm/TemplateFormActions.js +3 -2
- package/src/templates/components/templateForm/ValuesListForm.js +72 -1
- package/src/templates/components/templateForm/ValuesSelector.js +46 -7
- package/src/templates/components/templateForm/__tests__/DependentDomain.spec.js +2 -0
- package/src/templates/components/templateForm/__tests__/SwitchSegment.spec.js +1 -0
- package/src/templates/components/templateForm/__tests__/TemplateForm.spec.js +46 -2
- package/src/templates/components/templateForm/__tests__/TemplateFormActions.spec.js +7 -0
- package/src/templates/components/templateForm/__tests__/__snapshots__/ActiveGroupForm.spec.js.snap +6 -1
- package/src/templates/components/templateForm/__tests__/__snapshots__/DependentDomain.spec.js.snap +3 -0
- package/src/templates/components/templateForm/__tests__/__snapshots__/FieldForm.spec.js.snap +33 -7
- package/src/templates/components/templateForm/__tests__/__snapshots__/MandatoryConditional.spec.js.snap +3 -1
- package/src/templates/components/templateForm/__tests__/__snapshots__/SwitchListForm.spec.js.snap +10 -0
- package/src/templates/components/templateForm/__tests__/__snapshots__/TemplateForm.spec.js.snap +1250 -4
- package/src/templates/components/templateForm/__tests__/__snapshots__/TemplateFormActions.spec.js.snap +28 -0
- package/src/templates/components/templateForm/__tests__/__snapshots__/ValuesListForm.spec.js.snap +4 -0
- package/src/templates/components/templateForm/contentValidation.js +100 -15
|
@@ -2,7 +2,7 @@ import _ from "lodash/fp";
|
|
|
2
2
|
import React, { useEffect } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import { FormattedMessage, useIntl } from "react-intl";
|
|
5
|
-
import { Form, Button, Divider,
|
|
5
|
+
import { Form, Button, Divider, Label, Segment } from "semantic-ui-react";
|
|
6
6
|
import ValuesField from "./ValuesField";
|
|
7
7
|
import ConditionalFieldForm from "./ConditionalFieldForm";
|
|
8
8
|
import MandatoryConditional from "./MandatoryConditional";
|
|
@@ -130,6 +130,12 @@ export const FieldForm = ({
|
|
|
130
130
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
131
131
|
}, [widget, type]);
|
|
132
132
|
|
|
133
|
+
const isNullOrEmpty = (value) =>
|
|
134
|
+
!_.isNumber(value) && (!value || _.isEmpty(value));
|
|
135
|
+
|
|
136
|
+
const labelValue = label || "";
|
|
137
|
+
const nameValue = name || "";
|
|
138
|
+
|
|
133
139
|
return (
|
|
134
140
|
<Segment>
|
|
135
141
|
<Button.Group
|
|
@@ -163,8 +169,19 @@ export const FieldForm = ({
|
|
|
163
169
|
<Form.Input
|
|
164
170
|
name={`${fieldNamePrefix}.label`}
|
|
165
171
|
size="small"
|
|
166
|
-
label={
|
|
167
|
-
|
|
172
|
+
label={
|
|
173
|
+
<label>
|
|
174
|
+
{formatMessage({
|
|
175
|
+
id: "template.field.label",
|
|
176
|
+
})}
|
|
177
|
+
{isNullOrEmpty(labelValue) ? (
|
|
178
|
+
<Label pointing="left">
|
|
179
|
+
<FormattedMessage id="template.form.validation.empty_required" />
|
|
180
|
+
</Label>
|
|
181
|
+
) : null}
|
|
182
|
+
</label>
|
|
183
|
+
}
|
|
184
|
+
value={labelValue}
|
|
168
185
|
required
|
|
169
186
|
onChange={onChange}
|
|
170
187
|
/>
|
|
@@ -172,8 +189,19 @@ export const FieldForm = ({
|
|
|
172
189
|
name={`${fieldNamePrefix}.name`}
|
|
173
190
|
size="small"
|
|
174
191
|
fluid
|
|
175
|
-
label={
|
|
176
|
-
|
|
192
|
+
label={
|
|
193
|
+
<label>
|
|
194
|
+
{formatMessage({
|
|
195
|
+
id: "template.field.name",
|
|
196
|
+
})}
|
|
197
|
+
{isNullOrEmpty(nameValue) ? (
|
|
198
|
+
<Label pointing="left">
|
|
199
|
+
<FormattedMessage id="template.form.validation.empty_required" />
|
|
200
|
+
</Label>
|
|
201
|
+
) : null}
|
|
202
|
+
</label>
|
|
203
|
+
}
|
|
204
|
+
value={nameValue}
|
|
177
205
|
required
|
|
178
206
|
onChange={onChange}
|
|
179
207
|
disabled={disabledName || hasDependencies}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
|
-
import { useIntl } from "react-intl";
|
|
4
|
+
import { FormattedMessage, useIntl } from "react-intl";
|
|
5
|
+
import { Label } from "semantic-ui-react";
|
|
5
6
|
import DependentFormField from "./DependentFormField";
|
|
6
7
|
|
|
7
8
|
export const MandatoryConditional = ({
|
|
@@ -30,18 +31,40 @@ export const MandatoryConditional = ({
|
|
|
30
31
|
|
|
31
32
|
onChange(e, { name, value });
|
|
32
33
|
};
|
|
33
|
-
|
|
34
|
+
const fieldValue = field?.mandatory?.on;
|
|
35
|
+
const value = field?.mandatory?.to_be;
|
|
36
|
+
const isNullOrEmpty = (value) =>
|
|
37
|
+
!_.isNumber(value) && (!value || _.isEmpty(value));
|
|
34
38
|
return (
|
|
35
39
|
<DependentFormField
|
|
36
|
-
label={
|
|
40
|
+
label={
|
|
41
|
+
<label>
|
|
42
|
+
{formatMessage({ id: "template.field.mandatory.depends" })}
|
|
43
|
+
{!isNullOrEmpty(fieldValue) && isNullOrEmpty(value) ? (
|
|
44
|
+
<>
|
|
45
|
+
<span
|
|
46
|
+
style={{
|
|
47
|
+
color: "#D95C5C",
|
|
48
|
+
marginLeft: "3px",
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
*
|
|
52
|
+
</span>
|
|
53
|
+
<Label pointing="left">
|
|
54
|
+
<FormattedMessage id="template.form.validation.empty_required" />
|
|
55
|
+
</Label>
|
|
56
|
+
</>
|
|
57
|
+
) : null}
|
|
58
|
+
</label>
|
|
59
|
+
}
|
|
37
60
|
fieldName={`${fieldNamePrefix}.mandatory.on`}
|
|
38
61
|
fieldOptions={fieldOptions}
|
|
39
62
|
fieldPlaceholder={formatMessage({
|
|
40
63
|
id: "template.field.mandatory.depends.on",
|
|
41
64
|
})}
|
|
42
|
-
fieldValue={
|
|
65
|
+
fieldValue={fieldValue}
|
|
43
66
|
onChange={handleChange}
|
|
44
|
-
value={
|
|
67
|
+
value={value}
|
|
45
68
|
valueName={`${fieldNamePrefix}.mandatory.to_be`}
|
|
46
69
|
valueOptions={valueOptions}
|
|
47
70
|
valuePlaceholder={formatMessage({
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
|
-
import { injectIntl } from "react-intl";
|
|
5
|
-
import { Form, Icon, List } from "semantic-ui-react";
|
|
4
|
+
import { FormattedMessage, injectIntl } from "react-intl";
|
|
5
|
+
import { Form, Icon, List, Label } from "semantic-ui-react";
|
|
6
6
|
import SwitchSegment from "./SwitchSegment";
|
|
7
7
|
|
|
8
8
|
const initialState = {
|
|
@@ -56,11 +56,35 @@ export class SwitchListForm extends React.Component {
|
|
|
56
56
|
onChange,
|
|
57
57
|
} = this.props;
|
|
58
58
|
const { error } = this.state;
|
|
59
|
+
const isNullOrEmpty = (value) =>
|
|
60
|
+
!_.isNumber(value) && (!value || _.isEmpty(value));
|
|
59
61
|
return (
|
|
60
62
|
<List verticalAlign="middle">
|
|
61
63
|
<List.Item>
|
|
62
64
|
<Form.Input
|
|
63
65
|
value={on}
|
|
66
|
+
label={
|
|
67
|
+
<label>
|
|
68
|
+
{formatMessage({
|
|
69
|
+
id: "template.field.values.switch_field.label",
|
|
70
|
+
})}
|
|
71
|
+
{isNullOrEmpty(on) ? (
|
|
72
|
+
<>
|
|
73
|
+
<span
|
|
74
|
+
style={{
|
|
75
|
+
color: "#D95C5C",
|
|
76
|
+
marginLeft: "3px",
|
|
77
|
+
}}
|
|
78
|
+
>
|
|
79
|
+
*
|
|
80
|
+
</span>
|
|
81
|
+
<Label pointing="left">
|
|
82
|
+
<FormattedMessage id="template.form.validation.empty_required" />
|
|
83
|
+
</Label>
|
|
84
|
+
</>
|
|
85
|
+
) : null}
|
|
86
|
+
</label>
|
|
87
|
+
}
|
|
64
88
|
placeholder={formatMessage({
|
|
65
89
|
id: "template.field.values.switch_field",
|
|
66
90
|
})}
|
|
@@ -88,6 +112,28 @@ export class SwitchListForm extends React.Component {
|
|
|
88
112
|
<Form.Input
|
|
89
113
|
error={error}
|
|
90
114
|
value={this.state.value}
|
|
115
|
+
label={
|
|
116
|
+
<label>
|
|
117
|
+
{formatMessage({
|
|
118
|
+
id: "template.field.values.add_switch_value.label",
|
|
119
|
+
})}
|
|
120
|
+
{isNullOrEmpty(values) ? (
|
|
121
|
+
<>
|
|
122
|
+
<span
|
|
123
|
+
style={{
|
|
124
|
+
color: "#D95C5C",
|
|
125
|
+
marginLeft: "3px",
|
|
126
|
+
}}
|
|
127
|
+
>
|
|
128
|
+
*
|
|
129
|
+
</span>
|
|
130
|
+
<Label pointing="left">
|
|
131
|
+
<FormattedMessage id="template.form.validation.empty_required" />
|
|
132
|
+
</Label>
|
|
133
|
+
</>
|
|
134
|
+
) : null}
|
|
135
|
+
</label>
|
|
136
|
+
}
|
|
91
137
|
icon={<Icon name="add circle" />}
|
|
92
138
|
placeholder={formatMessage({
|
|
93
139
|
id: "template.field.values.add_switch_value",
|
|
@@ -2,7 +2,7 @@ import _ from "lodash/fp";
|
|
|
2
2
|
import React, { useState, useEffect } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import { connect } from "react-redux";
|
|
5
|
-
import { Header, Form, Grid, Divider } from "semantic-ui-react";
|
|
5
|
+
import { Header, Form, Grid, Label, Divider } from "semantic-ui-react";
|
|
6
6
|
import { useIntl, FormattedMessage } from "react-intl";
|
|
7
7
|
import GroupsList from "./GroupsList";
|
|
8
8
|
import ActiveGroupForm from "./ActiveGroupForm";
|
|
@@ -34,7 +34,7 @@ export const TemplateForm = ({ loading, template, onSubmit }) => {
|
|
|
34
34
|
const [activeGroup, setActiveGroup] = useState(0);
|
|
35
35
|
const [editedTemplate, setEditedTemplate] = useState({
|
|
36
36
|
...template,
|
|
37
|
-
content: template
|
|
37
|
+
content: template?.content || [],
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
useEffect(() => {
|
|
@@ -98,8 +98,25 @@ export const TemplateForm = ({ loading, template, onSubmit }) => {
|
|
|
98
98
|
|
|
99
99
|
const validatedContent = parseContentValidation(editedTemplate.content);
|
|
100
100
|
|
|
101
|
+
const hasContentErrors =
|
|
102
|
+
_.isEmpty(validatedContent) ||
|
|
103
|
+
_.some((group) => group?.errors?.hasErrors)(validatedContent);
|
|
104
|
+
|
|
105
|
+
const isNullOrEmpty = (value) =>
|
|
106
|
+
!_.isNumber(value) && (!value || _.isEmpty(value));
|
|
107
|
+
|
|
108
|
+
const isNameEmpty = isNullOrEmpty(editedTemplate.name);
|
|
109
|
+
const isLabelEmpty = isNullOrEmpty(editedTemplate.label);
|
|
110
|
+
const isScopeEmpty = isNullOrEmpty(editedTemplate.scope);
|
|
111
|
+
const isInvalidTemplate =
|
|
112
|
+
isNameEmpty || isLabelEmpty || isScopeEmpty || hasContentErrors;
|
|
113
|
+
|
|
114
|
+
const nameValue = editedTemplate.name || "";
|
|
115
|
+
const labelValue = editedTemplate.label || "";
|
|
116
|
+
const scopeValue = editedTemplate.scope || "";
|
|
117
|
+
const subscopeValue = editedTemplate.subscope || "";
|
|
101
118
|
return (
|
|
102
|
-
<Form loading={loading}>
|
|
119
|
+
<Form loading={loading} className="template-form">
|
|
103
120
|
<Divider horizontal>
|
|
104
121
|
<Header as="h4">
|
|
105
122
|
<FormattedMessage id="template.form.header" />
|
|
@@ -109,8 +126,17 @@ export const TemplateForm = ({ loading, template, onSubmit }) => {
|
|
|
109
126
|
<Form.Input
|
|
110
127
|
name="name"
|
|
111
128
|
width={6}
|
|
112
|
-
label={
|
|
113
|
-
|
|
129
|
+
label={
|
|
130
|
+
<label>
|
|
131
|
+
{formatMessage({ id: "template.form.name" })}
|
|
132
|
+
{isNullOrEmpty(nameValue) ? (
|
|
133
|
+
<Label pointing="left">
|
|
134
|
+
<FormattedMessage id="template.form.validation.empty_required" />
|
|
135
|
+
</Label>
|
|
136
|
+
) : null}
|
|
137
|
+
</label>
|
|
138
|
+
}
|
|
139
|
+
value={nameValue}
|
|
114
140
|
required
|
|
115
141
|
onChange={handleChange}
|
|
116
142
|
readOnly={!_.isEmpty(template)}
|
|
@@ -118,8 +144,17 @@ export const TemplateForm = ({ loading, template, onSubmit }) => {
|
|
|
118
144
|
<Form.Input
|
|
119
145
|
name="label"
|
|
120
146
|
width={6}
|
|
121
|
-
label={
|
|
122
|
-
|
|
147
|
+
label={
|
|
148
|
+
<label>
|
|
149
|
+
{formatMessage({ id: "template.form.label" })}
|
|
150
|
+
{isNullOrEmpty(labelValue) ? (
|
|
151
|
+
<Label pointing="left">
|
|
152
|
+
<FormattedMessage id="template.form.validation.empty_required" />
|
|
153
|
+
</Label>
|
|
154
|
+
) : null}
|
|
155
|
+
</label>
|
|
156
|
+
}
|
|
157
|
+
value={labelValue}
|
|
123
158
|
required
|
|
124
159
|
onChange={handleChange}
|
|
125
160
|
/>
|
|
@@ -128,8 +163,17 @@ export const TemplateForm = ({ loading, template, onSubmit }) => {
|
|
|
128
163
|
clearable
|
|
129
164
|
placeholder={formatMessage({ id: "template.form.scope.placeholder" })}
|
|
130
165
|
width={4}
|
|
131
|
-
label={
|
|
132
|
-
|
|
166
|
+
label={
|
|
167
|
+
<label>
|
|
168
|
+
{formatMessage({ id: "template.form.scope" })}
|
|
169
|
+
{isNullOrEmpty(scopeValue) ? (
|
|
170
|
+
<Label pointing="left">
|
|
171
|
+
<FormattedMessage id="template.form.validation.empty_required" />
|
|
172
|
+
</Label>
|
|
173
|
+
) : null}
|
|
174
|
+
</label>
|
|
175
|
+
}
|
|
176
|
+
value={scopeValue}
|
|
133
177
|
required
|
|
134
178
|
selection
|
|
135
179
|
options={scopeOptions(formatMessage)}
|
|
@@ -142,7 +186,7 @@ export const TemplateForm = ({ loading, template, onSubmit }) => {
|
|
|
142
186
|
id: "template.form.subscope.placeholder",
|
|
143
187
|
})}
|
|
144
188
|
label={formatMessage({ id: "template.form.subscope" })}
|
|
145
|
-
value={
|
|
189
|
+
value={subscopeValue}
|
|
146
190
|
onChange={handleChange}
|
|
147
191
|
disabled={editedTemplate?.scope !== "bg"}
|
|
148
192
|
/>
|
|
@@ -174,7 +218,10 @@ export const TemplateForm = ({ loading, template, onSubmit }) => {
|
|
|
174
218
|
</Grid.Column>
|
|
175
219
|
</Grid>
|
|
176
220
|
<Divider />
|
|
177
|
-
<TemplateFormActions
|
|
221
|
+
<TemplateFormActions
|
|
222
|
+
onSave={handleSubmit}
|
|
223
|
+
isInvalid={isInvalidTemplate}
|
|
224
|
+
/>
|
|
178
225
|
</Form>
|
|
179
226
|
);
|
|
180
227
|
};
|
|
@@ -10,6 +10,7 @@ export const TemplateFormActions = ({
|
|
|
10
10
|
templateSaving,
|
|
11
11
|
templateDeleting,
|
|
12
12
|
onSave,
|
|
13
|
+
isInvalid,
|
|
13
14
|
}) => {
|
|
14
15
|
const history = useHistory();
|
|
15
16
|
const onCancel = () => history.push(TEMPLATES);
|
|
@@ -20,7 +21,7 @@ export const TemplateFormActions = ({
|
|
|
20
21
|
content={<FormattedMessage id="actions.save" />}
|
|
21
22
|
onClick={onSave}
|
|
22
23
|
loading={templateSaving}
|
|
23
|
-
disabled={templateSaving || templateDeleting}
|
|
24
|
+
disabled={templateSaving || templateDeleting || isInvalid}
|
|
24
25
|
/>
|
|
25
26
|
<Button
|
|
26
27
|
content={<FormattedMessage id="actions.cancel" />}
|
|
@@ -31,9 +32,9 @@ export const TemplateFormActions = ({
|
|
|
31
32
|
};
|
|
32
33
|
|
|
33
34
|
TemplateFormActions.propTypes = {
|
|
34
|
-
template: PropTypes.object.isRequired,
|
|
35
35
|
templateDeleting: PropTypes.bool.isRequired,
|
|
36
36
|
templateSaving: PropTypes.bool.isRequired,
|
|
37
|
+
isInvalid: PropTypes.bool.isRequired,
|
|
37
38
|
onSave: PropTypes.func.isRequired,
|
|
38
39
|
};
|
|
39
40
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
|
-
import {
|
|
4
|
+
import { FormattedMessage } from "react-intl";
|
|
5
|
+
import { Form, Icon, Label, List, Popup } from "semantic-ui-react";
|
|
5
6
|
import { injectIntl } from "react-intl";
|
|
6
7
|
|
|
7
8
|
const initialState = {
|
|
@@ -121,6 +122,8 @@ export class ValuesListForm extends React.Component {
|
|
|
121
122
|
type,
|
|
122
123
|
} = this.props;
|
|
123
124
|
const { error } = this.state;
|
|
125
|
+
const isNullOrEmpty = (value) =>
|
|
126
|
+
!_.isNumber(value) && (!value || _.isEmpty(value));
|
|
124
127
|
return (
|
|
125
128
|
<List verticalAlign="middle">
|
|
126
129
|
{values.map((value, key) => (
|
|
@@ -172,6 +175,23 @@ export class ValuesListForm extends React.Component {
|
|
|
172
175
|
<Form.Input
|
|
173
176
|
error={error}
|
|
174
177
|
name="tuple_value"
|
|
178
|
+
label={
|
|
179
|
+
isNullOrEmpty(values) ? (
|
|
180
|
+
<label>
|
|
181
|
+
<Label pointing="below">
|
|
182
|
+
<FormattedMessage id="template.form.validation.empty_required" />
|
|
183
|
+
</Label>
|
|
184
|
+
<span
|
|
185
|
+
style={{
|
|
186
|
+
color: "#D95C5C",
|
|
187
|
+
marginLeft: "3px",
|
|
188
|
+
}}
|
|
189
|
+
>
|
|
190
|
+
*
|
|
191
|
+
</span>
|
|
192
|
+
</label>
|
|
193
|
+
) : null
|
|
194
|
+
}
|
|
175
195
|
value={this.state.tuple_value}
|
|
176
196
|
placeholder={formatMessage({
|
|
177
197
|
id: "template.field.values.add_value",
|
|
@@ -181,6 +201,23 @@ export class ValuesListForm extends React.Component {
|
|
|
181
201
|
/>
|
|
182
202
|
<Form.Input
|
|
183
203
|
name="tuple_text"
|
|
204
|
+
label={
|
|
205
|
+
isNullOrEmpty(values) ? (
|
|
206
|
+
<label>
|
|
207
|
+
<Label pointing="below">
|
|
208
|
+
<FormattedMessage id="template.form.validation.empty_required" />
|
|
209
|
+
</Label>
|
|
210
|
+
<span
|
|
211
|
+
style={{
|
|
212
|
+
color: "#D95C5C",
|
|
213
|
+
marginLeft: "3px",
|
|
214
|
+
}}
|
|
215
|
+
>
|
|
216
|
+
*
|
|
217
|
+
</span>
|
|
218
|
+
</label>
|
|
219
|
+
) : null
|
|
220
|
+
}
|
|
184
221
|
value={this.state.tuple_text}
|
|
185
222
|
icon={
|
|
186
223
|
<Icon
|
|
@@ -200,6 +237,23 @@ export class ValuesListForm extends React.Component {
|
|
|
200
237
|
{type == "fixed" && (
|
|
201
238
|
<Form.Input
|
|
202
239
|
error={error}
|
|
240
|
+
label={
|
|
241
|
+
isNullOrEmpty(values) ? (
|
|
242
|
+
<label>
|
|
243
|
+
<Label pointing="below">
|
|
244
|
+
<FormattedMessage id="template.form.validation.empty_required" />
|
|
245
|
+
</Label>
|
|
246
|
+
<span
|
|
247
|
+
style={{
|
|
248
|
+
color: "#D95C5C",
|
|
249
|
+
marginLeft: "3px",
|
|
250
|
+
}}
|
|
251
|
+
>
|
|
252
|
+
*
|
|
253
|
+
</span>
|
|
254
|
+
</label>
|
|
255
|
+
) : null
|
|
256
|
+
}
|
|
203
257
|
name="fixed_value"
|
|
204
258
|
value={this.state.fixed_value}
|
|
205
259
|
icon={
|
|
@@ -221,6 +275,23 @@ export class ValuesListForm extends React.Component {
|
|
|
221
275
|
<Form.Input
|
|
222
276
|
error={error}
|
|
223
277
|
name="column_name"
|
|
278
|
+
label={
|
|
279
|
+
isNullOrEmpty(values) ? (
|
|
280
|
+
<>
|
|
281
|
+
<Label pointing="below">
|
|
282
|
+
<FormattedMessage id="template.form.validation.empty_required" />
|
|
283
|
+
</Label>
|
|
284
|
+
<span
|
|
285
|
+
style={{
|
|
286
|
+
color: "#D95C5C",
|
|
287
|
+
marginLeft: "3px",
|
|
288
|
+
}}
|
|
289
|
+
>
|
|
290
|
+
*
|
|
291
|
+
</span>
|
|
292
|
+
</>
|
|
293
|
+
) : null
|
|
294
|
+
}
|
|
224
295
|
icon={
|
|
225
296
|
<Icon
|
|
226
297
|
name="add circle"
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
1
2
|
import React from "react";
|
|
2
3
|
import PropTypes from "prop-types";
|
|
3
|
-
import {
|
|
4
|
+
import { FormattedMessage } from "react-intl";
|
|
5
|
+
import { Form, Label } from "semantic-ui-react";
|
|
4
6
|
import DependentDomain from "./DependentDomain";
|
|
5
7
|
import SwitchListForm from "./SwitchListForm";
|
|
6
8
|
import HierarchiesList from "./HierarchiesList";
|
|
@@ -25,6 +27,8 @@ export const ValuesSelector = ({
|
|
|
25
27
|
value,
|
|
26
28
|
});
|
|
27
29
|
};
|
|
30
|
+
const isNullOrEmpty = (value) =>
|
|
31
|
+
!_.isNumber(value) && (!value || _.isEmpty(value));
|
|
28
32
|
return (
|
|
29
33
|
<>
|
|
30
34
|
{listFormat(type) ? (
|
|
@@ -50,24 +54,59 @@ export const ValuesSelector = ({
|
|
|
50
54
|
defaultValue={defaultValue}
|
|
51
55
|
onChange={onValueChange}
|
|
52
56
|
onDefaultValueChange={onDefaultValueChange}
|
|
57
|
+
required
|
|
53
58
|
values={values || {}}
|
|
54
59
|
/>
|
|
55
60
|
) : null}
|
|
56
61
|
{type === "role_users" ? (
|
|
57
62
|
<Form.Input
|
|
58
63
|
value={values || ""}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
label={
|
|
65
|
+
<label>
|
|
66
|
+
{formatMessage({
|
|
67
|
+
id: "template.field.values.role.label",
|
|
68
|
+
})}
|
|
69
|
+
<span
|
|
70
|
+
style={{
|
|
71
|
+
color: "#D95C5C",
|
|
72
|
+
marginLeft: "3px",
|
|
73
|
+
}}
|
|
74
|
+
>
|
|
75
|
+
*
|
|
76
|
+
</span>
|
|
77
|
+
{isNullOrEmpty(values) ? (
|
|
78
|
+
<Label pointing="left">
|
|
79
|
+
<FormattedMessage id="template.form.validation.empty_required" />
|
|
80
|
+
</Label>
|
|
81
|
+
) : null}
|
|
82
|
+
</label>
|
|
83
|
+
}
|
|
62
84
|
onChange={(e, { value }) => onValueChange(value)}
|
|
63
85
|
/>
|
|
64
86
|
) : null}
|
|
65
87
|
{type === "role_groups" ? (
|
|
66
88
|
<Form.Input
|
|
67
89
|
value={values || ""}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
90
|
+
label={
|
|
91
|
+
<label>
|
|
92
|
+
{formatMessage({
|
|
93
|
+
id: "template.field.values.role.label",
|
|
94
|
+
})}
|
|
95
|
+
<span
|
|
96
|
+
style={{
|
|
97
|
+
color: "#D95C5C",
|
|
98
|
+
marginLeft: "3px",
|
|
99
|
+
}}
|
|
100
|
+
>
|
|
101
|
+
*
|
|
102
|
+
</span>
|
|
103
|
+
{isNullOrEmpty(values) ? (
|
|
104
|
+
<Label pointing="left">
|
|
105
|
+
<FormattedMessage id="template.form.validation.empty_required" />
|
|
106
|
+
</Label>
|
|
107
|
+
) : null}
|
|
108
|
+
</label>
|
|
109
|
+
}
|
|
71
110
|
onChange={(e, { value }) => onValueChange(value)}
|
|
72
111
|
/>
|
|
73
112
|
) : null}
|
|
@@ -31,9 +31,11 @@ describe("<DependentDomain />", () => {
|
|
|
31
31
|
messages: {
|
|
32
32
|
en: {
|
|
33
33
|
"template.field.values.domain_field": "domain field",
|
|
34
|
+
"template.field.values.domain_label": "domain label",
|
|
34
35
|
"template.field.values.default.omit": "omit",
|
|
35
36
|
"template.field.values.default": "default",
|
|
36
37
|
"template.field.values.add_value": "add",
|
|
38
|
+
"template.field.values.add_value.label": "List value",
|
|
37
39
|
"template.field.values.add_text": "add text",
|
|
38
40
|
"template.field.values.add_format": "add format",
|
|
39
41
|
"template.field.values.add_file_config": "file config",
|
|
@@ -29,6 +29,7 @@ describe("<SwitchSegment />", () => {
|
|
|
29
29
|
"template.field.values.default.omit": "omit",
|
|
30
30
|
"template.field.values.default": "default",
|
|
31
31
|
"template.field.values.add_value": "add",
|
|
32
|
+
"template.field.values.add_value.label": "List value",
|
|
32
33
|
"template.field.values.add_text": "add text",
|
|
33
34
|
"template.field.values.add_format": "add format",
|
|
34
35
|
"template.field.values.add_file_config": "file config",
|
|
@@ -2,6 +2,14 @@ import React from "react";
|
|
|
2
2
|
import { render } from "@truedat/test/render";
|
|
3
3
|
import TemplateForm from "../TemplateForm";
|
|
4
4
|
|
|
5
|
+
const emptyTemplate = {
|
|
6
|
+
id: null,
|
|
7
|
+
name: "",
|
|
8
|
+
label: "",
|
|
9
|
+
scope: "",
|
|
10
|
+
content: [],
|
|
11
|
+
};
|
|
12
|
+
|
|
5
13
|
const template = {
|
|
6
14
|
id: 1,
|
|
7
15
|
name: "Name",
|
|
@@ -9,11 +17,47 @@ const template = {
|
|
|
9
17
|
scope: "bg",
|
|
10
18
|
};
|
|
11
19
|
|
|
20
|
+
const templateContent = [
|
|
21
|
+
{
|
|
22
|
+
fields: [
|
|
23
|
+
{
|
|
24
|
+
ai_suggestion: false,
|
|
25
|
+
cardinality: "*",
|
|
26
|
+
default: {
|
|
27
|
+
origin: "default",
|
|
28
|
+
value: "",
|
|
29
|
+
},
|
|
30
|
+
label: "field",
|
|
31
|
+
name: "field",
|
|
32
|
+
subscribable: false,
|
|
33
|
+
type: "string",
|
|
34
|
+
values: null,
|
|
35
|
+
widget: "string",
|
|
36
|
+
disabledName: true,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
name: "group",
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
const filledTemplate = {
|
|
44
|
+
...template,
|
|
45
|
+
content: templateContent,
|
|
46
|
+
};
|
|
47
|
+
|
|
12
48
|
describe("<TemplateForm />", () => {
|
|
13
|
-
it("matches the latest snapshot", () => {
|
|
49
|
+
it("matches the latest snapshot for empty template", () => {
|
|
14
50
|
const state = { templateSaving: false, templateDeleting: false };
|
|
15
51
|
const renderOpts = { state };
|
|
16
|
-
const props = {
|
|
52
|
+
const props = { emptyTemplate, onSubmit: jest.fn() };
|
|
53
|
+
const { container } = render(<TemplateForm {...props} />, renderOpts);
|
|
54
|
+
expect(container).toMatchSnapshot();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("matches the latest snapshot for filled template", () => {
|
|
58
|
+
const state = { templateSaving: false, templateDeleting: false };
|
|
59
|
+
const renderOpts = { state };
|
|
60
|
+
const props = { template: filledTemplate, onSubmit: jest.fn() };
|
|
17
61
|
const { container } = render(<TemplateForm {...props} />, renderOpts);
|
|
18
62
|
expect(container).toMatchSnapshot();
|
|
19
63
|
});
|
|
@@ -10,11 +10,13 @@ describe("<TemplateFormActions />", () => {
|
|
|
10
10
|
};
|
|
11
11
|
const templateSaving = false;
|
|
12
12
|
const templateDeleting = false;
|
|
13
|
+
const isInvalid = false;
|
|
13
14
|
const props = {
|
|
14
15
|
template,
|
|
15
16
|
templateSaving,
|
|
16
17
|
templateDeleting,
|
|
17
18
|
onSave,
|
|
19
|
+
isInvalid,
|
|
18
20
|
};
|
|
19
21
|
|
|
20
22
|
it("matches the latest snapshot", () => {
|
|
@@ -33,4 +35,9 @@ describe("<TemplateFormActions />", () => {
|
|
|
33
35
|
);
|
|
34
36
|
expect(wrapper).toMatchSnapshot();
|
|
35
37
|
});
|
|
38
|
+
|
|
39
|
+
it("matches the latest snapshot (invalid)", () => {
|
|
40
|
+
const wrapper = shallow(<TemplateFormActions {...props} isInvalid />);
|
|
41
|
+
expect(wrapper).toMatchSnapshot();
|
|
42
|
+
});
|
|
36
43
|
});
|