Skip to content

Commit 45abbb1

Browse files
authored
Fix issue 185 : Approve all button to approve only filtered images (#171)
1 parent ba0f367 commit 45abbb1

File tree

5 files changed

+159
-103
lines changed

5 files changed

+159
-103
lines changed

src/components/BuildDetails.tsx

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,56 +4,19 @@ import {
44
Chip,
55
Grid,
66
Box,
7-
Button,
87
LinearProgress,
98
} from "@material-ui/core";
109
import { BuildStatusChip } from "./BuildStatusChip";
11-
import { useSnackbar } from "notistack";
12-
import { buildsService } from "../services";
1310
import { formatDateTime } from "../_helpers/format.helper";
1411
import { useBuildState } from "../contexts";
1512

1613
const BuildDetails: React.FunctionComponent = () => {
17-
const { enqueueSnackbar } = useSnackbar();
1814
const { selectedBuild } = useBuildState();
1915

2016
if (!selectedBuild) {
2117
return null;
2218
}
2319

24-
const approveAllButton = selectedBuild.unresolvedCount > 0 && (
25-
<Grid item>
26-
<Button
27-
variant="contained"
28-
color="primary"
29-
size="small"
30-
onClick={async () => {
31-
enqueueSnackbar(
32-
"Wait for the confirmation message until approval is completed.",
33-
{
34-
variant: "info",
35-
}
36-
);
37-
38-
buildsService
39-
.approve(selectedBuild.id, selectedBuild.merge)
40-
.then(() =>
41-
enqueueSnackbar("All approved.", {
42-
variant: "success",
43-
})
44-
)
45-
.catch((err) =>
46-
enqueueSnackbar(err, {
47-
variant: "error",
48-
})
49-
);
50-
}}
51-
>
52-
Approve All
53-
</Button>
54-
</Grid>
55-
);
56-
5720
const loadingAnimation = selectedBuild.isRunning && <LinearProgress />;
5821

5922
return (
@@ -72,7 +35,6 @@ const BuildDetails: React.FunctionComponent = () => {
7235
<Grid item>
7336
<BuildStatusChip status={selectedBuild.status} />
7437
</Grid>
75-
{approveAllButton}
7638
</Grid>
7739
</Box>
7840
</Grid>

src/components/TestRunList/BulkDeleteButton.tsx

Lines changed: 0 additions & 60 deletions
This file was deleted.
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import React from "react";
2+
import { Typography, IconButton, Tooltip } from "@material-ui/core";
3+
import { BaseComponentProps, RowModel } from "@material-ui/data-grid";
4+
import { BaseModal } from "../BaseModal";
5+
import { useSnackbar } from "notistack";
6+
import { Delete, ThumbDown, ThumbUp } from "@material-ui/icons";
7+
import { testRunService } from "../../services";
8+
import { TestStatus } from "../../types";
9+
10+
export const BulkOperation: React.FunctionComponent<BaseComponentProps> = (
11+
props: BaseComponentProps
12+
) => {
13+
const { enqueueSnackbar } = useSnackbar();
14+
const [approveDialogOpen, setApproveDialogOpen] = React.useState(false);
15+
const [rejectDialogOpen, setRejectDialogOpen] = React.useState(false);
16+
const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false);
17+
18+
const rows: Record<React.ReactText, boolean> = props.state.selection;
19+
const count = Object.keys(rows).length;
20+
21+
const toggleApproveDialogOpen = () => {
22+
setApproveDialogOpen(!approveDialogOpen);
23+
};
24+
const toggleRejectDialogOpen = () => {
25+
setRejectDialogOpen(!rejectDialogOpen);
26+
};
27+
const toggleDeleteDialogOpen = () => {
28+
setDeleteDialogOpen(!deleteDialogOpen);
29+
};
30+
31+
const getTitle = () => {
32+
return submitButtonText() + " Test Runs";
33+
};
34+
35+
const submitButtonText = (): string => {
36+
if (deleteDialogOpen) {
37+
return "Delete";
38+
}
39+
if (approveDialogOpen) {
40+
return "Approve";
41+
}
42+
if (rejectDialogOpen) {
43+
return "Reject";
44+
}
45+
return "";
46+
};
47+
48+
const closeModal = () => {
49+
if (deleteDialogOpen) {
50+
return toggleDeleteDialogOpen();
51+
}
52+
if (approveDialogOpen) {
53+
return toggleApproveDialogOpen();
54+
}
55+
if (rejectDialogOpen) {
56+
return toggleRejectDialogOpen();
57+
}
58+
};
59+
60+
const isRowEligibleForApproveOrReject = (id: string) => {
61+
//Find the test status of the current row
62+
let currentRow: any = props.rows.find((value: RowModel) => value.id.toString().includes(id));
63+
let currentRowStatus = JSON.stringify(currentRow.status);
64+
//In line with how we can approve/reject only new and unresolved from details modal.
65+
return (currentRowStatus.includes(TestStatus.new) || currentRowStatus.includes(TestStatus.unresolved));
66+
};
67+
68+
const processAction = (id: string) => {
69+
if (deleteDialogOpen) {
70+
testRunService.remove(id);
71+
}
72+
if (isRowEligibleForApproveOrReject(id)) {
73+
processApproveReject(id);
74+
}
75+
};
76+
77+
const processApproveReject = (id: string) => {
78+
if (approveDialogOpen) {
79+
testRunService.approve(id, false);
80+
}
81+
if (rejectDialogOpen) {
82+
testRunService.reject(id);
83+
}
84+
};
85+
86+
const dismissDialog = () => {
87+
if (deleteDialogOpen) {
88+
return toggleDeleteDialogOpen();
89+
}
90+
if (approveDialogOpen) {
91+
return toggleApproveDialogOpen();
92+
}
93+
return toggleRejectDialogOpen();
94+
};
95+
96+
return (
97+
<>
98+
<Tooltip title="Approve unresolved in selected rows." aria-label="approve">
99+
<span>
100+
<IconButton disabled={count === 0} onClick={toggleApproveDialogOpen}>
101+
<ThumbUp />
102+
</IconButton>
103+
</span>
104+
</Tooltip>
105+
<Tooltip title="Reject unresolved in selected rows." aria-label="reject">
106+
<span>
107+
<IconButton disabled={count === 0} onClick={toggleRejectDialogOpen}>
108+
<ThumbDown />
109+
</IconButton>
110+
</span>
111+
</Tooltip>
112+
<Tooltip title="Delete selected rows." aria-label="delete">
113+
<span>
114+
<IconButton disabled={count === 0} onClick={toggleDeleteDialogOpen}>
115+
<Delete />
116+
</IconButton>
117+
</span>
118+
</Tooltip>
119+
120+
<BaseModal
121+
open={deleteDialogOpen || approveDialogOpen || rejectDialogOpen}
122+
title={getTitle()}
123+
submitButtonText={submitButtonText()}
124+
onCancel={dismissDialog}
125+
content={
126+
<Typography>{`Are you sure you want to ${submitButtonText().toLowerCase()} ${count} items?`}</Typography>
127+
}
128+
onSubmit={() => {
129+
enqueueSnackbar(
130+
"Wait for the confirmation message until operation is completed.",
131+
{
132+
variant: "info",
133+
}
134+
);
135+
136+
Promise.all(
137+
Object.keys(rows).map((id: string) => processAction(id))
138+
)
139+
.then(() => {
140+
enqueueSnackbar(`${count} test runs processed.`, {
141+
variant: "success",
142+
});
143+
})
144+
.catch((err) =>
145+
enqueueSnackbar(err, {
146+
variant: "error",
147+
})
148+
);
149+
closeModal();
150+
}}
151+
/>
152+
</>
153+
);
154+
};

src/components/TestRunList/DataGridCustomToolbar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
DensitySelector,
66
FilterToolbarButton,
77
} from "@material-ui/data-grid";
8-
import { BulkDeleteButton } from "./BulkDeleteButton";
8+
import { BulkOperation } from "./BulkOperation";
99

1010
export const DataGridCustomToolbar: React.FunctionComponent<BaseComponentProps> = (
1111
props: BaseComponentProps
@@ -16,7 +16,7 @@ export const DataGridCustomToolbar: React.FunctionComponent<BaseComponentProps>
1616
<FilterToolbarButton />
1717
<DensitySelector />
1818
<Box marginLeft="auto">
19-
<BulkDeleteButton {...props} />
19+
<BulkOperation {...props} />
2020
</Box>
2121
</Toolbar>
2222
</>

src/components/TestRunList/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ const TestRunList: React.FunctionComponent = () => {
7676
const { selectedBuildId } = useBuildState();
7777
const testRunDispatch = useTestRunDispatch();
7878

79-
const getTestRunListCalback = React.useCallback(
79+
const getTestRunListCallback = React.useCallback(
8080
() =>
8181
selectedBuildId &&
8282
getTestRunList(testRunDispatch, selectedBuildId).catch((err: string) =>
@@ -88,8 +88,8 @@ const TestRunList: React.FunctionComponent = () => {
8888
);
8989

9090
React.useEffect(() => {
91-
getTestRunListCalback();
92-
}, [getTestRunListCalback]);
91+
getTestRunListCallback();
92+
}, [getTestRunListCallback]);
9393

9494
return (
9595
<React.Fragment>

0 commit comments

Comments
 (0)