@truedat/dq 4.49.5 → 4.49.6
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 +6 -0
- package/package.json +4 -4
- package/src/components/NewRuleImplementation.js +9 -4
- package/src/components/RuleRoutes.js +4 -4
- package/src/components/__tests__/NewRuleImplementation.spec.js +52 -5
- package/src/components/__tests__/__fixtures__/NewRuleImplementationProps.js +7 -0
- package/src/components/__tests__/__fixtures__/newRuleImplementationHelper.js +0 -1
- package/src/components/__tests__/__snapshots__/NewRuleImplementation.spec.js.snap +83 -115
- package/src/components/ruleImplementationForm/InformationForm.js +38 -15
- package/src/components/ruleImplementationForm/RuleImplementationForm.js +297 -206
- package/src/components/ruleImplementationForm/RuleImplementationRawForm.js +64 -22
- package/src/components/ruleImplementationForm/__tests__/InformationForm.spec.js +59 -0
- package/src/components/ruleImplementationForm/__tests__/RuleImplementationForm.spec.js +19 -2
- package/src/components/ruleImplementationForm/__tests__/RuleImplementationRawForm.spec.js +17 -2
- package/src/components/ruleImplementationForm/__tests__/__snapshots__/InformationForm.spec.js.snap +260 -0
- package/src/components/ruleImplementationForm/__tests__/__snapshots__/RuleImplementationForm.spec.js.snap +46 -39
- package/src/components/ruleImplementationForm/__tests__/__snapshots__/RuleImplementationRawForm.spec.js.snap +8 -75
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import React, { useState } from "react";
|
|
2
|
+
import React, { useState, useEffect } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import { connect } from "react-redux";
|
|
5
5
|
import { useHistory } from "react-router-dom";
|
|
@@ -8,6 +8,8 @@ import { gql, useQuery } from "@apollo/client";
|
|
|
8
8
|
import { Loading } from "@truedat/core/components";
|
|
9
9
|
import { Button, Form, Icon, Popup } from "semantic-ui-react";
|
|
10
10
|
import { accentInsensitivePathOrder } from "@truedat/core/services/sort";
|
|
11
|
+
import { DomainSelector } from "@truedat/core/components";
|
|
12
|
+
import { DOMAIN_QUERY } from "@truedat/core/api/queries";
|
|
11
13
|
import LimitsForm from "./LimitsForm";
|
|
12
14
|
import { areLimitsValid } from "./limitsValidation";
|
|
13
15
|
|
|
@@ -15,9 +17,14 @@ const SelectableDynamicForm = React.lazy(() =>
|
|
|
15
17
|
import("@truedat/df/components/SelectableDynamicForm")
|
|
16
18
|
);
|
|
17
19
|
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
const DomainActionsLoader = ({ id, actions, onLoad }) => {
|
|
21
|
+
useQuery(DOMAIN_QUERY, {
|
|
22
|
+
fetchPolicy: "cache-and-network",
|
|
23
|
+
variables: { id, actions },
|
|
24
|
+
onCompleted: onLoad,
|
|
25
|
+
});
|
|
26
|
+
return null;
|
|
27
|
+
};
|
|
21
28
|
|
|
22
29
|
const Help = ({ message }) => {
|
|
23
30
|
const { formatMessage } = useIntl();
|
|
@@ -38,7 +45,6 @@ Help.propTypes = {
|
|
|
38
45
|
};
|
|
39
46
|
|
|
40
47
|
export const RuleImplementationRawForm = ({
|
|
41
|
-
actions,
|
|
42
48
|
implementationKey,
|
|
43
49
|
isSubmitting,
|
|
44
50
|
onChange,
|
|
@@ -51,10 +57,30 @@ export const RuleImplementationRawForm = ({
|
|
|
51
57
|
sources,
|
|
52
58
|
sourcesLoading,
|
|
53
59
|
}) => {
|
|
60
|
+
const domainActions = ["publishImplementation"];
|
|
54
61
|
const { formatMessage } = useIntl();
|
|
55
62
|
const history = useHistory();
|
|
56
63
|
const [isContentValid, setIsContentValid] = useState();
|
|
57
64
|
|
|
65
|
+
const [domains, setDomains] = useState();
|
|
66
|
+
const [canPublish, setCanPublish] = useState(false);
|
|
67
|
+
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
const currentDomainActions = _.flow(
|
|
70
|
+
_.find((domain) => domain.id === String(ruleImplementation.domain_id)),
|
|
71
|
+
_.pathOr([], "actions")
|
|
72
|
+
)(domains);
|
|
73
|
+
|
|
74
|
+
_.flow(
|
|
75
|
+
_.any((action) => action == "publishImplementation"),
|
|
76
|
+
setCanPublish
|
|
77
|
+
)(currentDomainActions);
|
|
78
|
+
|
|
79
|
+
return () => {
|
|
80
|
+
setCanPublish(false);
|
|
81
|
+
};
|
|
82
|
+
}, [domains, ruleImplementation.domain_id]);
|
|
83
|
+
|
|
58
84
|
const handleContentChange = ({ content, valid }) => {
|
|
59
85
|
onChange("dfContent", content);
|
|
60
86
|
setIsContentValid(_.isEmpty(valid));
|
|
@@ -68,10 +94,9 @@ export const RuleImplementationRawForm = ({
|
|
|
68
94
|
const hasNoErrors = (propName) =>
|
|
69
95
|
_.path([propName, "hasErrors"])(errors) == false;
|
|
70
96
|
|
|
71
|
-
const doSubmit = () => {
|
|
97
|
+
const doSubmit = (params) => {
|
|
72
98
|
if (isValidForm()) {
|
|
73
|
-
|
|
74
|
-
onSubmit(canPublish ? { status: "published" } : {});
|
|
99
|
+
onSubmit(params);
|
|
75
100
|
}
|
|
76
101
|
};
|
|
77
102
|
|
|
@@ -113,7 +138,7 @@ export const RuleImplementationRawForm = ({
|
|
|
113
138
|
ruleImplementation?.dfName &&
|
|
114
139
|
!_.isEmpty(ruleImplementation?.dfName) &&
|
|
115
140
|
isContentValid &&
|
|
116
|
-
(!_.isEmpty(rule) || _.
|
|
141
|
+
(!_.isEmpty(rule) || _.prop("domain_id")(ruleImplementation)) &&
|
|
117
142
|
areLimitsValid(ruleImplementation);
|
|
118
143
|
|
|
119
144
|
const isValidForm = () =>
|
|
@@ -147,7 +172,6 @@ export const RuleImplementationRawForm = ({
|
|
|
147
172
|
|
|
148
173
|
const doCancel = () => history.goBack();
|
|
149
174
|
const errors = getErrors();
|
|
150
|
-
|
|
151
175
|
const domainId = ruleImplementation?.domain_id || rule?.domain_id;
|
|
152
176
|
return (
|
|
153
177
|
<Form className="rule">
|
|
@@ -175,13 +199,26 @@ export const RuleImplementationRawForm = ({
|
|
|
175
199
|
disabled={ruleImplementation?.status === "published"}
|
|
176
200
|
/>
|
|
177
201
|
</Form.Field>
|
|
178
|
-
{_.isEmpty(rule) && !ruleImplementation?.rule_id
|
|
202
|
+
{_.isEmpty(rule) && !ruleImplementation?.rule_id ? (
|
|
179
203
|
<Form.Field>
|
|
180
|
-
<
|
|
181
|
-
|
|
204
|
+
<DomainSelector
|
|
205
|
+
action={
|
|
206
|
+
ruleImplementation.rule_id
|
|
207
|
+
? "manageRawImplementations"
|
|
208
|
+
: "manageRawRulelessImplementations"
|
|
209
|
+
}
|
|
210
|
+
value={ruleImplementation.domain_id}
|
|
211
|
+
domainActions={domainActions}
|
|
212
|
+
onLoad={(data) => setDomains(data.domains)}
|
|
182
213
|
onChange={(_e, { value }) => onChange("domain_id", value)}
|
|
183
214
|
/>
|
|
184
215
|
</Form.Field>
|
|
216
|
+
) : (
|
|
217
|
+
<DomainActionsLoader
|
|
218
|
+
id={domainId}
|
|
219
|
+
actions={domainActions}
|
|
220
|
+
onLoad={(data) => setDomains([data.domain])}
|
|
221
|
+
/>
|
|
185
222
|
)}
|
|
186
223
|
<LimitsForm onChange={onChange} ruleImplementation={ruleImplementation} />
|
|
187
224
|
<SelectableDynamicForm
|
|
@@ -303,13 +340,24 @@ export const RuleImplementationRawForm = ({
|
|
|
303
340
|
size="small"
|
|
304
341
|
value={_.prop("validations")(rawContent) || ""}
|
|
305
342
|
/>
|
|
306
|
-
|
|
343
|
+
{canPublish ? (
|
|
344
|
+
<Button
|
|
345
|
+
floated="right"
|
|
346
|
+
disabled={!isValidForm()}
|
|
347
|
+
type="submit"
|
|
348
|
+
primary
|
|
349
|
+
loading={isSubmitting}
|
|
350
|
+
onClick={() => doSubmit({ status: "published" })}
|
|
351
|
+
content={formatMessage({ id: "actions.publish" })}
|
|
352
|
+
/>
|
|
353
|
+
) : null}
|
|
354
|
+
<Button
|
|
307
355
|
floated="right"
|
|
308
356
|
disabled={!isValidForm()}
|
|
309
357
|
type="submit"
|
|
310
358
|
primary
|
|
311
359
|
loading={isSubmitting}
|
|
312
|
-
onClick={() => doSubmit()}
|
|
360
|
+
onClick={() => doSubmit({ status: "draft" })}
|
|
313
361
|
content={formatMessage({ id: "actions.save" })}
|
|
314
362
|
/>
|
|
315
363
|
<Button
|
|
@@ -323,7 +371,6 @@ export const RuleImplementationRawForm = ({
|
|
|
323
371
|
};
|
|
324
372
|
|
|
325
373
|
RuleImplementationRawForm.propTypes = {
|
|
326
|
-
actions: PropTypes.object,
|
|
327
374
|
implementationKey: PropTypes.string,
|
|
328
375
|
isSubmitting: PropTypes.bool,
|
|
329
376
|
onChange: PropTypes.func,
|
|
@@ -363,12 +410,7 @@ export const RuleImplementationRawFormLoader = (props) => {
|
|
|
363
410
|
);
|
|
364
411
|
};
|
|
365
412
|
|
|
366
|
-
const mapStateToProps = ({
|
|
367
|
-
implementationActions,
|
|
368
|
-
rule,
|
|
369
|
-
ruleImplementationCreating,
|
|
370
|
-
}) => ({
|
|
371
|
-
actions: implementationActions,
|
|
413
|
+
const mapStateToProps = ({ rule, ruleImplementationCreating }) => ({
|
|
372
414
|
isSubmitting: ruleImplementationCreating,
|
|
373
415
|
rule,
|
|
374
416
|
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { waitFor } from "@testing-library/react";
|
|
3
|
+
import { render } from "@truedat/test/render";
|
|
4
|
+
import { DOMAINS_QUERY } from "@truedat/core/api/queries";
|
|
5
|
+
import InformationForm from "../InformationForm";
|
|
6
|
+
|
|
7
|
+
const domains = [
|
|
8
|
+
{
|
|
9
|
+
id: "123",
|
|
10
|
+
name: "foo",
|
|
11
|
+
parentId: "",
|
|
12
|
+
actions: ["publishImplementation", "manageSegments"],
|
|
13
|
+
},
|
|
14
|
+
];
|
|
15
|
+
const requestVariables = {
|
|
16
|
+
action: "manageRulelessImplementations",
|
|
17
|
+
domainActions: ["publishImplementation", "manageSegments"],
|
|
18
|
+
};
|
|
19
|
+
const domainsMock = {
|
|
20
|
+
request: { query: DOMAINS_QUERY, variables: requestVariables },
|
|
21
|
+
result: { data: { domains: domains } },
|
|
22
|
+
};
|
|
23
|
+
const renderOpts = {
|
|
24
|
+
mocks: [domainsMock],
|
|
25
|
+
state: {
|
|
26
|
+
rule: {},
|
|
27
|
+
ruleImplementationCreating: true,
|
|
28
|
+
},
|
|
29
|
+
fallback: "lazy",
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
describe("<RuleImplementationForm />", () => {
|
|
33
|
+
const props = {
|
|
34
|
+
setImplementationKey: jest.fn(),
|
|
35
|
+
onChange: jest.fn(),
|
|
36
|
+
setIsValid: jest.fn(),
|
|
37
|
+
onDomainsLoad: jest.fn(),
|
|
38
|
+
ruleImplementation: {
|
|
39
|
+
implementationKey: "foo",
|
|
40
|
+
executable: true,
|
|
41
|
+
result_type: "percentage",
|
|
42
|
+
goal: 20,
|
|
43
|
+
minimum: 10,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
it("matches the latest snapshot", async () => {
|
|
48
|
+
const { container, queryByText } = render(
|
|
49
|
+
<InformationForm {...props} />,
|
|
50
|
+
renderOpts
|
|
51
|
+
);
|
|
52
|
+
await waitFor(() => expect(queryByText(/lazy/i)).not.toBeInTheDocument());
|
|
53
|
+
await waitFor(() =>
|
|
54
|
+
expect(queryByText(/loading/i)).not.toBeInTheDocument()
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
expect(container).toMatchSnapshot();
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -2,13 +2,30 @@ import React from "react";
|
|
|
2
2
|
import { waitFor } from "@testing-library/react";
|
|
3
3
|
import { render } from "@truedat/test/render";
|
|
4
4
|
import { multipleTemplatesMock } from "@truedat/test/mocks";
|
|
5
|
+
import { DOMAINS_QUERY } from "@truedat/core/api/queries";
|
|
5
6
|
import RuleImplementationForm from "../RuleImplementationForm";
|
|
6
7
|
|
|
8
|
+
const domains = [
|
|
9
|
+
{
|
|
10
|
+
id: "123",
|
|
11
|
+
name: "foo",
|
|
12
|
+
parentId: "",
|
|
13
|
+
actions: ["publishImplementation", "manageSegments"],
|
|
14
|
+
},
|
|
15
|
+
];
|
|
16
|
+
const requestVariables = {
|
|
17
|
+
action: "manageRulelessImplementations",
|
|
18
|
+
domainActions: ["publishImplementation", "manageSegments"],
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const domainsMock = {
|
|
22
|
+
request: { query: DOMAINS_QUERY, variables: requestVariables },
|
|
23
|
+
result: { data: { domains: domains } },
|
|
24
|
+
};
|
|
7
25
|
const renderOpts = {
|
|
8
|
-
mocks: [multipleTemplatesMock({ scope: "ri", domainIds: null })],
|
|
26
|
+
mocks: [multipleTemplatesMock({ scope: "ri", domainIds: null }), domainsMock],
|
|
9
27
|
state: {
|
|
10
28
|
rule: {},
|
|
11
|
-
implementationActions: { manage_segments: {} },
|
|
12
29
|
ruleImplementationCreating: true,
|
|
13
30
|
},
|
|
14
31
|
fallback: "lazy",
|
|
@@ -3,17 +3,32 @@ import React from "react";
|
|
|
3
3
|
import { waitFor } from "@testing-library/react";
|
|
4
4
|
import userEvent from "@testing-library/user-event";
|
|
5
5
|
import { render } from "@truedat/test/render";
|
|
6
|
+
import { DOMAIN_QUERY, DOMAINS_QUERY } from "@truedat/core/api/queries";
|
|
6
7
|
import { multipleTemplatesMock } from "@truedat/test/mocks";
|
|
7
8
|
import { RuleImplementationRawForm } from "../RuleImplementationRawForm";
|
|
8
9
|
|
|
9
10
|
jest.setTimeout(30000);
|
|
10
11
|
|
|
12
|
+
const domains = [{ id: 1, name: "domain1", actions: [] }];
|
|
13
|
+
const domainsMock = {
|
|
14
|
+
request: { query: DOMAINS_QUERY },
|
|
15
|
+
result: { data: { domains: domains } },
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const domainMock = {
|
|
19
|
+
request: { query: DOMAIN_QUERY },
|
|
20
|
+
result: { data: { domain: domains } },
|
|
21
|
+
};
|
|
22
|
+
|
|
11
23
|
const renderOpts = {
|
|
12
|
-
mocks: [
|
|
24
|
+
mocks: [
|
|
25
|
+
multipleTemplatesMock({ scope: "ri", domainIds: [1] }),
|
|
26
|
+
domainMock,
|
|
27
|
+
domainsMock,
|
|
28
|
+
],
|
|
13
29
|
state: {
|
|
14
30
|
rule: { domain_id: 1 },
|
|
15
31
|
ruleImplementationCreating: false,
|
|
16
|
-
domains: [{ id: 1, name: "domain1" }],
|
|
17
32
|
},
|
|
18
33
|
fallback: "lazy",
|
|
19
34
|
};
|
package/src/components/ruleImplementationForm/__tests__/__snapshots__/InformationForm.spec.js.snap
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<RuleImplementationForm /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="field"
|
|
7
|
+
style=""
|
|
8
|
+
>
|
|
9
|
+
<div
|
|
10
|
+
class="ui checked toggle checkbox"
|
|
11
|
+
>
|
|
12
|
+
<input
|
|
13
|
+
checked=""
|
|
14
|
+
class="hidden"
|
|
15
|
+
name="executable"
|
|
16
|
+
readonly=""
|
|
17
|
+
tabindex="0"
|
|
18
|
+
type="radio"
|
|
19
|
+
value=""
|
|
20
|
+
/>
|
|
21
|
+
<label>
|
|
22
|
+
Executable
|
|
23
|
+
</label>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
<div
|
|
27
|
+
class="field"
|
|
28
|
+
style=""
|
|
29
|
+
>
|
|
30
|
+
<label>
|
|
31
|
+
Implementation Key
|
|
32
|
+
<i
|
|
33
|
+
aria-hidden="true"
|
|
34
|
+
class="question circle outline icon rule-form-popup"
|
|
35
|
+
/>
|
|
36
|
+
</label>
|
|
37
|
+
<div
|
|
38
|
+
class="field"
|
|
39
|
+
>
|
|
40
|
+
<div
|
|
41
|
+
class="ui input"
|
|
42
|
+
>
|
|
43
|
+
<input
|
|
44
|
+
autocomplete="off"
|
|
45
|
+
name="implementation_key"
|
|
46
|
+
placeholder="Rule Implementation Key"
|
|
47
|
+
type="text"
|
|
48
|
+
value="foo"
|
|
49
|
+
/>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
<div
|
|
54
|
+
class="required field"
|
|
55
|
+
style=""
|
|
56
|
+
>
|
|
57
|
+
<label>
|
|
58
|
+
Domain
|
|
59
|
+
</label>
|
|
60
|
+
<div
|
|
61
|
+
class="field"
|
|
62
|
+
>
|
|
63
|
+
<div
|
|
64
|
+
aria-expanded="false"
|
|
65
|
+
aria-multiselectable="false"
|
|
66
|
+
class="ui floating dropdown"
|
|
67
|
+
role="listbox"
|
|
68
|
+
tabindex="0"
|
|
69
|
+
>
|
|
70
|
+
<label>
|
|
71
|
+
Select a domain...
|
|
72
|
+
</label>
|
|
73
|
+
<i
|
|
74
|
+
aria-hidden="true"
|
|
75
|
+
class="dropdown icon"
|
|
76
|
+
/>
|
|
77
|
+
<div
|
|
78
|
+
class="menu transition"
|
|
79
|
+
>
|
|
80
|
+
<div
|
|
81
|
+
class="ui left icon input search"
|
|
82
|
+
>
|
|
83
|
+
<input
|
|
84
|
+
type="text"
|
|
85
|
+
/>
|
|
86
|
+
<i
|
|
87
|
+
aria-hidden="true"
|
|
88
|
+
class="search icon"
|
|
89
|
+
/>
|
|
90
|
+
</div>
|
|
91
|
+
<div
|
|
92
|
+
class="scrolling menu transition"
|
|
93
|
+
>
|
|
94
|
+
<div
|
|
95
|
+
aria-selected="false"
|
|
96
|
+
class="item"
|
|
97
|
+
role="option"
|
|
98
|
+
>
|
|
99
|
+
<div
|
|
100
|
+
style="margin-left: 0px;"
|
|
101
|
+
>
|
|
102
|
+
<i
|
|
103
|
+
aria-hidden="true"
|
|
104
|
+
class="icon"
|
|
105
|
+
/>
|
|
106
|
+
foo
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
<div
|
|
115
|
+
class="ui segment"
|
|
116
|
+
style=""
|
|
117
|
+
>
|
|
118
|
+
<div
|
|
119
|
+
class="field"
|
|
120
|
+
>
|
|
121
|
+
<label
|
|
122
|
+
class="rule-form-label"
|
|
123
|
+
>
|
|
124
|
+
Result Type
|
|
125
|
+
<span>
|
|
126
|
+
*
|
|
127
|
+
</span>
|
|
128
|
+
<i
|
|
129
|
+
aria-hidden="true"
|
|
130
|
+
class="question circle outline icon rule-form-popup"
|
|
131
|
+
/>
|
|
132
|
+
</label>
|
|
133
|
+
<div
|
|
134
|
+
class="inline fields"
|
|
135
|
+
>
|
|
136
|
+
<div
|
|
137
|
+
class="field"
|
|
138
|
+
>
|
|
139
|
+
<div
|
|
140
|
+
class="ui checked radio checkbox"
|
|
141
|
+
>
|
|
142
|
+
<input
|
|
143
|
+
checked=""
|
|
144
|
+
class="hidden"
|
|
145
|
+
name="result_type"
|
|
146
|
+
readonly=""
|
|
147
|
+
tabindex="0"
|
|
148
|
+
type="radio"
|
|
149
|
+
value="percentage"
|
|
150
|
+
/>
|
|
151
|
+
<label>
|
|
152
|
+
Percentage
|
|
153
|
+
</label>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
<div
|
|
157
|
+
class="field"
|
|
158
|
+
>
|
|
159
|
+
<div
|
|
160
|
+
class="ui radio checkbox"
|
|
161
|
+
>
|
|
162
|
+
<input
|
|
163
|
+
class="hidden"
|
|
164
|
+
name="result_type"
|
|
165
|
+
readonly=""
|
|
166
|
+
tabindex="0"
|
|
167
|
+
type="radio"
|
|
168
|
+
value="deviation"
|
|
169
|
+
/>
|
|
170
|
+
<label>
|
|
171
|
+
Deviation
|
|
172
|
+
</label>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
<div
|
|
176
|
+
class="field"
|
|
177
|
+
>
|
|
178
|
+
<div
|
|
179
|
+
class="ui radio checkbox"
|
|
180
|
+
>
|
|
181
|
+
<input
|
|
182
|
+
class="hidden"
|
|
183
|
+
name="result_type"
|
|
184
|
+
readonly=""
|
|
185
|
+
tabindex="0"
|
|
186
|
+
type="radio"
|
|
187
|
+
value="errors_number"
|
|
188
|
+
/>
|
|
189
|
+
<label>
|
|
190
|
+
Error count
|
|
191
|
+
</label>
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
<div
|
|
197
|
+
class="field"
|
|
198
|
+
>
|
|
199
|
+
<label
|
|
200
|
+
class="rule-form-label"
|
|
201
|
+
>
|
|
202
|
+
Threshold
|
|
203
|
+
<span>
|
|
204
|
+
*
|
|
205
|
+
</span>
|
|
206
|
+
<i
|
|
207
|
+
aria-hidden="true"
|
|
208
|
+
class="question circle outline icon rule-form-popup"
|
|
209
|
+
/>
|
|
210
|
+
</label>
|
|
211
|
+
<div
|
|
212
|
+
class="field"
|
|
213
|
+
>
|
|
214
|
+
<div
|
|
215
|
+
class="ui input"
|
|
216
|
+
>
|
|
217
|
+
<input
|
|
218
|
+
autocomplete="off"
|
|
219
|
+
name="minimum"
|
|
220
|
+
placeholder="Threshold value"
|
|
221
|
+
type="text"
|
|
222
|
+
value="10"
|
|
223
|
+
/>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
</div>
|
|
227
|
+
<div
|
|
228
|
+
class="field"
|
|
229
|
+
>
|
|
230
|
+
<label
|
|
231
|
+
class="rule-form-label"
|
|
232
|
+
>
|
|
233
|
+
Goal
|
|
234
|
+
<span>
|
|
235
|
+
*
|
|
236
|
+
</span>
|
|
237
|
+
<i
|
|
238
|
+
aria-hidden="true"
|
|
239
|
+
class="question circle outline icon rule-form-popup"
|
|
240
|
+
/>
|
|
241
|
+
</label>
|
|
242
|
+
<div
|
|
243
|
+
class="field"
|
|
244
|
+
>
|
|
245
|
+
<div
|
|
246
|
+
class="ui input"
|
|
247
|
+
>
|
|
248
|
+
<input
|
|
249
|
+
autocomplete="off"
|
|
250
|
+
name="goal"
|
|
251
|
+
placeholder="Goal value"
|
|
252
|
+
type="text"
|
|
253
|
+
value="20"
|
|
254
|
+
/>
|
|
255
|
+
</div>
|
|
256
|
+
</div>
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
</div>
|
|
260
|
+
`;
|