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.
143 lines
4.7 KiB
JavaScript
143 lines
4.7 KiB
JavaScript
/////////////////////////////////////////////////////////////
|
|
//
|
|
// pgAdmin 4 - PostgreSQL Tools
|
|
//
|
|
// Copyright (C) 2013 - 2026, The pgAdmin Development Team
|
|
// This software is released under the PostgreSQL Licence
|
|
//
|
|
//////////////////////////////////////////////////////////////
|
|
import PropTypes from 'prop-types';
|
|
import { useContext, useState, useEffect } from 'react';
|
|
import { Box, Grid, Typography } from '@mui/material';
|
|
import { InputSelect } from '../../../../../static/js/components/FormComponents';
|
|
import { SchemaDiffEventsContext } from './SchemaDiffComponent';
|
|
import { SCHEMA_DIFF_EVENT } from '../SchemaDiffConstants';
|
|
|
|
export function InputComponent({ label, serverList, databaseList, schemaList, diff_type, selectedSid = null, selectedDid=null, selectedScid=null, onServerSchemaChange }) {
|
|
const [selectedServer, setSelectedServer] = useState(selectedSid);
|
|
const [selectedDatabase, setSelectedDatabase] = useState(selectedDid);
|
|
const [selectedSchema, setSelectedSchema] = useState(selectedScid);
|
|
const eventBus = useContext(SchemaDiffEventsContext);
|
|
const [disableDBSelection, setDisableDBSelection] = useState(selectedSid == null);
|
|
const [disableSchemaSelection, setDisableSchemaSelection] = useState(selectedDid == null);
|
|
|
|
|
|
useEffect(()=>{
|
|
changeServer(selectedSid);
|
|
},[selectedSid]);
|
|
|
|
useEffect(()=>{
|
|
changeDatabase(selectedDid);
|
|
},[selectedDid]);
|
|
|
|
useEffect(()=>{
|
|
changeSchema(selectedScid);
|
|
},[selectedScid]);
|
|
|
|
const changeServer = (selectedOption) => {
|
|
setDisableDBSelection(false);
|
|
setSelectedServer(selectedOption);
|
|
// Reset the Database selection if user deselect server from DD
|
|
if(selectedOption == null){
|
|
setSelectedDatabase(null);
|
|
setDisableDBSelection(true);
|
|
setSelectedSchema(null);
|
|
setDisableSchemaSelection(true);
|
|
}
|
|
eventBus.fireEvent(SCHEMA_DIFF_EVENT.TRIGGER_SELECT_SERVER, { selectedOption, diff_type, serverList });
|
|
};
|
|
|
|
|
|
const changeDatabase = (selectedDB) => {
|
|
setSelectedDatabase(selectedDB);
|
|
setDisableSchemaSelection(false);
|
|
// Reset the Schema selection if user deselect database from DD
|
|
if(selectedDB == null){
|
|
setSelectedSchema(null);
|
|
setDisableSchemaSelection(true);
|
|
}
|
|
eventBus.fireEvent(SCHEMA_DIFF_EVENT.TRIGGER_SELECT_DATABASE, {selectedServer, selectedDB, diff_type, databaseList});
|
|
onServerSchemaChange();
|
|
};
|
|
|
|
const changeSchema = (selectedSC) => {
|
|
setSelectedSchema(selectedSC);
|
|
eventBus.fireEvent(SCHEMA_DIFF_EVENT.TRIGGER_SELECT_SCHEMA, { selectedSC, diff_type });
|
|
onServerSchemaChange();
|
|
};
|
|
|
|
return (
|
|
<Box sx={{padding: '0rem'}}>
|
|
<Grid
|
|
container
|
|
direction="row"
|
|
sx={{
|
|
alignItems: 'center'
|
|
}}
|
|
>
|
|
<Grid sx={{padding: '0.3rem'}} size={{ lg: 2, md: 2, sm: 2, xs: 2 }}>
|
|
<Typography id={label}>{label}</Typography>
|
|
</Grid>
|
|
<Grid sx={{padding: '0.3rem'}} size={{ lg: 4, md: 4, sm: 4, xs: 4 }}>
|
|
<InputSelect
|
|
options={serverList}
|
|
optionsReloadBasis={serverList?.length}
|
|
onChange={changeServer}
|
|
value={selectedServer}
|
|
controlProps={
|
|
{
|
|
placeholder: 'Select server...'
|
|
}
|
|
}
|
|
key={'server_' + diff_type}
|
|
></InputSelect>
|
|
</Grid>
|
|
|
|
<Grid sx={{padding: '0.3rem'}} size={{ lg: 3, md: 3, sm: 3, xs: 3 }}>
|
|
<InputSelect
|
|
options={databaseList}
|
|
optionsReloadBasis={databaseList?.map ? _.join(databaseList.map((c)=>c.value), ',') : null}
|
|
onChange={changeDatabase}
|
|
value={selectedDatabase}
|
|
controlProps={
|
|
{
|
|
placeholder: 'Select Database...'
|
|
}
|
|
}
|
|
key={'database_' + diff_type}
|
|
readonly={disableDBSelection}
|
|
></InputSelect>
|
|
</Grid>
|
|
|
|
<Grid sx={{padding: '0.3rem'}} size={{ lg: 3, md: 3, sm: 3, xs: 3 }}>
|
|
<InputSelect
|
|
options={schemaList}
|
|
optionsReloadBasis={schemaList?.map ? _.join(schemaList.map((c)=>c.value), ',') : null}
|
|
onChange={changeSchema}
|
|
value={selectedSchema}
|
|
controlProps={
|
|
{
|
|
placeholder: 'Select Schema...'
|
|
}
|
|
}
|
|
key={'schema' + diff_type}
|
|
readonly={disableSchemaSelection}
|
|
></InputSelect>
|
|
</Grid>
|
|
</Grid>
|
|
</Box >
|
|
);
|
|
}
|
|
|
|
InputComponent.propTypes = {
|
|
label: PropTypes.string,
|
|
serverList: PropTypes.array,
|
|
databaseList:PropTypes.array,
|
|
schemaList:PropTypes.array,
|
|
diff_type:PropTypes.number,
|
|
selectedSid: PropTypes.number,
|
|
selectedDid: PropTypes.number,
|
|
selectedScid:PropTypes.number,
|
|
onServerSchemaChange:PropTypes.func
|
|
};
|