@truedat/dq 8.11.3 → 8.11.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/package.json +16 -16
- package/src/components/ExecutionForm.js +76 -75
- package/src/components/ExecutionPopup.js +27 -29
- package/src/components/ExecutionTemplateSelector.js +108 -0
- package/src/components/ExecutionWarning.js +36 -0
- package/src/components/ImplementationActions.js +4 -2
- package/src/components/RuleImplementation.js +2 -2
- package/src/components/Subscription.js +1 -1
- package/src/components/__tests__/ExecutionForm.spec.js +109 -15
- package/src/components/__tests__/ExecutionTemplateSelector.spec.js +168 -0
- package/src/components/__tests__/ExecutionWarning.spec.js +40 -0
- package/src/components/__tests__/RuleImplementation.spec.js +2 -2
- package/src/components/__tests__/__snapshots__/ExecutionForm.spec.js.snap +116 -72
- package/src/components/__tests__/__snapshots__/ExecutionPopup.spec.js.snap +8 -4
- package/src/components/__tests__/__snapshots__/ExecutionWarning.spec.js.snap +22 -0
- package/src/components/__tests__/__snapshots__/ImplementationActions.spec.js.snap +8 -4
- package/src/components/__tests__/__snapshots__/ImplementationSearchResults.spec.js.snap +18 -10
- package/src/components/__tests__/__snapshots__/RuleImplementation.spec.js.snap +79 -71
- package/src/components/__tests__/__snapshots__/RuleImplementationsActions.spec.js.snap +10 -6
- package/src/components/__tests__/__snapshots__/Subscription.spec.js.snap +1 -1
- package/src/styles/executionPopup.less +261 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import userEvent from "@testing-library/user-event";
|
|
2
|
+
import { render, waitForLoad } from "@truedat/test/render";
|
|
3
|
+
import { multipleTemplatesMock } from "@truedat/test/mocks";
|
|
4
|
+
import { ExecutionTemplateSelector } from "../ExecutionTemplateSelector";
|
|
5
|
+
|
|
6
|
+
const variables = { scope: "qe" };
|
|
7
|
+
const optionalTemplate = {
|
|
8
|
+
__typename: "Template",
|
|
9
|
+
id: "optional",
|
|
10
|
+
name: "optional",
|
|
11
|
+
scope: "qe",
|
|
12
|
+
label: "Optional template",
|
|
13
|
+
content: [
|
|
14
|
+
{
|
|
15
|
+
name: "additional_information",
|
|
16
|
+
fields: [{ name: "notes", label: "Notes" }],
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
};
|
|
20
|
+
const requiredTemplate = {
|
|
21
|
+
...optionalTemplate,
|
|
22
|
+
id: "required",
|
|
23
|
+
label: "Required template",
|
|
24
|
+
content: [
|
|
25
|
+
{
|
|
26
|
+
name: "additional_information",
|
|
27
|
+
fields: [
|
|
28
|
+
{ name: "notes", label: "Notes", type: "string", cardinality: "1" },
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const defaultProps = {
|
|
35
|
+
templates: [],
|
|
36
|
+
template: null,
|
|
37
|
+
content: {},
|
|
38
|
+
onTemplateSelected: jest.fn(),
|
|
39
|
+
onTemplatesLoaded: jest.fn(),
|
|
40
|
+
onContentChange: jest.fn(),
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const renderSelector = (
|
|
44
|
+
props = {},
|
|
45
|
+
mocks = [multipleTemplatesMock(variables)],
|
|
46
|
+
) =>
|
|
47
|
+
render(<ExecutionTemplateSelector {...defaultProps} {...props} />, { mocks });
|
|
48
|
+
|
|
49
|
+
describe("<ExecutionTemplateSelector />", () => {
|
|
50
|
+
describe("with multiple templates", () => {
|
|
51
|
+
it("shows the template selector label and combobox", async () => {
|
|
52
|
+
const rendered = renderSelector({
|
|
53
|
+
templates: [optionalTemplate, requiredTemplate],
|
|
54
|
+
});
|
|
55
|
+
await waitForLoad(rendered);
|
|
56
|
+
|
|
57
|
+
expect(rendered.getByText("Select template")).toBeInTheDocument();
|
|
58
|
+
expect(rendered.getByRole("combobox")).toBeInTheDocument();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("shows optional badge when selected template has no mandatory fields", async () => {
|
|
62
|
+
const rendered = renderSelector({
|
|
63
|
+
templates: [optionalTemplate, requiredTemplate],
|
|
64
|
+
template: optionalTemplate,
|
|
65
|
+
});
|
|
66
|
+
await waitForLoad(rendered);
|
|
67
|
+
|
|
68
|
+
expect(rendered.getByText("optional")).toHaveClass("optional-badge");
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("shows mandatory badge with pending state when required fields are not filled", async () => {
|
|
72
|
+
const rendered = renderSelector({
|
|
73
|
+
templates: [optionalTemplate, requiredTemplate],
|
|
74
|
+
template: requiredTemplate,
|
|
75
|
+
content: {},
|
|
76
|
+
});
|
|
77
|
+
await waitForLoad(rendered);
|
|
78
|
+
|
|
79
|
+
expect(rendered.getByText("Mandatory fields")).toHaveClass(
|
|
80
|
+
"mandatory-badge",
|
|
81
|
+
"pending",
|
|
82
|
+
);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe("with single template", () => {
|
|
87
|
+
it("hides the selector label", async () => {
|
|
88
|
+
const rendered = renderSelector({
|
|
89
|
+
templates: [optionalTemplate],
|
|
90
|
+
template: optionalTemplate,
|
|
91
|
+
});
|
|
92
|
+
await waitForLoad(rendered);
|
|
93
|
+
|
|
94
|
+
expect(rendered.queryByText("Select template")).not.toBeInTheDocument();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("shows single template label", async () => {
|
|
98
|
+
const rendered = renderSelector({
|
|
99
|
+
templates: [optionalTemplate],
|
|
100
|
+
template: optionalTemplate,
|
|
101
|
+
});
|
|
102
|
+
await waitForLoad(rendered);
|
|
103
|
+
|
|
104
|
+
expect(
|
|
105
|
+
rendered.getByText(
|
|
106
|
+
"Complete the template for additional information (optional)",
|
|
107
|
+
),
|
|
108
|
+
).toBeInTheDocument();
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe("dynamic form", () => {
|
|
113
|
+
it("shows the dynamic form when a template is selected", async () => {
|
|
114
|
+
const rendered = renderSelector({
|
|
115
|
+
templates: [optionalTemplate],
|
|
116
|
+
template: optionalTemplate,
|
|
117
|
+
});
|
|
118
|
+
await waitForLoad(rendered);
|
|
119
|
+
|
|
120
|
+
expect(rendered.getByText("Template fields")).toBeInTheDocument();
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it("hides the dynamic form when no template is selected", async () => {
|
|
124
|
+
const rendered = renderSelector({
|
|
125
|
+
templates: [optionalTemplate],
|
|
126
|
+
template: null,
|
|
127
|
+
});
|
|
128
|
+
await waitForLoad(rendered);
|
|
129
|
+
|
|
130
|
+
expect(rendered.queryByText("Template fields")).not.toBeInTheDocument();
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe("callbacks", () => {
|
|
135
|
+
it("calls onTemplateSelected when a template is selected", async () => {
|
|
136
|
+
const onTemplateSelected = jest.fn();
|
|
137
|
+
const rendered = renderSelector({
|
|
138
|
+
templates: [optionalTemplate, requiredTemplate],
|
|
139
|
+
onTemplateSelected,
|
|
140
|
+
});
|
|
141
|
+
await waitForLoad(rendered);
|
|
142
|
+
const user = userEvent.setup({ delay: null });
|
|
143
|
+
|
|
144
|
+
await user.click(rendered.getByRole("combobox"));
|
|
145
|
+
const options = rendered.getAllByRole("option");
|
|
146
|
+
await user.click(options[0]);
|
|
147
|
+
|
|
148
|
+
expect(onTemplateSelected).toHaveBeenCalled();
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("calls onContentChange when form content changes", async () => {
|
|
152
|
+
const onContentChange = jest.fn();
|
|
153
|
+
const rendered = renderSelector({
|
|
154
|
+
templates: [optionalTemplate],
|
|
155
|
+
template: optionalTemplate,
|
|
156
|
+
onContentChange,
|
|
157
|
+
});
|
|
158
|
+
await waitForLoad(rendered);
|
|
159
|
+
const user = userEvent.setup({ delay: null });
|
|
160
|
+
|
|
161
|
+
const input = rendered.container.querySelector('input[name="notes"]');
|
|
162
|
+
if (input) {
|
|
163
|
+
await user.type(input, "Test content");
|
|
164
|
+
expect(onContentChange).toHaveBeenCalled();
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { render } from "@truedat/test/render";
|
|
2
|
+
import { ExecutionWarning } from "../ExecutionWarning";
|
|
3
|
+
|
|
4
|
+
describe("<ExecutionWarning />", () => {
|
|
5
|
+
it("renders the warning message with the count", () => {
|
|
6
|
+
const rendered = render(<ExecutionWarning count={5} />);
|
|
7
|
+
|
|
8
|
+
expect(
|
|
9
|
+
rendered.getByText(/implementations will be executed/i),
|
|
10
|
+
).toBeInTheDocument();
|
|
11
|
+
expect(rendered.getByText("5")).toHaveClass("count");
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("renders the warning icon", () => {
|
|
15
|
+
const rendered = render(<ExecutionWarning count={3} />);
|
|
16
|
+
|
|
17
|
+
expect(rendered.container.querySelector(".warning")).toBeInTheDocument();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("renders the correct CSS class", () => {
|
|
21
|
+
const rendered = render(<ExecutionWarning count={2} />);
|
|
22
|
+
|
|
23
|
+
expect(rendered.container.firstChild).toHaveClass(
|
|
24
|
+
"execution-popup-warning",
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("formats the count with bold styling", () => {
|
|
29
|
+
const rendered = render(<ExecutionWarning count={10} />);
|
|
30
|
+
|
|
31
|
+
const countElement = rendered.getByText("10");
|
|
32
|
+
expect(countElement.tagName).toBe("STRONG");
|
|
33
|
+
expect(countElement).toHaveClass("count");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("matches snapshot", () => {
|
|
37
|
+
const rendered = render(<ExecutionWarning count={2} />);
|
|
38
|
+
expect(rendered.container).toMatchSnapshot();
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -51,7 +51,7 @@ describe("<RuleImplementation />", () => {
|
|
|
51
51
|
});
|
|
52
52
|
await waitForLoad(rendered);
|
|
53
53
|
expect(
|
|
54
|
-
rendered.getByText(/
|
|
54
|
+
rendered.getByText(/implementation.actions.do_execution/i),
|
|
55
55
|
).toBeInTheDocument();
|
|
56
56
|
});
|
|
57
57
|
|
|
@@ -61,7 +61,7 @@ describe("<RuleImplementation />", () => {
|
|
|
61
61
|
});
|
|
62
62
|
await waitForLoad(rendered);
|
|
63
63
|
expect(
|
|
64
|
-
rendered.queryByText(/
|
|
64
|
+
rendered.queryByText(/implementation.actions.do_execution/i),
|
|
65
65
|
).not.toBeInTheDocument();
|
|
66
66
|
});
|
|
67
67
|
});
|
|
@@ -1,102 +1,146 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
|
-
exports[`<ExecutionForm />
|
|
3
|
+
exports[`<ExecutionForm /> shows the template selector and the bulk execution warning 1`] = `
|
|
4
4
|
<div>
|
|
5
|
-
<
|
|
6
|
-
class="
|
|
5
|
+
<div
|
|
6
|
+
class="header"
|
|
7
7
|
>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
<div
|
|
9
|
+
class="execution-popup-header"
|
|
10
|
+
>
|
|
11
|
+
<div>
|
|
12
|
+
Implementations execution
|
|
13
|
+
<p
|
|
14
|
+
class="subtitle"
|
|
15
|
+
>
|
|
16
|
+
Select template for additional information
|
|
17
|
+
</p>
|
|
18
|
+
</div>
|
|
19
|
+
<button
|
|
20
|
+
aria-label="Close"
|
|
21
|
+
class="close-button"
|
|
22
|
+
type="button"
|
|
23
|
+
>
|
|
24
|
+
×
|
|
25
|
+
</button>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
<div
|
|
29
|
+
class="content"
|
|
12
30
|
>
|
|
13
31
|
<div
|
|
14
|
-
class="
|
|
32
|
+
class="execution-popup-template-area"
|
|
15
33
|
>
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
|
|
34
|
+
<div
|
|
35
|
+
class="execution-popup-selector-label"
|
|
36
|
+
>
|
|
37
|
+
<span>
|
|
38
|
+
Select template
|
|
39
|
+
</span>
|
|
40
|
+
<span
|
|
41
|
+
class="optional-badge"
|
|
42
|
+
>
|
|
43
|
+
optional
|
|
44
|
+
</span>
|
|
45
|
+
</div>
|
|
19
46
|
<div
|
|
20
47
|
class="field"
|
|
21
48
|
>
|
|
22
49
|
<div
|
|
23
|
-
|
|
24
|
-
aria-expanded="false"
|
|
25
|
-
class="ui search selection dropdown"
|
|
26
|
-
name="template"
|
|
27
|
-
role="combobox"
|
|
50
|
+
class="field"
|
|
28
51
|
>
|
|
29
|
-
<input
|
|
30
|
-
aria-autocomplete="list"
|
|
31
|
-
autocomplete="off"
|
|
32
|
-
class="search"
|
|
33
|
-
tabindex="0"
|
|
34
|
-
type="text"
|
|
35
|
-
value=""
|
|
36
|
-
/>
|
|
37
52
|
<div
|
|
38
|
-
aria-
|
|
39
|
-
aria-
|
|
40
|
-
class="
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
template.selector.placeholder
|
|
44
|
-
</div>
|
|
45
|
-
<i
|
|
46
|
-
aria-hidden="true"
|
|
47
|
-
class="dropdown icon"
|
|
48
|
-
/>
|
|
49
|
-
<div
|
|
50
|
-
class="menu transition"
|
|
51
|
-
role="listbox"
|
|
53
|
+
aria-busy="false"
|
|
54
|
+
aria-expanded="false"
|
|
55
|
+
class="ui search selection dropdown"
|
|
56
|
+
name="template"
|
|
57
|
+
role="combobox"
|
|
52
58
|
>
|
|
59
|
+
<input
|
|
60
|
+
aria-autocomplete="list"
|
|
61
|
+
autocomplete="off"
|
|
62
|
+
class="search"
|
|
63
|
+
tabindex="0"
|
|
64
|
+
type="text"
|
|
65
|
+
value=""
|
|
66
|
+
/>
|
|
53
67
|
<div
|
|
54
|
-
aria-
|
|
55
|
-
aria-
|
|
56
|
-
class="
|
|
57
|
-
role="
|
|
58
|
-
style="pointer-events: all;"
|
|
68
|
+
aria-atomic="true"
|
|
69
|
+
aria-live="polite"
|
|
70
|
+
class="divider default text"
|
|
71
|
+
role="alert"
|
|
59
72
|
>
|
|
60
|
-
|
|
61
|
-
class="text"
|
|
62
|
-
>
|
|
63
|
-
template1
|
|
64
|
-
</span>
|
|
73
|
+
template.selector.placeholder
|
|
65
74
|
</div>
|
|
75
|
+
<i
|
|
76
|
+
aria-hidden="true"
|
|
77
|
+
class="dropdown icon"
|
|
78
|
+
/>
|
|
66
79
|
<div
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
class="item"
|
|
70
|
-
role="option"
|
|
71
|
-
style="pointer-events: all;"
|
|
80
|
+
class="menu transition"
|
|
81
|
+
role="listbox"
|
|
72
82
|
>
|
|
73
|
-
<
|
|
74
|
-
|
|
83
|
+
<div
|
|
84
|
+
aria-checked="false"
|
|
85
|
+
aria-selected="true"
|
|
86
|
+
class="selected item"
|
|
87
|
+
role="option"
|
|
88
|
+
style="pointer-events: all;"
|
|
75
89
|
>
|
|
76
|
-
|
|
77
|
-
|
|
90
|
+
<span
|
|
91
|
+
class="text"
|
|
92
|
+
>
|
|
93
|
+
template1
|
|
94
|
+
</span>
|
|
95
|
+
</div>
|
|
96
|
+
<div
|
|
97
|
+
aria-checked="false"
|
|
98
|
+
aria-selected="false"
|
|
99
|
+
class="item"
|
|
100
|
+
role="option"
|
|
101
|
+
style="pointer-events: all;"
|
|
102
|
+
>
|
|
103
|
+
<span
|
|
104
|
+
class="text"
|
|
105
|
+
>
|
|
106
|
+
template2
|
|
107
|
+
</span>
|
|
108
|
+
</div>
|
|
78
109
|
</div>
|
|
79
110
|
</div>
|
|
80
111
|
</div>
|
|
81
112
|
</div>
|
|
82
113
|
</div>
|
|
83
|
-
<p>
|
|
84
|
-
implementation.actions.execution.confirmation.content
|
|
85
|
-
</p>
|
|
86
114
|
<div
|
|
87
|
-
class="
|
|
115
|
+
class="execution-popup-warning"
|
|
88
116
|
>
|
|
89
|
-
<
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
117
|
+
<i
|
|
118
|
+
aria-hidden="true"
|
|
119
|
+
class="yellow warning sign large icon"
|
|
120
|
+
/>
|
|
121
|
+
<p>
|
|
122
|
+
<strong
|
|
123
|
+
class="count"
|
|
124
|
+
>
|
|
125
|
+
2
|
|
126
|
+
</strong>
|
|
127
|
+
implementations will be executed. Is this correct?
|
|
128
|
+
</p>
|
|
99
129
|
</div>
|
|
100
|
-
</
|
|
130
|
+
</div>
|
|
131
|
+
<div
|
|
132
|
+
class="actions"
|
|
133
|
+
>
|
|
134
|
+
<button
|
|
135
|
+
class="ui secondary button"
|
|
136
|
+
>
|
|
137
|
+
Cancel
|
|
138
|
+
</button>
|
|
139
|
+
<button
|
|
140
|
+
class="ui primary button"
|
|
141
|
+
>
|
|
142
|
+
Execute
|
|
143
|
+
</button>
|
|
144
|
+
</div>
|
|
101
145
|
</div>
|
|
102
146
|
`;
|
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`<ExecutionPopup /> matches the latest snapshot 1`] = `
|
|
4
4
|
<div>
|
|
5
|
-
<
|
|
6
|
-
class="
|
|
5
|
+
<div
|
|
6
|
+
class="execution-popup-wrapper"
|
|
7
7
|
>
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
<button
|
|
9
|
+
class="ui primary button"
|
|
10
|
+
>
|
|
11
|
+
do_execution
|
|
12
|
+
</button>
|
|
13
|
+
</div>
|
|
10
14
|
</div>
|
|
11
15
|
`;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<ExecutionWarning /> matches snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="execution-popup-warning"
|
|
7
|
+
>
|
|
8
|
+
<i
|
|
9
|
+
aria-hidden="true"
|
|
10
|
+
class="yellow warning sign large icon"
|
|
11
|
+
/>
|
|
12
|
+
<p>
|
|
13
|
+
<strong
|
|
14
|
+
class="count"
|
|
15
|
+
>
|
|
16
|
+
2
|
|
17
|
+
</strong>
|
|
18
|
+
implementations will be executed. Is this correct?
|
|
19
|
+
</p>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
`;
|
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`<ImplementationActions /> matches the snapshot 1`] = `
|
|
4
4
|
<div>
|
|
5
|
-
<
|
|
6
|
-
class="
|
|
5
|
+
<div
|
|
6
|
+
class="execution-popup-wrapper"
|
|
7
7
|
>
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
<button
|
|
9
|
+
class="ui primary button"
|
|
10
|
+
>
|
|
11
|
+
implementation.actions.do_execution
|
|
12
|
+
</button>
|
|
13
|
+
</div>
|
|
10
14
|
<div
|
|
11
15
|
aria-expanded="false"
|
|
12
16
|
class="ui floating dropdown button icon group-actions"
|
|
@@ -24,13 +24,17 @@ exports[`<ImplementationSearchResults /> matches the latest snapshot 1`] = `
|
|
|
24
24
|
for="execute_checkbox"
|
|
25
25
|
/>
|
|
26
26
|
</div>
|
|
27
|
-
<
|
|
28
|
-
class="
|
|
29
|
-
disabled=""
|
|
30
|
-
tabindex="-1"
|
|
27
|
+
<div
|
|
28
|
+
class="execution-popup-wrapper"
|
|
31
29
|
>
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
<button
|
|
31
|
+
class="ui primary disabled button"
|
|
32
|
+
disabled=""
|
|
33
|
+
tabindex="-1"
|
|
34
|
+
>
|
|
35
|
+
implementation.actions.do_execution
|
|
36
|
+
</button>
|
|
37
|
+
</div>
|
|
34
38
|
<div
|
|
35
39
|
aria-disabled="false"
|
|
36
40
|
aria-expanded="false"
|
|
@@ -179,11 +183,15 @@ exports[`<ImplementationSearchResults /> renders executions on when executionEna
|
|
|
179
183
|
for="execute_checkbox"
|
|
180
184
|
/>
|
|
181
185
|
</div>
|
|
182
|
-
<
|
|
183
|
-
class="
|
|
186
|
+
<div
|
|
187
|
+
class="execution-popup-wrapper"
|
|
184
188
|
>
|
|
185
|
-
|
|
186
|
-
|
|
189
|
+
<button
|
|
190
|
+
class="ui primary button"
|
|
191
|
+
>
|
|
192
|
+
implementation.actions.do_execution
|
|
193
|
+
</button>
|
|
194
|
+
</div>
|
|
187
195
|
<div
|
|
188
196
|
aria-disabled="false"
|
|
189
197
|
aria-expanded="false"
|