Skip to content

Commit 33ad22f

Browse files
authored
214 bulk (#208)
1 parent ca727b0 commit 33ad22f

File tree

6 files changed

+97
-112
lines changed

6 files changed

+97
-112
lines changed

src/components/ApproveRejectButtons.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export const ApproveRejectButtons: React.FunctionComponent<{
1212

1313
const approve = () => {
1414
testRunService
15-
.approve(testRun.id, testRun.merge)
15+
.approveBulk([testRun.id], testRun.merge)
1616
.then(() =>
1717
enqueueSnackbar("Approved", {
1818
variant: "success",
@@ -27,7 +27,7 @@ export const ApproveRejectButtons: React.FunctionComponent<{
2727

2828
const reject = () => {
2929
testRunService
30-
.reject(testRun.id)
30+
.rejectBulk([testRun.id])
3131
.then(() =>
3232
enqueueSnackbar("Rejected", {
3333
variant: "success",

src/components/TestDetailsModal.tsx

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@ import {
1616
import { ToggleButton } from "@material-ui/lab";
1717
import { useHotkeys } from "react-hotkeys-hook";
1818
import { TestRun } from "../types";
19-
import {
20-
testRunService,
21-
testVariationService,
22-
staticService,
23-
} from "../services";
19+
import { testRunService, staticService } from "../services";
2420
import { TestStatus } from "../types/testStatus";
2521
import { useHistory, Prompt } from "react-router-dom";
2622
import { IgnoreArea } from "../types/ignoreArea";
@@ -112,12 +108,11 @@ const TestDetailsModal: React.FunctionComponent<{
112108
};
113109

114110
const saveTestRun = (ignoreAreas: IgnoreArea[], successMessage: string) => {
115-
Promise.all([
116-
// update in test run
117-
testRunService.setIgnoreAreas(testRun.id, ignoreAreas),
118-
// update in variation
119-
testVariationService.setIgnoreAreas(testRun.testVariationId, ignoreAreas),
120-
])
111+
testRunService
112+
.updateIgnoreAreas({
113+
ids: [testRun.id],
114+
ignoreAreas,
115+
})
121116
.then(() => {
122117
enqueueSnackbar(successMessage, {
123118
variant: "success",
@@ -349,15 +344,8 @@ const TestDetailsModal: React.FunctionComponent<{
349344
<CommentsPopper
350345
text={testRun.comment}
351346
onSave={(comment) =>
352-
Promise.all([
353-
// update in test run
354-
testRunService.setComment(testRun.id, comment),
355-
// update in variation
356-
testVariationService.setComment(
357-
testRun.testVariationId,
358-
comment
359-
),
360-
])
347+
testRunService
348+
.update(testRun.id, { comment })
361349
.then(() =>
362350
enqueueSnackbar("Comment updated", {
363351
variant: "success",

src/components/TestRunList/BulkOperation.tsx

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { useSnackbar } from "notistack";
1111
import { Delete, LayersClear, ThumbDown, ThumbUp } from "@material-ui/icons";
1212
import { testRunService } from "../../services";
1313
import { TestStatus } from "../../types";
14+
import { head } from "lodash";
1415

1516
export const BulkOperation: React.FunctionComponent<BaseComponentProps> = (
1617
props: BaseComponentProps
@@ -23,6 +24,34 @@ export const BulkOperation: React.FunctionComponent<BaseComponentProps> = (
2324
false
2425
);
2526
const [isProcessing, setIsProcessing] = React.useState(false);
27+
const ids: string[] = React.useMemo(
28+
() => Object.keys(props.state.selection),
29+
[props.state.selection]
30+
);
31+
const isMerge: boolean = React.useMemo(
32+
() =>
33+
!!head(
34+
props.rows.filter((value: RowModel) =>
35+
ids.includes(value.id.toString())
36+
)
37+
)?.merge,
38+
// eslint-disable-next-line
39+
[ids]
40+
);
41+
const idsEligibleForApproveOrReject: string[] = React.useMemo(
42+
() =>
43+
props.rows
44+
.filter(
45+
(value: RowModel) =>
46+
ids.includes(value.id.toString()) &&
47+
[TestStatus.new, TestStatus.unresolved].includes(
48+
value.status.toString()
49+
)
50+
)
51+
.map((value: RowModel) => value.id.toString()),
52+
// eslint-disable-next-line
53+
[ids]
54+
);
2655

2756
const selectedRows: Record<React.ReactText, boolean> = props.state.selection;
2857
const count = Object.keys(selectedRows).length;
@@ -78,38 +107,20 @@ export const BulkOperation: React.FunctionComponent<BaseComponentProps> = (
78107
}
79108
};
80109

81-
const isRowEligibleForApproveOrReject = (id: string) => {
82-
//Find the test status of the current row
83-
let currentRow: any = props.rows.find((value: RowModel) =>
84-
value.id.toString().includes(id)
85-
);
86-
let currentRowStatus = JSON.stringify(currentRow.status);
87-
//In line with how we can approve/reject only new and unresolved from details modal.
88-
return (
89-
currentRowStatus.includes(TestStatus.new) ||
90-
currentRowStatus.includes(TestStatus.unresolved)
91-
);
92-
};
93-
94-
const processAction = (id: string) => {
110+
const getBulkAction = () => {
95111
if (deleteDialogOpen) {
96-
testRunService.remove(id);
97-
}
98-
if (isRowEligibleForApproveOrReject(id)) {
99-
processApproveReject(id);
112+
return testRunService.removeBulk(ids);
100113
}
101-
if (clearIgnoreDialogOpen) {
102-
testRunService.setIgnoreAreas(id, []);
114+
if (rejectDialogOpen) {
115+
return testRunService.rejectBulk(idsEligibleForApproveOrReject);
103116
}
104-
};
105-
106-
const processApproveReject = (id: string) => {
107117
if (approveDialogOpen) {
108-
testRunService.approve(id, false);
109-
}
110-
if (rejectDialogOpen) {
111-
testRunService.reject(id);
118+
return testRunService.approveBulk(idsEligibleForApproveOrReject, isMerge);
112119
}
120+
return testRunService.updateIgnoreAreas({
121+
ids,
122+
ignoreAreas: [],
123+
});
113124
};
114125

115126
const dismissDialog = () => {
@@ -182,9 +193,7 @@ export const BulkOperation: React.FunctionComponent<BaseComponentProps> = (
182193
}
183194
onSubmit={() => {
184195
setIsProcessing(true);
185-
Promise.all(
186-
Object.keys(selectedRows).map((id: string) => processAction(id))
187-
)
196+
getBulkAction()
188197
.then(() => {
189198
setIsProcessing(false);
190199
enqueueSnackbar(`${count} test runs processed.`, {

src/services/testRun.service.ts

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { TestRun } from "../types";
22
import { handleResponse, authHeader } from "../_helpers/service.helpers";
33
import { API_URL } from "../_config/env.config";
4-
import { IgnoreArea } from "../types/ignoreArea";
4+
import { UpdateIgnoreAreaDto } from "../types/ignoreArea";
55

66
const ENDPOINT_URL = "/test-runs";
77

@@ -17,61 +17,74 @@ async function getList(buildId: string): Promise<TestRun[]> {
1717
).then(handleResponse);
1818
}
1919

20-
async function remove(id: string): Promise<TestRun> {
20+
async function removeBulk(ids: string[]): Promise<void> {
2121
const requestOptions = {
22-
method: "DELETE",
23-
headers: authHeader(),
22+
method: "POST",
23+
headers: { "Content-Type": "application/json", ...authHeader() },
24+
body: JSON.stringify(ids),
2425
};
2526

26-
return fetch(`${API_URL}${ENDPOINT_URL}/${id}`, requestOptions).then(
27+
return fetch(`${API_URL}${ENDPOINT_URL}/delete`, requestOptions).then(
2728
handleResponse
2829
);
2930
}
3031

31-
async function approve(id: string, merge: boolean): Promise<TestRun> {
32+
async function rejectBulk(ids: string[]): Promise<void> {
3233
const requestOptions = {
33-
method: "GET",
34-
headers: authHeader(),
34+
method: "POST",
35+
headers: { "Content-Type": "application/json", ...authHeader() },
36+
body: JSON.stringify(ids),
37+
};
38+
39+
return fetch(`${API_URL}${ENDPOINT_URL}/reject`, requestOptions).then(
40+
handleResponse
41+
);
42+
}
43+
44+
async function approveBulk(ids: string[], merge: boolean): Promise<void> {
45+
const requestOptions = {
46+
method: "POST",
47+
headers: { "Content-Type": "application/json", ...authHeader() },
48+
body: JSON.stringify(ids),
3549
};
3650

3751
return fetch(
38-
`${API_URL}${ENDPOINT_URL}/approve?id=${id}&merge=${merge}`,
52+
`${API_URL}${ENDPOINT_URL}/approve?merge=${merge}`,
3953
requestOptions
4054
).then(handleResponse);
4155
}
4256

43-
async function reject(id: string): Promise<TestRun> {
57+
async function updateIgnoreAreas(data: UpdateIgnoreAreaDto): Promise<void> {
4458
const requestOptions = {
45-
method: "GET",
46-
headers: authHeader(),
59+
method: "POST",
60+
headers: { "Content-Type": "application/json", ...authHeader() },
61+
body: JSON.stringify(data),
4762
};
4863

49-
return fetch(`${API_URL}${ENDPOINT_URL}/reject/${id}`, requestOptions).then(
50-
handleResponse
51-
);
64+
return fetch(
65+
`${API_URL}${ENDPOINT_URL}/ignoreAreas/update`,
66+
requestOptions
67+
).then(handleResponse);
5268
}
5369

54-
async function setIgnoreAreas(
55-
id: string,
56-
ignoreAreas: IgnoreArea[]
57-
): Promise<TestRun> {
70+
async function addIgnoreAreas(data: UpdateIgnoreAreaDto): Promise<void> {
5871
const requestOptions = {
59-
method: "PUT",
72+
method: "POST",
6073
headers: { "Content-Type": "application/json", ...authHeader() },
61-
body: JSON.stringify(ignoreAreas),
74+
body: JSON.stringify(data),
6275
};
6376

6477
return fetch(
65-
`${API_URL}${ENDPOINT_URL}/ignoreArea/${id}`,
78+
`${API_URL}${ENDPOINT_URL}/ignoreAreas/add`,
6679
requestOptions
6780
).then(handleResponse);
6881
}
6982

70-
async function setComment(id: string, comment: string): Promise<TestRun> {
83+
async function update(id: string, data: { comment: string }): Promise<TestRun> {
7184
const requestOptions = {
7285
method: "PUT",
7386
headers: { "Content-Type": "application/json", ...authHeader() },
74-
body: JSON.stringify({ comment }),
87+
body: JSON.stringify(data),
7588
};
7689

7790
return fetch(`${API_URL}${ENDPOINT_URL}/comment/${id}`, requestOptions).then(
@@ -81,9 +94,10 @@ async function setComment(id: string, comment: string): Promise<TestRun> {
8194

8295
export const testRunService = {
8396
getList,
84-
remove,
85-
approve,
86-
reject,
87-
setIgnoreAreas,
88-
setComment,
97+
removeBulk,
98+
rejectBulk,
99+
approveBulk,
100+
updateIgnoreAreas,
101+
addIgnoreAreas,
102+
update,
89103
};

src/services/testVariation.service.ts

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { TestVariation, Build } from "../types";
22
import { handleResponse, authHeader } from "../_helpers/service.helpers";
33
import { API_URL } from "../_config/env.config";
4-
import { IgnoreArea } from "../types/ignoreArea";
54

65
const ENDPOINT_URL = "/test-variations";
76

@@ -28,34 +27,6 @@ async function getDetails(id: String): Promise<TestVariation> {
2827
);
2928
}
3029

31-
async function setIgnoreAreas(
32-
variationId: string,
33-
ignoreAreas: IgnoreArea[]
34-
): Promise<TestVariation> {
35-
const requestOptions = {
36-
method: "PUT",
37-
headers: { "Content-Type": "application/json", ...authHeader() },
38-
body: JSON.stringify(ignoreAreas),
39-
};
40-
41-
return fetch(
42-
`${API_URL}${ENDPOINT_URL}/ignoreArea/${variationId}`,
43-
requestOptions
44-
).then(handleResponse);
45-
}
46-
47-
async function setComment(id: string, comment: string): Promise<TestVariation> {
48-
const requestOptions = {
49-
method: "PUT",
50-
headers: { "Content-Type": "application/json", ...authHeader() },
51-
body: JSON.stringify({ comment }),
52-
};
53-
54-
return fetch(`${API_URL}${ENDPOINT_URL}/comment/${id}`, requestOptions).then(
55-
handleResponse
56-
);
57-
}
58-
5930
async function merge(projectId: String, branchName: String): Promise<Build> {
6031
const requestOptions = {
6132
method: "GET",
@@ -82,8 +53,6 @@ async function remove(id: String): Promise<TestVariation> {
8253
export const testVariationService = {
8354
getList,
8455
getDetails,
85-
setIgnoreAreas,
86-
setComment,
8756
merge,
8857
remove,
8958
};

src/types/ignoreArea.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,8 @@ export interface IgnoreArea {
55
width: number;
66
height: number;
77
}
8+
9+
export interface UpdateIgnoreAreaDto {
10+
ids: string[];
11+
ignoreAreas: IgnoreArea[];
12+
}

0 commit comments

Comments
 (0)