Files
pgadmin4/web/pgadmin/static/js/ToolErrorView.jsx
T
Ashesh Vashi 5c10c322d1 chore(deps): bump @mui/material 7 -> 9 and @mui/x-date-pickers 8 -> 9
Supersedes dependabot #9843 and #9888, which must land together
because date-pickers v9 requires @mui/material v9 as a peer.
@mui/material skipped v8 on npm (7.x -> 9.x), so only v9's
breaking changes apply.

## Manifest changes

- @mui/material         ^7.3.10 -> ^9.0.0  (resolved 9.0.1)
- @mui/icons-material   ^7.3.10 -> ^9.0.0  (resolved 9.0.1)
- @mui/x-date-pickers   ^8.28.3 -> ^9.0.2  (resolved 9.2.0)

## Source changes (98 files, mostly mechanical)

1. Two legacy icon imports renamed (v9 removed these in favor of
   the *Outlined variants):

     -import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';
     +import ErrorOutlineIcon from '@mui/icons-material/ErrorOutlined';
     -import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
     +import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutlined';

   Both in web/pgadmin/static/js/Explain/AIInsights.jsx.

2. `styled(Box)` -> `styled('div')` across 50 files. v9's `Box`
   stopped filtering CSS-property-named keys (flexDirection,
   marginLeft, etc.) out of the props it forwarded to the DOM, so
   any `styled(Box)(({theme}) => ({ flexDirection: 'column', ... }))`
   leaked those CSS keys to the underlying `<div>` as React props.
   Using `styled('div')` keeps the CSS-in-JS layer working as
   expected and removes the now-redundant Box layer (every affected
   styled wrapper was a pure styling container, not using Box's
   sx-passthrough or component-swap behavior).

3. Box / Stack / Typography / Link / Grid / DialogContentText /
   TimelineContent / TimelineOppositeContent system props moved to
   `sx`. v9 removed individual system-prop syntax from these
   components; `<Box flexGrow={1}>` is now `<Box sx={{flexGrow: 1}}>`.
   Applied via the official codemod:

     npx @mui/codemod@latest v9.0.0/system-props pgadmin

   65 files transformed, 6 Jinja-templated `.js` files skipped
   (parse errors, not real JS; no MUI usage in them).

4. One test updated for v9's class-name split. Button's
   variant+color combo class (`MuiButton-containedPrimary`) is now
   emitted as two separate classes (`MuiButton-contained` +
   `MuiButton-colorPrimary`).

   web/regression/javascript/components/Buttons.spec.js

## Test plan

- [x] `yarn install` resolved cleanly
- [x] `yarn run test:js-once` -> 140/0/0 suites, 824/0/0 tests
- [x] `yarn run linter` -> clean (silent)
- [ ] CI matrix (Linux/Mac/Windows) passes
- [ ] Visual sweep of main UI surfaces in `yarn start`:
        login screen, browser tree, query tool, ERD, schema
        dialogs (table/function/trigger/index), theme switcher
        (light/dark/high-contrast), file manager, debugger panel,
        backup/restore dialogs.

## Notes for reviewers

The major risk surface for this PR is not API breakage (all caught
by jest) but **visual regression**. v9's "sx prop performance" and
"deprecated API cleanup" work shifts a few pixels in places — most
notably ListItemIcon spacing (which v9 changed from hardcoded
`minWidth` to theme spacing). Worth a careful look at menus and
toolbars.

The other Box-related changes (system props -> sx) preserve
behavior 1:1 — they're a pure syntactic migration.

`@mui/x-date-pickers`'s legacy `LocalizationProvider` API was
removed, but we already use the modern `dateAdapter={AdapterDateFns}`
form in `Theme/index.jsx`, so no change needed there.
2026-05-20 17:18:22 +05:30

37 lines
1.2 KiB
React

import PropTypes from 'prop-types';
import gettext from 'sources/gettext';
import { LAYOUT_EVENTS } from './helpers/Layout';
import { styled } from '@mui/material/styles';
import { FormHelperText } from '@mui/material';
import HTMLReactParse from 'html-react-parser';
import { useApplicationState } from '../../settings/static/ApplicationStateProvider';
const StyledBox = styled('div')(({theme}) => ({
color: theme.palette.text.primary,
margin: '24px auto 12px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
height: '100%',
}));
export default function ToolErrorView({error, panelId, panelDocker}){
const { deleteToolData } = useApplicationState();
panelDocker.eventBus.registerListener(LAYOUT_EVENTS.CLOSING, (id)=>{
if(panelId == id) {
panelDocker.close(panelId, true);
deleteToolData(panelId);
}
});
let err_msg = gettext(`An error occurred while opening the tool: ${error}`);
return (<StyledBox>
<FormHelperText variant="outlined" error= {true} style={{marginLeft: '4px'}} >{HTMLReactParse(err_msg)}</FormHelperText>
</StyledBox>);
}
ToolErrorView.propTypes = {
error: PropTypes.string,
panelId: PropTypes.string,
panelDocker: PropTypes.object,
};