@truedat/bg 6.0.2 → 6.0.3
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/ConceptDetails.js +1 -3
- package/src/concepts/components/ConceptEdit.js +124 -110
- package/src/concepts/components/ConceptForm.js +154 -123
- package/src/concepts/components/ConceptsUpdateButton.js +3 -2
- package/src/concepts/components/__tests__/ConceptForm.spec.js +23 -1
- package/src/concepts/components/__tests__/ConceptsActions.spec.js +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/bg",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.3",
|
|
4
4
|
"description": "Truedat Web Business Glossary",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@testing-library/jest-dom": "^5.16.5",
|
|
35
35
|
"@testing-library/react": "^12.0.0",
|
|
36
36
|
"@testing-library/user-event": "^13.2.1",
|
|
37
|
-
"@truedat/test": "6.0.
|
|
37
|
+
"@truedat/test": "6.0.3",
|
|
38
38
|
"babel-jest": "^28.1.0",
|
|
39
39
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
40
40
|
"babel-plugin-lodash": "^3.3.4",
|
|
@@ -86,9 +86,9 @@
|
|
|
86
86
|
]
|
|
87
87
|
},
|
|
88
88
|
"dependencies": {
|
|
89
|
-
"@truedat/core": "6.0.
|
|
90
|
-
"@truedat/df": "6.0.
|
|
91
|
-
"@truedat/lm": "6.0.
|
|
89
|
+
"@truedat/core": "6.0.3",
|
|
90
|
+
"@truedat/df": "6.0.3",
|
|
91
|
+
"@truedat/lm": "6.0.3",
|
|
92
92
|
"decode-uri-component": "^0.2.2",
|
|
93
93
|
"file-saver": "^2.0.5",
|
|
94
94
|
"moment": "^2.29.4",
|
|
@@ -111,5 +111,5 @@
|
|
|
111
111
|
"react-dom": ">= 16.8.6 < 17",
|
|
112
112
|
"semantic-ui-react": ">= 2.0.3 < 2.2"
|
|
113
113
|
},
|
|
114
|
-
"gitHead": "
|
|
114
|
+
"gitHead": "c88ddc501214b8c4e2732654ca0052ebbcc802c9"
|
|
115
115
|
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
3
|
import { connect } from "react-redux";
|
|
4
|
-
import { Segment
|
|
5
|
-
import { FormattedMessage } from "react-intl";
|
|
6
|
-
import { RichTextEditor } from "@truedat/core/components";
|
|
4
|
+
import { Segment } from "semantic-ui-react";
|
|
7
5
|
|
|
8
6
|
const DynamicFormViewer = React.lazy(() =>
|
|
9
7
|
import("@truedat/df/components/DynamicFormViewer")
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import React from "react";
|
|
2
|
+
import React, { useState, useEffect } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import {
|
|
5
5
|
Button,
|
|
@@ -14,8 +14,12 @@ import { compose } from "redux";
|
|
|
14
14
|
import { connect } from "react-redux";
|
|
15
15
|
import { injectIntl, FormattedMessage } from "react-intl";
|
|
16
16
|
import { HistoryBackButton } from "@truedat/core/components";
|
|
17
|
+
import { apiJsonPost } from "@truedat/core/services/api";
|
|
17
18
|
import { selectTemplate, selectDomain } from "@truedat/df/routines";
|
|
18
19
|
import { applyTemplate } from "@truedat/df/utils";
|
|
20
|
+
import { useAvailabilityCheck } from "@truedat/ai/hooks/useSuggestions";
|
|
21
|
+
import { API_SUGGESTIONS_REQUEST } from "@truedat/ai/api";
|
|
22
|
+
import SuggestionsWidget from "@truedat/ai/components/suggestions/SuggestionsWidget";
|
|
19
23
|
import { conceptAction } from "../routines";
|
|
20
24
|
|
|
21
25
|
const DynamicForm = React.lazy(() =>
|
|
@@ -28,135 +32,145 @@ const TemplateLoader = React.lazy(() =>
|
|
|
28
32
|
|
|
29
33
|
const actionKey = "update";
|
|
30
34
|
|
|
31
|
-
const staticFields = ["type", "name"];
|
|
32
|
-
|
|
33
|
-
const initialState = {
|
|
34
|
-
type: "",
|
|
35
|
-
name: "",
|
|
36
|
-
};
|
|
37
|
-
|
|
38
35
|
const isNonEmptyString = _.flow(_.trim, _.negate(_.isEmpty));
|
|
39
36
|
const isValid = _.conforms({
|
|
40
37
|
name: isNonEmptyString,
|
|
41
38
|
});
|
|
42
39
|
|
|
43
|
-
export
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
40
|
+
export const ConceptEdit = ({
|
|
41
|
+
concept,
|
|
42
|
+
loading,
|
|
43
|
+
intl: { formatMessage },
|
|
44
|
+
template,
|
|
45
|
+
action,
|
|
46
|
+
conceptAction,
|
|
47
|
+
applyTemplate,
|
|
48
|
+
selectDomain,
|
|
49
|
+
selectTemplate,
|
|
50
|
+
templateId,
|
|
51
|
+
}) => {
|
|
52
|
+
const { content: propContent, name: propName, domain } = concept;
|
|
53
|
+
const [content, setContent] = useState(propContent);
|
|
54
|
+
const [name, setName] = useState(propName);
|
|
55
|
+
const [hasSuggestions, setHasSuggestions] = useState(false);
|
|
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
|
+
}, []);
|
|
66
71
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
_.isUndefined(this.state.content) &&
|
|
70
|
-
!_.isUndefined(this.props.concept.content)
|
|
71
|
-
) {
|
|
72
|
-
const { content, domain, name, type } = this.props.concept;
|
|
73
|
-
this.setState({ content, name, type });
|
|
74
|
-
const { selectDomain, selectTemplate, templateId } = this.props;
|
|
75
|
-
const domain_id = _.prop("id")(domain);
|
|
76
|
-
selectDomain({ id: domain_id });
|
|
77
|
-
selectTemplate({ id: templateId });
|
|
78
|
-
}
|
|
72
|
+
if (_.isNil(content)) {
|
|
73
|
+
return null;
|
|
79
74
|
}
|
|
80
|
-
handleChange = (e, { name, value }) => {
|
|
81
|
-
e && e.preventDefault();
|
|
82
|
-
|
|
83
|
-
if (staticFields.includes(name)) {
|
|
84
|
-
this.setState({ [name]: value });
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
75
|
|
|
88
|
-
|
|
76
|
+
const isInvalid = () => _.negate(isValid)({ name });
|
|
89
77
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
handleSubmit = (e) => {
|
|
78
|
+
const handleSubmit = (e) => {
|
|
93
79
|
e.preventDefault();
|
|
94
|
-
const { action, concept, conceptAction, applyTemplate } = this.props;
|
|
95
|
-
const businessConceptVersion = _.pick(["name", "type"])(this.state);
|
|
96
80
|
|
|
97
|
-
const
|
|
81
|
+
const businessConceptVersion = { name, type: concept.type };
|
|
82
|
+
const newContent = applyTemplate(content, domain?.id);
|
|
98
83
|
|
|
99
84
|
conceptAction({
|
|
100
85
|
action: actionKey,
|
|
101
86
|
...action,
|
|
102
|
-
business_concept_version: {
|
|
87
|
+
business_concept_version: {
|
|
88
|
+
...businessConceptVersion,
|
|
89
|
+
content: newContent,
|
|
90
|
+
},
|
|
103
91
|
});
|
|
104
92
|
};
|
|
105
93
|
|
|
106
|
-
|
|
107
|
-
const {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
</
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
isModification={true}
|
|
144
|
-
/>
|
|
145
|
-
)}
|
|
146
|
-
<Button
|
|
147
|
-
primary
|
|
148
|
-
onClick={this.handleSubmit}
|
|
149
|
-
disabled={this.isInvalid()}
|
|
150
|
-
content={formatMessage({ id: "actions.save" })}
|
|
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
|
+
return (
|
|
109
|
+
<Container as={Segment} text>
|
|
110
|
+
<Header as="h2">
|
|
111
|
+
<Icon name="book" />
|
|
112
|
+
<Header.Content>
|
|
113
|
+
<FormattedMessage id="concepts.header.edit" />
|
|
114
|
+
</Header.Content>
|
|
115
|
+
</Header>
|
|
116
|
+
<TemplateLoader />
|
|
117
|
+
<Form loading={loading}>
|
|
118
|
+
<Form.Field required>
|
|
119
|
+
<label>
|
|
120
|
+
{formatMessage({ id: "concepts.props.name" })}
|
|
121
|
+
{_.isEmpty(name) ? (
|
|
122
|
+
<Label pointing="left">
|
|
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)}
|
|
151
131
|
/>
|
|
152
|
-
|
|
153
|
-
|
|
132
|
+
</Form.Field>
|
|
133
|
+
{hasSuggestions ? (
|
|
134
|
+
<SuggestionsWidget
|
|
135
|
+
requestAiSuggestion={requestAiSuggestion}
|
|
136
|
+
template={template}
|
|
137
|
+
applySuggestions={(suggestions) =>
|
|
138
|
+
setContent({ ...content, ...suggestions })
|
|
139
|
+
}
|
|
140
|
+
isModification={true}
|
|
154
141
|
/>
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
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>
|
|
159
|
+
);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
ConceptEdit.propTypes = {
|
|
163
|
+
action: PropTypes.object,
|
|
164
|
+
applyTemplate: PropTypes.func,
|
|
165
|
+
concept: PropTypes.object,
|
|
166
|
+
conceptAction: PropTypes.func.isRequired,
|
|
167
|
+
intl: PropTypes.object,
|
|
168
|
+
loading: PropTypes.bool,
|
|
169
|
+
selectDomain: PropTypes.func,
|
|
170
|
+
selectTemplate: PropTypes.func,
|
|
171
|
+
template: PropTypes.object,
|
|
172
|
+
templateId: PropTypes.number,
|
|
173
|
+
};
|
|
160
174
|
|
|
161
175
|
const mapStateToProps = ({
|
|
162
176
|
concept,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import React from "react";
|
|
2
|
+
import React, { useState, useEffect } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import {
|
|
5
5
|
Button,
|
|
@@ -13,11 +13,11 @@ import {
|
|
|
13
13
|
import { compose } from "redux";
|
|
14
14
|
import { connect } from "react-redux";
|
|
15
15
|
import { injectIntl, FormattedMessage } from "react-intl";
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
import { apiJsonPost } from "@truedat/core/services/api";
|
|
17
|
+
import { DomainSelector, HistoryBackButton } from "@truedat/core/components";
|
|
18
|
+
import { useAvailabilityCheck } from "@truedat/ai/hooks/useSuggestions";
|
|
19
|
+
import { API_SUGGESTIONS_REQUEST } from "@truedat/ai/api";
|
|
20
|
+
import SuggestionsWidget from "@truedat/ai/components/suggestions/SuggestionsWidget";
|
|
21
21
|
import { conceptAction } from "../routines";
|
|
22
22
|
|
|
23
23
|
const SelectableDynamicForm = React.lazy(() =>
|
|
@@ -26,64 +26,66 @@ const SelectableDynamicForm = React.lazy(() =>
|
|
|
26
26
|
|
|
27
27
|
const actionKey = "create";
|
|
28
28
|
|
|
29
|
-
const staticFields = ["name", "description"];
|
|
30
|
-
|
|
31
|
-
const INITIAL_STATE = {
|
|
32
|
-
name: "",
|
|
33
|
-
description: {},
|
|
34
|
-
content: {},
|
|
35
|
-
domainsLoading: true,
|
|
36
|
-
};
|
|
37
|
-
|
|
38
29
|
const isNonEmptyString = _.flow(_.trim, _.negate(_.isEmpty));
|
|
39
30
|
const isValid = _.conforms({
|
|
40
31
|
name: isNonEmptyString,
|
|
41
32
|
domain_id: _.isFinite,
|
|
42
|
-
description: _.negate(_.isEmpty),
|
|
43
33
|
type: isNonEmptyString,
|
|
44
34
|
});
|
|
45
35
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
36
|
+
const ConceptForm = ({
|
|
37
|
+
action,
|
|
38
|
+
conceptActionLoading,
|
|
39
|
+
conceptAction,
|
|
40
|
+
intl: { formatMessage },
|
|
41
|
+
}) => {
|
|
42
|
+
const [name, setName] = useState("");
|
|
43
|
+
const [content, setContent] = useState({});
|
|
44
|
+
const [type, setType] = useState();
|
|
45
|
+
const [template, setTemplate] = useState();
|
|
46
|
+
const [domainId, setDomainId] = useState();
|
|
47
|
+
const [domains, setDomains] = useState();
|
|
48
|
+
const [domainsLoading, setDomainsLoading] = useState(true);
|
|
49
|
+
const [hasSuggestions, setHasSuggestions] = useState(false);
|
|
50
|
+
|
|
51
|
+
const { trigger: checkSuggestionAvailability } = useAvailabilityCheck();
|
|
52
|
+
|
|
53
|
+
const loading = action && action.href && conceptActionLoading === action.href;
|
|
54
|
+
const templateDisabled = !domainId || !name;
|
|
55
|
+
const templateId = template?.id;
|
|
56
|
+
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
if (templateId && domainId) {
|
|
59
|
+
checkSuggestionAvailability({
|
|
60
|
+
template_id: templateId,
|
|
61
|
+
domain_ids: [domainId],
|
|
62
|
+
resource_type: "business_concept",
|
|
63
|
+
}).then((prop) =>
|
|
64
|
+
setHasSuggestions(_.prop("data.data.status")(prop) == "ok")
|
|
65
|
+
);
|
|
69
66
|
}
|
|
67
|
+
}, [templateId, domainId]);
|
|
68
|
+
|
|
69
|
+
const handleDomainSelected = (_e, { value }) =>
|
|
70
|
+
setDomainId(_.toInteger(value));
|
|
71
|
+
const handleContentChange = ({ content }) => setContent(content);
|
|
72
|
+
const handleDomainsLoaded = ({ domains }) => {
|
|
73
|
+
setDomains(domains);
|
|
74
|
+
setDomainsLoading(false);
|
|
70
75
|
};
|
|
71
76
|
|
|
72
|
-
|
|
77
|
+
const isInvalid = () =>
|
|
78
|
+
_.negate(isValid)({ name, domain_id: domainId, type });
|
|
73
79
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
isInvalid = () => _.negate(isValid)(this.state);
|
|
77
|
-
|
|
78
|
-
handleSubmit = (e) => {
|
|
80
|
+
const handleSubmit = (e) => {
|
|
79
81
|
e.preventDefault();
|
|
80
|
-
|
|
81
|
-
const business_concept_version =
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
82
|
+
|
|
83
|
+
const business_concept_version = {
|
|
84
|
+
name,
|
|
85
|
+
domain_id: domainId,
|
|
86
|
+
type,
|
|
87
|
+
content,
|
|
88
|
+
};
|
|
87
89
|
|
|
88
90
|
conceptAction({
|
|
89
91
|
action: actionKey,
|
|
@@ -92,85 +94,114 @@ export class ConceptForm extends React.Component {
|
|
|
92
94
|
});
|
|
93
95
|
};
|
|
94
96
|
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
<
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
97
|
+
const requestAiSuggestion = (callback) => {
|
|
98
|
+
const domainName = _.flow(
|
|
99
|
+
_.find({ id: domainId }),
|
|
100
|
+
_.prop("name")
|
|
101
|
+
)(domains);
|
|
102
|
+
const body = {
|
|
103
|
+
resource_type: "business_concept",
|
|
104
|
+
resource_body: {
|
|
105
|
+
name,
|
|
106
|
+
domain: domainName,
|
|
107
|
+
type,
|
|
108
|
+
},
|
|
109
|
+
domain_ids: [domainId],
|
|
110
|
+
template_id: templateId,
|
|
111
|
+
};
|
|
112
|
+
apiJsonPost(API_SUGGESTIONS_REQUEST, body).then(callback);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
<Container as={Segment} text>
|
|
117
|
+
<Header as="h2">
|
|
118
|
+
<Icon name="book" />
|
|
119
|
+
<Header.Content>
|
|
120
|
+
<FormattedMessage id="concepts.actions.create" />
|
|
121
|
+
</Header.Content>
|
|
122
|
+
</Header>
|
|
123
|
+
<Form loading={loading || domainsLoading}>
|
|
124
|
+
<Header
|
|
125
|
+
as="h3"
|
|
126
|
+
content={formatMessage({ id: "concepts.form.required_fields" })}
|
|
127
|
+
/>
|
|
128
|
+
<DomainSelector
|
|
129
|
+
action="createBusinessConcept"
|
|
130
|
+
label={formatMessage({ id: "domain.selector.label" })}
|
|
131
|
+
labels
|
|
132
|
+
required
|
|
133
|
+
onChange={handleDomainSelected}
|
|
134
|
+
onLoad={handleDomainsLoaded}
|
|
135
|
+
value={domainId}
|
|
136
|
+
/>
|
|
137
|
+
<Form.Field required>
|
|
138
|
+
<label>
|
|
139
|
+
<FormattedMessage id="concepts.props.name" />
|
|
140
|
+
{_.isEmpty(name) ? (
|
|
141
|
+
<Label pointing="left">
|
|
142
|
+
<FormattedMessage id="template.form.validation.empty_required" />
|
|
143
|
+
</Label>
|
|
144
|
+
) : null}
|
|
145
|
+
</label>
|
|
146
|
+
<Form.Input
|
|
147
|
+
name="name"
|
|
148
|
+
value={name}
|
|
149
|
+
onChange={(_e, { value }) => setName(value)}
|
|
129
150
|
/>
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
</label>
|
|
139
|
-
<Form.Input name="name" value={name} onChange={this.handleChange} />
|
|
140
|
-
</Form.Field>
|
|
141
|
-
<SelectableDynamicForm
|
|
142
|
-
scope="bg"
|
|
143
|
-
domainIds={_.isNil(domain_id) ? null : [domain_id]}
|
|
144
|
-
required
|
|
145
|
-
header={
|
|
151
|
+
</Form.Field>
|
|
152
|
+
<SelectableDynamicForm
|
|
153
|
+
disabled={templateDisabled}
|
|
154
|
+
scope="bg"
|
|
155
|
+
domainIds={_.isNil(domainId) ? null : [domainId]}
|
|
156
|
+
required
|
|
157
|
+
header={
|
|
158
|
+
<>
|
|
146
159
|
<Header
|
|
147
160
|
as="h3"
|
|
148
161
|
content={formatMessage({
|
|
149
162
|
id: "concepts.form.aditional_fields",
|
|
150
163
|
})}
|
|
151
164
|
/>
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
165
|
+
{hasSuggestions ? (
|
|
166
|
+
<SuggestionsWidget
|
|
167
|
+
requestAiSuggestion={requestAiSuggestion}
|
|
168
|
+
template={template}
|
|
169
|
+
applySuggestions={(suggestions) =>
|
|
170
|
+
setContent({ ...content, ...suggestions })
|
|
171
|
+
}
|
|
172
|
+
isModification={true}
|
|
173
|
+
/>
|
|
174
|
+
) : null}
|
|
175
|
+
</>
|
|
176
|
+
}
|
|
177
|
+
content={content}
|
|
178
|
+
name={type}
|
|
179
|
+
onChange={handleContentChange}
|
|
180
|
+
onNameChange={setType}
|
|
181
|
+
onTemplateChange={setTemplate}
|
|
182
|
+
/>
|
|
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" })}
|
|
157
192
|
/>
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
</Container>
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
193
|
+
</div>
|
|
194
|
+
</Form>
|
|
195
|
+
</Container>
|
|
196
|
+
);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
ConceptForm.propTypes = {
|
|
200
|
+
action: PropTypes.object,
|
|
201
|
+
conceptAction: PropTypes.func,
|
|
202
|
+
conceptActionLoading: PropTypes.string,
|
|
203
|
+
intl: PropTypes.object,
|
|
204
|
+
};
|
|
174
205
|
|
|
175
206
|
const mapStateToProps = ({ conceptActionLoading, conceptsActions }) => ({
|
|
176
207
|
action: _.prop(actionKey)(conceptsActions),
|
|
@@ -58,8 +58,9 @@ const mapStateToProps = ({
|
|
|
58
58
|
updateUrl:
|
|
59
59
|
conceptCount !== 0 &&
|
|
60
60
|
!conceptsLoading &&
|
|
61
|
-
existingTemplate(conceptFilters, conceptActiveFilters)
|
|
62
|
-
|
|
61
|
+
existingTemplate(conceptFilters, conceptActiveFilters)
|
|
62
|
+
? CONCEPTS_BULK_UPDATE
|
|
63
|
+
: null,
|
|
63
64
|
});
|
|
64
65
|
|
|
65
66
|
export default connect(mapStateToProps)(ConceptsUpdateButton);
|
|
@@ -9,6 +9,27 @@ import {
|
|
|
9
9
|
} from "@truedat/test/mocks";
|
|
10
10
|
import ConceptForm from "../ConceptForm";
|
|
11
11
|
|
|
12
|
+
jest.mock("@truedat/ai/hooks/useSuggestions", () => {
|
|
13
|
+
const originalModule = jest.requireActual("@truedat/ai/hooks/useSuggestions");
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
__esModule: true,
|
|
17
|
+
...originalModule,
|
|
18
|
+
useAvailabilityCheck: () => ({
|
|
19
|
+
trigger: jest.fn(
|
|
20
|
+
() =>
|
|
21
|
+
new Promise(() => ({
|
|
22
|
+
data: {
|
|
23
|
+
data: {
|
|
24
|
+
status: "ok",
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
}))
|
|
28
|
+
),
|
|
29
|
+
}),
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
|
|
12
33
|
const state = {
|
|
13
34
|
conceptActions: { create: {} },
|
|
14
35
|
conceptActionLoading: "",
|
|
@@ -39,13 +60,14 @@ describe("<ConceptForm />", () => {
|
|
|
39
60
|
});
|
|
40
61
|
|
|
41
62
|
it("renders dynamic fields when template is selected", async () => {
|
|
42
|
-
const { findByText, getByText, queryByText } = render(
|
|
63
|
+
const { findByText, getByText, queryByText, getAllByRole } = render(
|
|
43
64
|
<ConceptForm />,
|
|
44
65
|
renderOpts
|
|
45
66
|
);
|
|
46
67
|
await waitFor(() => expect(queryByText(/lazy/i)).not.toBeInTheDocument());
|
|
47
68
|
await waitFor(() => expect(queryByText(/fooDomain/)).toBeInTheDocument());
|
|
48
69
|
userEvent.click(await findByText("fooDomain"));
|
|
70
|
+
userEvent.type(getAllByRole("textbox")[1], "name");
|
|
49
71
|
userEvent.click(await findByText("template1"));
|
|
50
72
|
expect(getByText("field1")).toBeInTheDocument();
|
|
51
73
|
});
|