@truedat/dq 7.11.0 → 7.11.2
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 +3 -3
- package/src/api.js +12 -0
- package/src/components/ImplementationSearchResults.js +24 -42
- package/src/components/ImplementationUploadJobBreadcrumbs.js +25 -0
- package/src/components/Implementations.js +31 -17
- package/src/components/ImplementationsRoutes.js +9 -0
- package/src/components/ImplementationsUploadButton.js +38 -50
- package/src/components/ImplementationsUploadJob.js +217 -0
- package/src/components/ImplementationsUploadJobs.js +128 -0
- package/src/components/RuleFormImplementations.js +29 -10
- package/src/components/RuleImplementationActions.js +10 -20
- package/src/components/RuleImplementationsActions.js +15 -37
- package/src/components/RuleImplementationsDownload.js +26 -31
- package/src/components/RuleImplementationsDownloadXlsx.js +47 -0
- package/src/components/RuleImplementationsLabelResults.js +30 -39
- package/src/components/RuleImplementationsOptions.js +5 -3
- package/src/components/RuleImplementationsTable.js +7 -3
- package/src/components/RuleRoutes.js +1 -4
- package/src/components/SimpleRuleImplementationsTable.js +68 -0
- package/src/components/__tests__/ImplementationSearchResults.spec.js +32 -4
- package/src/components/__tests__/ImplementationUploadJobBreadcrumbs.spec.js +28 -0
- package/src/components/__tests__/Implementations.spec.js +43 -0
- package/src/components/__tests__/ImplementationsUploadButton.spec.js +67 -40
- package/src/components/__tests__/ImplementationsUploadJob.spec.js +112 -0
- package/src/components/__tests__/ImplementationsUploadJobs.spec.js +60 -0
- package/src/components/__tests__/RuleImplementationsActions.spec.js +71 -56
- package/src/components/__tests__/RuleImplementationsOptions.spec.js +28 -3
- package/src/components/__tests__/RuleImplementationsTable.spec.js +24 -0
- package/src/components/__tests__/__snapshots__/ImplementationSearchResults.spec.js.snap +113 -46
- package/src/components/__tests__/__snapshots__/ImplementationUploadJobBreadcrumbs.spec.js.snap +42 -0
- package/src/components/__tests__/__snapshots__/Implementations.spec.js.snap +125 -24
- package/src/components/__tests__/__snapshots__/RuleImplementationsActions.spec.js.snap +4 -8
- package/src/components/__tests__/__snapshots__/RuleImplementationsOptions.spec.js.snap +5 -8
- package/src/components/__tests__/implementationsUploadJobParser.spec.js +105 -0
- package/src/components/implementationsUploadJobParser.js +276 -0
- package/src/components/index.js +0 -2
- package/src/hooks/useImplementations.js +80 -0
- package/src/reducers/index.js +2 -0
- package/src/reducers/ruleImplementationSelectedFilter.js +1 -1
- package/src/reducers/ruleImplementationsDownloadingXlsx.js +14 -0
- package/src/routines.js +3 -0
- package/src/sagas/downloadRuleImplementationsXlsx.js +52 -0
- package/src/sagas/index.js +3 -0
- package/src/components/RuleImplementationFilters.js +0 -25
- package/src/components/RuleImplementationSelectedFilters.js +0 -99
- package/src/components/RuleImplementationsFromRuleLoader.js +0 -60
- package/src/components/RuleImplementationsPagination.js +0 -18
- package/src/components/RuleImplementationsSearch.js +0 -39
- package/src/components/__tests__/RuleImplementationsFromRuleLoader.spec.js +0 -63
- package/src/components/__tests__/RuleImplementationsSearch.spec.js +0 -29
- package/src/components/__tests__/__snapshots__/RuleImplementationsFromRuleLoader.spec.js.snap +0 -3
- package/src/components/__tests__/__snapshots__/RuleImplementationsSearch.spec.js.snap +0 -50
|
@@ -27,12 +27,14 @@ exports[`<Implementations /> matches the latest snapshot 1`] = `
|
|
|
27
27
|
class="ui bottom attached segment"
|
|
28
28
|
>
|
|
29
29
|
<div
|
|
30
|
+
border="1px red"
|
|
30
31
|
class="ui bottom attached segment"
|
|
31
32
|
>
|
|
32
33
|
<div
|
|
33
34
|
style="float: right;"
|
|
34
35
|
>
|
|
35
36
|
<div
|
|
37
|
+
aria-disabled="false"
|
|
36
38
|
aria-expanded="false"
|
|
37
39
|
class="ui floating dropdown button icon group-actions button-update"
|
|
38
40
|
role="listbox"
|
|
@@ -46,8 +48,8 @@ exports[`<Implementations /> matches the latest snapshot 1`] = `
|
|
|
46
48
|
class="menu transition left"
|
|
47
49
|
>
|
|
48
50
|
<div
|
|
49
|
-
aria-disabled="
|
|
50
|
-
class="
|
|
51
|
+
aria-disabled="false"
|
|
52
|
+
class="item"
|
|
51
53
|
role="option"
|
|
52
54
|
>
|
|
53
55
|
<i
|
|
@@ -55,15 +57,11 @@ exports[`<Implementations /> matches the latest snapshot 1`] = `
|
|
|
55
57
|
class="download icon"
|
|
56
58
|
/>
|
|
57
59
|
<span>
|
|
58
|
-
implementations.actions.
|
|
60
|
+
implementations.actions.downloadXlsx.tooltip
|
|
59
61
|
</span>
|
|
60
|
-
<p
|
|
61
|
-
class="menu-item-description"
|
|
62
|
-
>
|
|
63
|
-
implementations.actions.download.empty
|
|
64
|
-
</p>
|
|
65
62
|
</div>
|
|
66
63
|
<div
|
|
64
|
+
aria-disabled="false"
|
|
67
65
|
class="item"
|
|
68
66
|
role="option"
|
|
69
67
|
>
|
|
@@ -83,15 +81,14 @@ exports[`<Implementations /> matches the latest snapshot 1`] = `
|
|
|
83
81
|
<div
|
|
84
82
|
class="ui action left icon input"
|
|
85
83
|
>
|
|
86
|
-
<input
|
|
87
|
-
placeholder="implementations.search.placeholder"
|
|
88
|
-
type="text"
|
|
89
|
-
value="foo"
|
|
90
|
-
/>
|
|
91
84
|
<i
|
|
92
85
|
aria-hidden="true"
|
|
93
86
|
class="search link icon"
|
|
94
87
|
/>
|
|
88
|
+
<input
|
|
89
|
+
placeholder="search.placeholder"
|
|
90
|
+
type="text"
|
|
91
|
+
/>
|
|
95
92
|
<div
|
|
96
93
|
aria-expanded="false"
|
|
97
94
|
class="ui button floating labeled scrolling dropdown icon"
|
|
@@ -135,19 +132,123 @@ exports[`<Implementations /> matches the latest snapshot 1`] = `
|
|
|
135
132
|
>
|
|
136
133
|
ruleImplementations.retrieved.results
|
|
137
134
|
</div>
|
|
138
|
-
<
|
|
139
|
-
class="
|
|
135
|
+
<div
|
|
136
|
+
class="implementations-table-overflow"
|
|
140
137
|
>
|
|
141
|
-
<
|
|
142
|
-
|
|
143
|
-
class="search icon"
|
|
144
|
-
/>
|
|
145
|
-
<div
|
|
146
|
-
class="content"
|
|
138
|
+
<table
|
|
139
|
+
class="ui sortable table"
|
|
147
140
|
>
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
141
|
+
<thead
|
|
142
|
+
class=""
|
|
143
|
+
>
|
|
144
|
+
<tr
|
|
145
|
+
class=""
|
|
146
|
+
>
|
|
147
|
+
<th
|
|
148
|
+
class="two wide"
|
|
149
|
+
>
|
|
150
|
+
ruleImplementations.props.implementation_key
|
|
151
|
+
</th>
|
|
152
|
+
<th
|
|
153
|
+
class="two wide"
|
|
154
|
+
>
|
|
155
|
+
ruleImplementations.props.rule
|
|
156
|
+
</th>
|
|
157
|
+
<th
|
|
158
|
+
class="two wide ascending sorted disabled"
|
|
159
|
+
>
|
|
160
|
+
ruleImplementations.props.business_concepts
|
|
161
|
+
</th>
|
|
162
|
+
<th
|
|
163
|
+
class="two wide"
|
|
164
|
+
>
|
|
165
|
+
ruleImplementations.props.last_execution_at
|
|
166
|
+
</th>
|
|
167
|
+
<th
|
|
168
|
+
class="two wide"
|
|
169
|
+
>
|
|
170
|
+
ruleImplementations.props.result_type
|
|
171
|
+
</th>
|
|
172
|
+
<th
|
|
173
|
+
class="one wide"
|
|
174
|
+
>
|
|
175
|
+
ruleImplementations.props.minimum
|
|
176
|
+
</th>
|
|
177
|
+
<th
|
|
178
|
+
class="one wide"
|
|
179
|
+
>
|
|
180
|
+
ruleImplementations.props.goal
|
|
181
|
+
</th>
|
|
182
|
+
<th
|
|
183
|
+
class="two wide"
|
|
184
|
+
>
|
|
185
|
+
ruleImplementations.props.result
|
|
186
|
+
</th>
|
|
187
|
+
<th
|
|
188
|
+
class=""
|
|
189
|
+
>
|
|
190
|
+
ruleImplementations.props.inserted_at
|
|
191
|
+
</th>
|
|
192
|
+
<th
|
|
193
|
+
class=""
|
|
194
|
+
>
|
|
195
|
+
ruleImplementations.props.updated_at
|
|
196
|
+
</th>
|
|
197
|
+
</tr>
|
|
198
|
+
</thead>
|
|
199
|
+
<tbody
|
|
200
|
+
class=""
|
|
201
|
+
>
|
|
202
|
+
<tr
|
|
203
|
+
class=""
|
|
204
|
+
>
|
|
205
|
+
<td
|
|
206
|
+
class=""
|
|
207
|
+
>
|
|
208
|
+
<a
|
|
209
|
+
data-discover="true"
|
|
210
|
+
href="/implementations/1330"
|
|
211
|
+
>
|
|
212
|
+
bar_impl
|
|
213
|
+
</a>
|
|
214
|
+
</td>
|
|
215
|
+
<td
|
|
216
|
+
class=""
|
|
217
|
+
/>
|
|
218
|
+
<td
|
|
219
|
+
class=""
|
|
220
|
+
/>
|
|
221
|
+
<td
|
|
222
|
+
class=""
|
|
223
|
+
/>
|
|
224
|
+
<td
|
|
225
|
+
class=""
|
|
226
|
+
>
|
|
227
|
+
ruleImplementations.props.result_type.percentage
|
|
228
|
+
</td>
|
|
229
|
+
<td
|
|
230
|
+
class="right aligned"
|
|
231
|
+
>
|
|
232
|
+
10%
|
|
233
|
+
</td>
|
|
234
|
+
<td
|
|
235
|
+
class="right aligned"
|
|
236
|
+
>
|
|
237
|
+
20%
|
|
238
|
+
</td>
|
|
239
|
+
<td
|
|
240
|
+
class="center aligned"
|
|
241
|
+
/>
|
|
242
|
+
<td
|
|
243
|
+
class=""
|
|
244
|
+
/>
|
|
245
|
+
<td
|
|
246
|
+
class=""
|
|
247
|
+
/>
|
|
248
|
+
</tr>
|
|
249
|
+
</tbody>
|
|
250
|
+
</table>
|
|
251
|
+
</div>
|
|
151
252
|
</div>
|
|
152
253
|
</div>
|
|
153
254
|
</div>
|
|
@@ -58,8 +58,8 @@ exports[`<RuleImplementationsActions /> matches the latest snapshot 1`] = `
|
|
|
58
58
|
class="menu transition left"
|
|
59
59
|
>
|
|
60
60
|
<div
|
|
61
|
-
aria-disabled="
|
|
62
|
-
class="
|
|
61
|
+
aria-disabled="false"
|
|
62
|
+
class="item"
|
|
63
63
|
role="option"
|
|
64
64
|
>
|
|
65
65
|
<i
|
|
@@ -67,15 +67,11 @@ exports[`<RuleImplementationsActions /> matches the latest snapshot 1`] = `
|
|
|
67
67
|
class="download icon"
|
|
68
68
|
/>
|
|
69
69
|
<span>
|
|
70
|
-
implementations.actions.
|
|
70
|
+
implementations.actions.downloadXlsx.tooltip
|
|
71
71
|
</span>
|
|
72
|
-
<p
|
|
73
|
-
class="menu-item-description"
|
|
74
|
-
>
|
|
75
|
-
implementations.actions.download.empty
|
|
76
|
-
</p>
|
|
77
72
|
</div>
|
|
78
73
|
<div
|
|
74
|
+
aria-disabled="false"
|
|
79
75
|
class="item"
|
|
80
76
|
role="option"
|
|
81
77
|
>
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
exports[`<RuleImplementationsOptions /> matches the latest snapshot 1`] = `
|
|
4
4
|
<div>
|
|
5
5
|
<div
|
|
6
|
+
aria-disabled="false"
|
|
6
7
|
aria-expanded="false"
|
|
7
8
|
class="ui floating dropdown button icon group-actions button-update"
|
|
8
9
|
role="listbox"
|
|
@@ -16,8 +17,8 @@ exports[`<RuleImplementationsOptions /> matches the latest snapshot 1`] = `
|
|
|
16
17
|
class="menu transition left"
|
|
17
18
|
>
|
|
18
19
|
<div
|
|
19
|
-
aria-disabled="
|
|
20
|
-
class="
|
|
20
|
+
aria-disabled="false"
|
|
21
|
+
class="item"
|
|
21
22
|
role="option"
|
|
22
23
|
>
|
|
23
24
|
<i
|
|
@@ -25,15 +26,11 @@ exports[`<RuleImplementationsOptions /> matches the latest snapshot 1`] = `
|
|
|
25
26
|
class="download icon"
|
|
26
27
|
/>
|
|
27
28
|
<span>
|
|
28
|
-
implementations.actions.
|
|
29
|
+
implementations.actions.downloadXlsx.tooltip
|
|
29
30
|
</span>
|
|
30
|
-
<p
|
|
31
|
-
class="menu-item-description"
|
|
32
|
-
>
|
|
33
|
-
implementations.actions.download.empty
|
|
34
|
-
</p>
|
|
35
31
|
</div>
|
|
36
32
|
<div
|
|
33
|
+
aria-disabled="false"
|
|
37
34
|
class="item"
|
|
38
35
|
role="option"
|
|
39
36
|
>
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { render } from "@truedat/test/render";
|
|
2
|
+
import { StatusPill, ResponseCell } from "../implementationsUploadJobParser";
|
|
3
|
+
|
|
4
|
+
describe("<StatusPill />", () => {
|
|
5
|
+
it("renders with correct color based on status", async () => {
|
|
6
|
+
const statuses = ["COMPLETED", "FAILED", "ERROR", "INFO", "OTHER"];
|
|
7
|
+
const expectedColors = ["green", "red", "red", "blue", "grey"];
|
|
8
|
+
|
|
9
|
+
statuses.forEach((status, index) => {
|
|
10
|
+
const rendered = render(<StatusPill status={status} />);
|
|
11
|
+
const label = rendered.container.querySelector(".ui.label");
|
|
12
|
+
expect(label).toHaveClass(expectedColors[index]);
|
|
13
|
+
expect(
|
|
14
|
+
rendered.getByText(
|
|
15
|
+
new RegExp(`implementations.bulkUpload.event.status.${status}`, "i")
|
|
16
|
+
)
|
|
17
|
+
).toBeInTheDocument();
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
describe("<ResponseCell />", () => {
|
|
23
|
+
it("returns null when response is empty", () => {
|
|
24
|
+
const rendered = render(
|
|
25
|
+
<ResponseCell response={null} status="COMPLETED" />
|
|
26
|
+
);
|
|
27
|
+
expect(rendered.container.firstChild).toBeNull();
|
|
28
|
+
|
|
29
|
+
const rendered2 = render(<ResponseCell response={{}} status="COMPLETED" />);
|
|
30
|
+
expect(rendered2.container.firstChild).toBeNull();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("renders FAILED status with message", () => {
|
|
34
|
+
const response = { message: "missing_required_headers" };
|
|
35
|
+
const rendered = render(
|
|
36
|
+
<ResponseCell response={response} status="FAILED" />
|
|
37
|
+
);
|
|
38
|
+
expect(
|
|
39
|
+
rendered.getByText(
|
|
40
|
+
/implementations.bulkUpload.error.missing_required_headers/i
|
|
41
|
+
)
|
|
42
|
+
).toBeInTheDocument();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("renders ERROR status with details", () => {
|
|
46
|
+
const response = {
|
|
47
|
+
type: "missing_required_headers",
|
|
48
|
+
details: {
|
|
49
|
+
missing_headers: ["header1", "header2"],
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
const rendered = render(
|
|
53
|
+
<ResponseCell response={response} status="ERROR" />
|
|
54
|
+
);
|
|
55
|
+
expect(
|
|
56
|
+
rendered.getByText(
|
|
57
|
+
/implementations.bulkUpload.error.missing_required_headers/i
|
|
58
|
+
)
|
|
59
|
+
).toBeInTheDocument();
|
|
60
|
+
expect(rendered.getByText(/header1, header2/i)).toBeInTheDocument();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("renders COMPLETED status with summary", () => {
|
|
64
|
+
const response = {
|
|
65
|
+
insert_count: 2,
|
|
66
|
+
update_count: 1,
|
|
67
|
+
error_count: 0,
|
|
68
|
+
};
|
|
69
|
+
const rendered = render(
|
|
70
|
+
<ResponseCell response={response} status="COMPLETED" />
|
|
71
|
+
);
|
|
72
|
+
expect(
|
|
73
|
+
rendered.getByText(/implementations.bulkUpload.result.summary.created/i)
|
|
74
|
+
).toBeInTheDocument();
|
|
75
|
+
expect(
|
|
76
|
+
rendered.getByText(/implementations.bulkUpload.result.summary.updated/i)
|
|
77
|
+
).toBeInTheDocument();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("renders INFO status with implementation details", () => {
|
|
81
|
+
const response = {
|
|
82
|
+
type: "implementation_updated",
|
|
83
|
+
details: {
|
|
84
|
+
id: 123,
|
|
85
|
+
changes: {
|
|
86
|
+
name: "new name",
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
const rendered = render(<ResponseCell response={response} status="INFO" />);
|
|
91
|
+
expect(
|
|
92
|
+
rendered.getByText(
|
|
93
|
+
/implementations.bulkUpload.info.implementation_updated/i
|
|
94
|
+
)
|
|
95
|
+
).toBeInTheDocument();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("renders default case for unknown status", () => {
|
|
99
|
+
const response = "some text";
|
|
100
|
+
const rendered = render(
|
|
101
|
+
<ResponseCell response={response} status="UNKNOWN" />
|
|
102
|
+
);
|
|
103
|
+
expect(rendered.getByText(/some text/i)).toBeInTheDocument();
|
|
104
|
+
});
|
|
105
|
+
});
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { FormattedMessage, useIntl } from "react-intl";
|
|
4
|
+
import { Label } from "semantic-ui-react";
|
|
5
|
+
import { RichTextEditor } from "@truedat/core/components";
|
|
6
|
+
|
|
7
|
+
import RuleImplementationLink from "./RuleImplementationLink";
|
|
8
|
+
|
|
9
|
+
export const StatusPill = ({ status }) => (
|
|
10
|
+
<Label
|
|
11
|
+
color={_.cond([
|
|
12
|
+
[_.eq("COMPLETED"), _.constant("green")],
|
|
13
|
+
[_.eq("FAILED"), _.constant("red")],
|
|
14
|
+
[_.eq("ERROR"), _.constant("red")],
|
|
15
|
+
[_.eq("INFO"), _.constant("blue")],
|
|
16
|
+
[_.stubTrue, _.constant("grey")],
|
|
17
|
+
])(status)}
|
|
18
|
+
size="small"
|
|
19
|
+
>
|
|
20
|
+
<FormattedMessage
|
|
21
|
+
id={`implementations.bulkUpload.event.status.${status}`}
|
|
22
|
+
/>
|
|
23
|
+
</Label>
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
export const ResponseCell = ({ response, status }) => {
|
|
27
|
+
if (!response || (_.isObject(response) && _.isEmpty(response))) return null;
|
|
28
|
+
|
|
29
|
+
switch (status) {
|
|
30
|
+
case "FAILED":
|
|
31
|
+
return (
|
|
32
|
+
<FormattedMessage
|
|
33
|
+
id={`implementations.bulkUpload.error.${response.message}`}
|
|
34
|
+
/>
|
|
35
|
+
);
|
|
36
|
+
case "ERROR":
|
|
37
|
+
return <ErrorDetail response={response} />;
|
|
38
|
+
case "COMPLETED":
|
|
39
|
+
return <CompletedDetail response={response} />;
|
|
40
|
+
case "INFO":
|
|
41
|
+
return <InfoDetail response={response} />;
|
|
42
|
+
default:
|
|
43
|
+
return (
|
|
44
|
+
<pre
|
|
45
|
+
style={{
|
|
46
|
+
whiteSpace: "pre-wrap",
|
|
47
|
+
wordBreak: "break-all",
|
|
48
|
+
margin: 0,
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
{typeof response === "string"
|
|
52
|
+
? response
|
|
53
|
+
: JSON.stringify(response, null, 2)}
|
|
54
|
+
</pre>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const SheetAndLine = ({ response }) => (
|
|
60
|
+
<Label size="small">
|
|
61
|
+
<span>{response.sheet}</span>
|
|
62
|
+
{response.row_number ? (
|
|
63
|
+
<span>
|
|
64
|
+
{" "}
|
|
65
|
+
-{" "}
|
|
66
|
+
<FormattedMessage id="implementations.bulkUpload.result.prop.row_number" />
|
|
67
|
+
: {response.row_number}
|
|
68
|
+
</span>
|
|
69
|
+
) : null}
|
|
70
|
+
</Label>
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const CellHeader = ({ header, response }) => (
|
|
74
|
+
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
|
75
|
+
<b>
|
|
76
|
+
<FormattedMessage id={header} />
|
|
77
|
+
</b>
|
|
78
|
+
<div>
|
|
79
|
+
<SheetAndLine response={response} />
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const ErrorDetail = ({ response }) => {
|
|
85
|
+
const { formatMessage } = useIntl();
|
|
86
|
+
|
|
87
|
+
if (!response || !response.type) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const { type } = response;
|
|
91
|
+
const messagePrefix = "implementations.bulkUpload.detail";
|
|
92
|
+
|
|
93
|
+
const detailBuilders = {
|
|
94
|
+
missing_required_headers: (details) => [
|
|
95
|
+
[
|
|
96
|
+
formatMessage({ id: `${messagePrefix}.headers` }),
|
|
97
|
+
details.missing_headers?.join(", "),
|
|
98
|
+
],
|
|
99
|
+
],
|
|
100
|
+
invalid_template_name: (details) => [
|
|
101
|
+
[
|
|
102
|
+
formatMessage({ id: `${messagePrefix}.templateName` }),
|
|
103
|
+
details.template_name,
|
|
104
|
+
],
|
|
105
|
+
],
|
|
106
|
+
invalid_domain_external_id: (details) => [
|
|
107
|
+
[
|
|
108
|
+
formatMessage({ id: `${messagePrefix}.domainExternalId` }),
|
|
109
|
+
details.domain_external_id,
|
|
110
|
+
],
|
|
111
|
+
],
|
|
112
|
+
invalid_associated_rule: (details) => [
|
|
113
|
+
[formatMessage({ id: `${messagePrefix}.ruleName` }), details.rule_name],
|
|
114
|
+
],
|
|
115
|
+
implementation_creation_error: (details) =>
|
|
116
|
+
details?.map(([field, [error]]) => [field, error]),
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const detailBuilder = _.propOr(() => {}, type)(detailBuilders);
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<div>
|
|
123
|
+
<CellHeader
|
|
124
|
+
header={`implementations.bulkUpload.error.${type}`}
|
|
125
|
+
response={response}
|
|
126
|
+
/>
|
|
127
|
+
|
|
128
|
+
{response.details
|
|
129
|
+
? detailBuilder(response.details).map(([key, value], idx) => (
|
|
130
|
+
<div key={idx} style={{ paddingLeft: "10px" }}>
|
|
131
|
+
<span
|
|
132
|
+
style={{
|
|
133
|
+
fontSize: "0.85em",
|
|
134
|
+
fontWeight: "bold",
|
|
135
|
+
paddingRight: "5px",
|
|
136
|
+
}}
|
|
137
|
+
>
|
|
138
|
+
{key}:
|
|
139
|
+
</span>
|
|
140
|
+
{value}
|
|
141
|
+
</div>
|
|
142
|
+
))
|
|
143
|
+
: null}
|
|
144
|
+
</div>
|
|
145
|
+
);
|
|
146
|
+
};
|
|
147
|
+
const summaryItems = [
|
|
148
|
+
{
|
|
149
|
+
key: "invalid_sheet_count",
|
|
150
|
+
messageId: "implementations.bulkUpload.result.summary.invalid_sheets",
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
key: "insert_count",
|
|
154
|
+
messageId: "implementations.bulkUpload.result.summary.created",
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
key: "update_count",
|
|
158
|
+
messageId: "implementations.bulkUpload.result.summary.updated",
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
key: "unchanged_count",
|
|
162
|
+
messageId: "implementations.bulkUpload.result.summary.unchanged",
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
key: "error_count",
|
|
166
|
+
messageId: "implementations.bulkUpload.result.summary.errors",
|
|
167
|
+
},
|
|
168
|
+
];
|
|
169
|
+
const CompletedDetail = ({ response }) => (
|
|
170
|
+
<span style={{ display: "flex", gap: "5px" }}>
|
|
171
|
+
{_.flow([
|
|
172
|
+
_.filter((item) => _.get(item.key, response) > 0),
|
|
173
|
+
_.map((item) => (
|
|
174
|
+
<span
|
|
175
|
+
key={item.key}
|
|
176
|
+
// style={{
|
|
177
|
+
// border: "1px solid #ccc",
|
|
178
|
+
// padding: "5px",
|
|
179
|
+
// }}
|
|
180
|
+
>
|
|
181
|
+
<FormattedMessage id={item.messageId} />
|
|
182
|
+
{`: ${response[item.key]}`}
|
|
183
|
+
</span>
|
|
184
|
+
)),
|
|
185
|
+
])(summaryItems)}
|
|
186
|
+
</span>
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
const InfoDetail = ({ response }) =>
|
|
190
|
+
!response || !response.type ? null : (
|
|
191
|
+
<div>
|
|
192
|
+
<CellHeader
|
|
193
|
+
header={`implementations.bulkUpload.info.${response.type}`}
|
|
194
|
+
response={response}
|
|
195
|
+
/>
|
|
196
|
+
{response.details ? (
|
|
197
|
+
<div>
|
|
198
|
+
<RuleImplementationLink {...response.details} />{" "}
|
|
199
|
+
</div>
|
|
200
|
+
) : null}
|
|
201
|
+
<ChangesDetail changes={response?.details?.changes} />
|
|
202
|
+
</div>
|
|
203
|
+
);
|
|
204
|
+
const ChangesDetail = ({
|
|
205
|
+
changes,
|
|
206
|
+
header = "implementations.bulkUpload.result.prop.changes",
|
|
207
|
+
}) => {
|
|
208
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
209
|
+
if (!changes) return null;
|
|
210
|
+
const changesList = _.toPairs(changes);
|
|
211
|
+
|
|
212
|
+
return (
|
|
213
|
+
<div>
|
|
214
|
+
<div
|
|
215
|
+
onClick={() => setIsExpanded(!isExpanded)}
|
|
216
|
+
style={{
|
|
217
|
+
cursor: "pointer",
|
|
218
|
+
display: "flex",
|
|
219
|
+
gap: "5px",
|
|
220
|
+
alignItems: "center",
|
|
221
|
+
}}
|
|
222
|
+
>
|
|
223
|
+
<span>{isExpanded ? "▼" : "▶"}</span>
|
|
224
|
+
<span>
|
|
225
|
+
<FormattedMessage id={header} />
|
|
226
|
+
</span>
|
|
227
|
+
<span>({_.size(changesList)}) :</span>
|
|
228
|
+
</div>
|
|
229
|
+
{isExpanded &&
|
|
230
|
+
changesList.map(([key, value]) => (
|
|
231
|
+
<div key={key} style={{ paddingLeft: "10px" }}>
|
|
232
|
+
{key == "df_content" ? (
|
|
233
|
+
<ChangesDetail
|
|
234
|
+
changes={value}
|
|
235
|
+
header={`ruleImplementations.props.${key}`}
|
|
236
|
+
/>
|
|
237
|
+
) : (
|
|
238
|
+
<>
|
|
239
|
+
<span
|
|
240
|
+
style={{
|
|
241
|
+
fontSize: "0.85em",
|
|
242
|
+
fontWeight: "bold",
|
|
243
|
+
paddingRight: "5px",
|
|
244
|
+
}}
|
|
245
|
+
>
|
|
246
|
+
<FormattedMessage
|
|
247
|
+
id={`ruleImplementations.props.${key}`}
|
|
248
|
+
defaultMessage={key}
|
|
249
|
+
/>
|
|
250
|
+
:
|
|
251
|
+
</span>
|
|
252
|
+
{formatValue(value)}
|
|
253
|
+
</>
|
|
254
|
+
)}
|
|
255
|
+
</div>
|
|
256
|
+
))}
|
|
257
|
+
</div>
|
|
258
|
+
);
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
const formatValue = (value) => {
|
|
262
|
+
if (_.has("value")(value)) return formatValue(value.value);
|
|
263
|
+
if (_.isArray(value)) {
|
|
264
|
+
return _.flow(_.map(formatValue), _.join(", "))(value);
|
|
265
|
+
}
|
|
266
|
+
if (_.isObject(value)) {
|
|
267
|
+
if (_.has("document")(value))
|
|
268
|
+
return <RichTextEditor readOnly value={value} />;
|
|
269
|
+
if (_.has("url_value")(value))
|
|
270
|
+
return `[${value.url_name}] (${value.url_value})`;
|
|
271
|
+
|
|
272
|
+
return _.flow(_.keys, _.join(", "))(value);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return value;
|
|
276
|
+
};
|
package/src/components/index.js
CHANGED
|
@@ -12,7 +12,6 @@ import Rule from "./Rule";
|
|
|
12
12
|
import RuleForm from "./RuleForm";
|
|
13
13
|
import RuleFormImplementations from "./RuleFormImplementations";
|
|
14
14
|
import RuleImplementationEvents from "./RuleImplementationEvents";
|
|
15
|
-
import RuleImplementationsFromRuleLoader from "./RuleImplementationsFromRuleLoader";
|
|
16
15
|
import RuleImplementationsLoader from "./RuleImplementationsLoader";
|
|
17
16
|
import RuleLoader from "./RuleLoader";
|
|
18
17
|
import RuleProperties from "./RuleProperties";
|
|
@@ -36,7 +35,6 @@ export {
|
|
|
36
35
|
RuleFormImplementations,
|
|
37
36
|
RuleImplementationEvents,
|
|
38
37
|
RuleImplementationsLoader,
|
|
39
|
-
RuleImplementationsFromRuleLoader,
|
|
40
38
|
RuleLoader,
|
|
41
39
|
RuleProperties,
|
|
42
40
|
RuleRow,
|