Skip to content

Commit e51ba74

Browse files
committed
#3. Test filter added
1 parent 526a1e5 commit e51ba74

File tree

2 files changed

+210
-3
lines changed

2 files changed

+210
-3
lines changed

src/components/Filters.tsx

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
import React from "react";
2+
import {
3+
Grid,
4+
TextField,
5+
IconButton,
6+
Select,
7+
MenuItem,
8+
FormControl,
9+
InputLabel,
10+
} from "@material-ui/core";
11+
import { Clear } from "@material-ui/icons";
12+
import { TestRun } from "../types";
13+
14+
interface IProps {
15+
testRuns: TestRun[];
16+
queryState: [string, React.Dispatch<React.SetStateAction<string>>];
17+
osState: [string, React.Dispatch<React.SetStateAction<string>>];
18+
browserState: [string, React.Dispatch<React.SetStateAction<string>>];
19+
viewportState: [string, React.Dispatch<React.SetStateAction<string>>];
20+
testStatusState: [string, React.Dispatch<React.SetStateAction<string>>];
21+
}
22+
23+
const Filters: React.FunctionComponent<IProps> = ({
24+
testRuns,
25+
queryState,
26+
osState,
27+
browserState,
28+
viewportState,
29+
testStatusState,
30+
}) => {
31+
const [query, setQuery] = queryState;
32+
const [os, setOs] = osState;
33+
const [browser, setBrowser] = browserState;
34+
const [viewport, setViewport] = viewportState;
35+
const [testStatus, setTestStatus] = testStatusState;
36+
37+
const osList = testRuns
38+
.map((t) => t.testVariation.os)
39+
.filter((v, i, array) => v && array.indexOf(v) === i);
40+
41+
const browserList = testRuns
42+
.map((t) => t.testVariation.browser)
43+
.filter((v, i, array) => v && array.indexOf(v) === i);
44+
45+
const viewportList = testRuns
46+
.map((t) => t.testVariation.viewport)
47+
.filter((v, i, array) => v && array.indexOf(v) === i);
48+
49+
const testStatusList = testRuns
50+
.map((t) => t.status)
51+
.filter((v, i, array) => v && array.indexOf(v) === i);
52+
53+
return (
54+
<React.Fragment>
55+
<Grid container spacing={2} alignItems='flex-end'>
56+
<Grid item xs>
57+
<TextField
58+
fullWidth
59+
label="Name"
60+
value={query}
61+
onChange={(event) => setQuery(event?.target.value)}
62+
InputProps={{
63+
endAdornment: (
64+
<IconButton onClick={() => setQuery("")}>
65+
<Clear />
66+
</IconButton>
67+
),
68+
}}
69+
/>
70+
</Grid>
71+
{osList.length > 0 && (
72+
<Grid item xs>
73+
<FormControl fullWidth>
74+
<InputLabel shrink id="filter_os">
75+
OS
76+
</InputLabel>
77+
<Select
78+
id="filter_os"
79+
value={os}
80+
displayEmpty
81+
onChange={(event) => setOs(event.target.value as string)}
82+
>
83+
<MenuItem value="">
84+
<em>All</em>
85+
</MenuItem>
86+
{osList.map((os) => (
87+
<MenuItem key={os} value={os}>
88+
{os}
89+
</MenuItem>
90+
))}
91+
</Select>
92+
</FormControl>
93+
</Grid>
94+
)}
95+
{browserList.length > 0 && (
96+
<Grid item xs>
97+
<FormControl fullWidth>
98+
<InputLabel shrink id="filter_browser">
99+
Browser
100+
</InputLabel>
101+
<Select
102+
id="filter_browser"
103+
value={browser}
104+
displayEmpty
105+
onChange={(event) => setBrowser(event.target.value as string)}
106+
>
107+
<MenuItem value="">
108+
<em>All</em>
109+
</MenuItem>
110+
{browserList.map((item) => (
111+
<MenuItem key={item} value={item}>
112+
{item}
113+
</MenuItem>
114+
))}
115+
</Select>
116+
</FormControl>
117+
</Grid>
118+
)}
119+
{viewportList.length > 0 && (
120+
<Grid item xs>
121+
<FormControl fullWidth>
122+
<InputLabel shrink id="filter_viewport">
123+
Viewport
124+
</InputLabel>
125+
<Select
126+
id="filter_viewport"
127+
value={viewport}
128+
displayEmpty
129+
onChange={(event) => setViewport(event.target.value as string)}
130+
>
131+
<MenuItem value="">
132+
<em>All</em>
133+
</MenuItem>
134+
{viewportList.map((item) => (
135+
<MenuItem key={item} value={item}>
136+
{item}
137+
</MenuItem>
138+
))}
139+
</Select>
140+
</FormControl>
141+
</Grid>
142+
)}
143+
{testStatusList.length > 0 && (
144+
<Grid item xs>
145+
<FormControl fullWidth>
146+
<InputLabel shrink id="filter_testStatus">
147+
Status
148+
</InputLabel>
149+
<Select
150+
id="filter_testStatus"
151+
value={testStatus}
152+
displayEmpty
153+
onChange={(event) =>
154+
setTestStatus(event.target.value as string)
155+
}
156+
>
157+
<MenuItem value="">
158+
<em>All</em>
159+
</MenuItem>
160+
{testStatusList.map((item) => (
161+
<MenuItem key={item} value={item}>
162+
{item}
163+
</MenuItem>
164+
))}
165+
</Select>
166+
</FormControl>
167+
</Grid>
168+
)}
169+
</Grid>
170+
</React.Fragment>
171+
);
172+
};
173+
174+
export default Filters;

src/pages/ProjectPage.tsx

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useEffect, useState } from "react";
2-
import { Grid, Dialog, IconButton } from "@material-ui/core";
2+
import { Grid, Dialog, IconButton, Box } from "@material-ui/core";
33
import { useParams, useLocation, useHistory } from "react-router-dom";
44
import { Build, TestRun } from "../types";
55
import { projectsService, buildsService, testsService } from "../services";
@@ -9,6 +9,7 @@ import qs from "qs";
99
import TestRunList from "../components/TestRunList";
1010
import TestDetailsModal from "../components/TestDetailsModal";
1111
import { NavigateBefore, NavigateNext } from "@material-ui/icons";
12+
import Filters from "../components/Filters";
1213

1314
const getQueryParams = (guery: string) => {
1415
const queryParams = qs.parse(guery, { ignoreQueryPrefix: true });
@@ -50,6 +51,14 @@ const ProjectPage = () => {
5051
const [selectedTestdId, setSelectedTestId] = useState<string>();
5152
const [selectedTestRunIndex, setSelectedTestRunIndex] = useState<number>();
5253

54+
// filter
55+
const [query, setQuery] = React.useState("");
56+
const [os, setOs] = React.useState("");
57+
const [browser, setBrowser] = React.useState("");
58+
const [viewport, setViewport] = React.useState("");
59+
const [testStatus, setTestStatus] = React.useState("");
60+
const [filteredTestRuns, setFilteredTestRuns] = React.useState<TestRun[]>([]);
61+
5362
useEffect(() => {
5463
const queryParams = getQueryParams(location.search);
5564
if (queryParams.buildId) {
@@ -81,6 +90,19 @@ const ProjectPage = () => {
8190
}
8291
}, [selectedBuildId]);
8392

93+
useEffect(() => {
94+
setFilteredTestRuns(
95+
testRuns.filter(
96+
(t) =>
97+
t.testVariation.name.includes(query) && // by query
98+
(os ? t.testVariation.os === os : true) && // by OS
99+
(viewport ? t.testVariation.viewport === viewport : true) && // by viewport
100+
(testStatus ? t.status === testStatus : true) && // by status
101+
(browser ? t.testVariation.browser === browser : true) // by browser
102+
)
103+
);
104+
}, [query, os, browser, viewport, testStatus, testRuns]);
105+
84106
const updateTestRun = (testRun: TestRun) => {
85107
const updated = testRuns.map((t) => {
86108
if (t.id === testRun.id) {
@@ -109,10 +131,21 @@ const ProjectPage = () => {
109131
</Grid>
110132
<Grid item xs={9}>
111133
<Grid container direction="column">
112-
<Grid item>Pannel</Grid>
134+
<Grid item>
135+
<Box m={2}>
136+
<Filters
137+
testRuns={testRuns}
138+
queryState={[query, setQuery]}
139+
osState={[os, setOs]}
140+
browserState={[browser, setBrowser]}
141+
viewportState={[viewport, setViewport]}
142+
testStatusState={[testStatus, setTestStatus]}
143+
/>
144+
</Box>
145+
</Grid>
113146
<Grid item>
114147
<TestRunList
115-
items={testRuns}
148+
items={filteredTestRuns}
116149
selectedId={selectedTestdId}
117150
handleRemove={(id: string) =>
118151
testsService.remove(id).then((isRemoved) => {

0 commit comments

Comments
 (0)