Compare commits

..
3 Commits
Author SHA1 Message Date
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
Ashesh Vashi aad2dfd725 chore: Apply non-breaking dependency updates from open dependabot PRs (#9954)
Python:
- requirements.txt: google-auth-oauthlib 1.3.1 -> 1.4.0
  (#9929 / #9931), gated so Python 3.9 stays on 1.3.1 (1.4.0
  requires python_version >= 3.10). Mirrors the existing
  boto3 1.42.*/1.43.* split.
- tools/requirements.txt: requests >=2.33.1 -> >=2.34.2 on
  python_version > '3.9' (#9943 / #9944).
- web/regression/requirements.txt: selenium 4.43.0 -> 4.44.0
  (#9946). The selenium pin already requires Python >=3.10 in
  master, so the bump introduces no new 3.9 gap.

JavaScript (web/package.json, web/yarn.lock):
- postcss 8.5.12 -> 8.5.14 (#9874 / #9889)
- @tanstack/react-query 5.100.5 -> 5.100.9 (#9878)
- ip-address 10.1.0 -> 10.1.1 (#9918)
- packageManager pin yarn@4.14.0 -> yarn@4.15.0 and regenerate
  yarn.lock at lockfile __metadata.version 10. CI runs yarn
  4.15.0 with hardened mode on public PRs and refuses to migrate
  the lockfile from version 9 (yarn 4.14.x) to 10; master passes
  today only because hardened mode is PR-only.

Electron runtime (runtime/package.json, runtime/yarn.lock):
- axios 1.16.0 -> 1.16.1 (#9948)
- eslint 10.3.0 -> 10.4.0 (#9947)

Skipped (genuine breaking changes, deferred to follow-up PRs):
- @mui/material 7 -> 9 (#9843)
- @mui/x-date-pickers 8 -> 9 (#9888)
- cryptography 47.0.* -> 48.0.* (#9926 / #9932)
- paramiko 3.5.1 -> 5.0.0 (#9927 / #9930)
- electron 41.5.0 -> 42.1.0 (#9945)

Verified in an isolated worktree:

  - jest:        140/0/0 suites, 824/0/0 tests
  - eslint:      clean (web + runtime, both silent)
  - pycodestyle: 0 violations project-wide

Each version was cross-checked against the corresponding
dependabot PR diff via `gh pr diff`. Each Python bump was
cross-checked against PyPI's requires_python so Python 3.9
support stays intact.
2026-05-20 14:53:04 +05:30
Dave Page af888027a4 fix(docker): ship libpq-oauth-18.so and libcurl for PostgreSQL 18 OAuth (#9952)
libpq 18 dlopens libpq-oauth-18.so (the SASL OAUTHBEARER flow plugin)
when connecting to a server with an `oauth` pg_hba.conf rule. The
container previously copied only libpq.so.5.18 from postgres:18-alpine
and omitted both the plugin and its libcurl runtime dependency, so
OAuth connections failed with "no OAuth flows are available (try
installing the libpq-oauth package)" before any token exchange could
begin.

Add libpq-oauth-18.so to the existing pg18-builder COPY (it sits next
to libpq.so.5.18 in /usr/local/lib in postgres:18-alpine) and install
the libcurl apk package so the plugin can dlopen libcurl.so.4 at
runtime.

Closes #9951
2026-05-20 12:39:42 +05:30
104 changed files with 933 additions and 428 deletions

No files matched your search

+2 -1
View File
@@ -159,6 +159,7 @@ RUN apk update && apk upgrade && \
bash \
postfix \
krb5-libs \
libcurl \
libjpeg-turbo \
shadow \
sudo \
@@ -174,7 +175,7 @@ COPY --from=env-builder /venv /venv
# Copy in the tools
COPY --from=tool-builder /usr/local/pgsql /usr/local/
COPY --from=pg18-builder /usr/local/lib/libpq.so.5.18 /usr/lib/liblz4.so.1.10.0 /usr/lib/
COPY --from=pg18-builder /usr/local/lib/libpq.so.5.18 /usr/local/lib/libpq-oauth-18.so /usr/lib/liblz4.so.1.10.0 /usr/lib/
RUN ln -s libpq.so.5.18 /usr/lib/libpq.so.5 && \
ln -s libpq.so.5.18 /usr/lib/libpq.so && \
+2 -1
View File
@@ -37,7 +37,8 @@ Flask-WTF==1.2.*; python_version <= '3.9'
Flask-WTF==1.3.*; python_version > '3.9'
Flask==3.1.*
google-api-python-client==2.*
google-auth-oauthlib==1.3.1
google-auth-oauthlib==1.3.1; python_version <= '3.9'
google-auth-oauthlib==1.4.0; python_version > '3.9'
gssapi==1.11.*
jsonformatter~=0.3.4
keyring==25.*
+2 -2
View File
@@ -14,12 +14,12 @@
"devDependencies": {
"@eslint/js": "^10.0.1",
"electron": "^41.5.0",
"eslint": "^10.3.0",
"eslint": "^10.4.0",
"eslint-plugin-unused-imports": "^4.4.1",
"globals": "^17.6.0"
},
"dependencies": {
"axios": "^1.16.0",
"axios": "^1.16.1",
"electron-context-menu": "^4.1.2",
"electron-store": "^11.0.2"
}
+36 -16
View File
@@ -53,12 +53,12 @@ __metadata:
languageName: node
linkType: hard
"@eslint/config-helpers@npm:^0.5.5":
version: 0.5.5
resolution: "@eslint/config-helpers@npm:0.5.5"
"@eslint/config-helpers@npm:^0.6.0":
version: 0.6.0
resolution: "@eslint/config-helpers@npm:0.6.0"
dependencies:
"@eslint/core": "npm:^1.2.1"
checksum: 10c0/18889c062cd6bdbd4cd92fe57318c44465ea66184aa0ba204a4420712c66764c64093a7905b6c2ffde23e51b268ca2cec1a39c605d336bebf17ee1ba4f0fc0bb
checksum: 10c0/f9af20e8b60b0ba27edb74b8eb40c0c5d51a9bf9baf9e053bb57833a87cb0a1c49b4dfaad88fc24d49c907ad1324c8a0b668684fa9c321351dac4bc9155ec10a
languageName: node
linkType: hard
@@ -250,6 +250,15 @@ __metadata:
languageName: node
linkType: hard
"agent-base@npm:6":
version: 6.0.2
resolution: "agent-base@npm:6.0.2"
dependencies:
debug: "npm:4"
checksum: 10c0/dc4f757e40b5f3e3d674bc9beb4f1048f4ee83af189bae39be99f57bf1f48dde166a8b0a5342a84b5944ee8e6ed1e5a9d801858f4ad44764e84957122fe46261
languageName: node
linkType: hard
"ajv-formats@npm:^3.0.1":
version: 3.0.1
resolution: "ajv-formats@npm:3.0.1"
@@ -333,14 +342,15 @@ __metadata:
languageName: node
linkType: hard
"axios@npm:^1.16.0":
version: 1.16.0
resolution: "axios@npm:1.16.0"
"axios@npm:^1.16.1":
version: 1.16.1
resolution: "axios@npm:1.16.1"
dependencies:
follow-redirects: "npm:^1.16.0"
form-data: "npm:^4.0.5"
https-proxy-agent: "npm:^5.0.1"
proxy-from-env: "npm:^2.1.0"
checksum: 10c0/1c91a5221b77b76072026b4cc95ecdf38f7c3e33e63423abec09a85e6e9a12279637dcc9ac2ba1fc333e0c447fb3b0f46d7965acb5d7cea02d188e9c6d425c0b
checksum: 10c0/2f77e37e6552bbff8a772d058fb09500198e9188c6b20dc799d82dbe12a8cb506f6eed4e4e62a9ba612a35cbab496faa26d68f9bff14a53af6d15c3e136391a7
languageName: node
linkType: hard
@@ -471,7 +481,7 @@ __metadata:
languageName: node
linkType: hard
"debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2":
"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2":
version: 4.4.3
resolution: "debug@npm:4.4.3"
dependencies:
@@ -746,14 +756,14 @@ __metadata:
languageName: node
linkType: hard
"eslint@npm:^10.3.0":
version: 10.3.0
resolution: "eslint@npm:10.3.0"
"eslint@npm:^10.4.0":
version: 10.4.0
resolution: "eslint@npm:10.4.0"
dependencies:
"@eslint-community/eslint-utils": "npm:^4.8.0"
"@eslint-community/regexpp": "npm:^4.12.2"
"@eslint/config-array": "npm:^0.23.5"
"@eslint/config-helpers": "npm:^0.5.5"
"@eslint/config-helpers": "npm:^0.6.0"
"@eslint/core": "npm:^1.2.1"
"@eslint/plugin-kit": "npm:^0.7.1"
"@humanfs/node": "npm:^0.16.6"
@@ -787,7 +797,7 @@ __metadata:
optional: true
bin:
eslint: bin/eslint.js
checksum: 10c0/81e3ceba949f62d1b530660279db86cf814f5dc43d7cc3759a8008fe4fc679d46568279fe1cceb7ddbbc98ab57a96ae524f6e811ffc6897b49b90ea08aa785e5
checksum: 10c0/6bf644dc08fa5a6b23157d23a4a4638d45823d03a67da1daac8dc1085b03934fa98013efd2eac2cd6ec90fe88d36b336bdf38d5f000325f22d823a15f2031426
languageName: node
linkType: hard
@@ -1162,6 +1172,16 @@ __metadata:
languageName: node
linkType: hard
"https-proxy-agent@npm:^5.0.1":
version: 5.0.1
resolution: "https-proxy-agent@npm:5.0.1"
dependencies:
agent-base: "npm:6"
debug: "npm:4"
checksum: 10c0/6dd639f03434003577c62b27cafdb864784ef19b2de430d8ae2a1d45e31c4fd60719e5637b44db1a88a046934307da7089e03d6089ec3ddacc1189d8de8897d1
languageName: node
linkType: hard
"ignore@npm:^5.2.0":
version: 5.3.2
resolution: "ignore@npm:5.3.2"
@@ -1480,11 +1500,11 @@ __metadata:
resolution: "pgadmin4@workspace:."
dependencies:
"@eslint/js": "npm:^10.0.1"
axios: "npm:^1.16.0"
axios: "npm:^1.16.1"
electron: "npm:^41.5.0"
electron-context-menu: "npm:^4.1.2"
electron-store: "npm:^11.0.2"
eslint: "npm:^10.3.0"
eslint: "npm:^10.4.0"
eslint-plugin-unused-imports: "npm:^4.4.1"
globals: "npm:^17.6.0"
languageName: unknown
+2 -2
View File
@@ -1,7 +1,7 @@
requests>=2.32.5,<2.33; python_version <= '3.9'
requests>=2.33.1; python_version > '3.9'
requests>=2.34.2; python_version > '3.9'
requests[security]>=2.32.5,<2.33; python_version <= '3.9'
requests[security]>=2.33.1; python_version > '3.9'
requests[security]>=2.34.2; python_version > '3.9'
safety>=3.7.0
Sphinx==7.4.7
sphinxcontrib-youtube==1.5.0
+7 -7
View File
@@ -79,14 +79,14 @@
"@emotion/sheet": "^1.4.0",
"@fluentui/keyboard-key": "^0.4.23",
"@fortawesome/fontawesome-free": "latest",
"@mui/icons-material": "^7.3.10",
"@mui/material": "^7.3.10",
"@mui/x-date-pickers": "^8.28.3",
"@mui/icons-material": "^9.0.0",
"@mui/material": "^9.0.0",
"@mui/x-date-pickers": "^9.0.2",
"@nozbe/microfuzz": "^1.0.0",
"@projectstorm/react-diagrams": "^7.0.4",
"@simonwep/pickr": "^1.9.1",
"@szhsin/react-menu": "^4.5.1",
"@tanstack/react-query": "^5.100.5",
"@tanstack/react-query": "^5.100.9",
"@tanstack/react-table": "^8.21.3",
"@tanstack/react-virtual": "^3.13.24",
"@types/react": "^19.2.14",
@@ -113,7 +113,7 @@
"html-to-image": "1.11.11",
"immutability-helper": "^3.1.1",
"insert-if": "^1.2.0",
"ip-address": "^10.1.0",
"ip-address": "^10.1.1",
"json-bignumber": "^1.1.1",
"leaflet": "^1.9.4",
"lodash": "4.*",
@@ -124,7 +124,7 @@
"notistack": "^3.0.2",
"papaparse": "^5.5.3",
"path-fx": "^2.1.2",
"postcss": "^8.5.12",
"postcss": "^8.5.14",
"rc-dock": "^4.0.0-alpha.2",
"react": "^19.2.5",
"react-arborist": "^3.5.0",
@@ -180,7 +180,7 @@
"auditpy": "safety check --full-report -i 51668 -i 52495",
"audit-all": "yarn run auditjs && yarn run auditpy"
},
"packageManager": "yarn@4.14.0",
"packageManager": "yarn@4.15.0",
"browserslist": [
"defaults and fully supports es6-module"
]
+13 -2
View File
@@ -122,11 +122,22 @@ export default function AboutComponent() {
</Grid>
}
{ aboutData.settings &&
<Box flexGrow="1" display="flex" flexDirection="column" minHeight="0">
<Box
sx={{
flexGrow: '1',
display: 'flex',
flexDirection: 'column',
minHeight: '0'
}}>
<Box>
<InputLabel style={{fontWeight: 'bold'}}>{gettext('pgAdmin Server Configuration')}</InputLabel>
</Box>
<Box flexGrow="1" paddingTop="1px" minHeight="0">
<Box
sx={{
flexGrow: '1',
paddingTop: '1px',
minHeight: '0'
}}>
<InputSQL value={aboutData.settings}
controlProps={{
readonly: true,
+6 -6
View File
@@ -35,10 +35,10 @@ _.extend(pgBrowser.keyboardNavigation, {
hotkeys.unbind();
if (prefStore.version > 0) {
this.keyboardShortcut = {
...(prefStore.getPreferences('browser', 'main_menu_file')?.value) && {'file_shortcut': commonUtils.parseShortcutValue(prefStore.getPreferences('browser', 'main_menu_file')?.value)},
...(prefStore.getPreferences('browser', 'main_menu_object')?.value) && {'object_shortcut': commonUtils.parseShortcutValue(prefStore.getPreferences('browser', 'main_menu_object')?.value)},
...(prefStore.getPreferences('browser', 'main_menu_tools')?.value) && {'tools_shortcut': commonUtils.parseShortcutValue(prefStore.getPreferences('browser', 'main_menu_tools')?.value)},
...(prefStore.getPreferences('browser', 'main_menu_help')?.value) && {'help_shortcut': commonUtils.parseShortcutValue(prefStore.getPreferences('browser', 'main_menu_help')?.value)},
...((prefStore.getPreferences('browser', 'main_menu_file')?.value) && {'file_shortcut': commonUtils.parseShortcutValue(prefStore.getPreferences('browser', 'main_menu_file')?.value)}),
...((prefStore.getPreferences('browser', 'main_menu_object')?.value) && {'object_shortcut': commonUtils.parseShortcutValue(prefStore.getPreferences('browser', 'main_menu_object')?.value)}),
...((prefStore.getPreferences('browser', 'main_menu_tools')?.value) && {'tools_shortcut': commonUtils.parseShortcutValue(prefStore.getPreferences('browser', 'main_menu_tools')?.value)}),
...((prefStore.getPreferences('browser', 'main_menu_help')?.value) && {'help_shortcut': commonUtils.parseShortcutValue(prefStore.getPreferences('browser', 'main_menu_help')?.value)}),
'left_tree_shortcut': commonUtils.parseShortcutValue(prefStore.getPreferences('browser', 'browser_tree')?.value),
'tabbed_panel_backward': commonUtils.parseShortcutValue(prefStore.getPreferences('browser', 'tabbed_panel_backward')?.value),
'tabbed_panel_forward': commonUtils.parseShortcutValue(prefStore.getPreferences('browser', 'tabbed_panel_forward')?.value),
@@ -56,11 +56,11 @@ _.extend(pgBrowser.keyboardNavigation, {
};
this.shortcutMethods = {
...(prefStore.getPreferences('browser', 'main_menu_file')?.value) && {'bindMainMenu': {
...((prefStore.getPreferences('browser', 'main_menu_file')?.value) && {'bindMainMenu': {
'shortcuts': [this.keyboardShortcut.file_shortcut,
this.keyboardShortcut.object_shortcut, this.keyboardShortcut.tools_shortcut,
this.keyboardShortcut.help_shortcut],
}}, // Main menu
}}), // Main menu
'bindRightPanel': {'shortcuts': [this.keyboardShortcut.tabbed_panel_backward, this.keyboardShortcut.tabbed_panel_forward, this.keyboardShortcut.close_tab_panel]}, // Main window panels
'bindLeftTree': {'shortcuts': this.keyboardShortcut.left_tree_shortcut}, // Main menu,
'bindSubMenuQueryTool': {'shortcuts': this.keyboardShortcut.sub_menu_query_tool}, // Sub menu - Open Query Tool,
+50 -38
View File
@@ -948,41 +948,48 @@ function Dashboard({
label: gettext('Table based logs'),
};
const CustomLogHeader = () => {
return ( <Box className='Dashboard-cardHeader' display="flex" flexDirection="row">
<FormInputToggle
label={gettext('Log Format')}
className='Dashboard-searchInput'
value={logFormat}
onChange={(val) => {
setLogFormat(val);
}}
options={logConfigFormat}
controlProps={CustomLogHeaderLabel}
labelGridBasis={3}
controlGridBasis={3}
></FormInputToggle>
<FormInputSwitch
label={gettext('Tabular format?')}
labelPlacement="end"
className='Dashboard-searchInput'
value={logCol}
onChange={(e) => {
setDashData([]);
setLogCol(e.target.checked);
}}
controlProps={CustomLogHeaderLabel}
labelGridBasis={3}
controlGridBasis={3}
></FormInputSwitch>
<div className='Dashboard-download'><PgIconButton
size="xs"
className='Dashboard-downloadButton'
icon={<GetAppRoundedIcon />}
onClick={downloadServerLogs}
aria-label="Download"
title={gettext('Download logs ')}
></PgIconButton></div>
</Box>);
return (
<Box
className='Dashboard-cardHeader'
sx={{
display: 'flex',
flexDirection: 'row'
}}>
<FormInputToggle
label={gettext('Log Format')}
className='Dashboard-searchInput'
value={logFormat}
onChange={(val) => {
setLogFormat(val);
}}
options={logConfigFormat}
controlProps={CustomLogHeaderLabel}
labelGridBasis={3}
controlGridBasis={3}
></FormInputToggle>
<FormInputSwitch
label={gettext('Tabular format?')}
labelPlacement="end"
className='Dashboard-searchInput'
value={logCol}
onChange={(e) => {
setDashData([]);
setLogCol(e.target.checked);
}}
controlProps={CustomLogHeaderLabel}
labelGridBasis={3}
controlGridBasis={3}
></FormInputSwitch>
<div className='Dashboard-download'><PgIconButton
size="xs"
className='Dashboard-downloadButton'
icon={<GetAppRoundedIcon />}
onClick={downloadServerLogs}
aria-label="Download"
title={gettext('Download logs ')}
></PgIconButton></div>
</Box>
);
};
@@ -1021,7 +1028,7 @@ function Dashboard({
};
return (
(<Root>
<Root>
{sid && serverConnected ? (
<Box className='Dashboard-dashboardPanel'>
<Box className='Dashboard-panelContent'>
@@ -1133,7 +1140,12 @@ function Dashboard({
</TabPanel>
{/* System Statistics */}
<TabPanel value={mainTabVal} index={4} classNameRoot='Dashboard-tabPanel systemStorage'>
<Box height="100%" display="flex" flexDirection="column">
<Box
sx={{
height: '100%',
display: 'flex',
flexDirection: 'column'
}}>
{ssMsg === 'installed' && did === ldid ?
<ErrorBoundary>
<Box>
@@ -1203,7 +1215,7 @@ function Dashboard({
</Box>
</Box>
) : showDefaultContents() }
</Root>)
</Root>
);
}
@@ -165,7 +165,12 @@ export default function LogReplication({treeNodeInfo, pageVisible}) {
}, [pageVisible ]);
return (
<Box height="100%" display="flex" flexDirection="column">
<Box
sx={{
height: '100%',
display: 'flex',
flexDirection: 'column'
}}>
<SectionContainer
titleExtras={<RefreshButton onClick={()=>{
getReplicationData('replication_stats', setReplicationStats);
@@ -404,7 +404,12 @@ export default function PGDReplication({preferences, treeNodeInfo, pageVisible,
const replicationLagBytesData = useMemo(()=>transformData(replicationLagBytes, preferences['pgd_replication_lag_refresh'], theme.name), [replicationLagBytes, theme.name]);
return (
<Box height="100%" display="flex" flexDirection="column">
<Box
sx={{
height: '100%',
display: 'flex',
flexDirection: 'column'
}}>
<Grid container spacing={0.5}>
<Grid size={{ md: 6 }}>
<ChartContainer id='sessions-graph' title={gettext('Replication lag (Time)')}
@@ -183,7 +183,12 @@ export default function CpuDetails({preferences, sid, did, pageVisible, enablePo
}, enablePoll ? pollDelay : -1);
return (
<Box display="flex" flexDirection="column" height="100%">
<Box
sx={{
display: 'flex',
flexDirection: 'column',
height: '100%'
}}>
<div data-testid='graph-poll-delay' style={{display: 'none'}}>{pollDelay}</div>
{chartDrawnOnce &&
<CPUWrapper
@@ -217,7 +222,12 @@ export function CPUWrapper(props) {
lineBorderWidth: props.lineBorderWidth,
}), [props.showTooltip, props.showDataPoints, props.lineBorderWidth]);
return (
<Box display="flex" flexDirection="column" height="100%">
<Box
sx={{
display: 'flex',
flexDirection: 'column',
height: '100%'
}}>
<Grid container spacing={0.5} sx={{marginBottom: '4px'}}>
<Grid size={{ md: 6 }}>
<ChartContainer id='cu-graph' title={gettext('CPU usage')} datasets={props.cpuUsageInfo.datasets} errorMsg={props.errorMsg} isTest={props.isTest}>
@@ -230,7 +240,11 @@ export function CPUWrapper(props) {
</ChartContainer>
</Grid>
</Grid>
<Box flexGrow={1} minHeight={0}>
<Box
sx={{
flexGrow: 1,
minHeight: 0
}}>
<SectionContainer title={gettext('Process CPU usage')}>
<PgTable
columns={props.tableHeader}
@@ -188,7 +188,12 @@ export default function Memory({preferences, sid, did, pageVisible, enablePoll=t
});
}, enablePoll ? pollDelay : -1);
return (
<Box display="flex" flexDirection="column" height="100%">
<Box
sx={{
display: 'flex',
flexDirection: 'column',
height: '100%'
}}>
<div data-testid='graph-poll-delay' style={{display: 'none'}}>{pollDelay}</div>
{chartDrawnOnce &&
<MemoryWrapper
@@ -224,7 +229,12 @@ export function MemoryWrapper(props) {
}), [props.showTooltip, props.showDataPoints, props.lineBorderWidth]);
return (
<Box display="flex" flexDirection="column" height="100%">
<Box
sx={{
display: 'flex',
flexDirection: 'column',
height: '100%'
}}>
<Grid container spacing={0.5} sx={{marginBottom: '4px'}}>
<Grid size={{ md: 6 }}>
<ChartContainer id='m-graph' title={gettext('Memory')} datasets={props.memoryUsageInfo.datasets} errorMsg={props.errorMsg} isTest={props.isTest}>
@@ -239,7 +249,11 @@ export function MemoryWrapper(props) {
</ChartContainer>
</Grid>
</Grid>
<Box flexGrow={1} minHeight={0}>
<Box
sx={{
flexGrow: 1,
minHeight: 0
}}>
<SectionContainer title={gettext('Process memory usage')}>
<PgTable
columns={props.tableHeader}
@@ -500,7 +500,9 @@ export function StorageWrapper(props) {
</Grid>
{Object.keys(props.ioInfo).map((drive) => (
<SectionContainer key={drive} title={drive} style={{minHeight: 'unset', height: 'auto', marginBottom: '0.5px'}}>
<Grid container spacing={0.5} p={0.5}>
<Grid container spacing={0.5} sx={{
p: 0.5
}}>
{Object.keys(props.ioInfo[drive]).map((type, innerKeyIndex) => (
<Grid key={`${type}-${innerKeyIndex}`} size={{ md: 4, sm: 6 }}>
<ChartContainer id={`io-graph-${type}`} title={getChartContainerTitle(type)} datasets={transformData(props.ioInfo[drive][type], props.ioRefreshRate).datasets} errorMsg={props.errorMsg} isTest={props.isTest}>
@@ -40,7 +40,11 @@ export default function ChartContainer(props) {
return (
<StyledCard elevation={0} data-testid="chart-container">
<CardHeader title={<Box display="flex" justifyContent="space-between">
<CardHeader title={<Box
sx={{
display: 'flex',
justifyContent: 'space-between'
}}>
<div id={props.id}>{props.title}</div>
<div className='ChartContainer-chartLegend'>
<div style={{display: 'flex', flexWrap: 'wrap'}}>
@@ -11,7 +11,7 @@ import PropTypes from 'prop-types';
import { Box } from '@mui/material';
import { Resizable } from 're-resizable';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
...theme.mixins.panelBorder.all,
display: 'flex',
flexDirection: 'column',
@@ -48,7 +48,13 @@ export default function SectionContainer({title, titleExtras, children, style, r
{titleExtras}
</div>
</Box>
<Box height="100%" display="flex" flexDirection="column" minHeight={0}>
<Box
sx={{
height: '100%',
display: 'flex',
flexDirection: 'column',
minHeight: 0
}}>
{children}
</Box>
</>
+1 -1
View File
@@ -48,7 +48,7 @@ marked.setOptions({
});
const StyledBox = styled(Box)(({ theme }) => ({
const StyledBox = styled('div')(({ theme }) => ({
display: 'flex',
flexDirection: 'column',
height: '100%',
+1 -1
View File
@@ -30,7 +30,7 @@ marked.setOptions({
});
const StyledBox = styled(Box)(({ theme }) => ({
const StyledBox = styled('div')(({ theme }) => ({
display: 'flex',
flexDirection: 'column',
height: '100%',
@@ -8,7 +8,7 @@ import PropTypes from 'prop-types';
import gettext from 'sources/gettext';
import pgAdmin from 'sources/pgadmin';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
borderRadius: theme.shape.borderRadius,
padding: '0.25rem 1rem 1rem',
minWidth: '325px',
@@ -46,13 +46,24 @@ const AUTO_HIDE_DURATION = 10000; // In milliseconds
function ProcessNotifyMessage({title, desc, onClose, onViewProcess, success=true, dataTestSuffix=''}) {
return (
<StyledBox className={(success ? 'BgProcessNotify-containerSuccess' : 'BgProcessNotify-containerError')} data-test={'process-popup-' + dataTestSuffix}>
<Box display="flex" justifyContent="space-between" className='BgProcessNotify-containerHeader'>
<Box marginRight={'1rem'}>{title}</Box>
<Box
className='BgProcessNotify-containerHeader'
sx={{
display: 'flex',
justifyContent: 'space-between'
}}>
<Box sx={{
marginRight: '1rem'
}}>{title}</Box>
<PgIconButton size="xs" noBorder icon={<CloseIcon />} onClick={onClose} title={'Close'} className={success ? 'BgProcessNotify-iconSuccess' : 'BgProcessNotify-iconError'} />
</Box>
<Box className='BgProcessNotify-containerBody'>
<Box>{desc}</Box>
<Box marginTop={'1rem'} display="flex">
<Box
sx={{
marginTop: '1rem',
display: 'flex'
}}>
<DefaultButton startIcon={<DescriptionOutlinedIcon />} onClick={()=>{
onViewProcess();
onClose();
@@ -24,7 +24,7 @@ import pgAdmin from 'sources/pgadmin';
import FolderSharedRoundedIcon from '@mui/icons-material/FolderSharedRounded';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
backgroundColor: theme.palette.background.default,
height: '100%',
display: 'flex',
@@ -161,7 +161,13 @@ export default function ProcessDetails({data}) {
<Box>{gettext('Running query')}:</Box>
<Box data-test="process-cmd" className='ProcessDetails-cmd'>{data.details.query}</Box>
</>}
<Box display="flex" justifyContent="space-between" alignItems="center" flexWrap="wrap">
<Box
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
flexWrap: 'wrap'
}}>
<Box><span><AccessTimeRoundedIcon /> {gettext('Start time')}: {new Date(data.stime).toString()}</span></Box>
<Box>
{pgAdmin.server_mode == 'True' && data.current_storage_dir &&
@@ -174,7 +180,7 @@ export default function ProcessDetails({data}) {
</DefaultButton>
</Box>
</Box>
<Box flexGrow={1} className='ProcessDetails-logs'>
<Box sx={{flexGrow: 1}} className='ProcessDetails-logs'>
{logs == null && <span data-test="loading-logs">{gettext('Loading process logs...')}</span>}
{logs?.length == 0 && gettext('No logs available.')}
{logs?.map((log, i)=>{
@@ -186,7 +192,11 @@ export default function ProcessDetails({data}) {
}} key={id} className={errRe.test(log) ? 'ProcessDetails-logErr' : ''}>{log}</div>;
})}
</Box>
<Box display="flex" alignItems="center">
<Box
sx={{
display: 'flex',
alignItems: 'center'
}}>
<NotifierMessage type={notifyType} message={notifyText} closable={false} textCenter={true} style={{flexGrow: 1, marginRight: '8px'}} />
<Box>{gettext('Execution time')}: {timeTaken} {gettext('seconds')}</Box>
</Box>
@@ -425,10 +425,14 @@ export default function CloudWizard({ nodeInfo, nodeData, onClose, cloudPanelId}
</Box>
{cloudProvider == CLOUD_PROVIDERS.AWS && <AwsCredentials cloudProvider={cloudProvider} nodeInfo={nodeInfo} nodeData={nodeData} setCloudDBCred={setCloudDBCred}/>}
{ cloudProvider == CLOUD_PROVIDERS.AZURE &&
<Box flexGrow={1}>
<Box sx={{
flexGrow: 1
}}>
<AzureCredentials cloudProvider={cloudProvider} setAzureCredData={setAzureCredData}/>
</Box>}
<Box flexGrow={1}>
<Box sx={{
flexGrow: 1
}}>
{cloudProvider == CLOUD_PROVIDERS.GOOGLE && <GoogleCredentials cloudProvider={cloudProvider} setGoogleCredData={setGoogleCredData}/>}
</Box>
<FormFooterMessage type={errMsg[0]} message={errMsg[1]} onClose={onErrClose} />
@@ -37,7 +37,7 @@ import ErrorBoundary from '../../../../../static/js/helpers/ErrorBoundary';
import { MY_STORAGE } from './FileManagerConstants';
import _ from 'lodash';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
backgroundColor: theme.palette.background.default,
'& .FileManager-toolbar': {
padding: '4px',
@@ -452,8 +452,12 @@ export class FileManagerUtils {
function ConfirmFile({text, onYes, onNo}) {
return (
<Box className='FileManager-replaceOverlay'>
<Box margin={'8px'} className='FileManager-replaceDialog'>
<Box padding={'1rem'}>{text}{}</Box>
<Box className='FileManager-replaceDialog' sx={{
margin: '8px'
}}>
<Box sx={{
padding: '1rem'
}}>{text}{}</Box>
<Box className='FileManager-footer'>
<DefaultButton data-test="no" startIcon={<CloseIcon />} onClick={onNo} >{gettext('No')}</DefaultButton>
<PrimaryButton data-test="yes" className='FileManager-margin' startIcon={<CheckRoundedIcon />}
@@ -771,7 +775,14 @@ export default function FileManager({params, closeModal, onOK, onCancel, sharedS
return (
<ErrorBoundary>
<StyledBox display="flex" flexDirection="column" height="100%">
<Box flexGrow="1" display="flex" flexDirection="column" position="relative" overflow="hidden">
<Box
sx={{
flexGrow: '1',
display: 'flex',
flexDirection: 'column',
position: 'relative',
overflow: 'hidden'
}}>
<Loader message={loaderText} />
{Boolean(confirmText) && <ConfirmFile text={confirmText} onNo={()=>setConfirmFile([null, null])} onYes={onConfirmYes}/>}
<Box className='FileManager-toolbar'>
@@ -869,7 +880,14 @@ export default function FileManager({params, closeModal, onOK, onCancel, sharedS
</PgMenu>
}
</Box>
<Box flexGrow="1" display="flex" flexDirection="column" position="relative" overflow="hidden">
<Box
sx={{
flexGrow: '1',
display: 'flex',
flexDirection: 'column',
position: 'relative',
overflow: 'hidden'
}}>
{showUploader &&
<Uploader fmUtilsObj={fmUtilsObj}
onClose={async (filesUploaded)=>{
@@ -16,7 +16,7 @@ import StorageRoundedIcon from '@mui/icons-material/StorageRounded';
import PropTypes from 'prop-types';
import gettext from 'sources/gettext';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
'& .GridView-grid': {
display: 'flex',
fontSize: '13px',
@@ -143,7 +143,11 @@ export default function GridView({items, operation, onItemSelect, onItemEnter})
onItemEnter={onItemEnter} onEditComplete={operation.idx==i ? onEditComplete : null} />)
)}
</div>
{items.length == 0 && <Box textAlign="center" p={1}>{gettext('No files/folders found')}</Box>}
{items.length == 0 && <Box
sx={{
textAlign: 'center',
p: 1
}}>{gettext('No files/folders found')}</Box>}
</StyledBox>
);
}
@@ -19,7 +19,7 @@ import _ from 'lodash';
import PropTypes from 'prop-types';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
position: 'absolute',
top: 0,
bottom: 0,
@@ -104,9 +104,17 @@ export function UploadedFile({upfile, removeFile}) {
return (
<ListItem style={{cursor: 'auto'}}>
<Box display="flex" alignItems="flex-start">
<Box overflow="hidden" style={{overflowWrap: 'break-word'}} >{upfile.file.name}</Box>
<Box marginLeft="auto">
<Box
sx={{
display: 'flex',
alignItems: 'flex-start'
}}>
<Box style={{overflowWrap: 'break-word'}} sx={{
overflow: 'hidden'
}} >{upfile.file.name}</Box>
<Box sx={{
marginLeft: 'auto'
}}>
<PgIconButton title={gettext('Remove from list')} icon={<CloseIcon />} size="xs" noBorder onClick={removeFile} />
</Box>
</Box>
@@ -166,10 +174,19 @@ export default function Uploader({fmUtilsObj, onClose}) {
return (
<StyledBox>
<Box display="flex" justifyContent="flex-end">
<Box
sx={{
display: 'flex',
justifyContent: 'flex-end'
}}>
<PgIconButton title={gettext('Close')} icon={<CloseIcon />} size="xs" noBorder onClick={onClose} />
</Box>
<Box display="flex" flexGrow={1} overflow="hidden">
<Box
sx={{
display: 'flex',
flexGrow: 1,
overflow: 'hidden'
}}>
<Box className='Uploader-uploadArea' {...getRootProps()}>
<input {...getInputProps()} />
<Box>{gettext('Drop files here, or click to select files.')}</Box>
@@ -25,7 +25,7 @@ import { usePgAdmin } from '../../static/js/PgAdminProvider';
import { getSwitchCell } from '../../static/js/components/PgReactTableStyled';
import { parseApiError } from '../../static/js/api_instance';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
height: '100%',
'&.CollectionNodeProperties-emptyPanel': {
minHeight: '100%',
+4 -2
View File
@@ -20,7 +20,7 @@ import { usePgAdmin } from '../../static/js/PgAdminProvider';
import PropTypes from 'prop-types';
import _ from 'lodash';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
height: '100%',
background: theme.otherVars.emptySpaceBg,
display: 'flex',
@@ -41,7 +41,9 @@ function Properties(props) {
if(noPropertyMsg) {
return (
<StyledBox>
<Box margin={'4px auto'}>
<Box sx={{
margin: '4px auto'
}}>
<EmptyPanelMessage text={noPropertyMsg} />
</Box>
</StyledBox>
@@ -133,7 +133,9 @@ export default function WorkspaceToolbar() {
<WorkspaceButton icon={<QueryToolIcon />} value={WORKSPACES.QUERY_TOOL} title={gettext('Query Tool Workspace')} tooltipPlacement="right" options={{permission: AllPermissionTypes.TOOLS_QUERY_TOOL}} />
{pgAdmin['enable_psql'] && <WorkspaceButton icon={<TerminalRoundedIcon style={{height: '1.4rem'}}/>} value={WORKSPACES.PSQL_TOOL} title={gettext('PSQL Tool Workspace')} tooltipPlacement="right" options={{permission: AllPermissionTypes.TOOLS_PSQL_TOOL}} />}
<WorkspaceButton icon={<SchemaDiffIcon />} value={WORKSPACES.SCHEMA_DIFF_TOOL} title={gettext('Schema Diff Workspace')} tooltipPlacement="right" options={{permission: AllPermissionTypes.TOOLS_SCHEMA_DIFF}} />
<Box marginTop="auto">
<Box sx={{
marginTop: 'auto'
}}>
<WorkspaceButton icon={<SettingsIcon />} menuItem={menus['settings']} title={gettext('Preferences')} tooltipPlacement="right" />
</Box>
</Root>
@@ -73,7 +73,7 @@ const Root = styled('div')(({theme}) => ({
}
}));
const BackgroundSVG = styled(Box)(() => ({
const BackgroundSVG = styled('div')(() => ({
position: 'absolute',
top: 0,
bottom: 0,
@@ -40,7 +40,7 @@ import LeftTree from './LeftTree';
import RightPreference from './RightPreference';
// --- Styled Components ---
const Root = styled(Box)(({ theme }) => ({
const Root = styled('div')(({ theme }) => ({
height: '100%',
display: 'flex',
flexDirection: 'column',
@@ -303,7 +303,7 @@ export function getCollectionValue(_metadata, value, initVals) {
return val;
}
const StyledBox = styled(Box)(({ theme }) => ({
const StyledBox = styled('div')(({ theme }) => ({
'& .Alert-footer': {
display: 'flex',
justifyContent: 'flex-end',
@@ -348,7 +348,11 @@ export function showResetPrefModal(api, pgAdmin, preferencesStore, onReset) {
return (
<StyledBox display="flex" flexDirection="column" height="100%">
<Box flexGrow="1" p={2}>
<Box
sx={{
flexGrow: '1',
p: 2
}}>
{HTMLReactParser(text)}
</Box>
<Box className='Alert-footer'>
+1 -2
View File
@@ -6,7 +6,6 @@
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import { Box } from '@mui/material';
import { styled } from '@mui/material/styles';
import { useEffect } from 'react';
import { PrimaryButton } from './components/Buttons';
@@ -17,7 +16,7 @@ import { usePgAdmin } from '../../static/js/PgAdminProvider';
import { useForceUpdate } from './custom_hooks';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
height: '30px',
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastText,
@@ -11,7 +11,11 @@ import PropTypes from 'prop-types';
export default function ConfirmSaveContent({closeModal, text, onDontSave, onSave}) {
return (
<ModalContent>
<Box flexGrow="1" p={2}>{typeof(text) == 'string' ? HTMLReactParser(text) : text}</Box>
<Box
sx={{
flexGrow: '1',
p: 2
}}>{typeof(text) == 'string' ? HTMLReactParser(text) : text}</Box>
<ModalFooter>
<DefaultButton data-test="close" startIcon={<CloseIcon />} onClick={()=>{
closeModal();
@@ -59,7 +59,11 @@ export default function ConnectServerContent({closeModal, data, onOK, setHeight,
return (
<ModalContent ref={containerRef}>
<Box flexGrow="1" p={2}>
<Box
sx={{
flexGrow: '1',
p: 2
}}>
{data.prompt_tunnel_password && <>
<Box>
<span style={{fontWeight: 'bold'}}>
@@ -69,11 +73,18 @@ export default function ConnectServerContent({closeModal, data, onOK, setHeight,
}
</span>
</Box>
<Box marginTop='12px'>
<Box sx={{
marginTop: '12px'
}}>
<InputText inputRef={firstEleRef} type="password" value={formData['tunnel_password']} controlProps={{maxLength:null, autoComplete:'new-password'}}
onChange={(e)=>onTextChange(e, 'tunnel_password')} onKeyDown={(e)=>onKeyDown(e)} />
</Box>
<Box marginTop='12px' marginBottom='12px' visibility={hideSavePassword ? 'hidden' : 'unset'}>
<Box
sx={{
marginTop: '12px',
marginBottom: '12px',
visibility: hideSavePassword ? 'hidden' : 'unset'
}}>
<InputCheckbox controlProps={{label: gettext('Save Password')}} value={formData['save_tunnel_password']}
onChange={(e)=>onTextChange(e.target.checked, 'save_tunnel_password')} disabled={!data.allow_save_tunnel_password} />
</Box>
@@ -87,7 +98,9 @@ export default function ConnectServerContent({closeModal, data, onOK, setHeight,
}
</span>
</Box>
<Box marginTop='12px'>
<Box sx={{
marginTop: '12px'
}}>
<InputText inputRef={(ele)=>{
if(!data.prompt_tunnel_password) {
/* Set only if no tunnel password asked */
@@ -96,7 +109,11 @@ export default function ConnectServerContent({closeModal, data, onOK, setHeight,
}} type="password" value={formData['password']} controlProps={{maxLength:null}}
onChange={(e)=>onTextChange(e, 'password')} onKeyDown={(e)=>onKeyDown(e)}/>
</Box>
<Box marginTop='12px' visibility={hideSavePassword ? 'hidden' : 'unset'}>
<Box
sx={{
marginTop: '12px',
visibility: hideSavePassword ? 'hidden' : 'unset'
}}>
<InputCheckbox controlProps={{label: gettext('Save Password')}} value={formData['save_password']}
onChange={(e)=>onTextChange(e.target.checked, 'save_password')} disabled={!data.allow_save_password} />
</Box>
@@ -57,7 +57,11 @@ export default function MasterPasswordContent({ closeModal, onResetPassowrd, onO
return (
<ModalContent ref={containerRef}>
{isKeyring ?
<Box flexGrow="1" p={2}>
<Box
sx={{
flexGrow: '1',
p: 2
}}>
<Box>
<span style={{ fontWeight: 'bold' }}>
{gettext('Please enter your master password.')}
@@ -67,7 +71,9 @@ export default function MasterPasswordContent({ closeModal, onResetPassowrd, onO
<FormNote text={gettext(`Saved passwords are encrypted using encryption key stored in ${keyringName}. Enter the master password for your existing pgAdmin saved passwords and they will be re-encrypted and saved when you click OK.`)}></FormNote>
</span>
</Box>
<Box marginTop='12px'>
<Box sx={{
marginTop: '12px'
}}>
<InputText inputRef={firstEleRef} type="password" value={formData['password']} maxLength={null}
onChange={(e) => onTextChange(e, 'password')} onKeyDown={(e) => onKeyDown(e)}/>
</Box>
@@ -75,7 +81,11 @@ export default function MasterPasswordContent({ closeModal, onResetPassowrd, onO
position: 'unset', padding: '12px 0px 0px'
}} />
</Box> :
<Box flexGrow="1" p={2}>
<Box
sx={{
flexGrow: '1',
p: 2
}}>
<Box>
<span style={{ fontWeight: 'bold' }}>
{isPWDPresent ? gettext('Please enter your master password.') : gettext('Please set a master password for pgAdmin.')}
@@ -85,7 +95,9 @@ export default function MasterPasswordContent({ closeModal, onResetPassowrd, onO
{isPWDPresent ? gettext('This is required to unlock saved passwords and reconnect to the database server(s).') : gettext('This will be used to secure and later unlock saved passwords and other credentials.')}
</span>
</Box>
<Box marginTop='12px'>
<Box sx={{
marginTop: '12px'
}}>
<InputText inputRef={firstEleRef} type="password" value={formData['password']} maxLength={null}
onChange={(e) => onTextChange(e, 'password')} onKeyDown={(e) => onKeyDown(e)} controlProps={{autoComplete: 'new-password'}}/>
</Box>
@@ -129,7 +141,8 @@ export default function MasterPasswordContent({ closeModal, onResetPassowrd, onO
{gettext('OK')}
</PrimaryButton>
</ModalFooter>
</ModalContent>);
</ModalContent>
);
}
MasterPasswordContent.propTypes = {
@@ -55,13 +55,19 @@ export default function NamedRestoreContent({closeModal, onOK, setHeight}) {
return (
<ModalContent ref={containerRef}>
<Box flexGrow="1" p={2}>
<Box
sx={{
flexGrow: '1',
p: 2
}}>
<Box>
<span style={{fontWeight: 'bold'}}>
{gettext('Enter the name of the restore point to add')}
</span>
</Box>
<Box marginTop='12px'>
<Box sx={{
marginTop: '12px'
}}>
<InputText inputRef={firstEleRef} type="text" value={formData['namedRestorePoint']}
onChange={(e)=>onTextChange(e, 'namedRestorePoint')} onKeyDown={(e)=>onKeyDown(e)}/>
</Box>
@@ -63,8 +63,12 @@ export default function RenameTabContent({ panelId, panelDocker, closeModal}) {
return (
<ModalContent ref={containerRef}>
<Box padding="8px">
<Box marginBottom="4px">Current: {initialTitle}</Box>
<Box sx={{
padding: '8px'
}}>
<Box sx={{
marginBottom: '4px'
}}>Current: {initialTitle}</Box>
<InputText type="text" value={formData['title']} controlProps={{ maxLength: null }}
onChange={(e) => onTextChange(e, 'title')} onKeyDown={(e) => onKeyDown(e)} autoFocus />
</Box>
@@ -21,7 +21,9 @@ import { ModalContent, ModalFooter }from '../../../static/js/components/ModalCon
export default function UrlDialogContent({ url, helpFile, onClose }) {
return (
<ModalContent>
<Box flexGrow="1">
<Box sx={{
flexGrow: '1'
}}>
<iframe src={url} title=" " width="100%" height="100%" onLoad={(e)=>{
e.target?.contentWindow?.focus();
}}/>
+12 -12
View File
@@ -22,10 +22,10 @@ import DownloadIcon from '@mui/icons-material/Download';
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
import AddIcon from '@mui/icons-material/Add';
import WarningAmberIcon from '@mui/icons-material/WarningAmber';
import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';
import ErrorOutlineIcon from '@mui/icons-material/ErrorOutlined';
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
import LightbulbOutlinedIcon from '@mui/icons-material/LightbulbOutlined';
import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutlined';
import PropTypes from 'prop-types';
import gettext from 'sources/gettext';
import url_for from 'sources/url_for';
@@ -35,7 +35,7 @@ import Loader from '../components/Loader';
import EmptyPanelMessage from '../components/EmptyPanelMessage';
import { DefaultButton, PrimaryButton } from '../components/Buttons';
const StyledContainer = styled(Box)(({ theme }) => ({
const StyledContainer = styled('div')(({ theme }) => ({
height: '100%',
display: 'flex',
flexDirection: 'column',
@@ -43,7 +43,7 @@ const StyledContainer = styled(Box)(({ theme }) => ({
backgroundColor: theme.palette.background.default,
}));
const Header = styled(Box)(({ theme }) => ({
const Header = styled('div')(({ theme }) => ({
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
@@ -52,7 +52,7 @@ const Header = styled(Box)(({ theme }) => ({
backgroundColor: theme.palette.background.paper,
}));
const ContentArea = styled(Box)({
const ContentArea = styled('div')({
flex: 1,
overflow: 'auto',
padding: '16px',
@@ -60,21 +60,21 @@ const ContentArea = styled(Box)({
cursor: 'auto',
});
const Section = styled(Box)(({ theme }) => ({
const Section = styled('div')(({ theme }) => ({
marginBottom: theme.spacing(2),
padding: theme.spacing(2),
backgroundColor: theme.palette.background.default,
borderRadius: theme.shape.borderRadius,
}));
const SectionHeader = styled(Box)(({ theme }) => ({
const SectionHeader = styled('div')(({ theme }) => ({
display: 'flex',
alignItems: 'center',
gap: theme.spacing(1),
marginBottom: theme.spacing(1.5),
}));
const BottleneckItem = styled(Box)(({ theme, severity }) => ({
const BottleneckItem = styled('div')(({ theme, severity }) => ({
display: 'flex',
gap: theme.spacing(1.5),
padding: theme.spacing(1.5),
@@ -93,7 +93,7 @@ const BottleneckItem = styled(Box)(({ theme, severity }) => ({
},
}));
const RecommendationItem = styled(Box)(({ theme }) => ({
const RecommendationItem = styled('div')(({ theme }) => ({
padding: theme.spacing(1.5),
marginBottom: theme.spacing(1),
borderRadius: theme.shape.borderRadius,
@@ -104,7 +104,7 @@ const RecommendationItem = styled(Box)(({ theme }) => ({
},
}));
const SQLBox = styled(Box)(({ theme }) => ({
const SQLBox = styled('div')(({ theme }) => ({
marginTop: theme.spacing(1),
padding: theme.spacing(1),
backgroundColor: theme.palette.action.hover,
@@ -116,14 +116,14 @@ const SQLBox = styled(Box)(({ theme }) => ({
border: `1px solid ${theme.palette.text.disabled}`,
}));
const ActionButtons = styled(Box)(({ theme }) => ({
const ActionButtons = styled('div')(({ theme }) => ({
display: 'flex',
gap: theme.spacing(0.5),
marginTop: theme.spacing(1),
justifyContent: 'flex-end',
}));
const LoadingContainer = styled(Box)({
const LoadingContainer = styled('div')({
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
@@ -8,14 +8,14 @@
//////////////////////////////////////////////////////////////
import React from 'react';
import { styled } from '@mui/material/styles';
import { Box, Grid } from '@mui/material';
import { Grid } from '@mui/material';
import gettext from 'sources/gettext';
import _ from 'lodash';
import PropTypes from 'prop-types';
import Table from '../components/Table';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
'& .ExplainStatistics-title': {
fontWeight: 'bold',
padding: '4px',
+15 -4
View File
@@ -23,7 +23,7 @@ import CloseIcon from '@mui/icons-material/CloseRounded';
import PropTypes from 'prop-types';
import Table from '../components/Table';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
'& .Graphical-explainDetails': {
minWidth: '200px',
maxWidth: '300px',
@@ -419,7 +419,14 @@ export default function Graphical({planData, ctx}) {
return (
<StyledBox ref={graphContainerRef} height="100%" width="100%" overflow="auto">
<Box position="absolute" top="4px" left="4px" gap="4px" display="flex">
<Box
sx={{
position: 'absolute',
top: '4px',
left: '4px',
gap: '4px',
display: 'flex'
}}>
<PgButtonGroup size="small">
<PgIconButton title={gettext('Zoom in')} icon={<ZoomInIcon />} onClick={()=>onCmdClick('in')}/>
<PgIconButton title={gettext('Zoom to original')} icon={<ZoomOutMapIcon />} onClick={()=>onCmdClick()}/>
@@ -434,9 +441,13 @@ export default function Graphical({planData, ctx}) {
/>
{Boolean(explainPlanDetails) &&
<Card className='Graphical-explainDetails' data-label="explain-details">
<CardHeader title={<Box display="flex">
<CardHeader title={<Box sx={{
display: 'flex'
}}>
{explainPlanTitle}
<Box marginLeft="auto">
<Box sx={{
marginLeft: 'auto'
}}>
<PgIconButton title={gettext('Close')} icon={<CloseIcon />} size="xs" noBorder onClick={()=>setExplainPlanDetails([null, null])}/>
</Box>
</Box>} />
+1 -1
View File
@@ -22,7 +22,7 @@ import AIInsights from './AIInsights';
import PropTypes from 'prop-types';
import EmptyPanelMessage from '../components/EmptyPanelMessage';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
'& .Explain-tabPanel': {
padding: '0 !important',
backgroundColor: theme.palette.background.default + ' !important',
@@ -33,7 +33,7 @@ registerOptionEvaluator(
'headerFormVisible', booleanEvaluator, false, ['collection']
);
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
'& .DataGridFormHeader-border': {
...theme.mixins.panelBorder,
borderBottom: 0,
@@ -38,7 +38,9 @@ export default function InlineView({
return <></>;
}
return (
<Grid container spacing={0} className='FormView-controlRow' rowGap="8px">
<Grid container spacing={0} className='FormView-controlRow' sx={{
rowGap: '8px'
}}>
{children}
</Grid>
);
@@ -212,7 +212,9 @@ export default function SchemaDialogView({
/>
</Box>
}
<Box marginLeft='auto'>
<Box sx={{
marginLeft: 'auto'
}}>
{
Boolean(customCloseBtnName) &&
<DefaultButton data-test='Close' onClick={props.onClose}
@@ -7,10 +7,9 @@
//
//////////////////////////////////////////////////////////////
import Box from '@mui/material/Box';
import { styled } from '@mui/material/styles';
export const StyledBox = styled(Box)(({theme}) => ({
export const StyledBox = styled('div')(({theme}) => ({
display: 'flex',
flexDirection: 'column',
height: '100%',
@@ -50,7 +49,7 @@ export const StyledBox = styled(Box)(({theme}) => ({
},
}));
export const StyleDataGridBox = styled(Box)(({theme}) => ({
export const StyleDataGridBox = styled('div')(({theme}) => ({
'& .DataGridView-grid': {
...theme.mixins.panelBorder,
backgroundColor: theme.palette.background.default,
@@ -123,7 +122,7 @@ export const StyleDataGridBox = styled(Box)(({theme}) => ({
}
}));
export const FormContentBox = styled(Box)(({theme}) => ({
export const FormContentBox = styled('div')(({theme}) => ({
'& .FormView-nestedControl': {
height: 'unset !important',
'& .FormView-controlRow': {
+12 -12
View File
@@ -19,18 +19,18 @@ export const isModeSupportedByField = (field, helperProps) => (
export const isFieldSupportedByPgVersion = (field, helperProps) => {
return (
// serverInfo not found
_.isUndefined(helperProps.serverInfo) ||
// serverInfo found and it's within range
(
_.isUndefined(field.server_type) ? true :
(helperProps.serverInfo.type in field.server_type)
) && (
_.isUndefined(field.min_version) ? true :
(helperProps.serverInfo.version >= field.min_version)
) && (
_.isUndefined(field.max_version) ? true :
(helperProps.serverInfo.version <= field.max_version)
));
(_.isUndefined(helperProps.serverInfo) || // serverInfo found and it's within range
(
_.isUndefined(field.server_type) ? true :
(helperProps.serverInfo.type in field.server_type)
) && (
_.isUndefined(field.min_version) ? true :
(helperProps.serverInfo.version >= field.min_version)
) && (
_.isUndefined(field.max_version) ? true :
(helperProps.serverInfo.version <= field.max_version)
))
);
};
/*
@@ -7,7 +7,7 @@ import { FinalNotifyContent } from '../helpers/Notifier';
import PropTypes from 'prop-types';
import CustomPropTypes from '../custom_prop_types';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastText,
display: 'flex',
@@ -78,14 +78,31 @@ export default function BasePage({pageImage, title, children, messages}) {
}, [messages]);
return (
<StyledBox >
<Box display="flex" minWidth="80%" gap="40px" alignItems="center" padding="20px 80px">
<Box flexGrow={1} height="80%" textAlign="center">
<Box
sx={{
display: 'flex',
minWidth: '80%',
gap: '40px',
alignItems: 'center',
padding: '20px 80px'
}}>
<Box
sx={{
flexGrow: 1,
height: '80%',
textAlign: 'center'
}}>
{pageImage}
</Box>
<Box className='BasePage-pageContent'>
<Box className='BasePage-item'><div className='BasePage-logo' /></Box>
<Box className='BasePage-item'>{title}</Box>
<Box display="flex" flexDirection="column" minHeight={0}>{children}</Box>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
minHeight: 0
}}>{children}</Box>
</Box>
</Box>
</StyledBox>
@@ -37,7 +37,11 @@ export default function LoginPage({userLanguage, langOptions, forgotPassUrl, csr
controlProps={{autoComplete: null}} />
<InputText name="password" value={form.password} onChange={(v)=>onTextChange('password', v)} type="password" placeholder={gettext('Password')}
controlProps={{autoComplete: null}} />
<Box textAlign="right" marginTop="-10px">
<Box
sx={{
textAlign: 'right',
marginTop: '-10px'
}}>
<a style={{color: 'inherit'}} href={forgotPassUrl}>{gettext('Forgotten your password?')}</a>
</Box>
<InputSelectNonSearch name="language" options={langOptions} value={form.language} onChange={(v)=>onTextChange('language', v.target.value)} />
@@ -81,14 +81,23 @@ export default function MfaRegisterPage({actionUrl, mfaList, nextUrl, mfaView, .
{mfaView ? <>
{mfaView.auth_method == 'email' && <EmailRegisterView mfaView={mfaView} />}
{mfaView.auth_method == 'authenticator' && <AuthenticatorRegisterView mfaView={mfaView} />}
<Box display="flex" gap="15px">
<Box
sx={{
display: 'flex',
gap: '15px'
}}>
<SecurityButton name="continue" value="Continue">{gettext('Continue')}</SecurityButton>
<DefaultButton type="submit" name="cancel" value="Cancel" style={{width: '100%'}}>{gettext('Cancel')}</DefaultButton>
</Box>
</>:<>
{mfaList?.map((m)=>{
return (
<Box display="flex" width="100%" key={m.label}>
<Box
key={m.label}
sx={{
display: 'flex',
width: '100%'
}}>
<div style={{
width: '10%', mask: `url(${m.icon})`, maskRepeat: 'no-repeat',
WebkitMask: `url(${m.icon})`, WebkitMaskRepeat: 'no-repeat',
+2 -2
View File
@@ -2,11 +2,11 @@ import PropTypes from 'prop-types';
import gettext from 'sources/gettext';
import { LAYOUT_EVENTS } from './helpers/Layout';
import { styled } from '@mui/material/styles';
import { FormHelperText, Box } from '@mui/material';
import { FormHelperText } from '@mui/material';
import HTMLReactParse from 'html-react-parser';
import { useApplicationState } from '../../settings/static/ApplicationStateProvider';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
color: theme.palette.text.primary,
margin: '24px auto 12px',
display: 'flex',
@@ -8,11 +8,10 @@
//////////////////////////////////////////////////////////////
import { styled } from '@mui/material/styles';
import { Box } from '@mui/material';
import InfoRoundedIcon from '@mui/icons-material/InfoRounded';
import PropTypes from 'prop-types';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
color: theme.palette.text.primary,
margin: '24px auto 12px',
fontSize: '0.8rem',
@@ -1153,7 +1153,9 @@ export function FormNote({ text, className, controlProps }) {
<Root>
<Box className={className}>
<Paper elevation={0} className={controlProps?.raw ? '' : 'Form-noteRoot'}>
{!controlProps?.raw && <Box paddingRight="0.25rem"><DescriptionIcon fontSize="small" /></Box>}
{!controlProps?.raw && <Box sx={{
paddingRight: '0.25rem'
}}><DescriptionIcon fontSize="small" /></Box>}
<Box>{HTMLReactParse(text || '')}</Box>
</Paper>
</Box>
@@ -1167,7 +1169,7 @@ FormNote.propTypes = {
};
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
padding: theme.spacing(0.5),
position: 'absolute',
bottom: 0,
@@ -1258,7 +1260,7 @@ FormInputSelectThemes.propTypes = {
labelTooltip: PropTypes.string
};
const StyledNotifierMessageBox = styled(Box)(({theme}) => ({
const StyledNotifierMessageBox = styled('div')(({theme}) => ({
borderWidth: '1px',
borderStyle: 'solid',
borderRadius: theme.shape.borderRadius,
@@ -76,12 +76,13 @@ export default function KeyboardShortcuts({ value, onChange, fields, name }) {
return (
<Box
display="flex"
alignItems="center"
flexWrap="wrap"
gap="5px"
rowGap="5px"
>
sx={{
display: 'flex',
alignItems: 'center',
flexWrap: 'wrap',
gap: '5px',
rowGap: '5px'
}}>
{hasKeys &&
<>
<ToggleButtonGroup value={value?.shift ? ['shift'] : []} onChange={(e, val)=>{
+1 -1
View File
@@ -11,7 +11,7 @@ import { CircularProgress, Box, Typography } from '@mui/material';
import { styled } from '@mui/material/styles';
import PropTypes from 'prop-types';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
position: 'absolute',
top: 0,
bottom: 0,
@@ -11,7 +11,7 @@ import { styled } from '@mui/material/styles';
import CustomPropTypes from '../custom_prop_types';
import { Box } from '@mui/material';
const StyledBox = styled(Box)(({theme})=>({
const StyledBox = styled('div')(({theme})=>({
backgroundColor: theme.palette.background.default,
display: 'flex',
flexDirection: 'column',
@@ -6,7 +6,6 @@
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import { Box } from '@mui/material';
import { styled } from '@mui/material/styles';
import { useState, useEffect } from 'react';
import AccountTreeIcon from '@mui/icons-material/AccountTree';
@@ -15,7 +14,7 @@ import ArrowForwardIosRoundedIcon from '@mui/icons-material/ArrowForwardIosRound
import { usePgAdmin } from '../../../static/js/PgAdminProvider';
import usePreferences from '../../../preferences/static/js/store';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
position: 'absolute',
bottom: 0,
width: 'auto',
@@ -159,7 +159,12 @@ export default function PgReactDataGrid({gridRef, className, hasSelectColumn=tru
renderers={{
renderRow,
renderSortStatus,
noRowsFallback: <Box textAlign="center" gridColumn="1/-1" p={1}>{noRowsIcon}{noRowsText || gettext('No rows found.')}</Box>,
noRowsFallback: <Box
sx={{
textAlign: 'center',
gridColumn: '1/-1',
p: 1
}}>{noRowsIcon}{noRowsText || gettext('No rows found.')}</Box>,
}}
{...props}
/>
+3 -1
View File
@@ -326,7 +326,9 @@ export default function PgTable({ caveTable = true, tableNoBorder = true, tableN
<StyledPgTableRoot className={[tableNoBorder ? '' : 'pgtable-pgrt-border', caveTable ? 'pgtable-pgrt-cave' : ''].join(' ')} data-test={props['data-test']}>
{!tableNoHeader && <Box className='pgtable-header'>
{props.customHeader && (<Box className={['pgtable-custom-header-section', props['className']].join(' ')}> {props.customHeader }</Box>)}
<Box marginLeft="auto">
<Box sx={{
marginLeft: 'auto'
}}>
<InputText
placeholder={gettext('Search')}
controlProps={{ title: gettext('Search') }}
@@ -37,7 +37,9 @@ export default function QueryThresholds({ value, onChange }) {
<Grid
container
direction="row"
alignItems="center"
sx={{
alignItems: 'center'
}}
>
<Grid size={{ lg: 2, md: 2, sm: 2, xs: 12 }}>
<Typography>{gettext('Warning')}</Typography>
@@ -32,7 +32,7 @@ import {
replaceAll,
} from '@codemirror/search';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
position: 'absolute',
zIndex: 99,
right: '4px',
@@ -166,8 +166,9 @@ export default function FindDialog({editor, show, replace, onClose}) {
onChange={(value)=>setReplaceVal(value)}
onKeyPress={onReplaceEnter}
/>}
<Box display="flex" className='CodeMirror-marginTop'>
<Box className='CodeMirror-marginTop' sx={{
display: 'flex'
}}>
<PgIconButton title={gettext('Previous')} icon={<ArrowUpwardRoundedIcon />} size="xs" noBorder onClick={onFindPrev}
style={{marginRight: '2px'}} />
<PgIconButton title={gettext('Next')} icon={<ArrowDownwardRoundedIcon />} size="xs" noBorder onClick={onFindNext}
@@ -177,7 +178,9 @@ export default function FindDialog({editor, show, replace, onClose}) {
style={{marginRight: '2px'}} />
<PgIconButton title={gettext('Replace All')} icon={<SwapCallsRoundedIcon />} size="xs" noBorder onClick={onReplaceAll}/>
</>}
<Box marginLeft="auto">
<Box sx={{
marginLeft: 'auto'
}}>
<PgIconButton title={gettext('Close')} icon={<CloseIcon />} size="xs" noBorder onClick={clearAndClose}/>
</Box>
</Box>
@@ -11,12 +11,12 @@ import { useEffect, useRef, useState } from 'react';
import { styled } from '@mui/material/styles';
import PropTypes from 'prop-types';
import gettext from 'sources/gettext';
import { Box, FormControl } from '@mui/material';
import { FormControl } from '@mui/material';
import { InputText } from '../../FormComponents';
import { PgIconButton } from '../../Buttons';
import CloseIcon from '@mui/icons-material/CloseRounded';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
position: 'absolute',
zIndex: 99,
right: '4px',
@@ -21,7 +21,7 @@ import gettext from 'sources/gettext';
import { usePgAdmin } from '../PgAdminProvider';
import { clearOptionsCache } from '../../../preferences/static/js/components/PreferencesHelper';
const StyledBox = styled(Box)(() => ({
const StyledBox = styled('div')(() => ({
display: 'flex',
alignItems: 'flex-start',
'& .SelectRefresh-selectContainer': {
@@ -13,7 +13,7 @@ import PropTypes from 'prop-types';
import CustomPropTypes from '../custom_prop_types';
const StyledBox = styled(Box)(({theme})=>({
const StyledBox = styled('div')(({theme})=>({
...theme.mixins.tabPanel,
'& .TabPanel-content':{
height: '100%',
+30 -8
View File
@@ -62,7 +62,14 @@ export function TabTitle({id, closable, defaultInternal}) {
}, []);
return (
<Box display="flex" alignItems="center" title={attrs.tooltip} onContextMenu={onContextMenu} width="100%">
<Box
title={attrs.tooltip}
onContextMenu={onContextMenu}
sx={{
display: 'flex',
alignItems: 'center',
width: '100%'
}}>
{attrs.icon && <span className={`dock-tab-icon ${attrs.icon}`}></span>}
<span style={{textOverflow: 'ellipsis', overflow: 'hidden', whiteSpace: 'nowrap'}} data-visible={layoutDocker.isTabVisible(id)}>{attrs.title}</span>
{closable && <PgIconButton title={gettext('Close')} icon={<CloseIcon style={{height: '0.7em'}} />} size="xs" noBorder onClick={()=>{
@@ -433,7 +440,11 @@ function DialogClose({panelData}) {
// In a dialog, panelData is the data of the container panel and not the
// data of actual dialog tab. panelData.activeId gives the id of dialog tab.
return (
<Box display="flex" alignItems="center">
<Box
sx={{
display: 'flex',
alignItems: 'center'
}}>
<PgIconButton title={gettext('Close')} icon={<CloseIcon />} size="xs" noBorder onClick={()=>{
layoutDocker.close(panelData.activeId);
}} style={{marginRight: '-4px'}}/>
@@ -469,11 +480,17 @@ export function getDefaultGroup() {
icon = <MinimizeDialogIcon />;
title = gettext('Restore');
}
return <Box display="flex" alignItems="center">
{Boolean(panelData.maximizable) && <PgIconButton title={title} icon={icon} size="xs" noBorder onClick={()=>{
context.dockMove(panelData, null, 'maximize');
}} />}
</Box>;
return (
<Box
sx={{
display: 'flex',
alignItems: 'center'
}}>
{Boolean(panelData.maximizable) && <PgIconButton title={title} icon={icon} size="xs" noBorder onClick={()=>{
context.dockMove(panelData, null, 'maximize');
}} />}
</Box>
);
}
};
}
@@ -619,7 +636,12 @@ export default function Layout({groups, noContextGroups, getLayoutInstance, layo
return (
<ApplicationStateProvider>
<LayoutDockerContext.Provider value={layoutDockerObj}>
<Box height="100%" width="100%" display={isLayoutVisible ? 'initial' : 'none'} >
<Box
sx={{
height: '100%',
width: '100%',
display: isLayoutVisible ? 'initial' : 'none'
}}>
{useMemo(()=>(<DockLayout
style={{
height: '100%',
@@ -19,7 +19,11 @@ import PropTypes from 'prop-types';
export default function MainMoreToolbar({tabsData}) {
const layoutDocker = React.useContext(LayoutDockerContext);
return (
<Box display="flex" alignItems="center">
<Box
sx={{
display: 'flex',
alignItems: 'center'
}}>
<PgIconButton title={gettext('More')} icon={<MoreVertIcon />} size="xs" noBorder onClick={(e)=>{
e.preventDefault();
const box = e.target.getBoundingClientRect();
@@ -26,7 +26,7 @@ import { styled } from '@mui/material/styles';
export const ModalContext = React.createContext({});
const MIN_HEIGHT = 190;
const MIN_WIDTH = 500;
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
'& .Alert-footer': {
display: 'flex',
justifyContent: 'flex-end',
@@ -50,7 +50,12 @@ export function useModal() {
function AlertContent({ text, confirm, okLabel = gettext('OK'), cancelLabel = gettext('Cancel'), onOkClick, onCancelClick, okIcon = 'default'}) {
return (
<StyledBox display="flex" flexDirection="column" height="100%">
<Box flexGrow="1" p={2} whiteSpace='pre-line'>{typeof (text) == 'string' ? HTMLReactParser(text) : text}</Box>
<Box
sx={{
flexGrow: '1',
p: 2,
whiteSpace: 'pre-line'
}}>{typeof (text) == 'string' ? HTMLReactParser(text) : text}</Box>
<Box className='Alert-footer'>
{confirm &&
<DefaultButton startIcon={<CloseIcon />} onClick={onCancelClick}>{cancelLabel}</DefaultButton>
@@ -106,7 +111,11 @@ function confirmDelete(title, text, onDeleteClick, onCancelClick, deleteLabel =
};
return (
<StyledBox display="flex" flexDirection="column" height="100%">
<Box flexGrow="1" p={2}>
<Box
sx={{
flexGrow: '1',
p: 2
}}>
{typeof (text) == 'string' ? HTMLReactParser(text) : text}
</Box>
<Box className='Alert-footer'>
@@ -331,7 +340,9 @@ function ModalContainer({ id, title, content, dialogHeight, dialogWidth, onClose
<Box className='Modal-iconButtonStyle'><PgIconButton title={gettext('Minimize')} icon={<MinimizeDialogIcon className='Modal-icon' />} size="xs" noBorder onClick={() => { setIsFullScreen(!isFullScreen); }} /></Box>
}
<Box marginLeft="auto"><PgIconButton title={gettext('Close')} icon={<CloseIcon />} size="xs" noBorder onClick={closeModal} /></Box>
<Box sx={{
marginLeft: 'auto'
}}><PgIconButton title={gettext('Close')} icon={<CloseIcon />} size="xs" noBorder onClick={closeModal} /></Box>
</Box>
</DialogTitle>
}
+11 -2
View File
@@ -53,8 +53,17 @@ FinalNotifyContent.propTypes = {
function AlertContent({text, confirm, okLabel=gettext('OK'), cancelLabel=gettext('Cancel'), onOkClick, onCancelClick}) {
return (
<Box display="flex" flexDirection="column" height="100%">
<Box flexGrow="1" p={2}>{HTMLReactParser(text)}</Box>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
height: '100%'
}}>
<Box
sx={{
flexGrow: '1',
p: 2
}}>{HTMLReactParser(text)}</Box>
<Box className='Notifier-footer'>
{confirm &&
<DefaultButton startIcon={<CloseIcon />} onClick={onCancelClick} >{cancelLabel}</DefaultButton>
@@ -14,7 +14,7 @@ import PropTypes from 'prop-types';
import { DefaultButton, PgIconButton } from '../components/Buttons';
import pgAdmin from 'sources/pgadmin';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
borderRadius: theme.shape.borderRadius,
padding: '0.25rem 1rem 1rem',
minWidth: '325px',
@@ -53,20 +53,38 @@ function UpdateWarningNotifier({desc, title, onClose, onClick, status, uniqueKey
};
return (
<StyledBox className={'UpdateWarningNotifier-containerWarning'} data-test={'Update-popup-warning'}>
<Box display="flex" justifyContent="space-between" className='UpdateWarningNotifier-containerHeader'>
<Box marginRight={'1rem'}>{title}</Box>
<Box
className='UpdateWarningNotifier-containerHeader'
sx={{
display: 'flex',
justifyContent: 'space-between'
}}>
<Box sx={{
marginRight: '1rem'
}}>{title}</Box>
<PgIconButton size="xs" noBorder icon={<CloseIcon />} onClick={handleClose} title={'Close'} className={'UpdateWarningNotifier-iconWarning'} />
</Box>
<Box className='UpdateWarningNotifier-containerBody'>
{desc && <Box>{desc}</Box>}
<Box display="flex">
{onClick && <Box marginTop={'1rem'} display="flex">
<Box sx={{
display: 'flex'
}}>
{onClick && <Box
sx={{
marginTop: '1rem',
display: 'flex'
}}>
<DefaultButton color={'warning'} onClick={()=>{
onClick();
handleClose();
}}>{status == 'download_update' ? 'Download Update' : 'Install and Restart'}</DefaultButton>
</Box>}
{status == 'update_downloaded' && <Box marginTop={'1rem'} display="flex" marginLeft={'1rem'}>
{status == 'update_downloaded' && <Box
sx={{
marginTop: '1rem',
display: 'flex',
marginLeft: '1rem'
}}>
<DefaultButton color={'default'} onClick={()=>{
handleClose();
}}>Install Later</DefaultButton>
@@ -20,7 +20,7 @@ import { Box } from '@mui/material';
import gettext from 'sources/gettext';
import Loader from 'sources/components/Loader';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
height: '100%',
display: 'flex',
flexDirection: 'column',
@@ -205,7 +205,9 @@ function Wizard({ stepList, onStepChange, onSave, className, ...props }) {
<PgIconButton data-test="dialog-help" onClick={() => props.onHelp()} icon={<HelpIcon />} title="Help for this dialog."
disabled={props.disableDialogHelp} />
</Box>
<Box className='Wizard-actionBtn' marginLeft="auto">
<Box className='Wizard-actionBtn' sx={{
marginLeft: 'auto'
}}>
<DefaultButton onClick={handleBack} disabled={activeStep === 0} className='Wizard-buttonMargin' startIcon={<FastRewindIcon />}>
{gettext('Back')}
</DefaultButton>
@@ -78,7 +78,12 @@ export default function ObjectExplorerToolbar() {
}, []);
return (
<Box display="flex" alignItems="center" gap="2px">
<Box
sx={{
display: 'flex',
alignItems: 'center',
gap: '2px'
}}>
<PgButtonGroup size="small">
<ToolbarButton icon={
<Badge badgeContent=" " overlap="circular" variant='dot' color="success" invisible={!hasFilters}>
+1 -1
View File
@@ -6,4 +6,4 @@
//problems with requirejs.exec()/transpiler plugins that may not be strict.
/*jslint regexp: true, nomen: true, sloppy: true */
/*global window, navigator, document, importScripts, setTimeout, opera */
var requirejs,require,define;!function(global,setTimeout){var req,s,head,baseElement,dataMain,src,interactiveScript,currentlyAddingScript,mainScript,subPath,version="2.3.6",commentRegExp=/\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/gm,cjsRequireRegExp=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,jsSuffixRegExp=/\.js$/,currDirRegExp=/^\.\//,op=Object.prototype,ostring=op.toString,hasOwn=op.hasOwnProperty,isBrowser=!("undefined"==typeof window||"undefined"==typeof navigator||!window.document),isWebWorker=!isBrowser&&"undefined"!=typeof importScripts,readyRegExp=isBrowser&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,defContextName="_",isOpera="undefined"!=typeof opera&&"[object Opera]"===opera.toString(),contexts={},cfg={},globalDefQueue=[],useInteractive=!1;function commentReplace(e,t){return t||""}function isFunction(e){return"[object Function]"===ostring.call(e)}function isArray(e){return"[object Array]"===ostring.call(e)}function each(e,t){var i;if(e)for(i=0;i<e.length&&(!e[i]||!t(e[i],i,e));i+=1);}function eachReverse(e,t){var i;if(e)for(i=e.length-1;i>-1&&(!e[i]||!t(e[i],i,e));i-=1);}function hasProp(e,t){return hasOwn.call(e,t)}function getOwn(e,t){return hasProp(e,t)&&e[t]}function eachProp(e,t){var i;for(i in e)if(hasProp(e,i)&&t(e[i],i))break}function mixin(e,t,i,r){return t&&eachProp(t,function(t,n){!i&&hasProp(e,n)||(!r||"object"!=typeof t||!t||isArray(t)||isFunction(t)||t instanceof RegExp?e[n]=t:(e[n]||(e[n]={}),mixin(e[n],t,i,r)))}),e}function bind(e,t){return function(){return t.apply(e,arguments)}}function scripts(){return document.getElementsByTagName("script")}function defaultOnError(e){throw e}function getGlobal(e){if(!e)return e;var t=global;return each(e.split("."),function(e){t=t[e]}),t}function makeError(e,t,i,r){var n=new Error(t+"\nhttps://requirejs.org/docs/errors.html#"+e);return n.requireType=e,n.requireModules=r,i&&(n.originalError=i),n}if(void 0===define){if(void 0!==requirejs){if(isFunction(requirejs))return;cfg=requirejs,requirejs=void 0}void 0===require||isFunction(require)||(cfg=require,require=void 0),req=requirejs=function(e,t,i,r){var n,o,a=defContextName;return isArray(e)||"string"==typeof e||(o=e,isArray(t)?(e=t,t=i,i=r):e=[]),o&&o.context&&(a=o.context),(n=getOwn(contexts,a))||(n=contexts[a]=req.s.newContext(a)),o&&n.configure(o),n.require(e,t,i)},req.config=function(e){return req(e)},req.nextTick=void 0!==setTimeout?function(e){setTimeout(e,4)}:function(e){e()},require||(require=req),req.version=version,req.jsExtRegExp=/^\/|:|\?|\.js$/,req.isBrowser=isBrowser,s=req.s={contexts:contexts,newContext:newContext},req({}),each(["toUrl","undef","defined","specified"],function(e){req[e]=function(){var t=contexts[defContextName];return t.require[e].apply(t,arguments)}}),isBrowser&&(head=s.head=document.getElementsByTagName("head")[0],baseElement=document.getElementsByTagName("base")[0],baseElement&&(head=s.head=baseElement.parentNode)),req.onError=defaultOnError,req.createNode=function(e,t,i){var r=e.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");return r.type=e.scriptType||"text/javascript",r.charset="utf-8",r.async=!0,r},req.load=function(e,t,i){var r,n=e&&e.config||{};if(isBrowser)return(r=req.createNode(n,t,i)).setAttribute("data-requirecontext",e.contextName),r.setAttribute("data-requiremodule",t),!r.attachEvent||r.attachEvent.toString&&r.attachEvent.toString().indexOf("[native code")<0||isOpera?(r.addEventListener("load",e.onScriptLoad,!1),r.addEventListener("error",e.onScriptError,!1)):(useInteractive=!0,r.attachEvent("onreadystatechange",e.onScriptLoad)),r.src=i,n.onNodeCreated&&n.onNodeCreated(r,n,t,i),currentlyAddingScript=r,baseElement?head.insertBefore(r,baseElement):head.appendChild(r),currentlyAddingScript=null,r;if(isWebWorker)try{setTimeout(function(){},0),importScripts(i),e.completeLoad(t)}catch(r){e.onError(makeError("importscripts","importScripts failed for "+t+" at "+i,r,[t]))}},isBrowser&&!cfg.skipDataMain&&eachReverse(scripts(),function(e){if(head||(head=e.parentNode),dataMain=e.getAttribute("data-main"))return mainScript=dataMain,cfg.baseUrl||-1!==mainScript.indexOf("!")||(src=mainScript.split("/"),mainScript=src.pop(),subPath=src.length?src.join("/")+"/":"./",cfg.baseUrl=subPath),mainScript=mainScript.replace(jsSuffixRegExp,""),req.jsExtRegExp.test(mainScript)&&(mainScript=dataMain),cfg.deps=cfg.deps?cfg.deps.concat(mainScript):[mainScript],!0}),define=function(e,t,i){var r,n;"string"!=typeof e&&(i=t,t=e,e=null),isArray(t)||(i=t,t=null),!t&&isFunction(i)&&(t=[],i.length&&(i.toString().replace(commentRegExp,commentReplace).replace(cjsRequireRegExp,function(e,i){t.push(i)}),t=(1===i.length?["require"]:["require","exports","module"]).concat(t))),useInteractive&&(r=currentlyAddingScript||getInteractiveScript())&&(e||(e=r.getAttribute("data-requiremodule")),n=contexts[r.getAttribute("data-requirecontext")]),n?(n.defQueue.push([e,t,i]),n.defQueueMap[e]=!0):globalDefQueue.puLine truncated
var requirejs,require,define;!function(global,setTimeout){var req,s,head,baseElement,dataMain,src,interactiveScript,currentlyAddingScript,mainScript,subPath,version="2.3.6",commentRegExp=/\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/gm,cjsRequireRegExp=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,jsSuffixRegExp=/\.js$/,currDirRegExp=/^\.\//,op=Object.prototype,ostring=op.toString,hasOwn=op.hasOwnProperty,isBrowser=!("undefined"==typeof window||"undefined"==typeof navigator||!window.document),isWebWorker=!isBrowser&&"undefined"!=typeof importScripts,readyRegExp=isBrowser&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,defContextName="_",isOpera="undefined"!=typeof opera&&"[object Opera]"===opera.toString(),contexts={},cfg={},globalDefQueue=[],useInteractive=!1;function commentReplace(e,t){return t||""}function isFunction(e){return"[object Function]"===ostring.call(e)}function isArray(e){return"[object Array]"===ostring.call(e)}function each(e,t){var i;if(e)for(i=0;i<e.length&&(!e[i]||!t(e[i],i,e));i+=1);}function eachReverse(e,t){var i;if(e)for(i=e.length-1;i>-1&&(!e[i]||!t(e[i],i,e));i-=1);}function hasProp(e,t){return hasOwn.call(e,t)}function getOwn(e,t){return hasProp(e,t)&&e[t]}function eachProp(e,t){var i;for(i in e)if(hasProp(e,i)&&t(e[i],i))break}function mixin(e,t,i,r){return t&&eachProp(t,function(t,n){!i&&hasProp(e,n)||(!r||"object"!=typeof t||!t||isArray(t)||isFunction(t)||t instanceof RegExp?e[n]=t:(e[n]||(e[n]={}),mixin(e[n],t,i,r)))}),e}function bind(e,t){return function(){return t.apply(e,arguments)}}function scripts(){return document.getElementsByTagName("script")}function defaultOnError(e){throw e}function getGlobal(e){if(!e)return e;var t=global;return each(e.split("."),function(e){t=t[e]}),t}function makeError(e,t,i,r){var n=new Error(t+"\nhttps://requirejs.org/docs/errors.html#"+e);return n.requireType=e,n.requireModules=r,i&&(n.originalError=i),n}if(void 0===define){if(void 0!==requirejs){if(isFunction(requirejs))return;cfg=requirejs,requirejs=void 0}void 0===require||isFunction(require)||(cfg=require,require=void 0),req=requirejs=function(e,t,i,r){var n,o,a=defContextName;return isArray(e)||"string"==typeof e||(o=e,isArray(t)?(e=t,t=i,i=r):e=[]),o&&o.context&&(a=o.context),(n=getOwn(contexts,a))||(n=contexts[a]=req.s.newContext(a)),o&&n.configure(o),n.require(e,t,i)},req.config=function(e){return req(e)},req.nextTick=void 0!==setTimeout?function(e){setTimeout(e,4)}:function(e){e()},require||(require=req),req.version=version,req.jsExtRegExp=/^\/|:|\?|\.js$/,req.isBrowser=isBrowser,s=req.s={contexts:contexts,newContext:newContext},req({}),each(["toUrl","undef","defined","specified"],function(e){req[e]=function(){var t=contexts[defContextName];return t.require[e].apply(t,arguments)}}),isBrowser&&(head=s.head=document.getElementsByTagName("head")[0],baseElement=document.getElementsByTagName("base")[0],baseElement&&(head=s.head=baseElement.parentNode)),req.onError=defaultOnError,req.createNode=function(e,t,i){var r=e.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");return r.type=e.scriptType||"text/javascript",r.charset="utf-8",r.async=!0,r},req.load=function(e,t,i){var r,n=e&&e.config||{};if(isBrowser)return(r=req.createNode(n,t,i)).setAttribute("data-requirecontext",e.contextName),r.setAttribute("data-requiremodule",t),!r.attachEvent||r.attachEvent.toString&&r.attachEvent.toString().indexOf("[native code")<0||isOpera?(r.addEventListener("load",e.onScriptLoad,!1),r.addEventListener("error",e.onScriptError,!1)):(useInteractive=!0,r.attachEvent("onreadystatechange",e.onScriptLoad)),r.src=i,n.onNodeCreated&&n.onNodeCreated(r,n,t,i),currentlyAddingScript=r,baseElement?head.insertBefore(r,baseElement):head.appendChild(r),currentlyAddingScript=null,r;if(isWebWorker)try{setTimeout(function(){},0),importScripts(i),e.completeLoad(t)}catch(r){e.onError(makeError("importscripts","importScripts failed for "+t+" at "+i,r,[t]))}},isBrowser&&!cfg.skipDataMain&&eachReverse(scripts(),function(e){if(head||(head=e.parentNode),dataMain=e.getAttribute("data-main"))return mainScript=dataMain,cfg.baseUrl||-1!==mainScript.indexOf("!")||(src=mainScript.split("/"),mainScript=src.pop(),subPath=src.length?src.join("/")+"/":"./",cfg.baseUrl=subPath),mainScript=mainScript.replace(jsSuffixRegExp,""),req.jsExtRegExp.test(mainScript)&&(mainScript=dataMain),cfg.deps=cfg.deps?cfg.deps.concat(mainScript):[mainScript],!0}),define=function(e,t,i){var r,n;"string"!=typeof e&&(i=t,t=e,e=null),isArray(t)||(i=t,t=null),!t&&isFunction(i)&&(t=[],i.length&&(i.toString().replace(commentRegExp,commentReplace).replace(cjsRequireRegExp,function(e,i){t.push(i)}),t=(1===i.length?["require"]:["require","exports","module"]).concat(t))),useInteractive&&(r=currentlyAddingScript||getInteractiveScript())&&(e||(e=r.getAttribute("data-requiremodule")),n=contexts[r.getAttribute("data-requirecontext")]),n?(n.defQueue.push([e,t,i]),n.defQueueMap[e]=!0):globalDefQueue.puLine truncated
@@ -33,7 +33,7 @@ import { BROWSER_PANELS } from '../../../../../browser/static/js/constants';
import usePreferences from '../../../../../preferences/static/js/store';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
display: 'flex',
flexDirection: 'column',
flexGrow: 1,
@@ -861,7 +861,9 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug,
{gettext('Clear All')}
</DefaultButton>
</Box>
<Box className='DebuggerArgument-actionBtn' marginLeft="auto">
<Box className='DebuggerArgument-actionBtn' sx={{
marginLeft: 'auto'
}}>
<DefaultButton className='DebuggerArgument-buttonMargin' onClick={() => { props.closeModal(); }} startIcon={<CloseSharpIcon onClick={() => { props.closeModal(); }} />}>
{gettext('Cancel')}
</DefaultButton>
@@ -1155,7 +1155,16 @@ export default function DebuggerComponent({ pgAdmin, selectedNodeInfo, panelId,
<DebuggerContext.Provider value={DebuggerContextValue}>
<DebuggerEventsContext.Provider value={eventBus.current}>
<Loader message={loaderText} />
<Box width="100%" height="100%" display="flex" flexDirection="column" flexGrow="1" tabIndex="0" ref={containerRef}>
<Box
tabIndex="0"
ref={containerRef}
sx={{
width: '100%',
height: '100%',
display: 'flex',
flexDirection: 'column',
flexGrow: '1'
}}>
<ToolBar
containerRef={containerRef}
/>
@@ -11,7 +11,6 @@ import { useCallback, useContext, useEffect, useState } from 'react';
import { styled } from '@mui/material/styles';
import { Box } from '@mui/material';
import FormatIndentIncreaseIcon from '@mui/icons-material/FormatIndentIncrease';
import FormatIndentDecreaseIcon from '@mui/icons-material/FormatIndentDecrease';
import PlayCircleFilledWhiteIcon from '@mui/icons-material/PlayCircleFilledWhite';
@@ -31,7 +30,7 @@ import { useKeyboardShortcuts } from '../../../../../static/js/custom_hooks';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
padding: '2px 4px',
display: 'flex',
alignItems: 'center',
@@ -15,7 +15,7 @@ import { DefaultButton, PgButtonGroup, PgIconButton } from '../../../../../../st
import { Box, Tooltip, CircularProgress } from '@mui/material';
import { ConnectedIcon, DisconnectedIcon } from '../../../../../../static/js/components/ExternalIcon';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
padding: '2px 4px',
display: 'flex',
alignItems: 'center',
@@ -77,8 +77,17 @@ export default function ConnectionBar({status, bgcolor, fgcolor, title}) {
/>
<DefaultButton className='Status-connectionButton' style={{backgroundColor: bgcolor, color: fgcolor}} data-test="btn-conn-title">
<Tooltip title={title}>
<Box display="flex" width="100%">
<Box textOverflow="ellipsis" overflow="hidden" marginRight="auto">
<Box
sx={{
display: 'flex',
width: '100%'
}}>
<Box
sx={{
textOverflow: 'ellipsis',
overflow: 'hidden',
marginRight: 'auto'
}}>
{status == STATUS.CONNECTING && (gettext('(Obtaining connection...)')+' ')}
{status == STATUS.FAILED && (gettext('(Connection failed)')+' ')}
{title}
@@ -26,7 +26,6 @@ import ERDDialogs from '../dialogs';
import ConfirmSaveContent from '../../../../../../static/js/Dialogs/ConfirmSaveContent';
import Loader from '../../../../../../static/js/components/Loader';
import { MainToolBar } from './MainToolBar';
import { Box } from '@mui/material';
import EventBus from '../../../../../../static/js/helpers/EventBus';
import { ERD_EVENTS } from '../ERDConstants';
import getApiInstance, { callFetch, parseApiError } from '../../../../../../static/js/api_instance';
@@ -85,7 +84,7 @@ const getCanvasGrid = (theme)=>{
return `url("data:image/svg+xml, %3Csvg width='100%25' viewBox='0 0 45 45' style='background-color:${erdCanvasBg}' height='100%25' xmlns='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3Cpattern id='smallGrid' width='15' height='15' patternUnits='userSpaceOnUse'%3E%3Cpath d='M 15 0 L 0 0 0 15' fill='none' stroke='${erdGridColor}' stroke-width='0.5'/%3E%3C/pattern%3E%3Cpattern id='grid' width='45' height='45' patternUnits='userSpaceOnUse'%3E%3Crect width='100' height='100' fill='url(%23smallGrid)'/%3E%3Cpath d='M 100 0 L 0 0 0 100' fill='none' stroke='${erdGridColor}' stroke-width='1'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width='100%25' height='100%25' fill='url(%23grid)' /%3E%3C/svg%3E%0A")`;
};
const StyledBox = styled(Box)(({theme})=>({
const StyledBox = styled('div')(({theme})=>({
'& .ERDTool-diagramContainer': {
position: 'relative',
width: '100%',
@@ -9,7 +9,7 @@
import React, {useCallback, useEffect, useState} from 'react';
import _ from 'lodash';
import { styled } from '@mui/material/styles';
import { Box, useTheme } from '@mui/material';
import { useTheme } from '@mui/material';
import { PgButtonGroup, PgIconButton } from '../../../../../../static/js/components/Buttons';
import FolderRoundedIcon from '@mui/icons-material/FolderRounded';
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
@@ -42,7 +42,7 @@ import { withColorPicker } from '../../../../../../static/js/helpers/withColorPi
import { useApplicationState } from '../../../../../../settings/static/ApplicationStateProvider';
import { useDelayDebounce } from '../../../../../../static/js/custom_hooks';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
padding: '2px 4px',
display: 'flex',
alignItems: 'center',
@@ -360,18 +360,34 @@ export class TableNodeWidget extends React.Component {
return (
<Box className='TableNode-columnSection' key={col.attnum} data-test="column-row">
<Box marginRight="auto" padding="0" minHeight="0" display="flex" alignItems="center">
<Box
sx={{
marginRight: 'auto',
padding: '0',
minHeight: '0',
display: 'flex',
alignItems: 'center'
}}>
{this.generatePort(leftPort)}
</Box>
<Box className='TableNode-columnName'>
<RowIcon icon={icon} />
<Box margin="auto 0">
<Box sx={{
margin: 'auto 0'
}}>
<span data-test="column-name">{col.name}</span>&nbsp;
{this.state.show_details &&
<span data-test="column-type">{cltype + (col.colconstype == 'i' ? ` (${gettext('IDENTITY')})`:'')}</span>}
</Box>
</Box>
<Box marginLeft="auto" padding="0" minHeight="0" display="flex" alignItems="center">
<Box
sx={{
marginLeft: 'auto',
padding: '0',
minHeight: '0',
display: 'flex',
alignItems: 'center'
}}>
{this.generatePort(rightPort)}
</Box>
</Box>
@@ -25,7 +25,7 @@ import PropTypes from 'prop-types';
import pgAdmin from 'sources/pgadmin';
import Table from '../../../../static/js/components/Table';
const StyledBox = styled(Box)(({theme}) =>
const StyledBox = styled('div')(({theme}) =>
({
height: '100%',
'& .ImportExportServers-noOverflow': {
@@ -8,7 +8,7 @@
//////////////////////////////////////////////////////////////
import React, { useEffect } from 'react';
import { Box, styled, useTheme } from '@mui/material';
import { styled, useTheme } from '@mui/material';
import url_for from 'sources/url_for';
import PropTypes from 'prop-types';
@@ -23,7 +23,7 @@ import gettext from 'sources/gettext';
import { useApplicationState } from '../../../../../settings/static/ApplicationStateProvider';
import { LAYOUT_EVENTS } from '../../../../../static/js/helpers/Layout';
const Root = styled(Box)(()=>({
const Root = styled('div')(()=>({
width: '100%',
height: '100%',
display: 'flex',
@@ -71,7 +71,9 @@ export function InputComponent({ label, serverList, databaseList, schemaList, di
<Grid
container
direction="row"
alignItems="center"
sx={{
alignItems: 'center'
}}
>
<Grid sx={{padding: '0.3rem'}} size={{ lg: 2, md: 2, sm: 2, xs: 2 }}>
<Typography id={label}>{label}</Typography>
@@ -24,7 +24,7 @@ import PgReactDataGrid from '../../../../../static/js/components/PgReactDataGrid
import { usePgAdmin } from '../../../../../static/js/PgAdminProvider';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
paddingTop: '0.5rem',
display: 'flex',
height: '100%',
@@ -749,7 +749,9 @@ export function SchemaDiffCompare({ params }) {
<Grid
container
direction="row"
alignItems="center"
sx={{
alignItems: 'center'
}}
>
<Grid size={{ lg: 7, md: 7, sm: 10, xs: 10 }}>
<InputComponent
@@ -773,7 +775,9 @@ export function SchemaDiffCompare({ params }) {
<Grid
container
direction="row"
alignItems="center"
sx={{
alignItems: 'center'
}}
>
<Grid size={{ lg: 7, md: 7, sm: 10, xs: 10 }}>
<InputComponent
@@ -17,7 +17,6 @@ import url_for from 'sources/url_for';
import pgAdmin from 'sources/pgadmin';
import gettext from 'sources/gettext';
import { Box } from '@mui/material';
import { Results } from './Results';
import { SchemaDiffCompare } from './SchemaDiffCompare';
import EventBus from '../../../../../static/js/helpers/EventBus';
@@ -28,7 +27,7 @@ import usePreferences from '../../../../../preferences/static/js/store';
export const SchemaDiffEventsContext = createContext();
export const SchemaDiffContext = createContext();
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
'& .SchemaDiff-resultPanel': {
backgroundColor: theme.palette.default.main,
zIndex: 5,
@@ -21,7 +21,7 @@ import { PrimaryButton, PgIconButton } from '../../../../static/js/components/Bu
import { FormFooterMessage, InputSelect, InputText, MESSAGE_TYPE } from '../../../../static/js/components/FormComponents';
import PgReactDataGrid from '../../../../static/js/components/PgReactDataGrid';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
display:'flex',
flexGrow: '1',
flexDirection:'column',
@@ -409,7 +409,14 @@ export default function SearchObjects({nodeData}) {
<PrimaryButton style={{width: '120px'}} data-test="search" className='SearchObjects-Btnmargin' startIcon={<SearchRoundedIcon />}
onClick={onSearch} disabled={search.length < 3}>{gettext('Search')}</PrimaryButton>
</Box>
<Box flexGrow="1" display="flex" flexDirection="column" position="relative" overflow="hidden">
<Box
sx={{
flexGrow: '1',
display: 'flex',
flexDirection: 'column',
position: 'relative',
overflow: 'hidden'
}}>
<PgReactDataGrid
id="searchobjects"
className='SearchObjects-grid'
@@ -953,7 +953,16 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
<QueryToolContext.Provider value={queryToolContextValue}>
<QueryToolConnectionContext.Provider value={queryToolConnContextValue}>
<QueryToolEventsContext.Provider value={eventBus.current}>
<Box width="100%" height="100%" display="flex" flexDirection="column" flexGrow="1" tabIndex="0" ref={containerRef}>
<Box
tabIndex="0"
ref={containerRef}
sx={{
width: '100%',
height: '100%',
display: 'flex',
flexDirection: 'column',
flexGrow: '1'
}}>
<ConnectionBar
connected={qtState.connected}
connecting={qtState.obtaining_conn}
@@ -21,7 +21,7 @@ import { usePgAdmin } from '../../../../../../static/js/PgAdminProvider';
import CustomPropTypes from '../../../../../../static/js/custom_prop_types';
const StyledEditorDiv = styled(Box)(({ theme }) => ({
const StyledEditorDiv = styled('div')(({ theme }) => ({
'&.Editors-textEditor': {
position: 'absolute',
zIndex: 1080,
@@ -265,7 +265,11 @@ export function TextEditor({row, column, onRowChange, onClose}) {
<ResizableDiv columnIndex={column.idx}
className='Editors-textEditor' data-label="pg-editor" resizeKey={'text'} defaultSize={{height:'80px', width:'250px'}} onKeyDown={suppressEnterKey} >
<textarea ref={autoFocusAndSelect} className='Editors-textarea' value={localVal} onChange={onChange} onKeyDown={onkeydown} />
<Box display="flex" justifyContent="flex-end">
<Box
sx={{
display: 'flex',
justifyContent: 'flex-end'
}}>
<DefaultButton startIcon={<CloseIcon />} onClick={()=>onClose(false)} size="small">
{gettext('Cancel')}
</DefaultButton>
@@ -461,7 +465,12 @@ export function JsonTextEditor({row, column, onRowChange, onClose}) {
}}
className={'jsoneditor-div'}
/>
<Box display="flex" justifyContent="flex-end" marginTop="0.25rem">
<Box
sx={{
display: 'flex',
justifyContent: 'flex-end',
marginTop: '0.25rem'
}}>
<DefaultButton startIcon={<CloseIcon />} onClick={()=>onClose(false)} size="small">
{gettext('Cancel')}
</DefaultButton>
@@ -193,14 +193,18 @@ function SelectableHeaderRenderer({column, isSelected, onColumnSelected, isCellS
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_RENDER_GEOMETRIES, column);
}}/>
</Box>}
<Box marginRight="auto">
<Box sx={{
marginRight: 'auto'
}}>
<span className='QueryTool-columnName'>{column.display_name}</span><br/>
<span>{column.display_type}</span>
</Box>
<Box marginLeft="4px">{column.can_edit ?
<EditIcon fontSize="small" style={{fontSize: '0.875rem'}} data-label="EditIcon"/>:
<LockIcon fontSize="small" style={{fontSize: '0.875rem'}} data-label="LockIcon"/>
}</Box>
<Box sx={{
marginLeft: '4px'
}}>{column.can_edit ?
<EditIcon fontSize="small" style={{fontSize: '0.875rem'}} data-label="EditIcon"/>:
<LockIcon fontSize="small" style={{fontSize: '0.875rem'}} data-label="LockIcon"/>
}</Box>
</Box>
);
}
@@ -10,7 +10,11 @@ import PropTypes from 'prop-types';
export default function CloseRunningDialog({closeModal, text, onYes}) {
return (
<ModalContent>
<Box flexGrow="1" p={2}>{typeof(text) == 'string' ? HTMLReactParser(text) : text}</Box>
<Box
sx={{
flexGrow: '1',
p: 2
}}>{typeof(text) == 'string' ? HTMLReactParser(text) : text}</Box>
<ModalFooter>
<DefaultButton data-test="no" startIcon={<CloseIcon />} onClick={()=>{
closeModal();
@@ -27,7 +27,11 @@ export default function ConfirmPromotionContent({ onContinue, onClose, closeModa
return (
<ModalContent>
<Box flexGrow="1" p={2}>{typeof (text) == 'string' ? HTMLReactParser(text) : text}</Box>
<Box
sx={{
flexGrow: '1',
p: 2
}}>{typeof (text) == 'string' ? HTMLReactParser(text) : text}</Box>
<StyledFooter>
<InputCheckbox controlProps={{ label: gettext('Don\'t ask again') }} value={formData['save_user_choice']}
onChange={(e) => setFormData((prev) => ({ ...prev, 'save_user_choice': e.target.checked }))} />
@@ -10,7 +10,11 @@ import PropTypes from 'prop-types';
export default function ConfirmTransactionContent({closeModal, text, onRollback, onCommit}) {
return (
<ModalContent>
<Box flexGrow="1" p={2}>{typeof(text) == 'string' ? HTMLReactParser(text) : text}</Box>
<Box
sx={{
flexGrow: '1',
p: 2
}}>{typeof(text) == 'string' ? HTMLReactParser(text) : text}</Box>
<ModalFooter>
<DefaultButton data-test="cancel" startIcon={<CloseIcon />} onClick={()=>{
closeModal();
@@ -7,9 +7,8 @@ import { QueryToolContext, getRandomName } from '../QueryToolComponent';
import url_for from 'sources/url_for';
import _ from 'lodash';
import PropTypes from 'prop-types';
import { Box } from '@mui/material';
const StyledBox = styled(Box)(() => ({
const StyledBox = styled('div')(() => ({
height: '100%',
'& .MacrosDialog-root': {
padding: 0 + ' !important',
@@ -99,7 +99,7 @@ export function ConnectionBar({connected, connecting, connectionStatus, connecti
const connTitle = React.useMemo(()=>_.find(connectionList, (c)=>c.is_selected)?.conn_title, [connectionList]);
return (
(<Root>
<Root>
<Box className='ConnectionBar-root'>
<PgButtonGroup size="small">
{queryToolCtx.preferences?.sqleditor?.connection_status &&
@@ -111,9 +111,22 @@ export function ConnectionBar({connected, connecting, connectionStatus, connecti
style={{backgroundColor: queryToolCtx.params.bgcolor, color: queryToolCtx.params.fgcolor}}
>
<Tooltip title={queryToolCtx.params.is_query_tool ? '' : connTitle}>
<Box display="flex" width="100%">
<Box textOverflow="ellipsis" overflow="hidden" marginRight="auto">{connecting && gettext('(Obtaining connection)')}{connTitle}</Box>
{queryToolCtx.params.is_query_tool && <Box display="flex" alignItems="center"><KeyboardArrowDownIcon /></Box>}
<Box
sx={{
display: 'flex',
width: '100%'
}}>
<Box
sx={{
textOverflow: 'ellipsis',
overflow: 'hidden',
marginRight: 'auto'
}}>{connecting && gettext('(Obtaining connection)')}{connTitle}</Box>
{queryToolCtx.params.is_query_tool && <Box
sx={{
display: 'flex',
alignItems: 'center'
}}><KeyboardArrowDownIcon /></Box>}
</Box>
</Tooltip>
</DefaultButton>
@@ -138,7 +151,7 @@ export function ConnectionBar({connected, connecting, connectionStatus, connecti
})}
<PgMenuItem onClick={onNewConnClick}>{`< ${gettext('New Connection...')} >`}</PgMenuItem>
</PgMenu>
</Root>)
</Root>
);
}
@@ -17,12 +17,11 @@ import {Buffer} from 'buffer';
import gettext from 'sources/gettext';
import Theme from 'sources/Theme';
import PropTypes from 'prop-types';
import { Box } from '@mui/material';
import EmptyPanelMessage from '../../../../../../static/js/components/EmptyPanelMessage';
import { PANELS } from '../QueryToolConstants';
import { QueryToolContext } from '../QueryToolComponent';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
position: 'relative',
'& .GeometryViewer-mapContainer': {
backgroundColor: theme.palette.background.default,
@@ -29,7 +29,7 @@ import { QUERY_TOOL_EVENTS, PANELS } from '../QueryToolConstants';
import DownloadUtils from '../../../../../../static/js/DownloadUtils';
import { getChartColor } from '../../../../../../static/js/utils';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
width: '100%',
height: '100%',
overflowY: 'scroll',
@@ -433,7 +433,12 @@ export function GraphVisualiser({initColumns}) {
</>
}
</Box>
<Box display="flex" marginLeft="3px" marginTop="3px">
<Box
sx={{
display: 'flex',
marginLeft: '3px',
marginTop: '3px'
}}>
<PgButtonGroup size="small">
<PgIconButton title={gettext('Zoom to original')} icon={<ZoomOutMapIcon style={{height: '1.2rem'}}/>}
onClick={()=>onResetZoom()} disabled={ graphData.datasets.length <= 0 }/>
@@ -8,7 +8,6 @@
//////////////////////////////////////////////////////////////
import React, {useContext, useCallback, useEffect, useState} from 'react';
import { styled } from '@mui/material/styles';
import { Box } from '@mui/material';
import { PgButtonGroup, PgIconButton } from '../../../../../../static/js/components/Buttons';
import FolderRoundedIcon from '@mui/icons-material/FolderRounded';
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
@@ -35,7 +34,7 @@ import ConfirmTransactionContent from '../dialogs/ConfirmTransactionContent';
import { LayoutDocker } from '../../../../../../static/js/helpers/Layout';
import CloseRunningDialog from '../dialogs/CloseRunningDialog';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
padding: '2px 4px',
display: 'flex',
alignItems: 'center',
@@ -91,7 +91,7 @@ const MessageBubble = styled(Paper)(({ theme, isuser }) => ({
}),
}));
const SQLPreviewBox = styled(Box)(({ theme }) => ({
const SQLPreviewBox = styled('div')(({ theme }) => ({
marginTop: theme.spacing(1),
'& .sql-preview-header': {
display: 'flex',
@@ -126,14 +126,14 @@ const InputArea = styled('div')(({ theme }) => ({
alignItems: 'flex-end',
}));
const ThinkingIndicator = styled(Box)(({ theme }) => ({
const ThinkingIndicator = styled('div')(({ theme }) => ({
display: 'flex',
alignItems: 'center',
gap: theme.spacing(1),
color: theme.palette.text.secondary,
}));
const MarkdownContent = styled(Box)(({ theme }) => ({
const MarkdownContent = styled('div')(({ theme }) => ({
fontSize: theme.typography.body2.fontSize,
lineHeight: theme.typography.body2.lineHeight,
'& p': { margin: `${theme.spacing(0.5)} 0` },
@@ -545,7 +545,9 @@ function ChatMessage({ message, onInsertSQL, onReplaceSQL, textColors, cmKey, fo
isuser="false"
sx={{ backgroundColor: 'error.light', borderColor: 'error.main' }}
>
<Typography variant="body2" color="error.dark">
<Typography variant="body2" sx={{
color: 'error.dark'
}}>
{message.content}
</Typography>
</MessageBubble>
@@ -1131,17 +1133,17 @@ export function NLQChatPanel() {
{gettext('Clear')}
</DefaultButton>
</HeaderBar>
<MessagesArea>
{messages.length === 0 ? (
<Box
display="flex"
alignItems="center"
justifyContent="center"
height="100%"
textAlign="center"
p={2}
>
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
height: '100%',
textAlign: 'center',
p: 2
}}>
<Typography variant="body2" style={{ color: textColors.secondary }}>
{gettext(
'Ask a question about your database or describe the SQL you need ' +
@@ -1165,7 +1167,6 @@ export function NLQChatPanel() {
)}
<div ref={messagesEndRef} />
</MessagesArea>
<InputArea>
<TextField
inputRef={inputRef}
@@ -272,16 +272,25 @@ QuerySourceIcon.propTypes = {
};
function HistoryEntry({entry, formatEntryDate, itemKey, selectedItemKey, onClick}) {
return <ListItemButton component='li' tabIndex="0" data-label="history-entry" data-pgadmin={entry.is_pgadmin_query}
className={'QuerySources-fontSourceCode ' + (entry.status ? '' : 'QuerySources-itemError')} selected={selectedItemKey==itemKey} onClick={onClick}>
<Box whiteSpace="nowrap" textOverflow="ellipsis" overflow="hidden" >
<QuerySourceIcon source={entry.query_source}/>
{entry.query}
</Box>
<Box fontSize="12px">
{formatEntryDate(entry.start_time)}
</Box>
</ListItemButton>;
return (
<ListItemButton component='li' tabIndex="0" data-label="history-entry" data-pgadmin={entry.is_pgadmin_query}
className={'QuerySources-fontSourceCode ' + (entry.status ? '' : 'QuerySources-itemError')} selected={selectedItemKey==itemKey} onClick={onClick}>
<Box
sx={{
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
overflow: 'hidden'
}}>
<QuerySourceIcon source={entry.query_source}/>
{entry.query}
</Box>
<Box sx={{
fontSize: '12px'
}}>
{formatEntryDate(entry.start_time)}
</Box>
</ListItemButton>
);
}
const EntryPropType = PropTypes.shape({
@@ -322,15 +331,23 @@ function QueryHistoryDetails({entry}) {
}, [entry]);
if(!entry) {
return <Box display="flex" height="100%">
<EmptyPanelMessage text={gettext('Select an history entry to see details.')} />
</Box>;
return (
<Box
sx={{
display: 'flex',
height: '100%'
}}>
<EmptyPanelMessage text={gettext('Select an history entry to see details.')} />
</Box>
);
}
return (
<>
{entry.info && <Box className='QuerySources-infoHeader'>{entry.info}</Box>}
<Box padding="0.5rem" data-label="history-detail">
<Box data-label="history-detail" sx={{
padding: '0.5rem'
}}>
<Grid container>
<Grid size={{ sm: 4 }}>{getDateFormatted(entry.start_time) + ' ' + getTimeFormatted(entry.start_time)}</Grid>
<Grid size={{ sm: 4 }}>{entry?.row_affected > 0 && entry.row_affected}</Grid>
@@ -355,9 +372,16 @@ function QueryHistoryDetails({entry}) {
className='QuerySources-queryMargin'
/>
</Box>
<Box marginTop="0.5rem">
<Box sx={{
marginTop: '0.5rem'
}}>
<Box>{gettext('Messages')}</Box>
<Box className='QuerySources-fontSourceCode' fontSize="13px" whiteSpace="pre-wrap">{_.isObject(entry.message) ? JSON.stringify(entry.message) : entry.message}</Box>
<Box
className='QuerySources-fontSourceCode'
sx={{
fontSize: '13px',
whiteSpace: 'pre-wrap'
}}>{_.isObject(entry.message) ? JSON.stringify(entry.message) : entry.message}</Box>
</Box>
</Box>
</>
@@ -521,7 +545,9 @@ export function QueryHistory() {
<>
<Box className='QuerySources-leftRoot'>
<Box className='QuerySources-header'>
<Box marginRight="auto">
<Box sx={{
marginRight: 'auto'
}}>
{gettext('Show queries generated internally by pgAdmin?')}
<InputSwitch value={showInternal} onChange={(e)=>{
setShowInternal(e.target.checked);
@@ -535,7 +561,12 @@ export function QueryHistory() {
className='QuerySources-removeBtnMargin' onClick={onRemoveAll}>{gettext('Remove All')}</DefaultButton>
</Box>
</Box>
<Box flexGrow="1" overflow="auto" className='QuerySources-listRoot'>
<Box
className='QuerySources-listRoot'
sx={{
flexGrow: '1',
overflow: 'auto'
}}>
<List ref={listRef} subheader={<li />} tabIndex="0" onKeyDown={onKeyPressed}>
{qhu.current.getGroups().map(([groupKey, groupHeader]) => (
<ListItem key={`section-${groupKey}`} className='QuerySources-removePadding'>
@@ -551,7 +582,12 @@ export function QueryHistory() {
</List>
</Box>
</Box>
<Box flexBasis="50%" maxWidth="50%" overflow="auto">
<Box
sx={{
flexBasis: '50%',
maxWidth: '50%',
overflow: 'auto'
}}>
<QueryHistoryDetails entry={selectedEntry}/>
</Box>
</>}
@@ -33,7 +33,7 @@ import pgAdmin from 'sources/pgadmin';
import { connectServer, connectServerModal } from '../connectServer';
import { useLatestFunc } from '../../../../../../static/js/custom_hooks';
const StyledBox = styled(Box)(({theme}) => ({
const StyledBox = styled('div')(({theme}) => ({
display: 'flex',
height: '100%',
flexDirection: 'column',
@@ -1680,7 +1680,11 @@ export function ResultSet() {
canEdit={queryData.can_edit} totalRowCount={queryData?.rows_affected}
pagination={queryData?.pagination ?? {}} allRowsSelect={allRowsSelect}
/>
<Box flexGrow="1" minHeight="0">
<Box
sx={{
flexGrow: '1',
minHeight: '0'
}}>
<QueryToolDataGrid
columns={columns}
rows={rows}
@@ -181,7 +181,12 @@ function PaginationInputs({pagination, totalRowCount, clearSelection, serverCurs
return (
<Box className='PaginationInputs'>
{editPageRange ?
<Box display="flex" gap="2px" alignItems="center">
<Box
sx={{
display: 'flex',
gap: '2px',
alignItems: 'center'
}}>
<div>{gettext('Showing rows:')}</div>
<InputText
type="int"
@@ -411,7 +416,12 @@ export function ResultSetToolbar({query, canEdit, totalRowCount, pagination, all
return (
<>
<StyledDiv>
<Box display="flex" alignItems="center" gap="4px">
<Box
sx={{
display: 'flex',
alignItems: 'center',
gap: '4px'
}}>
<PgButtonGroup size="small">
<PgIconButton title={gettext('Add row')} icon={<PlaylistAddRoundedIcon style={{height: 'unset'}}/>}
shortcut={queryToolPref.btn_add_row} disabled={!canEdit} onClick={addRow} />
Loaded 100 of 104 files, more files were not shown because too many files have changed in this diff. Show more