diff --git a/package.json b/package.json
index f1d5ede0870..3652a6e3952 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,8 @@
"@fortawesome/free-regular-svg-icons": "6.7.2",
"@fortawesome/free-solid-svg-icons": "6.7.2",
"@fortawesome/react-fontawesome": "0.2.2",
+ "@mui/material": "7.1.1",
+ "@mui/styled-engine-sc": "npm:@mui/styled-engine-sc@latest",
"@types/react": "*",
"@types/react-dom": "*",
"ajv": "8.17.1",
@@ -70,7 +72,6 @@
},
"devDependencies": {
"@babel/core": "7.26.10",
- "@babel/eslint-parser": "7.25.9",
"@babel/eslint-parser": "7.26.10",
"@babel/plugin-proposal-class-properties": "7.18.6",
"@babel/plugin-syntax-dynamic-import": "7.8.3",
@@ -135,6 +136,7 @@
"test:watch": "node ./node_modules/jest/bin/jest --watch"
},
"resolutions": {
- "cacache": "19.0.1"
+ "cacache": "19.0.1",
+ "@mui/styled-engine": "npm:@mui/styled-engine-sc@latest"
}
}
diff --git a/ui/css/react-table.css b/ui/css/react-table.css
index d417fa8f8b0..3ecc6beb997 100644
--- a/ui/css/react-table.css
+++ b/ui/css/react-table.css
@@ -504,3 +504,12 @@
-ms-user-select: none;
user-select: none;
}
+
+.ReactTable .MuiAutocomplete-inputRoot {
+ max-height: 2em;
+}
+
+.ReactTable .MuiAutocomplete-inputRoot .MuiOutlinedInput-input {
+ border: none;
+ height: 1em;
+}
diff --git a/ui/intermittent-failures/MainView.jsx b/ui/intermittent-failures/MainView.jsx
index 2dad5b5fe3c..6de670a8b21 100644
--- a/ui/intermittent-failures/MainView.jsx
+++ b/ui/intermittent-failures/MainView.jsx
@@ -3,6 +3,10 @@ import { Row, Col, Breadcrumb, BreadcrumbItem } from 'reactstrap';
import PropTypes from 'prop-types';
import moment from 'moment';
import ReactTable from 'react-table-6';
+import Checkbox from '@mui/material/Checkbox';
+import TextField from '@mui/material/TextField';
+import Autocomplete from '@mui/material/Autocomplete';
+import Popper from '@mui/material/Popper';
import { bugsEndpoint } from '../helpers/url';
import { setUrlParam, getUrlParam } from '../helpers/location';
@@ -18,6 +22,16 @@ import withView from './View';
import Layout from './Layout';
import DateRangePicker from './DateRangePicker';
+const CustomPopper = (props) => {
+ return (
+
+ );
+};
+
const MainView = (props) => {
const {
graphData,
@@ -32,6 +46,10 @@ const MainView = (props) => {
updateAppState,
} = props;
+ const [selectedFilter, setSelectedFilter] = React.useState({
+ product: [],
+ component: [],
+ });
const textFilter = (filter, row) => {
if (getUrlParam(filter.id) !== filter.value) {
setUrlParam(filter.id, filter.value);
@@ -43,6 +61,49 @@ const MainView = (props) => {
}
};
+ const autoCompleteFilter = ({ column, onChange }) => {
+ const options = [...new Set(tableData.map((d) => d[column.id]))];
+ options.sort();
+ return (
+ {
+ setUrlParam(column.id, values);
+ onChange(values);
+ setSelectedFilter({ ...selectedFilter, [column.id]: values });
+ }}
+ disableCloseOnSelect
+ defaultValue={selectedFilter[column.id]}
+ fullWidth
+ renderOption={(props, option, { selected }) => {
+ const { key, ...optionProps } = props;
+ return (
+
+
+ {option}
+
+ );
+ }}
+ renderInput={(params) => (
+
+ )}
+ />
+ );
+ };
+
const columns = [
{
Header: 'Bug',
@@ -75,13 +136,29 @@ const MainView = (props) => {
Header: 'Product',
accessor: 'product',
maxWidth: 100,
- filterMethod: (filter, row) => textFilter(filter, row),
+ filterMethod: (filter, row) => {
+ if (filter.value) {
+ const regex = RegExp(filter.value.join('|'), 'i');
+ if (regex.test(row.product)) {
+ return row;
+ }
+ }
+ },
+ Filter: autoCompleteFilter,
},
{
Header: 'Component',
accessor: 'component',
maxWidth: 100,
- filterMethod: (filter, row) => textFilter(filter, row),
+ filterMethod: (filter, row) => {
+ if (filter.value) {
+ const regex = RegExp(filter.value.join('|'), 'i');
+ if (regex.test(row.component)) {
+ return row;
+ }
+ }
+ },
+ Filter: autoCompleteFilter,
},
{
Header: 'Summary',
@@ -128,7 +205,22 @@ const MainView = (props) => {
for (const header of ['product', 'component', 'summary', 'whiteboard']) {
const param = getUrlParam(header);
if (param) {
- filters.push({ id: header, value: getUrlParam(header) });
+ if (header === 'product') {
+ filters.push({ id: header, value: param.split(',') });
+ if (selectedFilter.product.length === 0) {
+ setSelectedFilter({ ...selectedFilter, product: param.split(',') });
+ }
+ } else if (header === 'component') {
+ filters.push({ id: header, value: param.split(',') });
+ if (selectedFilter.component.length === 0) {
+ setSelectedFilter({
+ ...selectedFilter,
+ component: param.split(','),
+ });
+ }
+ } else {
+ filters.push({ id: header, value: param });
+ }
}
}
return filters;
diff --git a/yarn.lock b/yarn.lock
index b56ad159c7e..401e1c48ade 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1015,6 +1015,11 @@
dependencies:
regenerator-runtime "^0.14.0"
+"@babel/runtime@^7.27.1", "@babel/runtime@^7.5.5":
+ version "7.27.6"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.6.tgz#ec4070a04d76bae8ddbb10770ba55714a417b7c6"
+ integrity sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==
+
"@babel/template@^7.25.9", "@babel/template@^7.26.9", "@babel/template@^7.27.0", "@babel/template@^7.3.3":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.0.tgz#b253e5406cc1df1c57dcd18f11760c2dbf40c0b4"
@@ -1583,6 +1588,93 @@
dependencies:
"@types/whatwg-streams" "^0.0.7"
+"@mui/core-downloads-tracker@^7.1.1":
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-7.1.1.tgz#43532ccf57be19055eb20e7802508520293cf286"
+ integrity sha512-yBckQs4aQ8mqukLnPC6ivIRv6guhaXi8snVl00VtyojBbm+l6VbVhyTSZ68Abcx7Ah8B+GZhrB7BOli+e+9LkQ==
+
+"@mui/material@7.1.1":
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/@mui/material/-/material-7.1.1.tgz#5f75b25936925be14cb34abe0489cda82a6f8413"
+ integrity sha512-mTpdmdZCaHCGOH3SrYM41+XKvNL0iQfM9KlYgpSjgadXx/fEKhhvOktxm8++Xw6FFeOHoOiV+lzOI8X1rsv71A==
+ dependencies:
+ "@babel/runtime" "^7.27.1"
+ "@mui/core-downloads-tracker" "^7.1.1"
+ "@mui/system" "^7.1.1"
+ "@mui/types" "^7.4.3"
+ "@mui/utils" "^7.1.1"
+ "@popperjs/core" "^2.11.8"
+ "@types/react-transition-group" "^4.4.12"
+ clsx "^2.1.1"
+ csstype "^3.1.3"
+ prop-types "^15.8.1"
+ react-is "^19.1.0"
+ react-transition-group "^4.4.5"
+
+"@mui/private-theming@^7.1.1":
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-7.1.1.tgz#c2ecc57a9b97fbfdd850430de500c42a0f2571fe"
+ integrity sha512-M8NbLUx+armk2ZuaxBkkMk11ultnWmrPlN0Xe3jUEaBChg/mcxa5HWIWS1EE4DF36WRACaAHVAvyekWlDQf0PQ==
+ dependencies:
+ "@babel/runtime" "^7.27.1"
+ "@mui/utils" "^7.1.1"
+ prop-types "^15.8.1"
+
+"@mui/styled-engine-sc@npm:@mui/styled-engine-sc@latest":
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/@mui/styled-engine-sc/-/styled-engine-sc-7.1.1.tgz#44fb74e14f36a091a37b64da0cab5f2678dd1367"
+ integrity sha512-wUh1/aUMLQ1JAD33oL+ZFdx97JB8On1XLFtpsllJR5lNNMAkeLKj+ZDRB4Bm2VqPgGMuv3aVYFYtlJR2FFg73A==
+ dependencies:
+ "@babel/runtime" "^7.27.1"
+ "@types/hoist-non-react-statics" "^3.3.6"
+ csstype "^3.1.3"
+ hoist-non-react-statics "^3.3.2"
+ prop-types "^15.8.1"
+
+"@mui/styled-engine@^7.1.1", "@mui/styled-engine@npm:@mui/styled-engine-sc@latest":
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/@mui/styled-engine-sc/-/styled-engine-sc-7.1.1.tgz#44fb74e14f36a091a37b64da0cab5f2678dd1367"
+ integrity sha512-wUh1/aUMLQ1JAD33oL+ZFdx97JB8On1XLFtpsllJR5lNNMAkeLKj+ZDRB4Bm2VqPgGMuv3aVYFYtlJR2FFg73A==
+ dependencies:
+ "@babel/runtime" "^7.27.1"
+ "@types/hoist-non-react-statics" "^3.3.6"
+ csstype "^3.1.3"
+ hoist-non-react-statics "^3.3.2"
+ prop-types "^15.8.1"
+
+"@mui/system@^7.1.1":
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/@mui/system/-/system-7.1.1.tgz#eff52e597b0bfed8ecf2e973f4575ef737430727"
+ integrity sha512-Kj1uhiqnj4Zo7PDjAOghtXJtNABunWvhcRU0O7RQJ7WOxeynoH6wXPcilphV8QTFtkKaip8EiNJRiCD+B3eROA==
+ dependencies:
+ "@babel/runtime" "^7.27.1"
+ "@mui/private-theming" "^7.1.1"
+ "@mui/styled-engine" "^7.1.1"
+ "@mui/types" "^7.4.3"
+ "@mui/utils" "^7.1.1"
+ clsx "^2.1.1"
+ csstype "^3.1.3"
+ prop-types "^15.8.1"
+
+"@mui/types@^7.4.3":
+ version "7.4.3"
+ resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.4.3.tgz#b205ee3404db0478cd93227fc21967e2cb8630fe"
+ integrity sha512-2UCEiK29vtiZTeLdS2d4GndBKacVyxGvReznGXGr+CzW/YhjIX+OHUdCIczZjzcRAgKBGmE9zCIgoV9FleuyRQ==
+ dependencies:
+ "@babel/runtime" "^7.27.1"
+
+"@mui/utils@^7.1.1":
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-7.1.1.tgz#de315ec45ac9e16c637dcc2b32cd7912edb4e234"
+ integrity sha512-BkOt2q7MBYl7pweY2JWwfrlahhp+uGLR8S+EhiyRaofeRYUWL2YKbSGQvN4hgSN1i8poN0PaUiii1kEMrchvzg==
+ dependencies:
+ "@babel/runtime" "^7.27.1"
+ "@mui/types" "^7.4.3"
+ "@types/prop-types" "^15.7.14"
+ clsx "^2.1.1"
+ prop-types "^15.8.1"
+ react-is "^19.1.0"
+
"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1":
version "5.1.1-v1"
resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129"
@@ -1715,6 +1807,11 @@
qs "^6.10.1"
url-parse "^1.5.3"
+"@popperjs/core@^2.11.8":
+ version "2.11.8"
+ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f"
+ integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==
+
"@puppeteer/browsers@2.7.1":
version "2.7.1"
resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-2.7.1.tgz#6df07e95d8e22239b77599f3ceaef4041b933e62"
@@ -2042,7 +2139,7 @@
dependencies:
"@types/node" "*"
-"@types/hoist-non-react-statics@^3.3.1":
+"@types/hoist-non-react-statics@^3.3.1", "@types/hoist-non-react-statics@^3.3.6":
version "3.3.6"
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz#6bba74383cdab98e8db4e20ce5b4a6b98caed010"
integrity sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==
@@ -2129,6 +2226,11 @@
dependencies:
undici-types "~6.20.0"
+"@types/prop-types@^15.7.14":
+ version "15.7.15"
+ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.15.tgz#e6e5a86d602beaca71ce5163fadf5f95d70931c7"
+ integrity sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==
+
"@types/qs@*":
version "6.9.18"
resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.18.tgz#877292caa91f7c1b213032b34626505b746624c2"
@@ -2144,6 +2246,11 @@
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.0.4.tgz#bedba97f9346bd4c0fe5d39e689713804ec9ac89"
integrity sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==
+"@types/react-transition-group@^4.4.12":
+ version "4.4.12"
+ resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.12.tgz#b5d76568485b02a307238270bfe96cb51ee2a044"
+ integrity sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==
+
"@types/react@*":
version "19.0.12"
resolved "https://registry.yarnpkg.com/@types/react/-/react-19.0.12.tgz#338b3f7854adbb784be454b3a83053127af96bd3"
@@ -3400,7 +3507,7 @@ clsx@^1.0.4:
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
-clsx@^2.0.0:
+clsx@^2.0.0, clsx@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999"
integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==
@@ -3772,7 +3879,7 @@ cssstyle@^2.3.0:
dependencies:
cssom "~0.3.6"
-csstype@3.1.3, csstype@^3.0.2:
+csstype@3.1.3, csstype@^3.0.2, csstype@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
@@ -4170,7 +4277,7 @@ dom-helpers@^3.4.0:
dependencies:
"@babel/runtime" "^7.1.2"
-dom-helpers@^5.1.3:
+dom-helpers@^5.0.1, dom-helpers@^5.1.3:
version "5.2.1"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
@@ -8564,6 +8671,11 @@ react-is@^18.0.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e"
integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==
+react-is@^19.1.0:
+ version "19.1.0"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-19.1.0.tgz#805bce321546b7e14c084989c77022351bbdd11b"
+ integrity sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==
+
react-lazylog@4.5.3:
version "4.5.3"
resolved "https://registry.yarnpkg.com/react-lazylog/-/react-lazylog-4.5.3.tgz#289e24995b5599e75943556ac63f5e2c04d0001e"
@@ -8725,6 +8837,16 @@ react-transition-group@^3.0.0:
prop-types "^15.6.2"
react-lifecycles-compat "^3.0.4"
+react-transition-group@^4.4.5:
+ version "4.4.5"
+ resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1"
+ integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==
+ dependencies:
+ "@babel/runtime" "^7.5.5"
+ dom-helpers "^5.0.1"
+ loose-envify "^1.4.0"
+ prop-types "^15.6.2"
+
react-virtualized@^9.21.0:
version "9.22.6"
resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.6.tgz#3ae2aa69eca61cf3af332e2f9d6b4aa5638786d5"