Skip to content

Commit 478fea6

Browse files
committed
feat: add mui autocomplete checkboxes for component filter
1 parent c898e0c commit 478fea6

File tree

1 file changed

+75
-41
lines changed

1 file changed

+75
-41
lines changed

ui/intermittent-failures/MainView.jsx

Lines changed: 75 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import ReactTable from 'react-table-6';
66
import Checkbox from '@mui/material/Checkbox';
77
import TextField from '@mui/material/TextField';
88
import Autocomplete from '@mui/material/Autocomplete';
9+
import Popper from '@mui/material/Popper';
910

1011
import { bugsEndpoint } from '../helpers/url';
1112
import { setUrlParam, getUrlParam } from '../helpers/location';
@@ -21,6 +22,16 @@ import withView from './View';
2122
import Layout from './Layout';
2223
import DateRangePicker from './DateRangePicker';
2324

25+
const CustomPopper = (props) => {
26+
return (
27+
<Popper
28+
{...props}
29+
style={{ width: '350px', textAlign: 'left' }}
30+
placement="bottom-start"
31+
/>
32+
);
33+
};
34+
2435
const MainView = (props) => {
2536
const {
2637
graphData,
@@ -35,7 +46,10 @@ const MainView = (props) => {
3546
updateAppState,
3647
} = props;
3748

38-
const [selectedProduct, setSelectedProduct] = React.useState([]);
49+
const [selectedFilter, setSelectedFilter] = React.useState({
50+
product: [],
51+
component: [],
52+
});
3953
const textFilter = (filter, row) => {
4054
if (getUrlParam(filter.id) !== filter.value) {
4155
setUrlParam(filter.id, filter.value);
@@ -47,6 +61,41 @@ const MainView = (props) => {
4761
}
4862
};
4963

64+
const autoCompleteFilter = ({ column, onChange }) => {
65+
const options = [...new Set(tableData.map((d) => d[column.id]))];
66+
options.sort();
67+
return (
68+
<Autocomplete
69+
slots={{ popper: CustomPopper }}
70+
size="small"
71+
multiple
72+
limitTags={0}
73+
id="checkboxes-tags-filter"
74+
options={options}
75+
onChange={(_event, values) => {
76+
setUrlParam(column.id, values);
77+
onChange(values);
78+
setSelectedFilter({ ...selectedFilter, [column.id]: values });
79+
}}
80+
disableCloseOnSelect
81+
defaultValue={selectedFilter[column.id]}
82+
fullWidth
83+
renderOption={(props, option, { selected }) => {
84+
const { key, ...optionProps } = props;
85+
return (
86+
<li key={key} {...optionProps}>
87+
<Checkbox style={{ marginRight: 8 }} checked={selected} />
88+
{option}
89+
</li>
90+
);
91+
}}
92+
renderInput={(params) => (
93+
<TextField style={{ border: 'none', padding: '0' }} {...params} />
94+
)}
95+
/>
96+
);
97+
};
98+
5099
const columns = [
51100
{
52101
Header: 'Bug',
@@ -80,51 +129,28 @@ const MainView = (props) => {
80129
accessor: 'product',
81130
maxWidth: 100,
82131
filterMethod: (filter, row) => {
83-
const regex = RegExp(filter.value.join('|'), 'i');
84-
if (regex.test(row.product)) {
85-
return row;
132+
if (filter.value) {
133+
const regex = RegExp(filter.value.join('|'), 'i');
134+
if (regex.test(row.product)) {
135+
return row;
136+
}
86137
}
87138
},
88-
Filter: ({ onChange }) => {
89-
return (
90-
<Autocomplete
91-
multiple
92-
id="checkboxes-tags-filter"
93-
options={[...new Set(tableData.map((d) => d.product))]}
94-
onChange={(_event, values) => {
95-
setUrlParam('product', values);
96-
onChange(values);
97-
}}
98-
limitTags={2}
99-
disableCloseOnSelect
100-
defaultValue={selectedProduct}
101-
style={{
102-
width: '20em',
103-
}}
104-
renderOption={(props, option, { selected }) => {
105-
const { key, ...optionProps } = props;
106-
return (
107-
<li key={key} {...optionProps}>
108-
<Checkbox style={{ marginRight: 8 }} checked={selected} />
109-
{option}
110-
</li>
111-
);
112-
}}
113-
renderInput={(params) => (
114-
<TextField
115-
style={{ border: 'none', height: '0.3em', padding: '0' }}
116-
{...params}
117-
/>
118-
)}
119-
/>
120-
);
121-
},
139+
Filter: autoCompleteFilter,
122140
},
123141
{
124142
Header: 'Component',
125143
accessor: 'component',
126144
maxWidth: 100,
127-
filterMethod: (filter, row) => textFilter(filter, row),
145+
filterMethod: (filter, row) => {
146+
if (filter.value) {
147+
const regex = RegExp(filter.value.join('|'), 'i');
148+
if (regex.test(row.component)) {
149+
return row;
150+
}
151+
}
152+
},
153+
Filter: autoCompleteFilter,
128154
},
129155
{
130156
Header: 'Summary',
@@ -173,8 +199,16 @@ const MainView = (props) => {
173199
if (param) {
174200
if (header === 'product') {
175201
filters.push({ id: header, value: param.split(',') });
176-
if (selectedProduct.length === 0) {
177-
setSelectedProduct(param.split(','));
202+
if (selectedFilter.product.length === 0) {
203+
setSelectedFilter({ ...selectedFilter, product: param.split(',') });
204+
}
205+
} else if (header === 'component') {
206+
filters.push({ id: header, value: param.split(',') });
207+
if (selectedFilter.component.length === 0) {
208+
setSelectedFilter({
209+
...selectedFilter,
210+
component: param.split(','),
211+
});
178212
}
179213
} else {
180214
filters.push({ id: header, value: param });

0 commit comments

Comments
 (0)