From b9336d1a861b0deff59807a98039f7a0f123d9df Mon Sep 17 00:00:00 2001 From: Matt Fleury Date: Fri, 17 Oct 2025 11:24:57 -0400 Subject: [PATCH 01/17] updating material ui, minus dates --- ui/package-lock.json | 294 ++++-------------- ui/package.json | 10 +- ui/src/App.tsx | 6 +- ui/src/app/NavBar.tsx | 28 +- ui/src/components/ApiKeys.tsx | 4 +- ui/src/components/AutoCompleteField.tsx | 9 +- ui/src/components/EnhancedTable.tsx | 11 +- .../__tests__/ActivityTable.test.tsx | 32 +- .../__tests__/EnhancedTable.test.tsx | 7 +- ui/src/pages/MainPage.tsx | 6 +- ui/src/pages/ResultsPage.tsx | 30 +- ui/src/pages/SearchPage.tsx | 13 +- ui/src/pages/UserSettings.tsx | 2 +- ui/src/pages/UsersPage.tsx | 6 +- .../SecretAddDialog.test.tsx | 7 +- .../VulnEditDialog.test.tsx | 15 +- .../MainPage/SkipWelcomeDialog.test.tsx | 6 +- .../__tests__/SearchPage/SearchPage.test.tsx | 137 +++++--- .../SearchPage/SearchPageRepos.test.tsx | 192 ++++++++---- .../SearchPage/SearchPageVulns.test.tsx | 10 +- .../__tests__/UserSettings/UserInfo.test.tsx | 12 +- ui/src/pages/__tests__/UsersPage.test.tsx | 8 +- ui/src/setupTests.ts | 2 + ui/src/test-utils.tsx | 8 +- 24 files changed, 398 insertions(+), 457 deletions(-) diff --git a/ui/package-lock.json b/ui/package-lock.json index 1f8aacda4..f72ee34a9 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -13,11 +13,12 @@ "@date-io/luxon": "^3.2.0", "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", + "@fontsource/roboto": "^5.2.8", "@lingui/core": "^4.14.0", "@lingui/react": "^4.14.0", - "@mui/icons-material": "^6.4.12", - "@mui/material": "^6.4.8", - "@mui/x-date-pickers": "^7.29.4", + "@mui/icons-material": "^7.3.2", + "@mui/material": "^7.3.2", + "@mui/x-date-pickers": "^8.12.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.6.0", "@reduxjs/toolkit": "^1.9.7", "@svgr/webpack": "^8.1.0", @@ -72,7 +73,6 @@ "style-loader": "^4.0.0", "terser-webpack-plugin": "^5.3.14", "tss-react": "^4.9.19", - "typeface-roboto": "1.1.13", "typescript": "~5.9.2", "webpack": "^5.101.3", "webpack-dev-server": "^5.2.2", @@ -4223,6 +4223,15 @@ "npm": ">=6.0.0" } }, + "node_modules/@fontsource/roboto": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-5.2.8.tgz", + "integrity": "sha512-oh9g4Cg3loVMz9MWeKWfDI+ooxxG1aRVetkiKIb2ESS2rrryGecQ/y4pAj4z5A5ebyw450dYRi/c4k/I3UBhHA==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -5384,9 +5393,9 @@ "license": "MIT" }, "node_modules/@mui/core-downloads-tracker": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.5.0.tgz", - "integrity": "sha512-LGb8t8i6M2ZtS3Drn3GbTI1DVhDY6FJ9crEey2lZ0aN2EMZo8IZBZj9wRf4vqbZHaWjsYgtbOnJw5V8UWbmK2Q==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.3.2.tgz", + "integrity": "sha512-AOyfHjyDKVPGJJFtxOlept3EYEdLoar/RvssBTWVAvDJGIE676dLi2oT/Kx+FoVXFoA/JdV7DEMq/BVWV3KHRw==", "license": "MIT", "funding": { "type": "opencollective", @@ -5394,12 +5403,12 @@ } }, "node_modules/@mui/icons-material": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.5.0.tgz", - "integrity": "sha512-VPuPqXqbBPlcVSA0BmnoE4knW4/xG6Thazo8vCLWkOKusko6DtwFV6B665MMWJ9j0KFohTIf3yx2zYtYacvG1g==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.3.2.tgz", + "integrity": "sha512-TZWazBjWXBjR6iGcNkbKklnwodcwj0SrChCNHc9BhD9rBgET22J1eFhHsEmvSvru9+opDy3umqAimQjokhfJlQ==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.26.0" + "@babel/runtime": "^7.28.3" }, "engines": { "node": ">=14.0.0" @@ -5409,7 +5418,7 @@ "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "@mui/material": "^6.5.0", + "@mui/material": "^7.3.2", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, @@ -5420,22 +5429,22 @@ } }, "node_modules/@mui/material": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.5.0.tgz", - "integrity": "sha512-yjvtXoFcrPLGtgKRxFaH6OQPtcLPhkloC0BML6rBG5UeldR0nPULR/2E2BfXdo5JNV7j7lOzrrLX2Qf/iSidow==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-7.3.2.tgz", + "integrity": "sha512-qXvbnawQhqUVfH1LMgMaiytP+ZpGoYhnGl7yYq2x57GYzcFL/iPzSZ3L30tlbwEjSVKNYcbiKO8tANR1tadjUg==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.26.0", - "@mui/core-downloads-tracker": "^6.5.0", - "@mui/system": "^6.5.0", - "@mui/types": "~7.2.24", - "@mui/utils": "^6.4.9", + "@babel/runtime": "^7.28.3", + "@mui/core-downloads-tracker": "^7.3.2", + "@mui/system": "^7.3.2", + "@mui/types": "^7.4.6", + "@mui/utils": "^7.3.2", "@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.0.0", + "react-is": "^19.1.1", "react-transition-group": "^4.4.5" }, "engines": { @@ -5448,7 +5457,7 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@mui/material-pigment-css": "^6.5.0", + "@mui/material-pigment-css": "^7.3.2", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -5468,113 +5477,11 @@ } } }, - "node_modules/@mui/material/node_modules/@mui/private-theming": { - "version": "6.4.9", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.4.9.tgz", - "integrity": "sha512-LktcVmI5X17/Q5SkwjCcdOLBzt1hXuc14jYa7NPShog0GBDCDvKtcnP0V7a2s6EiVRlv7BzbWEJzH6+l/zaCxw==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.26.0", - "@mui/utils": "^6.4.9", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/material/node_modules/@mui/styled-engine": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.5.0.tgz", - "integrity": "sha512-8woC2zAqF4qUDSPIBZ8v3sakj+WgweolpyM/FXf8jAx6FMls+IE4Y8VDZc+zS805J7PRz31vz73n2SovKGaYgw==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.26.0", - "@emotion/cache": "^11.13.5", - "@emotion/serialize": "^1.3.3", - "@emotion/sheet": "^1.4.0", - "csstype": "^3.1.3", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.4.1", - "@emotion/styled": "^11.3.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - } - } - }, - "node_modules/@mui/material/node_modules/@mui/system": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.5.0.tgz", - "integrity": "sha512-XcbBYxDS+h/lgsoGe78ExXFZXtuIlSBpn/KsZq8PtZcIkUNJInkuDqcLd2rVBQrDC1u+rvVovdaWPf2FHKJf3w==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.26.0", - "@mui/private-theming": "^6.4.9", - "@mui/styled-engine": "^6.5.0", - "@mui/types": "~7.2.24", - "@mui/utils": "^6.4.9", - "clsx": "^2.1.1", - "csstype": "^3.1.3", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.5.0", - "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "@types/react": { - "optional": true - } - } - }, "node_modules/@mui/private-theming": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.3.2.tgz", "integrity": "sha512-ha7mFoOyZGJr75xeiO9lugS3joRROjc8tG1u4P50dH0KR7bwhHznVMcYg7MouochUy0OxooJm/OOSpJ7gKcMvg==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.28.3", "@mui/utils": "^7.3.2", @@ -5597,61 +5504,11 @@ } } }, - "node_modules/@mui/private-theming/node_modules/@mui/types": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.6.tgz", - "integrity": "sha512-NVBbIw+4CDMMppNamVxyTccNv0WxtDb7motWDlMeSC8Oy95saj1TIZMGynPpFLePt3yOD8TskzumeqORCgRGWw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/runtime": "^7.28.3" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/private-theming/node_modules/@mui/utils": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.3.2.tgz", - "integrity": "sha512-4DMWQGenOdLnM3y/SdFQFwKsCLM+mqxzvoWp9+x2XdEzXapkznauHLiXtSohHs/mc0+5/9UACt1GdugCX2te5g==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/runtime": "^7.28.3", - "@mui/types": "^7.4.6", - "@types/prop-types": "^15.7.15", - "clsx": "^2.1.1", - "prop-types": "^15.8.1", - "react-is": "^19.1.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@mui/styled-engine": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.3.2.tgz", "integrity": "sha512-PkJzW+mTaek4e0nPYZ6qLnW5RGa0KN+eRTf5FA2nc7cFZTeM+qebmGibaTLrgQBy3UpcpemaqfzToBNkzuxqew==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.28.3", "@emotion/cache": "^11.14.0", @@ -5686,7 +5543,6 @@ "resolved": "https://registry.npmjs.org/@mui/system/-/system-7.3.2.tgz", "integrity": "sha512-9d8JEvZW+H6cVkaZ+FK56R53vkJe3HsTpcjMUtH8v1xK6Y1TjzHdZ7Jck02mGXJsE6MQGWVs3ogRHTQmS9Q/rA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.28.3", "@mui/private-theming": "^7.3.2", @@ -5722,12 +5578,11 @@ } } }, - "node_modules/@mui/system/node_modules/@mui/types": { + "node_modules/@mui/types": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.6.tgz", "integrity": "sha512-NVBbIw+4CDMMppNamVxyTccNv0WxtDb7motWDlMeSC8Oy95saj1TIZMGynPpFLePt3yOD8TskzumeqORCgRGWw==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.28.3" }, @@ -5740,12 +5595,11 @@ } } }, - "node_modules/@mui/system/node_modules/@mui/utils": { + "node_modules/@mui/utils": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.3.2.tgz", "integrity": "sha512-4DMWQGenOdLnM3y/SdFQFwKsCLM+mqxzvoWp9+x2XdEzXapkznauHLiXtSohHs/mc0+5/9UACt1GdugCX2te5g==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.28.3", "@mui/types": "^7.4.6", @@ -5771,60 +5625,16 @@ } } }, - "node_modules/@mui/types": { - "version": "7.2.24", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.24.tgz", - "integrity": "sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==", - "license": "MIT", - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/utils": { - "version": "6.4.9", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.9.tgz", - "integrity": "sha512-Y12Q9hbK9g+ZY0T3Rxrx9m2m10gaphDuUMgWxyV5kNJevVxXYCLclYUCC9vXaIk1/NdNDTcW2Yfr2OGvNFNmHg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.26.0", - "@mui/types": "~7.2.24", - "@types/prop-types": "^15.7.14", - "clsx": "^2.1.1", - "prop-types": "^15.8.1", - "react-is": "^19.0.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@mui/x-date-pickers": { - "version": "7.29.4", - "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.29.4.tgz", - "integrity": "sha512-wJ3tsqk/y6dp+mXGtT9czciAMEO5Zr3IIAHg9x6IL0Eqanqy0N3chbmQQZv3iq0m2qUpQDLvZ4utZBUTJdjNzw==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-8.12.0.tgz", + "integrity": "sha512-CDcjdBNwMcTy3flZTCKZqSUS6deBFGKLqy3Vl6bgr5KTo8Vky2v+S+zNi56fv23Qs+P47GwpILcm3QZt/0BP0A==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.25.7", - "@mui/utils": "^5.16.6 || ^6.0.0 || ^7.0.0", - "@mui/x-internals": "7.29.0", - "@types/react-transition-group": "^4.4.11", + "@babel/runtime": "^7.28.2", + "@mui/utils": "^7.3.2", + "@mui/x-internals": "8.12.0", + "@types/react-transition-group": "^4.4.12", "clsx": "^2.1.1", "prop-types": "^15.8.1", "react-transition-group": "^4.4.5" @@ -5882,13 +5692,15 @@ } }, "node_modules/@mui/x-internals": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.29.0.tgz", - "integrity": "sha512-+Gk6VTZIFD70XreWvdXBwKd8GZ2FlSCuecQFzm6znwqXg1ZsndavrhG9tkxpxo2fM1Zf7Tk8+HcOO0hCbhTQFA==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-8.12.0.tgz", + "integrity": "sha512-KCZgFHwuPg0v8I2gpjeC6k3eDRXPPX8RIGSNDXe8zSZ8dAw+p6Q2pzT9kKvctqCXSFK8ct/5YQwqx8Quhs8Ndg==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.25.7", - "@mui/utils": "^5.16.6 || ^6.0.0 || ^7.0.0" + "@babel/runtime": "^7.28.2", + "@mui/utils": "^7.3.2", + "reselect": "^5.1.1", + "use-sync-external-store": "^1.5.0" }, "engines": { "node": ">=14.0.0" @@ -5901,6 +5713,12 @@ "react": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/@mui/x-internals/node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "license": "MIT" + }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", @@ -24219,12 +24037,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/typeface-roboto": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/typeface-roboto/-/typeface-roboto-1.1.13.tgz", - "integrity": "sha512-YXvbd3a1QTREoD+FJoEkl0VQNJoEjewR2H11IjVv4bp6ahuIcw0yyw/3udC4vJkHw3T3cUh85FTg8eWef3pSaw==", - "license": "MIT" - }, "node_modules/typescript": { "version": "5.9.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", diff --git a/ui/package.json b/ui/package.json index 3bf1c0e28..bcc5552fb 100644 --- a/ui/package.json +++ b/ui/package.json @@ -17,11 +17,12 @@ "@date-io/luxon": "^3.2.0", "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", + "@fontsource/roboto": "^5.2.8", "@lingui/core": "^4.14.0", "@lingui/react": "^4.14.0", - "@mui/icons-material": "^6.4.12", - "@mui/material": "^6.4.8", - "@mui/x-date-pickers": "^7.29.4", + "@mui/icons-material": "^7.3.2", + "@mui/material": "^7.3.2", + "@mui/x-date-pickers": "^8.12.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.6.0", "@reduxjs/toolkit": "^1.9.7", "@svgr/webpack": "^8.1.0", @@ -76,7 +77,6 @@ "style-loader": "^4.0.0", "terser-webpack-plugin": "^5.3.14", "tss-react": "^4.9.19", - "typeface-roboto": "1.1.13", "typescript": "~5.9.2", "webpack": "^5.101.3", "webpack-dev-server": "^5.2.2", @@ -132,7 +132,7 @@ "start": "npm run redocly && npm run compile && node scripts/start.js", "build": "npm run redocly && npm run compile -- strict && node scripts/build.js", "build:nonprod": "npm run redocly && npm run compile -- strict && env-cmd -f ./.env.nonprod node scripts/build.js", - "test": "npm run compile && node scripts/test.js --reporters=default --reporters=jest-html-reporter", + "test": "node scripts/test.js", "test-debug": "npm run compile && react-scripts --inspect-brk test --runInBand --no-cache", "test-precommit": "node scripts/test.js --watchAll=false --env=jsdom --coverage --reporters=default --reporters=jest-html-reporter --silent", "extract": "lingui extract", diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 81baa016f..5723af24c 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -7,7 +7,7 @@ import { Routes, Route, } from "react-router-dom"; -import "typeface-roboto"; +import "@fontsource/roboto"; import store, { AppDispatch } from "app/store"; import { Provider } from "react-redux"; @@ -15,7 +15,7 @@ import { i18n } from "@lingui/core"; import { I18nProvider } from "@lingui/react"; import { messages as enMessages } from "locale/en/messages"; -// apply material-ui cross-browser style normalizaion +// apply material-ui cross-browser style normalization import CssBaseline from "@mui/material/CssBaseline"; import useMediaQuery from "@mui/material/useMediaQuery"; import { makeStyles } from "tss-react/mui"; @@ -283,7 +283,7 @@ const ThemedApp = () => { ); // TODO i18n: Date/Time pickers have changed the way they handle i18n - // instead of overriding indivudal strings like okText, cancelText, etc. you now wrap the component in a with an "adapterLocale" set + // instead of overriding individual strings like okText, cancelText, etc. you now wrap the component in a with an "adapterLocale" set // this is more complete, since it also translates items like calendar month names // see: https://mui.com/x/react-date-pickers/date-picker/#localization diff --git a/ui/src/app/NavBar.tsx b/ui/src/app/NavBar.tsx index 17082c4c8..3653c80cd 100644 --- a/ui/src/app/NavBar.tsx +++ b/ui/src/app/NavBar.tsx @@ -14,7 +14,6 @@ import { AppBar, Box, CircularProgress, - Hidden, IconButton, ListItemIcon, ListItemText, @@ -261,20 +260,19 @@ const NavBar = (props: INavBar) => { {systemStatus.maintenance.message} )} - - - {currentUser?.last_login && ( - - - Last Login: {formatDate(currentUser.last_login, "long")} - - - )} - - + + {currentUser?.last_login && ( + + + Last Login: {formatDate(currentUser.last_login, "long")} + + + )} + ); }; diff --git a/ui/src/components/ApiKeys.tsx b/ui/src/components/ApiKeys.tsx index 29df004de..96341d631 100644 --- a/ui/src/components/ApiKeys.tsx +++ b/ui/src/components/ApiKeys.tsx @@ -28,7 +28,7 @@ import { FormGroup, FormHelperText, FormLabel, - Grid2 as Grid, + Grid, IconButton, InputAdornment, LinearProgress, @@ -199,7 +199,7 @@ interface ScrollToTopProps { } // element that will appear as user approaches bottom of target element -// and will scroll back to element indentified by selector +// and will scroll back to element identified by selector // will usually wrap a child element function ScrollTop(props: ScrollToTopProps) { const { children, selector, target } = props; diff --git a/ui/src/components/AutoCompleteField.tsx b/ui/src/components/AutoCompleteField.tsx index 36d402420..5cff11e1e 100644 --- a/ui/src/components/AutoCompleteField.tsx +++ b/ui/src/components/AutoCompleteField.tsx @@ -39,13 +39,15 @@ const AutoCompleteField = React.forwardRef( ref={ref} name={allParams.name} error={allParams.error} - InputProps={InputProps} helperText={allParams.helperText} label={ loading ? i18n._(t`Loading options...`) : allParams.label } placeholder={allParams.placeholder} variant="outlined" + slotProps={{ + input: InputProps, + }} /> ); }} @@ -62,9 +64,10 @@ const AutoCompleteField = React.forwardRef( } const matches = match(optionLabel, inputValue); const parts = parse(optionLabel, matches); - + // don't pass key in with rest of props + const { key, ...otherProps } = renderProps; return ( -
  • +
  • {parts.map((part, index) => ( { }; } + const newLastPage = Math.max(0, Math.ceil(count / rowsPerPage) - 1); + + let showPage = page; + if (newLastPage < page) { + showPage = 0; + } + return (
    @@ -769,7 +776,7 @@ const EnhancedTable = (props: EnhancedTableProps) => { component="div" count={count} rowsPerPage={rowsPerPage} - page={page} + page={showPage} onPageChange={handleChangePage} onRowsPerPageChange={handleChangeRowsPerPage} /> diff --git a/ui/src/components/__tests__/ActivityTable.test.tsx b/ui/src/components/__tests__/ActivityTable.test.tsx index c9c34deee..2a8885c3f 100644 --- a/ui/src/components/__tests__/ActivityTable.test.tsx +++ b/ui/src/components/__tests__/ActivityTable.test.tsx @@ -110,7 +110,7 @@ describe("ActivityTable component", () => { screen.getByRole("button", { name: /refresh/i }), ).toBeInTheDocument(); expect( - screen.getByRole("checkbox", { name: /auto refresh/i }), + screen.getByRole("switch", { name: /auto refresh/i }), ).toBeInTheDocument(); expect( screen.getByRole("columnheader", { name: /actions/i }), @@ -739,7 +739,7 @@ describe("ActivityTable component", () => { expect(mockOnDataLoad.mock.calls.length).toBe(1); // called once as data initially loaded // check default auto-reload toggle state is checked/enabled - const checkbox = screen.getByRole("checkbox", { + const checkbox = screen.getByRole("switch", { name: /auto refresh/i, }) as HTMLInputElement; expect(checkbox.checked).toEqual(true); @@ -772,7 +772,7 @@ describe("ActivityTable component", () => { expect(mockOnDataLoad.mock.calls.length).toBe(1); // called once as data initially loaded // check default auto-reload toggle state is checked/enabled - const checkbox = screen.getByRole("checkbox", { + const checkbox = screen.getByRole("switch", { name: /auto refresh/i, }) as HTMLInputElement; expect(checkbox.checked).toEqual(true); @@ -811,7 +811,7 @@ describe("ActivityTable component", () => { expect(mockOnDataLoad.mock.calls.length).toBe(1); // called once as data initially loaded // check default auto-reload toggle state is checked/enabled - const checkbox = screen.getByRole("checkbox", { + const checkbox = screen.getByRole("switch", { name: /auto refresh/i, }) as HTMLInputElement; expect(checkbox.checked).toEqual(true); @@ -849,7 +849,7 @@ describe("ActivityTable component", () => { expect(mockOnDataLoad.mock.calls.length).toBe(1); // called once as data initially loaded // check default auto-reload toggle state is checked/enabled - const checkbox = screen.getByRole("checkbox", { + const checkbox = screen.getByRole("switch", { name: /auto refresh/i, }) as HTMLInputElement; expect(checkbox.checked).toEqual(true); @@ -984,13 +984,13 @@ describe("ActivityTable component", () => { }); // associated filter toggles should be disabled - const toggleShowScans = screen.getByRole("checkbox", { + const toggleShowScans = screen.getByRole("switch", { name: /Show only my scans/i, }); expect(toggleShowScans).toBeEnabled(); expect(toggleShowScans).not.toBeChecked(); - const toggleIncludeBatch = screen.getByRole("checkbox", { + const toggleIncludeBatch = screen.getByRole("switch", { name: /Include batched scans/i, }); expect(toggleIncludeBatch).toBeEnabled(); @@ -1015,12 +1015,12 @@ describe("ActivityTable component", () => { />, ); // associated filter toggles should be disabled - const toggleShowScans = screen.getByRole("checkbox", { + const toggleShowScans = screen.getByRole("switch", { name: /Show only my scans/i, }); expect(toggleShowScans).toBeDisabled(); - const toggleIncludeBatch = screen.getByRole("checkbox", { + const toggleIncludeBatch = screen.getByRole("switch", { name: /Include batched scans/i, }); expect(toggleIncludeBatch).toBeDisabled(); @@ -1049,7 +1049,7 @@ describe("ActivityTable component", () => { itemsPerPage: defaultRowsPerPage, }); - const toggleShowScans = screen.getByRole("checkbox", { + const toggleShowScans = screen.getByRole("switch", { name: /Show only my scans/i, }); expect(toggleShowScans).toBeEnabled(); @@ -1101,7 +1101,7 @@ describe("ActivityTable component", () => { itemsPerPage: defaultRowsPerPage, }); - const toggleIncludeBatch = screen.getByRole("checkbox", { + const toggleIncludeBatch = screen.getByRole("switch", { name: /Include batched scans/i, }); expect(toggleIncludeBatch).toBeEnabled(); @@ -1153,7 +1153,7 @@ describe("ActivityTable component", () => { itemsPerPage: defaultRowsPerPage, }); - const toggleIncludeBatch = screen.getByRole("checkbox", { + const toggleIncludeBatch = screen.getByRole("switch", { name: /Include batched scans/i, }); expect(toggleIncludeBatch).toBeEnabled(); @@ -1172,7 +1172,7 @@ describe("ActivityTable component", () => { itemsPerPage: defaultRowsPerPage, }); - const toggleShowScans = screen.getByRole("checkbox", { + const toggleShowScans = screen.getByRole("switch", { name: /Show only my scans/i, }); expect(toggleShowScans).toBeEnabled(); @@ -1219,7 +1219,7 @@ describe("ActivityTable component", () => { itemsPerPage: defaultRowsPerPage, }); - const toggleShowScans = screen.getByRole("checkbox", { + const toggleShowScans = screen.getByRole("switch", { name: /Show only my scans/i, }); expect(toggleShowScans).toBeEnabled(); @@ -1238,7 +1238,7 @@ describe("ActivityTable component", () => { itemsPerPage: defaultRowsPerPage, }); - const toggleIncludeBatch = screen.getByRole("checkbox", { + const toggleIncludeBatch = screen.getByRole("switch", { name: /Include batched scans/i, }); expect(toggleIncludeBatch).toBeEnabled(); @@ -1287,7 +1287,7 @@ describe("ActivityTable component", () => { itemsPerPage: defaultRowsPerPage, }); - const toggleIncludeBatch = screen.getByRole("checkbox", { + const toggleIncludeBatch = screen.getByRole("switch", { name: /Include batched scans/i, }); expect(toggleIncludeBatch).toBeEnabled(); diff --git a/ui/src/components/__tests__/EnhancedTable.test.tsx b/ui/src/components/__tests__/EnhancedTable.test.tsx index 099994c41..7066dc559 100644 --- a/ui/src/components/__tests__/EnhancedTable.test.tsx +++ b/ui/src/components/__tests__/EnhancedTable.test.tsx @@ -319,7 +319,10 @@ describe("EnhancedTable component", () => { await screen.findByText(`11–${rows.length} of ${rows.length}`); // change filter, expect page to reset to 1 - filters.data.filter = "row 1"; + const newFilters = { + ...filters, + data: { ...filters.data, filter: "row 1" }, + }; rowsPerPage = 3; // filtered matches rerender( { rows={rows} id="data" defaultOrderBy="data" - filters={filters} + filters={newFilters} />, ); await screen.findByText(`1–${rowsPerPage} of ${rowsPerPage}`); diff --git a/ui/src/pages/MainPage.tsx b/ui/src/pages/MainPage.tsx index 06ef665e9..eb2b8902b 100644 --- a/ui/src/pages/MainPage.tsx +++ b/ui/src/pages/MainPage.tsx @@ -36,7 +36,7 @@ import { FormGroup, FormHelperText, FormLabel, - Grid2 as Grid, + Grid, InputAdornment, LinearProgress, Paper, @@ -279,7 +279,7 @@ const MainPage = () => { // empty form values for initializing form on first load or resetting form const emptyValues: ScanOptionsForm = { - vcsOrg: null, // Autoselect component - when no option selected defaults to null + vcsOrg: null, // Auto-select component - when no option selected defaults to null repo: "", branch: "", secrets: true, // all scan categories except sbom selected by default @@ -292,7 +292,7 @@ const MainPage = () => { depth: "", includeDev: false, submitContext: "view" as SubmitContext, - // We need the api names for the formik initial state in order to create the prechecked checkboxes. + // We need the api names for the formik initial state in order to create the pre-checked checkboxes. secretPlugins, staticPlugins: staticPlugins.filter((p) => !excludePlugins.includes(p)), techPlugins, diff --git a/ui/src/pages/ResultsPage.tsx b/ui/src/pages/ResultsPage.tsx index d60ed43f9..32ed515b9 100644 --- a/ui/src/pages/ResultsPage.tsx +++ b/ui/src/pages/ResultsPage.tsx @@ -66,7 +66,7 @@ import { FormControlLabel, FormGroup, FormLabel, - Grid2 as Grid, + Grid, IconButton, InputAdornment, InputBaseComponentProps, @@ -94,7 +94,6 @@ import { Zoom, } from "@mui/material"; import { useTheme } from "@mui/material/styles"; -import createPalette from "@mui/material/styles/createPalette"; import { Field, Form, Formik, FormikHelpers } from "formik"; import { Select, TextField } from "formik-mui"; import { DateTime } from "luxon"; @@ -993,7 +992,7 @@ export const HiddenFindingDialog = (props: { .max(512, i18n._(t`Must be between 1-512 characters`)), }); - // form submission succeeds, reset hiddingFinding redux status + // form submission succeeds, reset hiddenFinding redux status // and close the dialog // success notification will be viewed as a global app notification useEffect(() => { @@ -1265,7 +1264,7 @@ export const HiddenFindingDialog = (props: { ); // form submitted and encountered an error - // reset form submittion state (isSubmitting) + // reset form submission state (isSubmitting) // so form fields are editable again if (isSubmitting) { setSubmitting(false); @@ -1345,7 +1344,7 @@ export const HiddenFindingDialog = (props: { ); } - // last unshifted item, so this will appear as first item in list + // last un-shifted item, so this will appear as first item in list if (createdBy) { details.unshift(