diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 43487a6..e5684e0 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -19,6 +19,16 @@ updates: interval: weekly open-pull-requests-limit: 10 groups: + # @mui/material and @mui/icons-material must move in lockstep (icons + # peer-depends on material), so group them — including majors — into a + # single PR. Listed before `web` so MUI deps land here, not there. + mui: + patterns: + - "@mui/*" + update-types: + - "major" + - "minor" + - "patch" web: patterns: - "*" diff --git a/web/package-lock.json b/web/package-lock.json index 6d4167a..4d63a92 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -10,8 +10,8 @@ "dependencies": { "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.0", - "@mui/icons-material": "^7.3.1", - "@mui/material": "^7.3.1", + "@mui/icons-material": "^9.1.1", + "@mui/material": "^9.1.1", "@reduxjs/toolkit": "^2.11.2", "@tanstack/react-query": "^5.101.0", "axios": "^1.18.0", @@ -1186,9 +1186,9 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "7.3.11", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.3.11.tgz", - "integrity": "sha512-a7I/b/nBTdXYz2cOSlEmkQ9WWE1x8FHpqMhFPp+Y1VPFxcOw91G5ELOHARQAGSPy5V+UCgJua6K/1x70bAtQPw==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-9.1.1.tgz", + "integrity": "sha512-AupmMICbdJHqAh6FfOMaaiiIr7dfEgZJn5DFfiPuGNrbs+ZZy9cD1APwO0TSVBz5j08MJEEY6n7iC76/2wjMEA==", "license": "MIT", "funding": { "type": "opencollective", @@ -1196,12 +1196,12 @@ } }, "node_modules/@mui/icons-material": { - "version": "7.3.11", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.3.11.tgz", - "integrity": "sha512-+hz5ilwHZ3djd5es3sCErLioqe/NhZcYTsV/TNXZAMdJdb23F4xzJjqnnZdnurc3S1+ietcssRNqieOhPQLZ7Q==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-9.1.1.tgz", + "integrity": "sha512-OXhm9DajemStb58AumM06DuPhHTa3XD36TFD4yf6WtJyNRO5DfEZbbnHlBg/US2Y2oOXwM/XurMTBOD6L/YYZw==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.28.6" + "@babel/runtime": "^7.29.2" }, "engines": { "node": ">=14.0.0" @@ -1211,7 +1211,7 @@ "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "@mui/material": "^7.3.11", + "@mui/material": "^9.1.1", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, @@ -1222,22 +1222,22 @@ } }, "node_modules/@mui/material": { - "version": "7.3.11", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-7.3.11.tgz", - "integrity": "sha512-yq8bPc3LxOwKRWpcjRgDkYFmpM6aKlARfESTmOQcvLYFeJwtHte2tw6hJDrb8sk8wcvpDprHEHVaoUU0MslIkw==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-9.1.1.tgz", + "integrity": "sha512-Wv+gInjrpf99l1Q0oHe0eOWGTnlbkzs5nowClX65KCT/2fyPMwcbFEEkUsOHdpcHhB5UAbz/d7jlwt5ajWVvlA==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.28.6", - "@mui/core-downloads-tracker": "^7.3.11", - "@mui/system": "^7.3.11", - "@mui/types": "^7.4.12", - "@mui/utils": "^7.3.11", + "@babel/runtime": "^7.29.2", + "@mui/core-downloads-tracker": "^9.1.1", + "@mui/system": "^9.1.1", + "@mui/types": "^9.1.1", + "@mui/utils": "^9.1.1", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.12", "clsx": "^2.1.1", "csstype": "^3.2.3", "prop-types": "^15.8.1", - "react-is": "^19.2.3", + "react-is": "^19.2.6", "react-transition-group": "^4.4.5" }, "engines": { @@ -1250,7 +1250,7 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@mui/material-pigment-css": "^7.3.11", + "@mui/material-pigment-css": "^9.1.1", "@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" @@ -1271,13 +1271,13 @@ } }, "node_modules/@mui/private-theming": { - "version": "7.3.11", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.3.11.tgz", - "integrity": "sha512-9B+YKms0fRHbNrqp9tOT/DNbNnU5gyvJ1o3qAGXfq8GmZcbJnE3At9x07Zr/o0pkhzg4aDdwXVqe4+AcgtOCPA==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-9.1.1.tgz", + "integrity": "sha512-oH6c+d6sJ1CZT0Vg2/fHdUQ5zvo9Pn+f+WWk0tlQliHqqIRdN32DZ7UxjalW3LUj4OkHbdWR31biWuLxK9i7Cg==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.28.6", - "@mui/utils": "^7.3.11", + "@babel/runtime": "^7.29.2", + "@mui/utils": "^9.1.1", "prop-types": "^15.8.1" }, "engines": { @@ -1298,12 +1298,12 @@ } }, "node_modules/@mui/styled-engine": { - "version": "7.3.10", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.3.10.tgz", - "integrity": "sha512-WxE9SiF8xskAQqGjsp0poXCkCqsoXFEsSr0HBXfApmGHR+DBnXRp+z46Vsltg4gpPM4Z96DeAQRpeAOnhNg7Ng==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-9.1.1.tgz", + "integrity": "sha512-neaYKdJfvEG54q8efHLJR7swpHG/gfSv9xGqW5iTSMsubD7yPCPFrhVBt284j1DOF3uZaaDJSHQL7gz6jGF21Q==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.28.6", + "@babel/runtime": "^7.29.2", "@emotion/cache": "^11.14.0", "@emotion/serialize": "^1.3.3", "@emotion/sheet": "^1.4.0", @@ -1332,16 +1332,16 @@ } }, "node_modules/@mui/system": { - "version": "7.3.11", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-7.3.11.tgz", - "integrity": "sha512-7izwGWdNawAKpBKcRlx7f2gFnAAjmASBWvMcyX4YYEeLOFsbfGRbUYGInvnAcUeql3rPxI7F9Ft4oY2OLRz44g==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-9.1.1.tgz", + "integrity": "sha512-q+aqNa58QZUwmmyUvJKKrStrej+4BcWFw4M0Ug+zRylPIQgR64cqvBnE3QTfLZm4OXulydp8Hl3zwKxMayrdsA==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.28.6", - "@mui/private-theming": "^7.3.11", - "@mui/styled-engine": "^7.3.10", - "@mui/types": "^7.4.12", - "@mui/utils": "^7.3.11", + "@babel/runtime": "^7.29.2", + "@mui/private-theming": "^9.1.1", + "@mui/styled-engine": "^9.1.1", + "@mui/types": "^9.1.1", + "@mui/utils": "^9.1.1", "clsx": "^2.1.1", "csstype": "^3.2.3", "prop-types": "^15.8.1" @@ -1372,12 +1372,12 @@ } }, "node_modules/@mui/types": { - "version": "7.4.12", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.12.tgz", - "integrity": "sha512-iKNAF2u9PzSIj40CjvKJWxFXJo122jXVdrmdh0hMYd+FR+NuJMkr/L88XwWLCRiJ5P1j+uyac25+Kp6YC4hu6w==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-9.1.1.tgz", + "integrity": "sha512-Zjt7u8wNvDg40rPTGoL+TnfkpuSKjwubsNSFRH1KAVZLcaV4I3AFNHIFbvH7p4F3alEibSbdd90xAgn5Rnfndg==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.28.6" + "@babel/runtime": "^7.29.2" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -1389,17 +1389,17 @@ } }, "node_modules/@mui/utils": { - "version": "7.3.11", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.3.11.tgz", - "integrity": "sha512-XTjGnifwteg71/ij+0e7Y7d+hwyntMYP5wPoA/g2drdGH+Flkvjwy0OfrVpKBbaOvofq4zU/LIyUZyKgmWu18g==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-9.1.1.tgz", + "integrity": "sha512-qSNfnkzZMptaaWFFklpDf4NPJztgwsMDVfM/sSDt+wq4ssYSBhLYwwjuB6eS/+p2IUYbeRzHluzXbw0Zn7aI4A==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.28.6", - "@mui/types": "^7.4.12", + "@babel/runtime": "^7.29.2", + "@mui/types": "^9.1.1", "@types/prop-types": "^15.7.15", "clsx": "^2.1.1", "prop-types": "^15.8.1", - "react-is": "^19.2.3" + "react-is": "^19.2.6" }, "engines": { "node": ">=14.0.0" @@ -3471,9 +3471,9 @@ } }, "node_modules/react-is": { - "version": "19.2.6", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.6.tgz", - "integrity": "sha512-XjBR15BhXuylgWGuslhDKqlSayuqvqBX91BP8pauG8kd1zY8kotkNWbXksTCNRarse4kuGbe2kIY05ARtwNIvw==", + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.7.tgz", + "integrity": "sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==", "license": "MIT" }, "node_modules/react-redux": { diff --git a/web/package.json b/web/package.json index 22de8f8..6452980 100644 --- a/web/package.json +++ b/web/package.json @@ -13,8 +13,8 @@ "dependencies": { "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.0", - "@mui/icons-material": "^7.3.1", - "@mui/material": "^7.3.1", + "@mui/icons-material": "^9.1.1", + "@mui/material": "^9.1.1", "@reduxjs/toolkit": "^2.11.2", "@tanstack/react-query": "^5.101.0", "axios": "^1.18.0", diff --git a/web/src/components/Sidebar.tsx b/web/src/components/Sidebar.tsx index 086e282..617277b 100644 --- a/web/src/components/Sidebar.tsx +++ b/web/src/components/Sidebar.tsx @@ -106,7 +106,7 @@ export default function Sidebar() { {item.icon} {!isCollapsed && ( - + )} ); diff --git a/web/src/pages/admin/customers/CustomerManagementPage.tsx b/web/src/pages/admin/customers/CustomerManagementPage.tsx index 9248b98..f5ec909 100644 --- a/web/src/pages/admin/customers/CustomerManagementPage.tsx +++ b/web/src/pages/admin/customers/CustomerManagementPage.tsx @@ -27,7 +27,7 @@ import { import SearchIcon from '@mui/icons-material/Search'; import AddIcon from '@mui/icons-material/Add'; import EditIcon from '@mui/icons-material/Edit'; -import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'; +import ErrorOutlineIcon from '@mui/icons-material/ErrorOutlined'; import { toast } from 'react-toastify'; import { customersApi, diff --git a/web/src/pages/admin/dashboard/AdminDashboard.tsx b/web/src/pages/admin/dashboard/AdminDashboard.tsx index 40289c4..bdf4578 100644 --- a/web/src/pages/admin/dashboard/AdminDashboard.tsx +++ b/web/src/pages/admin/dashboard/AdminDashboard.tsx @@ -34,7 +34,7 @@ import TimerIcon from '@mui/icons-material/Timer'; import DescriptionIcon from '@mui/icons-material/Description'; import WarningAmberIcon from '@mui/icons-material/WarningAmber'; import ReportIcon from '@mui/icons-material/Report'; -import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'; +import ErrorOutlineIcon from '@mui/icons-material/ErrorOutlined'; import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight'; import { usePaginatedList } from '../../../hooks/usePaginatedList'; diff --git a/web/src/pages/admin/pricing-library/PricingLibraryPage.tsx b/web/src/pages/admin/pricing-library/PricingLibraryPage.tsx index 95feec0..099c2a7 100644 --- a/web/src/pages/admin/pricing-library/PricingLibraryPage.tsx +++ b/web/src/pages/admin/pricing-library/PricingLibraryPage.tsx @@ -28,7 +28,7 @@ import { import AddIcon from '@mui/icons-material/Add'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; -import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'; +import ErrorOutlineIcon from '@mui/icons-material/ErrorOutlined'; import { toast } from 'react-toastify'; import { pricingLibraryApi, diff --git a/web/src/pages/dashboard/Dashboard.tsx b/web/src/pages/dashboard/Dashboard.tsx index 7f3383a..3728186 100644 --- a/web/src/pages/dashboard/Dashboard.tsx +++ b/web/src/pages/dashboard/Dashboard.tsx @@ -22,7 +22,7 @@ import DescriptionIcon from '@mui/icons-material/Description'; import HourglassTopIcon from '@mui/icons-material/HourglassTop'; import CheckCircleIcon from '@mui/icons-material/CheckCircle'; import SendIcon from '@mui/icons-material/Send'; -import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'; +import ErrorOutlineIcon from '@mui/icons-material/ErrorOutlined'; import Tooltip from '@mui/material/Tooltip'; import { proposalsApi, type ProposalListItem, type ProposalStats } from '../../lib/api/proposals'; import { QUERY_KEYS } from '../../constants/queryKeys'; diff --git a/web/src/pages/proposals/form/ProposalFormPage.tsx b/web/src/pages/proposals/form/ProposalFormPage.tsx index 713f49f..2d1d6b9 100644 --- a/web/src/pages/proposals/form/ProposalFormPage.tsx +++ b/web/src/pages/proposals/form/ProposalFormPage.tsx @@ -267,12 +267,13 @@ export default function ProposalFormPage() { required placeholder="Search or type a customer name..." slotProps={{ + ...params.slotProps, input: { - ...params.InputProps, + ...params.slotProps.input, endAdornment: ( <> {customerLoading && } - {params.InputProps.endAdornment} + {params.slotProps.input.endAdornment} ), }, @@ -417,12 +418,13 @@ export default function ProposalFormPage() { required placeholder="Search by site code..." slotProps={{ + ...params.slotProps, input: { - ...params.InputProps, + ...params.slotProps.input, endAdornment: ( <> {siteLoading && } - {params.InputProps.endAdornment} + {params.slotProps.input.endAdornment} ), }, diff --git a/web/vitest.config.ts b/web/vitest.config.ts index 4f6d395..e47388f 100644 --- a/web/vitest.config.ts +++ b/web/vitest.config.ts @@ -8,5 +8,13 @@ export default defineConfig({ globals: true, setupFiles: ['./src/test/setup.ts'], include: ['src/**/*.test.{ts,tsx}'], + server: { + deps: { + // MUI v9's ESM build (Transition.mjs) does a directory import of + // react-transition-group/TransitionGroupContext, which Node's native + // ESM loader can't resolve. Inline these so Vite resolves them. + inline: [/@mui\/material/, 'react-transition-group'], + }, + }, }, });