@truedat/bg 6.1.4 → 6.2.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 +6 -6
- package/src/concepts/components/ConceptCompleteness.js +88 -10
- package/src/concepts/components/ConceptCreate.js +116 -0
- package/src/concepts/components/ConceptCrumbs.js +15 -5
- package/src/concepts/components/ConceptDetails.js +80 -9
- package/src/concepts/components/ConceptEdit.js +86 -134
- package/src/concepts/components/ConceptForm.js +68 -112
- package/src/concepts/components/ConceptFormTabs.js +75 -0
- package/src/concepts/components/ConceptForms.js +196 -0
- package/src/concepts/components/ConceptHeader.js +8 -10
- package/src/concepts/components/ConceptRoutes.js +2 -2
- package/src/concepts/components/__tests__/ConceptDetails.spec.js +11 -7
- package/src/concepts/components/__tests__/ConceptForm.spec.js +62 -45
- package/src/concepts/components/__tests__/__snapshots__/ConceptCompleteness.spec.js.snap +1 -39
- package/src/concepts/components/__tests__/__snapshots__/ConceptDetails.spec.js.snap +5 -15
- package/src/concepts/components/__tests__/__snapshots__/ConceptForm.spec.js.snap +172 -202
- package/src/concepts/components/__tests__/__snapshots__/ConceptsBulkUpdate.spec.js.snap +1 -0
- package/src/concepts/components/__tests__/__snapshots__/SharedToForm.spec.js.snap +1 -0
- package/src/concepts/index.js +1 -0
- package/src/concepts/reducers/concept.js +3 -2
- package/src/concepts/styles/conceptForms.less +12 -0
- package/src/messages/en.js +0 -1
- package/src/messages/es.js +0 -1
|
@@ -1,161 +1,117 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import React, { useState
|
|
2
|
+
import React, { useState } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
|
-
import {
|
|
5
|
-
Button,
|
|
6
|
-
Container,
|
|
7
|
-
Form,
|
|
8
|
-
Header,
|
|
9
|
-
Icon,
|
|
10
|
-
Label,
|
|
11
|
-
Segment,
|
|
12
|
-
} from "semantic-ui-react";
|
|
13
4
|
import { compose } from "redux";
|
|
14
5
|
import { connect } from "react-redux";
|
|
15
|
-
import { injectIntl, FormattedMessage } from "react-intl";
|
|
16
|
-
import { HistoryBackButton } from "@truedat/core/components";
|
|
17
|
-
import { apiJsonPost } from "@truedat/core/services/api";
|
|
18
|
-
import { selectTemplate, selectDomain } from "@truedat/df/routines";
|
|
19
6
|
import { applyTemplate } from "@truedat/df/utils";
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
|
|
7
|
+
import { useLocales } from "@truedat/core/hooks";
|
|
8
|
+
import {
|
|
9
|
+
splitTranslatableFields,
|
|
10
|
+
formatLocales,
|
|
11
|
+
} from "@truedat/core/services/i18nContent";
|
|
23
12
|
import { conceptAction } from "../routines";
|
|
24
13
|
|
|
25
|
-
|
|
26
|
-
import("@truedat/df/components/DynamicForm")
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
const TemplateLoader = React.lazy(() =>
|
|
30
|
-
import("@truedat/df/templates/components/TemplateLoader")
|
|
31
|
-
);
|
|
32
|
-
|
|
14
|
+
import ConceptForms from "./ConceptForms";
|
|
33
15
|
const actionKey = "update";
|
|
34
16
|
|
|
35
|
-
const isNonEmptyString = _.flow(_.trim, _.negate(_.isEmpty));
|
|
36
|
-
const isValid = _.conforms({
|
|
37
|
-
name: isNonEmptyString,
|
|
38
|
-
});
|
|
39
|
-
|
|
40
17
|
export const ConceptEdit = ({
|
|
41
18
|
concept,
|
|
42
19
|
loading,
|
|
43
|
-
intl: { formatMessage },
|
|
44
20
|
template,
|
|
45
21
|
action,
|
|
46
22
|
conceptAction,
|
|
47
23
|
applyTemplate,
|
|
48
|
-
selectDomain,
|
|
49
|
-
selectTemplate,
|
|
50
|
-
templateId,
|
|
51
24
|
}) => {
|
|
52
25
|
const { content: propContent, name: propName, domain } = concept;
|
|
53
|
-
const
|
|
54
|
-
const [
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const { trigger: checkSuggestionAvailability } = useAvailabilityCheck();
|
|
58
|
-
|
|
59
|
-
useEffect(() => {
|
|
60
|
-
const domain_id = _.prop("id")(domain);
|
|
61
|
-
selectDomain({ id: domain_id });
|
|
62
|
-
selectTemplate({ id: templateId });
|
|
63
|
-
checkSuggestionAvailability({
|
|
64
|
-
template_id: templateId,
|
|
65
|
-
domain_ids: [domain.id],
|
|
66
|
-
resource_type: "business_concept",
|
|
67
|
-
}).then((prop) =>
|
|
68
|
-
setHasSuggestions(_.prop("data.data.status")(prop) == "ok")
|
|
69
|
-
);
|
|
70
|
-
}, []);
|
|
71
|
-
|
|
72
|
-
if (_.isNil(content)) {
|
|
26
|
+
const { locales, loading: localesLoading } = useLocales(false);
|
|
27
|
+
const [i18nConcept, setI18nConcept] = useState({});
|
|
28
|
+
|
|
29
|
+
if (_.isNil(propContent)) {
|
|
73
30
|
return null;
|
|
74
31
|
}
|
|
75
32
|
|
|
76
|
-
|
|
33
|
+
if (_.isEmpty(i18nConcept)) {
|
|
34
|
+
const i18n_content = concept.i18n_content || {};
|
|
35
|
+
|
|
36
|
+
const { translatable: translatableFields } =
|
|
37
|
+
splitTranslatableFields(template);
|
|
38
|
+
|
|
39
|
+
const i18nConceptInit = _.flow(
|
|
40
|
+
_.filter(({ is_enabled }) => is_enabled),
|
|
41
|
+
_.map(({ id, lang, is_default, is_required }) => {
|
|
42
|
+
const contentLang = _.get(lang)(i18n_content);
|
|
43
|
+
|
|
44
|
+
const langContent = is_default
|
|
45
|
+
? propContent
|
|
46
|
+
: { ...translatableFields, ...contentLang?.content };
|
|
47
|
+
const langName = is_default ? propName : contentLang?.name || "";
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
id,
|
|
51
|
+
lang,
|
|
52
|
+
is_default,
|
|
53
|
+
is_required,
|
|
54
|
+
name: langName,
|
|
55
|
+
content: langContent,
|
|
56
|
+
};
|
|
57
|
+
}),
|
|
58
|
+
_.keyBy("lang")
|
|
59
|
+
)(locales);
|
|
60
|
+
|
|
61
|
+
setI18nConcept(i18nConceptInit);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const templateFields = splitTranslatableFields(template);
|
|
65
|
+
|
|
66
|
+
const translatableKeys = _.keys(templateFields.translatable);
|
|
67
|
+
const noTranslatableKeys = _.keys(templateFields.noTranslatable);
|
|
68
|
+
const langs = formatLocales(locales);
|
|
69
|
+
const defaultContent = _.flow(_.find("is_default"))(i18nConcept);
|
|
77
70
|
|
|
78
71
|
const handleSubmit = (e) => {
|
|
79
72
|
e.preventDefault();
|
|
80
73
|
|
|
81
|
-
const
|
|
82
|
-
|
|
74
|
+
const i18nSendConcept = _.flow(
|
|
75
|
+
_.omit(defaultContent.lang),
|
|
76
|
+
_.mapValues((langConcept) =>
|
|
77
|
+
_.flow(_.pick(["name", "content"]), ({ name, content }) => {
|
|
78
|
+
return { name, content: _.pick(translatableKeys)(content) };
|
|
79
|
+
})(langConcept)
|
|
80
|
+
)
|
|
81
|
+
)(i18nConcept);
|
|
82
|
+
|
|
83
|
+
const newContent = applyTemplate(defaultContent.content, domain?.id);
|
|
84
|
+
|
|
85
|
+
const business_concept_version = {
|
|
86
|
+
name: defaultContent.name,
|
|
87
|
+
domain_id: domain.id,
|
|
88
|
+
type: template.name,
|
|
89
|
+
content: newContent,
|
|
90
|
+
i18n_content: i18nSendConcept,
|
|
91
|
+
};
|
|
83
92
|
|
|
84
93
|
conceptAction({
|
|
85
94
|
action: actionKey,
|
|
86
95
|
...action,
|
|
87
|
-
business_concept_version
|
|
88
|
-
...businessConceptVersion,
|
|
89
|
-
content: newContent,
|
|
90
|
-
},
|
|
96
|
+
business_concept_version,
|
|
91
97
|
});
|
|
92
98
|
};
|
|
93
99
|
|
|
94
|
-
const requestAiSuggestion = (callback) => {
|
|
95
|
-
const body = {
|
|
96
|
-
resource_type: "business_concept",
|
|
97
|
-
resource_body: {
|
|
98
|
-
name,
|
|
99
|
-
domain: domain.name,
|
|
100
|
-
type: template.name,
|
|
101
|
-
},
|
|
102
|
-
domain_ids: [domain.id],
|
|
103
|
-
template_id: templateId,
|
|
104
|
-
};
|
|
105
|
-
apiJsonPost(API_SUGGESTIONS_REQUEST, body).then(callback);
|
|
106
|
-
};
|
|
107
|
-
|
|
108
100
|
return (
|
|
109
|
-
|
|
110
|
-
<
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
<FormattedMessage id="template.form.validation.empty_required" />
|
|
124
|
-
</Label>
|
|
125
|
-
) : null}
|
|
126
|
-
</label>
|
|
127
|
-
<Form.Input
|
|
128
|
-
name="name"
|
|
129
|
-
value={name}
|
|
130
|
-
onChange={(_e, { value }) => setName(value)}
|
|
131
|
-
/>
|
|
132
|
-
</Form.Field>
|
|
133
|
-
{hasSuggestions ? (
|
|
134
|
-
<SuggestionsWidget
|
|
135
|
-
requestAiSuggestion={requestAiSuggestion}
|
|
136
|
-
template={template}
|
|
137
|
-
applySuggestions={(suggestions) =>
|
|
138
|
-
setContent({ ...content, ...suggestions })
|
|
139
|
-
}
|
|
140
|
-
isModification={true}
|
|
141
|
-
/>
|
|
142
|
-
) : null}
|
|
143
|
-
{_.isEmpty(template) || _.isNil(content) ? null : (
|
|
144
|
-
<DynamicForm
|
|
145
|
-
onChange={setContent}
|
|
146
|
-
content={content}
|
|
147
|
-
isModification={true}
|
|
148
|
-
/>
|
|
149
|
-
)}
|
|
150
|
-
<Button
|
|
151
|
-
primary
|
|
152
|
-
onClick={handleSubmit}
|
|
153
|
-
disabled={isInvalid()}
|
|
154
|
-
content={formatMessage({ id: "actions.save" })}
|
|
155
|
-
/>
|
|
156
|
-
<HistoryBackButton content={formatMessage({ id: "actions.cancel" })} />
|
|
157
|
-
</Form>
|
|
158
|
-
</Container>
|
|
101
|
+
<>
|
|
102
|
+
<ConceptForms
|
|
103
|
+
actionKey={actionKey}
|
|
104
|
+
domainId={domain.id}
|
|
105
|
+
template={template}
|
|
106
|
+
i18nConcept={i18nConcept}
|
|
107
|
+
loading={loading || localesLoading}
|
|
108
|
+
langs={langs}
|
|
109
|
+
noTranslatableFields={noTranslatableKeys}
|
|
110
|
+
translatableFields={translatableKeys}
|
|
111
|
+
setI18nConcept={setI18nConcept}
|
|
112
|
+
onSubmit={handleSubmit}
|
|
113
|
+
/>
|
|
114
|
+
</>
|
|
159
115
|
);
|
|
160
116
|
};
|
|
161
117
|
|
|
@@ -169,7 +125,6 @@ ConceptEdit.propTypes = {
|
|
|
169
125
|
selectDomain: PropTypes.func,
|
|
170
126
|
selectTemplate: PropTypes.func,
|
|
171
127
|
template: PropTypes.object,
|
|
172
|
-
templateId: PropTypes.number,
|
|
173
128
|
};
|
|
174
129
|
|
|
175
130
|
const mapStateToProps = ({
|
|
@@ -178,29 +133,26 @@ const mapStateToProps = ({
|
|
|
178
133
|
conceptActions,
|
|
179
134
|
templateLoading,
|
|
180
135
|
templates,
|
|
181
|
-
template,
|
|
182
136
|
}) => {
|
|
183
137
|
const action = _.prop(actionKey)(conceptActions);
|
|
184
138
|
const loading =
|
|
185
139
|
templateLoading ||
|
|
186
140
|
(action && action.href && conceptActionLoading === action.href);
|
|
187
141
|
|
|
188
|
-
const
|
|
142
|
+
const template =
|
|
189
143
|
templates && concept && concept.type
|
|
190
|
-
? _.flow(_.find(_.propEq("name", concept.type))
|
|
144
|
+
? _.flow(_.find(_.propEq("name", concept.type)))(templates)
|
|
191
145
|
: null;
|
|
192
146
|
return {
|
|
193
147
|
action,
|
|
194
148
|
concept,
|
|
195
149
|
loading,
|
|
196
|
-
templateId,
|
|
197
150
|
template,
|
|
198
151
|
loading,
|
|
199
152
|
applyTemplate: applyTemplate(template),
|
|
200
153
|
};
|
|
201
154
|
};
|
|
202
155
|
|
|
203
|
-
export default compose(
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
)(ConceptEdit);
|
|
156
|
+
export default compose(connect(mapStateToProps, { conceptAction }))(
|
|
157
|
+
ConceptEdit
|
|
158
|
+
);
|
|
@@ -1,57 +1,39 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
2
|
import React, { useState, useEffect } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
Container,
|
|
7
|
-
Form,
|
|
8
|
-
Header,
|
|
9
|
-
Icon,
|
|
10
|
-
Label,
|
|
11
|
-
Segment,
|
|
12
|
-
} from "semantic-ui-react";
|
|
13
|
-
import { compose } from "redux";
|
|
14
|
-
import { connect } from "react-redux";
|
|
15
|
-
import { injectIntl, FormattedMessage } from "react-intl";
|
|
4
|
+
import { Form, Header, Label } from "semantic-ui-react";
|
|
5
|
+
import { useIntl, FormattedMessage } from "react-intl";
|
|
16
6
|
import { apiJsonPost } from "@truedat/core/services/api";
|
|
17
|
-
import { DomainSelector
|
|
7
|
+
import { DomainSelector } from "@truedat/core/components";
|
|
18
8
|
import { useAvailabilityCheck } from "@truedat/ai/hooks/useSuggestions";
|
|
19
9
|
import { API_SUGGESTIONS_REQUEST } from "@truedat/ai/api";
|
|
20
10
|
import SuggestionsWidget from "@truedat/ai/components/suggestions/SuggestionsWidget";
|
|
21
|
-
import { conceptAction } from "../routines";
|
|
22
11
|
|
|
23
12
|
const SelectableDynamicForm = React.lazy(() =>
|
|
24
13
|
import("@truedat/df/components/SelectableDynamicForm")
|
|
25
14
|
);
|
|
26
15
|
|
|
27
|
-
const actionKey = "create";
|
|
28
|
-
|
|
29
|
-
const isNonEmptyString = _.flow(_.trim, _.negate(_.isEmpty));
|
|
30
|
-
const isValid = _.conforms({
|
|
31
|
-
name: isNonEmptyString,
|
|
32
|
-
domain_id: _.isFinite,
|
|
33
|
-
type: isNonEmptyString,
|
|
34
|
-
});
|
|
35
|
-
|
|
36
16
|
const ConceptForm = ({
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
17
|
+
actionKey,
|
|
18
|
+
domainId,
|
|
19
|
+
template,
|
|
20
|
+
concept,
|
|
21
|
+
loading,
|
|
22
|
+
defaultContent,
|
|
23
|
+
noTranslatableFields,
|
|
24
|
+
onChangeDomainId,
|
|
25
|
+
onChangeName,
|
|
26
|
+
onChangeTemplate,
|
|
27
|
+
onChangeConceptContent,
|
|
41
28
|
}) => {
|
|
42
|
-
const
|
|
43
|
-
const [content, setContent] = useState({});
|
|
44
|
-
const [type, setType] = useState();
|
|
45
|
-
const [template, setTemplate] = useState();
|
|
46
|
-
const [domainId, setDomainId] = useState();
|
|
29
|
+
const { formatMessage } = useIntl();
|
|
47
30
|
const [domains, setDomains] = useState();
|
|
48
31
|
const [domainsLoading, setDomainsLoading] = useState(true);
|
|
49
32
|
const [hasSuggestions, setHasSuggestions] = useState(false);
|
|
50
33
|
|
|
51
34
|
const { trigger: checkSuggestionAvailability } = useAvailabilityCheck();
|
|
52
35
|
|
|
53
|
-
const
|
|
54
|
-
const templateDisabled = !domainId || !name;
|
|
36
|
+
const templateDisabled = !domainId || (!concept?.name && concept?.is_default);
|
|
55
37
|
const templateId = template?.id;
|
|
56
38
|
|
|
57
39
|
useEffect(() => {
|
|
@@ -66,33 +48,14 @@ const ConceptForm = ({
|
|
|
66
48
|
}
|
|
67
49
|
}, [templateId, domainId]);
|
|
68
50
|
|
|
69
|
-
const handleDomainSelected = (_e, { value }) =>
|
|
70
|
-
setDomainId(_.toInteger(value));
|
|
71
|
-
const handleContentChange = ({ content }) => setContent(content);
|
|
72
51
|
const handleDomainsLoaded = ({ domains }) => {
|
|
73
52
|
setDomains(domains);
|
|
74
53
|
setDomainsLoading(false);
|
|
75
54
|
};
|
|
76
55
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const handleSubmit = (e) => {
|
|
81
|
-
e.preventDefault();
|
|
82
|
-
|
|
83
|
-
const business_concept_version = {
|
|
84
|
-
name,
|
|
85
|
-
domain_id: domainId,
|
|
86
|
-
type,
|
|
87
|
-
content,
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
conceptAction({
|
|
91
|
-
action: actionKey,
|
|
92
|
-
...action,
|
|
93
|
-
business_concept_version,
|
|
94
|
-
});
|
|
95
|
-
};
|
|
56
|
+
if (domainsLoading && domainId) {
|
|
57
|
+
setDomainsLoading(false);
|
|
58
|
+
}
|
|
96
59
|
|
|
97
60
|
const requestAiSuggestion = (callback) => {
|
|
98
61
|
const domainName = _.flow(
|
|
@@ -102,9 +65,9 @@ const ConceptForm = ({
|
|
|
102
65
|
const body = {
|
|
103
66
|
resource_type: "business_concept",
|
|
104
67
|
resource_body: {
|
|
105
|
-
name,
|
|
68
|
+
name: concept.name,
|
|
106
69
|
domain: domainName,
|
|
107
|
-
type,
|
|
70
|
+
type: template?.name,
|
|
108
71
|
},
|
|
109
72
|
domain_ids: [domainId],
|
|
110
73
|
template_id: templateId,
|
|
@@ -112,32 +75,29 @@ const ConceptForm = ({
|
|
|
112
75
|
apiJsonPost(API_SUGGESTIONS_REQUEST, body).then(callback);
|
|
113
76
|
};
|
|
114
77
|
|
|
78
|
+
const handleOnChangeConceptContent = (content) =>
|
|
79
|
+
onChangeConceptContent(concept.lang, content);
|
|
80
|
+
|
|
115
81
|
return (
|
|
116
|
-
|
|
117
|
-
<Header as="h2">
|
|
118
|
-
<Icon name="book" />
|
|
119
|
-
<Header.Content>
|
|
120
|
-
<FormattedMessage id="concepts.actions.create" />
|
|
121
|
-
</Header.Content>
|
|
122
|
-
</Header>
|
|
82
|
+
<>
|
|
123
83
|
<Form loading={loading || domainsLoading}>
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
84
|
+
{actionKey == "create" ? (
|
|
85
|
+
<DomainSelector
|
|
86
|
+
action="createBusinessConcept"
|
|
87
|
+
label={formatMessage({ id: "domain.selector.label" })}
|
|
88
|
+
labels
|
|
89
|
+
required
|
|
90
|
+
disabled={!concept?.is_default}
|
|
91
|
+
onChange={onChangeDomainId}
|
|
92
|
+
onLoad={handleDomainsLoaded}
|
|
93
|
+
value={domainId}
|
|
94
|
+
/>
|
|
95
|
+
) : null}
|
|
96
|
+
|
|
137
97
|
<Form.Field required>
|
|
138
98
|
<label>
|
|
139
99
|
<FormattedMessage id="concepts.props.name" />
|
|
140
|
-
{_.isEmpty(name) ? (
|
|
100
|
+
{_.isEmpty(concept?.name) ? (
|
|
141
101
|
<Label pointing="left">
|
|
142
102
|
<FormattedMessage id="template.form.validation.empty_required" />
|
|
143
103
|
</Label>
|
|
@@ -145,11 +105,13 @@ const ConceptForm = ({
|
|
|
145
105
|
</label>
|
|
146
106
|
<Form.Input
|
|
147
107
|
name="name"
|
|
148
|
-
value={name}
|
|
149
|
-
onChange={(_e, { value }) =>
|
|
108
|
+
value={concept?.name}
|
|
109
|
+
onChange={(_e, { value }) => onChangeName(concept?.lang, value)}
|
|
150
110
|
/>
|
|
151
111
|
</Form.Field>
|
|
152
112
|
<SelectableDynamicForm
|
|
113
|
+
key={concept?.lang}
|
|
114
|
+
disableSelector={!concept?.is_default}
|
|
153
115
|
disabled={templateDisabled}
|
|
154
116
|
scope="bg"
|
|
155
117
|
domainIds={_.isNil(domainId) ? null : [domainId]}
|
|
@@ -162,53 +124,47 @@ const ConceptForm = ({
|
|
|
162
124
|
id: "concepts.form.aditional_fields",
|
|
163
125
|
})}
|
|
164
126
|
/>
|
|
165
|
-
{hasSuggestions ? (
|
|
127
|
+
{hasSuggestions && concept?.is_default ? (
|
|
166
128
|
<SuggestionsWidget
|
|
167
129
|
requestAiSuggestion={requestAiSuggestion}
|
|
168
130
|
template={template}
|
|
169
131
|
applySuggestions={(suggestions) =>
|
|
170
|
-
|
|
132
|
+
handleOnChangeConceptContent({
|
|
133
|
+
...concept?.content,
|
|
134
|
+
...suggestions,
|
|
135
|
+
})
|
|
171
136
|
}
|
|
172
137
|
isModification={true}
|
|
173
138
|
/>
|
|
174
139
|
) : null}
|
|
175
140
|
</>
|
|
176
141
|
}
|
|
177
|
-
content={content}
|
|
178
|
-
name={
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
142
|
+
content={{ ...defaultContent, ...concept?.content }}
|
|
143
|
+
name={template?.name}
|
|
144
|
+
noTranslatableFields={noTranslatableFields}
|
|
145
|
+
actionKey={actionKey}
|
|
146
|
+
onChange={handleOnChangeConceptContent}
|
|
147
|
+
onNameChange={onChangeName}
|
|
148
|
+
onTemplateChange={onChangeTemplate}
|
|
149
|
+
selectedTemplate={template}
|
|
182
150
|
/>
|
|
183
|
-
<div className="actions">
|
|
184
|
-
<HistoryBackButton
|
|
185
|
-
content={formatMessage({ id: "actions.cancel" })}
|
|
186
|
-
/>
|
|
187
|
-
<Button
|
|
188
|
-
primary
|
|
189
|
-
disabled={isInvalid()}
|
|
190
|
-
onClick={handleSubmit}
|
|
191
|
-
content={formatMessage({ id: "actions.create" })}
|
|
192
|
-
/>
|
|
193
|
-
</div>
|
|
194
151
|
</Form>
|
|
195
|
-
|
|
152
|
+
</>
|
|
196
153
|
);
|
|
197
154
|
};
|
|
198
155
|
|
|
199
156
|
ConceptForm.propTypes = {
|
|
200
|
-
|
|
201
|
-
|
|
157
|
+
domainId: PropTypes.number,
|
|
158
|
+
template: PropTypes.object,
|
|
159
|
+
concept: PropTypes.object,
|
|
160
|
+
defaultContent: PropTypes.object,
|
|
161
|
+
noTranslatableFields: PropTypes.array,
|
|
162
|
+
onChangeDomainId: PropTypes.func,
|
|
163
|
+
onChangeName: PropTypes.func,
|
|
164
|
+
onChangeTemplate: PropTypes.func,
|
|
165
|
+
onChangeConceptContent: PropTypes.func,
|
|
166
|
+
actionKey: PropTypes.string,
|
|
202
167
|
conceptActionLoading: PropTypes.string,
|
|
203
|
-
intl: PropTypes.object,
|
|
204
168
|
};
|
|
205
169
|
|
|
206
|
-
|
|
207
|
-
action: _.prop(actionKey)(conceptsActions),
|
|
208
|
-
conceptActionLoading,
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
export default compose(
|
|
212
|
-
injectIntl,
|
|
213
|
-
connect(mapStateToProps, { conceptAction })
|
|
214
|
-
)(ConceptForm);
|
|
170
|
+
export default ConceptForm;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { Grid, Tab } from "semantic-ui-react";
|
|
5
|
+
import { useIntl } from "react-intl";
|
|
6
|
+
import ConceptForm from "./ConceptForm";
|
|
7
|
+
|
|
8
|
+
const ConceptFormTabs = ({
|
|
9
|
+
domainId,
|
|
10
|
+
template,
|
|
11
|
+
langs,
|
|
12
|
+
conceptActionLoading,
|
|
13
|
+
i18nConcept,
|
|
14
|
+
noTranslatableFields = [],
|
|
15
|
+
actionKey,
|
|
16
|
+
onChangeDomainId,
|
|
17
|
+
onChangeName,
|
|
18
|
+
onChangeTemplate,
|
|
19
|
+
onChangeConceptContent,
|
|
20
|
+
}) => {
|
|
21
|
+
const { formatMessage } = useIntl();
|
|
22
|
+
|
|
23
|
+
const defaultContent = _.flow(
|
|
24
|
+
_.find("is_default"),
|
|
25
|
+
_.get("content")
|
|
26
|
+
)(i18nConcept);
|
|
27
|
+
|
|
28
|
+
const panes = _.map((locale) => {
|
|
29
|
+
const { lang, name, local_name, is_required, is_default } = locale;
|
|
30
|
+
return {
|
|
31
|
+
menuItem: `${formatMessage({
|
|
32
|
+
id: `i18n.messages.locale.${lang}`,
|
|
33
|
+
defaultMessage: `${name} ( ${local_name} )`,
|
|
34
|
+
})} ${is_required && !is_default ? "*" : ""}`,
|
|
35
|
+
render: () => (
|
|
36
|
+
<ConceptForm
|
|
37
|
+
domainId={domainId}
|
|
38
|
+
template={template}
|
|
39
|
+
concept={i18nConcept[lang]}
|
|
40
|
+
defaultContent={defaultContent}
|
|
41
|
+
noTranslatableFields={noTranslatableFields}
|
|
42
|
+
onChangeDomainId={onChangeDomainId}
|
|
43
|
+
onChangeName={onChangeName}
|
|
44
|
+
onChangeTemplate={onChangeTemplate}
|
|
45
|
+
onChangeConceptContent={onChangeConceptContent}
|
|
46
|
+
actionKey={actionKey}
|
|
47
|
+
conceptActionLoading={conceptActionLoading}
|
|
48
|
+
/>
|
|
49
|
+
),
|
|
50
|
+
};
|
|
51
|
+
})(langs);
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<Grid.Column>
|
|
55
|
+
<Tab className="concept-forms-tab" panes={panes} />
|
|
56
|
+
</Grid.Column>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
ConceptFormTabs.propTypes = {
|
|
61
|
+
domainId: PropTypes.number,
|
|
62
|
+
template: PropTypes.object,
|
|
63
|
+
langs: PropTypes.object,
|
|
64
|
+
action: PropTypes.object,
|
|
65
|
+
actionKey: PropTypes.string,
|
|
66
|
+
conceptActionLoading: PropTypes.string,
|
|
67
|
+
i18nConcept: PropTypes.object,
|
|
68
|
+
noTranslatableFields: PropTypes.array,
|
|
69
|
+
onChangeDomainId: PropTypes.func,
|
|
70
|
+
onChangeName: PropTypes.func,
|
|
71
|
+
onChangeTemplate: PropTypes.func,
|
|
72
|
+
onChangeConceptContent: PropTypes.func,
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export default ConceptFormTabs;
|