@truedat/dq 4.44.2 → 4.44.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/CHANGELOG.md +8 -1
- package/package.json +5 -5
- package/src/components/EditRule.js +1 -1
- package/src/components/ExecutionForm.js +68 -78
- package/src/components/ExecutionPopup.js +10 -6
- package/src/components/NewRule.js +1 -1
- package/src/components/NewRuleImplementation.js +91 -111
- package/src/components/RemediationForm.js +32 -43
- package/src/components/RuleForm.js +102 -103
- package/src/components/RuleImplementation.js +29 -13
- package/src/components/RuleImplementationActions.js +11 -21
- package/src/components/RuleImplementationsActions.js +1 -1
- package/src/components/RuleResultsRoutes.js +41 -56
- package/src/components/RuleRoutes.js +40 -56
- package/src/components/RulesRoutes.js +0 -5
- package/src/components/__tests__/ExecutionForm.spec.js +7 -1
- package/src/components/__tests__/ExecutionPopup.spec.js +3 -2
- package/src/components/__tests__/ImplementationResultBar.spec.js +44 -63
- package/src/components/__tests__/InformationSummary.spec.js +2 -6
- package/src/components/__tests__/NewRuleImplementation.spec.js +4 -6
- package/src/components/__tests__/RemediationForm.spec.js +47 -58
- package/src/components/__tests__/RuleForm.spec.js +80 -207
- package/src/components/__tests__/RuleImplementation.spec.js +45 -22
- package/src/components/__tests__/RuleImplementationsActions.spec.js +0 -1
- package/src/components/__tests__/RuleImplementationsOptions.spec.js +1 -10
- package/src/components/__tests__/RuleResultsUpload.spec.js +1 -5
- package/src/components/__tests__/RuleSummary.spec.js +6 -11
- package/src/components/__tests__/__snapshots__/EditRule.spec.js.snap +1 -1
- package/src/components/__tests__/__snapshots__/ExecutionForm.spec.js.snap +1 -2
- package/src/components/__tests__/__snapshots__/NewRule.spec.js.snap +1 -1
- package/src/components/__tests__/__snapshots__/RemediationForm.spec.js.snap +2 -3
- package/src/components/__tests__/__snapshots__/RuleForm.spec.js.snap +699 -385
- package/src/components/__tests__/__snapshots__/RuleImplementation.spec.js.snap +71 -5
- package/src/components/__tests__/__snapshots__/RuleImplementationsActions.spec.js.snap +1 -1
- package/src/components/index.js +0 -2
- package/src/components/ruleImplementationForm/InformationForm.js +40 -76
- package/src/components/ruleImplementationForm/RuleImplementationForm.js +40 -40
- package/src/components/ruleImplementationForm/RuleImplementationRawForm.js +63 -101
- package/src/components/ruleImplementationForm/__tests__/LimitsForm.spec.js +9 -35
- package/src/components/ruleImplementationForm/__tests__/RuleImplementationForm.spec.js +23 -50
- package/src/components/ruleImplementationForm/__tests__/RuleImplementationRawForm.spec.js +2 -2
- package/src/components/ruleImplementationForm/__tests__/__snapshots__/RuleImplementationForm.spec.js.snap +86 -19
- package/src/components/ruleImplementationForm/__tests__/__snapshots__/RuleImplementationRawForm.spec.js.snap +7 -1
- package/src/messages/en.js +3 -6
- package/src/messages/es.js +3 -6
- package/src/components/DynamicRuleForm.js +0 -78
- package/src/components/__tests__/DynamicRuleForm.spec.js +0 -51
- package/src/components/__tests__/__snapshots__/DynamicRuleForm.spec.js.snap +0 -3
|
@@ -6,20 +6,16 @@ import { applyTemplate, validateContent } from "@truedat/df/utils";
|
|
|
6
6
|
import { connect } from "react-redux";
|
|
7
7
|
import { useParams } from "react-router-dom";
|
|
8
8
|
import { Button, Form } from "semantic-ui-react";
|
|
9
|
+
import { TemplateSelector } from "@truedat/core/components";
|
|
9
10
|
import { createRemediation, updateRemediation } from "../routines";
|
|
10
11
|
|
|
11
12
|
const DynamicForm = React.lazy(() =>
|
|
12
13
|
import("@truedat/df/components/DynamicForm")
|
|
13
14
|
);
|
|
14
15
|
|
|
15
|
-
const TemplateSelector = React.lazy(() =>
|
|
16
|
-
import("@truedat/df/templates/components/TemplateSelector")
|
|
17
|
-
);
|
|
18
|
-
|
|
19
16
|
export const RemediationForm = ({
|
|
20
17
|
createRemediation,
|
|
21
18
|
updateRemediation,
|
|
22
|
-
templates,
|
|
23
19
|
remediation,
|
|
24
20
|
onSave,
|
|
25
21
|
latestResultId,
|
|
@@ -36,8 +32,18 @@ export const RemediationForm = ({
|
|
|
36
32
|
const isValidContent = _.flow(validateContent(template), _.isEmpty);
|
|
37
33
|
const isValid = _.has("name")(template) && isValidContent(content);
|
|
38
34
|
|
|
39
|
-
const
|
|
40
|
-
|
|
35
|
+
const handleTemplatesLoaded = ({ templates }) => {
|
|
36
|
+
const name = remediation?.df_name;
|
|
37
|
+
const template = name
|
|
38
|
+
? _.find(_.propEq("name", name))(templates)
|
|
39
|
+
: _.size(templates) == 1
|
|
40
|
+
? templates[0]
|
|
41
|
+
: null;
|
|
42
|
+
setTemplate(template);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const handleTemplateSelected = (e, { template }) => {
|
|
46
|
+
setTemplate(template);
|
|
41
47
|
};
|
|
42
48
|
|
|
43
49
|
const handleContentChange = (content) => {
|
|
@@ -63,41 +69,29 @@ export const RemediationForm = ({
|
|
|
63
69
|
};
|
|
64
70
|
|
|
65
71
|
useEffect(() => {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
],
|
|
73
|
-
]),
|
|
74
|
-
(template) => {
|
|
75
|
-
setTemplate(template);
|
|
76
|
-
return template;
|
|
77
|
-
},
|
|
78
|
-
(template) => applyTemplate(template)(remediation?.df_content),
|
|
79
|
-
setContent
|
|
80
|
-
)(templates);
|
|
81
|
-
}, [remediation, templates]);
|
|
72
|
+
const content =
|
|
73
|
+
template && remediation?.df_content
|
|
74
|
+
? applyTemplate(template)(remediation.df_content)
|
|
75
|
+
: null;
|
|
76
|
+
setContent(content);
|
|
77
|
+
}, [remediation, template]);
|
|
82
78
|
|
|
83
79
|
return (
|
|
84
80
|
<Form aria-label="remediation-form">
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
{!template ? null : (
|
|
81
|
+
<TemplateSelector
|
|
82
|
+
scope="remediation"
|
|
83
|
+
selectedValue={template?.id}
|
|
84
|
+
onChange={handleTemplateSelected}
|
|
85
|
+
onLoad={handleTemplatesLoaded}
|
|
86
|
+
required
|
|
87
|
+
/>
|
|
88
|
+
{template ? (
|
|
94
89
|
<DynamicForm
|
|
95
90
|
template={template}
|
|
96
91
|
onChange={handleContentChange}
|
|
97
92
|
content={content || {}}
|
|
98
93
|
/>
|
|
99
|
-
)}
|
|
100
|
-
|
|
94
|
+
) : null}
|
|
101
95
|
<Button
|
|
102
96
|
primary
|
|
103
97
|
disabled={!isValid}
|
|
@@ -112,18 +106,13 @@ export const RemediationForm = ({
|
|
|
112
106
|
|
|
113
107
|
RemediationForm.propTypes = {
|
|
114
108
|
createRemediation: PropTypes.func.isRequired,
|
|
115
|
-
updateRemediation: PropTypes.func,
|
|
116
|
-
templates: PropTypes.array,
|
|
117
|
-
remediation: PropTypes.object,
|
|
118
|
-
onSave: PropTypes.func,
|
|
119
109
|
latestResultId: PropTypes.number,
|
|
110
|
+
onSave: PropTypes.func,
|
|
111
|
+
remediation: PropTypes.object,
|
|
112
|
+
updateRemediation: PropTypes.func,
|
|
120
113
|
};
|
|
121
114
|
|
|
122
|
-
|
|
123
|
-
templates,
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
export default connect(mapStateToProps, {
|
|
115
|
+
export default connect(null, {
|
|
127
116
|
createRemediation,
|
|
128
117
|
updateRemediation,
|
|
129
118
|
})(RemediationForm);
|
|
@@ -1,7 +1,7 @@
|
|
|
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";
|
|
4
|
+
import { FormattedMessage, injectIntl } from "react-intl";
|
|
5
5
|
import { connect } from "react-redux";
|
|
6
6
|
import { withRouter } from "react-router-dom";
|
|
7
7
|
import { compose } from "redux";
|
|
@@ -16,11 +16,10 @@ import {
|
|
|
16
16
|
Popup,
|
|
17
17
|
Icon,
|
|
18
18
|
} from "semantic-ui-react";
|
|
19
|
-
import { HistoryBackButton } from "@truedat/core/components";
|
|
19
|
+
import { HistoryBackButton, TemplateSelector } from "@truedat/core/components";
|
|
20
20
|
import { applyTemplate } from "@truedat/df/utils";
|
|
21
21
|
import { selectDomain } from "@truedat/df/routines";
|
|
22
22
|
import { getDomainSelectorOptions } from "@truedat/bg/selectors";
|
|
23
|
-
import DynamicRuleForm from "./DynamicRuleForm";
|
|
24
23
|
|
|
25
24
|
const DomainDropdownSelector = React.lazy(() =>
|
|
26
25
|
import("@truedat/bg/taxonomy/components/DomainDropdownSelector")
|
|
@@ -34,6 +33,10 @@ const ConceptSelector = React.lazy(() =>
|
|
|
34
33
|
import("@truedat/bg/concepts/relations/components/ConceptSelector")
|
|
35
34
|
);
|
|
36
35
|
|
|
36
|
+
const DynamicForm = React.lazy(() =>
|
|
37
|
+
import("@truedat/df/components/DynamicForm")
|
|
38
|
+
);
|
|
39
|
+
|
|
37
40
|
export const FieldLabelWrapping = ({
|
|
38
41
|
children,
|
|
39
42
|
label,
|
|
@@ -44,8 +47,8 @@ export const FieldLabelWrapping = ({
|
|
|
44
47
|
<Form.Field>
|
|
45
48
|
<label className="rule-form-label">
|
|
46
49
|
{label}
|
|
47
|
-
{required
|
|
48
|
-
{tooltip
|
|
50
|
+
{required ? <span>*</span> : null}
|
|
51
|
+
{tooltip ? (
|
|
49
52
|
<Popup
|
|
50
53
|
trigger={
|
|
51
54
|
<Icon className="rule-form-popup" name="question circle outline" />
|
|
@@ -54,9 +57,9 @@ export const FieldLabelWrapping = ({
|
|
|
54
57
|
on="click"
|
|
55
58
|
hideOnScroll
|
|
56
59
|
/>
|
|
57
|
-
)}
|
|
58
|
-
{messages.map((msg,
|
|
59
|
-
<Label key={
|
|
60
|
+
) : null}
|
|
61
|
+
{messages.map((msg, key) => (
|
|
62
|
+
<Label key={key} pointing="left">
|
|
60
63
|
{msg}
|
|
61
64
|
</Label>
|
|
62
65
|
))}
|
|
@@ -88,11 +91,12 @@ export class RuleForm extends React.Component {
|
|
|
88
91
|
type_params: {},
|
|
89
92
|
df_name: "",
|
|
90
93
|
df_content: {},
|
|
94
|
+
template: null,
|
|
95
|
+
templatesLoading: true,
|
|
91
96
|
};
|
|
92
97
|
|
|
93
98
|
componentDidMount() {
|
|
94
99
|
const { rule, concept, selectDomain } = this.props;
|
|
95
|
-
const isConceptPreselected = concept !== undefined;
|
|
96
100
|
const description = rule ? _.propOr({}, "description")(rule) : {};
|
|
97
101
|
if (rule) {
|
|
98
102
|
!_.isNil(rule.domain_id) && selectDomain({ id: rule.domain_id });
|
|
@@ -102,35 +106,45 @@ export class RuleForm extends React.Component {
|
|
|
102
106
|
name: rule?.current_business_concept_version?.name,
|
|
103
107
|
business_concept_id: rule.business_concept_id,
|
|
104
108
|
},
|
|
105
|
-
isConceptPreselected,
|
|
106
109
|
});
|
|
107
|
-
} else if (_.
|
|
110
|
+
} else if (!_.isEmpty(concept)) {
|
|
108
111
|
!_.isNil(concept.domain.id) && selectDomain({ id: concept.domain.id });
|
|
109
|
-
this.setState({
|
|
110
|
-
concept,
|
|
111
|
-
isConceptPreselected,
|
|
112
|
-
});
|
|
112
|
+
this.setState({ concept });
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
this.updateDescription(description);
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
updateRule = (rule) => {
|
|
119
|
+
this.setState({ ...rule });
|
|
120
|
+
};
|
|
121
121
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
122
|
+
handleTemplateChange = (template) => {
|
|
123
|
+
const { domain_id, df_content } = this.state;
|
|
124
|
+
this.setState({
|
|
125
|
+
template,
|
|
126
|
+
df_name: template?.name || null,
|
|
127
|
+
df_content: template
|
|
128
|
+
? applyTemplate(template)(df_content, domain_id)
|
|
129
|
+
: null,
|
|
130
|
+
});
|
|
131
|
+
};
|
|
130
132
|
|
|
131
|
-
|
|
133
|
+
handleTemplatesLoaded = ({ templates }) => {
|
|
134
|
+
const name = this.props.rule?.df_name;
|
|
135
|
+
const template = name
|
|
136
|
+
? _.find(_.propEq("name", name))(templates)
|
|
137
|
+
: _.size(templates) == 1
|
|
138
|
+
? templates[0]
|
|
139
|
+
: null;
|
|
140
|
+
this.setState({ template, templatesLoading: false });
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
handleTemplateSelected = (e, { template }) => {
|
|
144
|
+
this.setState({ template });
|
|
145
|
+
};
|
|
132
146
|
|
|
133
|
-
|
|
147
|
+
handleContentChange = (df_content) => this.setState({ df_content });
|
|
134
148
|
|
|
135
149
|
messagesInformed = (messages) => _.some(_.negate(_.isNil))(messages);
|
|
136
150
|
|
|
@@ -165,49 +179,37 @@ export class RuleForm extends React.Component {
|
|
|
165
179
|
handleSubmit = (e) => {
|
|
166
180
|
e.preventDefault();
|
|
167
181
|
if (this.messagesInformed(this.generateValidationMessages())) return;
|
|
168
|
-
const {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const df_content = applyTemplate(rule?.df_content, rule?.domain_id);
|
|
182
|
+
const { onSubmit, match } = this.props;
|
|
183
|
+
// eslint-disable-next-line no-unused-vars
|
|
184
|
+
const { template, concept, templatesLoading, ...rule } = this.state;
|
|
185
|
+
const df_content = template
|
|
186
|
+
? applyTemplate(template)(rule?.df_content, rule?.domain_id)
|
|
187
|
+
: null;
|
|
175
188
|
|
|
176
|
-
|
|
177
|
-
rule: {
|
|
178
|
-
...rule,
|
|
179
|
-
df_name: template.name,
|
|
180
|
-
df_content,
|
|
181
|
-
},
|
|
189
|
+
onSubmit({
|
|
190
|
+
rule: { ...rule, df_content },
|
|
182
191
|
ids: match.params,
|
|
183
192
|
});
|
|
184
193
|
};
|
|
185
194
|
|
|
186
|
-
withConceptId = (rule) => {
|
|
187
|
-
const business_concept_id = _.negate(_.isNil)(
|
|
188
|
-
_.path("concept.business_concept_id")(rule)
|
|
189
|
-
)
|
|
190
|
-
? _.path("concept.business_concept_id")(rule).toString()
|
|
191
|
-
: null;
|
|
192
|
-
return { ...rule, business_concept_id };
|
|
193
|
-
};
|
|
194
|
-
|
|
195
195
|
handleConceptSelected = (concept) => {
|
|
196
|
-
this.setState({
|
|
196
|
+
this.setState({
|
|
197
|
+
concept,
|
|
198
|
+
business_concept_id: concept?.business_concept_id || null,
|
|
199
|
+
});
|
|
197
200
|
concept && this.handleSelectionClick();
|
|
198
201
|
};
|
|
199
202
|
|
|
200
203
|
handleDomainSelected = (e, { value }) => {
|
|
201
204
|
const domain_id = value;
|
|
202
|
-
|
|
203
205
|
const { selectDomain, editMode } = this.props;
|
|
204
206
|
!_.isString(domain_id) && selectDomain({ id: domain_id });
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
207
|
+
|
|
208
|
+
this.setState(
|
|
209
|
+
editMode
|
|
210
|
+
? { concept: null, business_concept_id: null, domain_id }
|
|
211
|
+
: { domain_id }
|
|
212
|
+
);
|
|
211
213
|
};
|
|
212
214
|
|
|
213
215
|
handleSelectionClick = () => {
|
|
@@ -237,10 +239,9 @@ export class RuleForm extends React.Component {
|
|
|
237
239
|
render() {
|
|
238
240
|
const {
|
|
239
241
|
isSubmitting,
|
|
240
|
-
templatesLoaded,
|
|
241
242
|
intl: { formatMessage },
|
|
242
243
|
} = this.props;
|
|
243
|
-
const rule = this.state;
|
|
244
|
+
const { template, ...rule } = this.state;
|
|
244
245
|
const { domain_id } = rule;
|
|
245
246
|
const { concept, domainOptions } = this.props;
|
|
246
247
|
const messages = this.generateValidationMessages();
|
|
@@ -270,6 +271,7 @@ export class RuleForm extends React.Component {
|
|
|
270
271
|
required
|
|
271
272
|
>
|
|
272
273
|
<Form.Input
|
|
274
|
+
aria-label={formatMessage({ id: "rule.props.name.placeholder" })}
|
|
273
275
|
name="name"
|
|
274
276
|
onChange={this.handleChange}
|
|
275
277
|
value={rule.name}
|
|
@@ -288,30 +290,30 @@ export class RuleForm extends React.Component {
|
|
|
288
290
|
onChange={this.handleEditorChange}
|
|
289
291
|
/>
|
|
290
292
|
)}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
293
|
+
</FieldLabelWrapping>
|
|
294
|
+
<FieldLabelWrapping
|
|
295
|
+
label={formatMessage({ id: "domain.selector.label" })}
|
|
296
|
+
messages={_.prop("domain")(messages)}
|
|
297
|
+
required
|
|
298
|
+
>
|
|
299
|
+
<DomainDropdownSelector
|
|
300
|
+
name="domain"
|
|
301
|
+
domainOptions={
|
|
302
|
+
domainOptions
|
|
303
|
+
? getDomainSelectorOptions({ domains: domainOptions })
|
|
304
|
+
: null
|
|
305
|
+
}
|
|
306
|
+
hideLabel
|
|
307
|
+
invalid={!_.isFinite(this.state.domain_id)}
|
|
308
|
+
onChange={this.handleDomainSelected}
|
|
309
|
+
value={this.state.domain_id}
|
|
310
|
+
/>
|
|
309
311
|
</FieldLabelWrapping>
|
|
310
312
|
{_.isEmpty(concept) && (
|
|
311
313
|
<Segment disabled={_.isNil(domain_id)}>
|
|
312
314
|
<Form.Group inline>
|
|
313
315
|
<label className="rule-form-label">
|
|
314
|
-
|
|
316
|
+
<FormattedMessage id="rule.form.concept.label" />
|
|
315
317
|
</label>
|
|
316
318
|
{_.path("concept.name")(rule) && (
|
|
317
319
|
<Label size={"medium"}>
|
|
@@ -329,34 +331,37 @@ export class RuleForm extends React.Component {
|
|
|
329
331
|
|
|
330
332
|
<Accordion>
|
|
331
333
|
<Accordion.Title
|
|
332
|
-
active={rule.activeSelection &&
|
|
334
|
+
active={rule.activeSelection && !!domain_id}
|
|
333
335
|
onClick={this.handleSelectionClick}
|
|
334
336
|
>
|
|
335
337
|
<Icon name="dropdown" />
|
|
336
|
-
|
|
338
|
+
<FormattedMessage id="rule.form.accordion.select" />
|
|
337
339
|
</Accordion.Title>
|
|
338
|
-
<Accordion.Content
|
|
339
|
-
active={rule.activeSelection && !_.isNil(domain_id)}
|
|
340
|
-
>
|
|
340
|
+
<Accordion.Content active={rule.activeSelection && !!domain_id}>
|
|
341
341
|
<ConceptSelector
|
|
342
342
|
showTitle={false}
|
|
343
343
|
defaultFilters={defaultFilters}
|
|
344
344
|
handleConceptSelected={this.handleConceptSelected}
|
|
345
|
-
businessConceptId={
|
|
346
|
-
rule
|
|
347
|
-
)}
|
|
345
|
+
businessConceptId={rule?.concept?.business_concept_id}
|
|
348
346
|
/>
|
|
349
347
|
</Accordion.Content>
|
|
350
348
|
</Accordion>
|
|
351
349
|
</Segment>
|
|
352
350
|
)}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
351
|
+
<TemplateSelector
|
|
352
|
+
scope="dq"
|
|
353
|
+
selectedValue={template?.id}
|
|
354
|
+
onChange={this.handleTemplateSelected}
|
|
355
|
+
onLoad={this.handleTemplatesLoaded}
|
|
356
|
+
required
|
|
357
|
+
/>
|
|
358
|
+
{template ? (
|
|
359
|
+
<DynamicForm
|
|
360
|
+
onChange={this.handleContentChange}
|
|
361
|
+
content={rule.df_content}
|
|
362
|
+
template={template}
|
|
358
363
|
/>
|
|
359
|
-
)}
|
|
364
|
+
) : null}
|
|
360
365
|
<div className="actions">
|
|
361
366
|
<HistoryBackButton
|
|
362
367
|
content={formatMessage({ id: "actions.cancel" })}
|
|
@@ -385,25 +390,19 @@ export class RuleForm extends React.Component {
|
|
|
385
390
|
|
|
386
391
|
RuleForm.propTypes = {
|
|
387
392
|
concept: PropTypes.object,
|
|
388
|
-
|
|
389
|
-
handleSubmit: PropTypes.func.isRequired,
|
|
393
|
+
domainOptions: PropTypes.array,
|
|
390
394
|
editMode: PropTypes.bool,
|
|
395
|
+
intl: PropTypes.object,
|
|
391
396
|
isSubmitting: PropTypes.bool,
|
|
392
|
-
|
|
397
|
+
match: PropTypes.object,
|
|
398
|
+
onSubmit: PropTypes.func.isRequired,
|
|
393
399
|
rule: PropTypes.object,
|
|
394
400
|
selectDomain: PropTypes.func,
|
|
395
|
-
template: PropTypes.object,
|
|
396
|
-
match: PropTypes.object,
|
|
397
|
-
intl: PropTypes.object,
|
|
398
|
-
domainOptions: PropTypes.array,
|
|
399
401
|
};
|
|
400
402
|
|
|
401
403
|
const mapStateToProps = (state) => ({
|
|
402
404
|
isSubmitting: state.ruleCreating || state.ruleUpdating,
|
|
403
405
|
concept: state.concept,
|
|
404
|
-
templatesLoaded: !state.templatesLoading && !_.isEmpty(state.templates),
|
|
405
|
-
template: state.template,
|
|
406
|
-
applyTemplate: applyTemplate(state.template),
|
|
407
406
|
domainOptions: _.pathOr(null, "conceptRulesActions.domain_ids")(state),
|
|
408
407
|
});
|
|
409
408
|
|
|
@@ -8,9 +8,10 @@ import { Header, Label, Menu, Grid, Icon } from "semantic-ui-react";
|
|
|
8
8
|
import { ConfirmModal, GroupActions } from "@truedat/core/components";
|
|
9
9
|
import { useAuthorized } from "@truedat/core/hooks";
|
|
10
10
|
import { linkTo } from "@truedat/core/routes";
|
|
11
|
-
import { setRuleImplementationStatus } from "../routines";
|
|
11
|
+
import { createExecutionGroup, setRuleImplementationStatus } from "../routines";
|
|
12
12
|
import RuleImplementationTabs from "./RuleImplementationTabs";
|
|
13
13
|
import ImplementationResultBar from "./ImplementationResultBar";
|
|
14
|
+
import ExecutionPopup from "./ExecutionPopup";
|
|
14
15
|
|
|
15
16
|
const getAvailableActions = (props, formatMessage) => {
|
|
16
17
|
const contentActions = _.isEmpty(props?.ruleImplementation)
|
|
@@ -73,7 +74,7 @@ const getAvailableActions = (props, formatMessage) => {
|
|
|
73
74
|
to: linkTo.IMPLEMENTATION_EDIT({
|
|
74
75
|
implementation_id: _.path("ruleImplementation.id")(props),
|
|
75
76
|
}),
|
|
76
|
-
filter: props.
|
|
77
|
+
filter: props.canEdit,
|
|
77
78
|
selected: false,
|
|
78
79
|
active: false,
|
|
79
80
|
},
|
|
@@ -157,10 +158,12 @@ OptionModal.propTypes = {
|
|
|
157
158
|
|
|
158
159
|
export const RuleImplementation = ({
|
|
159
160
|
children,
|
|
161
|
+
createExecutionGroup,
|
|
162
|
+
canExecute,
|
|
160
163
|
setRuleImplementationStatus,
|
|
161
164
|
ruleImplementation,
|
|
162
|
-
|
|
163
|
-
|
|
165
|
+
canEdit,
|
|
166
|
+
canManage,
|
|
164
167
|
}) => {
|
|
165
168
|
const authorized = useAuthorized();
|
|
166
169
|
const { formatMessage } = useIntl();
|
|
@@ -172,10 +175,16 @@ export const RuleImplementation = ({
|
|
|
172
175
|
authorized,
|
|
173
176
|
ruleImplementation,
|
|
174
177
|
setRuleImplementationStatus,
|
|
175
|
-
|
|
178
|
+
canEdit,
|
|
176
179
|
},
|
|
177
180
|
formatMessage
|
|
178
181
|
);
|
|
182
|
+
|
|
183
|
+
const handleSubmit = (df_content) => {
|
|
184
|
+
const query = { filters: { id: [ruleImplementation?.id] } };
|
|
185
|
+
createExecutionGroup({ ...query, df_content });
|
|
186
|
+
};
|
|
187
|
+
|
|
179
188
|
return (
|
|
180
189
|
<>
|
|
181
190
|
<Grid>
|
|
@@ -190,6 +199,9 @@ export const RuleImplementation = ({
|
|
|
190
199
|
</Grid.Column>
|
|
191
200
|
<Grid.Column width={8} textAlign="right">
|
|
192
201
|
<>
|
|
202
|
+
{canExecute && ruleImplementation.executable ? (
|
|
203
|
+
<ExecutionPopup onSubmit={handleSubmit} count={1} />
|
|
204
|
+
) : null}
|
|
193
205
|
{deletedAt && (
|
|
194
206
|
<Label
|
|
195
207
|
className="alert warning"
|
|
@@ -199,7 +211,7 @@ export const RuleImplementation = ({
|
|
|
199
211
|
icon={{ name: "warning circle", color: "red" }}
|
|
200
212
|
/>
|
|
201
213
|
)}
|
|
202
|
-
{
|
|
214
|
+
{canManage && !_.isEmpty(availableActions) && (
|
|
203
215
|
<GroupActions availableActions={availableActions} />
|
|
204
216
|
)}
|
|
205
217
|
</>
|
|
@@ -212,20 +224,24 @@ export const RuleImplementation = ({
|
|
|
212
224
|
};
|
|
213
225
|
|
|
214
226
|
RuleImplementation.propTypes = {
|
|
227
|
+
createExecutionGroup: PropTypes.func,
|
|
228
|
+
canExecute: PropTypes.bool,
|
|
215
229
|
ruleImplementation: PropTypes.object.isRequired,
|
|
216
230
|
setRuleImplementationStatus: PropTypes.func,
|
|
217
231
|
ruleImplementation: PropTypes.object,
|
|
218
|
-
|
|
219
|
-
|
|
232
|
+
canEdit: PropTypes.bool,
|
|
233
|
+
canManage: PropTypes.bool,
|
|
220
234
|
children: PropTypes.node,
|
|
221
235
|
};
|
|
222
236
|
|
|
223
237
|
const mapStateToProps = ({ ruleImplementation, implementationActions }) => ({
|
|
224
238
|
ruleImplementation,
|
|
225
|
-
|
|
226
|
-
|
|
239
|
+
canExecute: !!implementationActions?.execute,
|
|
240
|
+
canEdit: !!implementationActions?.edit,
|
|
241
|
+
canManage: !!implementationActions?.manage,
|
|
227
242
|
});
|
|
228
243
|
|
|
229
|
-
export default connect(mapStateToProps, {
|
|
230
|
-
|
|
231
|
-
|
|
244
|
+
export default connect(mapStateToProps, {
|
|
245
|
+
createExecutionGroup,
|
|
246
|
+
setRuleImplementationStatus,
|
|
247
|
+
})(RuleImplementation);
|
|
@@ -1,34 +1,31 @@
|
|
|
1
|
-
import _ from "lodash/fp";
|
|
2
1
|
import React from "react";
|
|
3
2
|
import PropTypes from "prop-types";
|
|
4
|
-
import {
|
|
3
|
+
import { useIntl } from "react-intl";
|
|
5
4
|
import { connect } from "react-redux";
|
|
6
5
|
import { Link, useParams } from "react-router-dom";
|
|
7
6
|
import { Button } from "semantic-ui-react";
|
|
8
7
|
import { linkTo } from "@truedat/core/routes";
|
|
9
8
|
|
|
10
|
-
const RuleImplementationActions = ({
|
|
11
|
-
|
|
12
|
-
manageRawRuleImplementationAction,
|
|
13
|
-
}) => {
|
|
9
|
+
const RuleImplementationActions = ({ canCreate, canCreateRaw }) => {
|
|
10
|
+
const { formatMessage } = useIntl();
|
|
14
11
|
const params = useParams();
|
|
15
12
|
return (
|
|
16
13
|
<>
|
|
17
|
-
{
|
|
14
|
+
{canCreateRaw && (
|
|
18
15
|
<Button
|
|
19
16
|
as={Link}
|
|
20
17
|
to={linkTo.RULE_IMPLEMENTATION_NEW_RAW(params)}
|
|
21
18
|
className="primary_action"
|
|
22
|
-
content={
|
|
19
|
+
content={formatMessage({ id: "quality.rule.actions.create_raw" })}
|
|
23
20
|
/>
|
|
24
21
|
)}
|
|
25
|
-
{
|
|
22
|
+
{canCreate && (
|
|
26
23
|
<Button
|
|
27
24
|
primary
|
|
28
25
|
as={Link}
|
|
29
26
|
to={linkTo.RULE_IMPLEMENTATION_NEW(params)}
|
|
30
27
|
className="primary_action"
|
|
31
|
-
content={
|
|
28
|
+
content={formatMessage({ id: "quality.rule.actions.create" })}
|
|
32
29
|
/>
|
|
33
30
|
)}
|
|
34
31
|
</>
|
|
@@ -36,20 +33,13 @@ const RuleImplementationActions = ({
|
|
|
36
33
|
};
|
|
37
34
|
|
|
38
35
|
RuleImplementationActions.propTypes = {
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
canCreate: PropTypes.bool,
|
|
37
|
+
canCreateRaw: PropTypes.bool,
|
|
41
38
|
};
|
|
42
39
|
|
|
43
40
|
const mapStateToProps = ({ userRulePermissions }) => ({
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
false,
|
|
47
|
-
"manage_quality_rule_implementations"
|
|
48
|
-
)(userRulePermissions),
|
|
49
|
-
manageRawRuleImplementationAction: _.propOr(
|
|
50
|
-
false,
|
|
51
|
-
"manage_raw_quality_rule_implementations"
|
|
52
|
-
)(userRulePermissions),
|
|
41
|
+
canCreate: !!userRulePermissions?.manage_quality_rule_implementations,
|
|
42
|
+
canCreateRaw: !!userRulePermissions?.manage_raw_quality_rule_implementations,
|
|
53
43
|
});
|
|
54
44
|
|
|
55
45
|
export default connect(mapStateToProps)(RuleImplementationActions);
|