Skip to content

Commit 267f5bf

Browse files
Fix button focus issue.#6513
1 parent 9cd8492 commit 267f5bf

File tree

8 files changed

+93
-82
lines changed

8 files changed

+93
-82
lines changed

web/pgadmin/browser/server_groups/servers/databases/static/js/database.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,8 @@ define('pgadmin.node.database', [
271271
},
272272
function() { return true;},
273273
gettext('Disconnect'),
274-
gettext('Cancel')
274+
gettext('Cancel'),
275+
'disconnect'
275276
);
276277
}
277278

@@ -565,7 +566,8 @@ define('pgadmin.node.database', [
565566
},
566567
function() { return true; },
567568
gettext('Disconnect'),
568-
gettext('Cancel')
569+
gettext('Cancel'),
570+
'disconnect'
569571
);
570572
} else {
571573
disconnect();

web/pgadmin/browser/server_groups/servers/static/js/server.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ define('pgadmin.node.server', [
261261
function() { return true;},
262262
gettext('Disconnect'),
263263
gettext('Cancel'),
264+
'disconnect'
264265
);
265266
}
266267
return false;
@@ -868,7 +869,8 @@ define('pgadmin.node.server', [
868869
function() { disconnect(); },
869870
function() { return true;},
870871
gettext('Disconnect'),
871-
gettext('Cancel')
872+
gettext('Cancel'),
873+
'disconnect'
872874
);
873875
} else {
874876
disconnect();

web/pgadmin/preferences/static/js/components/PreferencesComponent.jsx

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import React, { useEffect, useMemo } from 'react';
1515
import { FileType } from 'react-aspen';
1616
import { Box } from '@mui/material';
1717
import PropTypes from 'prop-types';
18+
import CloseIcon from '@mui/icons-material/CloseRounded';
19+
import HTMLReactParser from 'html-react-parser/lib/index';
1820
import SchemaView from '../../../../static/js/SchemaView';
1921
import getApiInstance from '../../../../static/js/api_instance';
2022
import CloseSharpIcon from '@mui/icons-material/CloseSharp';
@@ -85,6 +87,16 @@ const StyledBox = styled(Box)(({theme}) => ({
8587
marginLeft: '0.5em'
8688
},
8789
},
90+
91+
},
92+
'& .Alert-footer': {
93+
display: 'flex',
94+
justifyContent: 'flex-end',
95+
padding: '0.5rem',
96+
...theme.mixins.panelBorder.top,
97+
},
98+
'& .Alert-margin': {
99+
marginLeft: '0.25rem',
88100
},
89101
}));
90102

@@ -655,36 +667,31 @@ export default function PreferencesComponent({ ...props }) {
655667
};
656668

657669
const reset = () => {
658-
pgAdmin.Browser.notifier.confirm(
670+
const text = `${gettext('All preferences will be reset to their default values.')}<br><br>${gettext('Do you want to proceed?')}<br><br>
671+
${gettext('Note:')}<br> <ul style="padding-left:20px"><li style="list-style-type:disc">${gettext('The object explorer tree will be refreshed automatically to reflect the changes.')}</li>
672+
<li style="list-style-type:disc">${gettext('If the application language changes, a reload of the application will be required. You can choose to reload later at your convenience.')}</li></ul>`;
673+
674+
pgAdmin.Browser.notifier.showModal(
659675
gettext('Reset all preferences'),
660-
`${gettext('All preferences will be reset to their default values.')}<br><br>${gettext('Do you want to proceed?')}<br><br>
661-
${gettext('Note:')}<br> <ul style="padding-left:20px"><li style="list-style-type:disc">${gettext('The object explorer tree will be refreshed automatically to reflect the changes.')}</li>
662-
<li style="list-style-type:disc">${gettext('If the application language changes, a reload of the application will be required. You can choose to reload later at your convenience.')}</li></ul>`,
663-
function () {},
664-
function () {},
665-
'',
666-
'Cancel',
667-
function (closeModal) {
668-
return [
669-
{
670-
type: 'default',
671-
icon: <SaveSharpIcon />,
672-
label: gettext('Save & Reload'),
673-
onclick: () => {
674-
resetPrefsToDefault(true);
675-
closeModal();
676-
}
677-
}, {
678-
type: 'primary',
679-
icon: <SaveSharpIcon />,
680-
label: gettext('Save & Reload Later'),
681-
onclick: () => {
682-
resetPrefsToDefault(false);
683-
closeModal();
684-
}
685-
}
686-
];
687-
}
676+
(closeModal)=>{
677+
const onClick = (reset) => {
678+
resetPrefsToDefault(reset);
679+
closeModal();
680+
};
681+
return(
682+
<StyledBox display="flex" flexDirection="column" height="100%">
683+
<Box flexGrow="1" p={2}>
684+
{HTMLReactParser(text)}
685+
</Box>
686+
<Box className='Alert-footer'>
687+
<DefaultButton className='Alert-margin' startIcon={<CloseIcon />} onClick={()=> closeModal()}>{'Cancel'}</DefaultButton>
688+
<DefaultButton className='Alert-margin' startIcon={<SaveSharpIcon />} onClick={() => onClick(true)} >{gettext('Save & Reload')}</DefaultButton>
689+
<PrimaryButton className='Alert-margin' startIcon={ <SaveSharpIcon />} onClick={()=>onClick(false)}>{gettext('Save & Reload Later')}</PrimaryButton>
690+
</Box>
691+
</StyledBox>
692+
);
693+
},
694+
{ isFullScreen: false, isResizeable: false, showFullScreen: false, isFullWidth: false, showTitle: true},
688695
);
689696
};
690697

web/pgadmin/static/js/components/ExternalIcon.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ ClearIcon.propTypes = {style: PropTypes.object};
7171
export const ConnectedIcon = ({style})=><ExternalIcon Icon={ConnectedSvg} style={{height: '1rem', ...style}} data-label="ConnectedIcon" />;
7272
ConnectedIcon.propTypes = {style: PropTypes.object};
7373

74-
export const DisonnectedIcon = ({style})=><ExternalIcon Icon={DisconnectedSvg} style={{height: '1rem', ...style}} data-label="DisonnectedIcon" />;
75-
DisonnectedIcon.propTypes = {style: PropTypes.object};
74+
export const DisconnectedIcon = ({style})=><ExternalIcon Icon={DisconnectedSvg} style={{height: '1rem', ...style}} data-label="DisconnectedIcon" />;
75+
DisconnectedIcon.propTypes = {style: PropTypes.object};
7676

7777
export const RegexIcon = ({style})=><ExternalIcon Icon={RegexSvg} style={style} data-label="RegexIcon" />;
7878
RegexIcon.propTypes = {style: PropTypes.object};

web/pgadmin/static/js/helpers/ModalProvider.jsx

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ import { getEpoch } from 'sources/utils';
1313
import { DefaultButton, PgIconButton, PrimaryButton } from '../components/Buttons';
1414
import Draggable from 'react-draggable';
1515
import CloseIcon from '@mui/icons-material/CloseRounded';
16+
import DeleteIcon from '@mui/icons-material/Delete';
1617
import CustomPropTypes from '../custom_prop_types';
1718
import PropTypes from 'prop-types';
1819
import gettext from 'sources/gettext';
1920
import HTMLReactParser from 'html-react-parser';
2021
import CheckRoundedIcon from '@mui/icons-material/CheckRounded';
2122
import { Rnd } from 'react-rnd';
22-
import { ExpandDialogIcon, MinimizeDialogIcon } from '../components/ExternalIcon';
23+
import { ExpandDialogIcon, MinimizeDialogIcon, DisconnectedIcon } from '../components/ExternalIcon';
2324
import { styled } from '@mui/material/styles';
2425

2526
export const ModalContext = React.createContext({});
@@ -37,35 +38,24 @@ const StyledBox = styled(Box)(({theme}) => ({
3738
},
3839
}));
3940

41+
const buttonIconMap = {
42+
disconnect: <DisconnectedIcon />,
43+
default: <CheckRoundedIcon />
44+
};
45+
4046
export function useModal() {
4147
return React.useContext(ModalContext);
4248
}
4349

44-
function renderExtraButtons(button) {
45-
switch(button.type) {
46-
case 'primary':
47-
return <PrimaryButton className='Alert-margin' startIcon={button.icon} onClick={button.onClick}>{button.label}</PrimaryButton>;
48-
case 'default':
49-
return <DefaultButton className='Alert-margin' startIcon={button.icon} onClick={button.onClick} color={button?.color}>{button.label}</DefaultButton>;
50-
default:
51-
return <DefaultButton className='Alert-margin' startIcon={button.icon} onClick={button.onClick}>{button.label}</DefaultButton>;
52-
};
53-
}
54-
55-
function AlertContent({ text, confirm, okLabel = gettext('OK'), cancelLabel = gettext('Cancel'), onOkClick, onCancelClick, extraButtons }) {
50+
function AlertContent({ text, confirm, okLabel = gettext('OK'), cancelLabel = gettext('Cancel'), onOkClick, onCancelClick, okIcon = 'default'}) {
5651
return (
5752
<StyledBox display="flex" flexDirection="column" height="100%">
5853
<Box flexGrow="1" p={2}>{typeof (text) == 'string' ? HTMLReactParser(text) : text}</Box>
5954
<Box className='Alert-footer'>
6055
{confirm &&
61-
<DefaultButton startIcon={<CloseIcon />} onClick={onCancelClick} autoFocus={true}>{cancelLabel}</DefaultButton>
62-
}
63-
{
64-
extraButtons?.length ?
65-
extraButtons.map(button=>renderExtraButtons(button))
66-
:
67-
<PrimaryButton className='Alert-margin' startIcon={<CheckRoundedIcon />} onClick={onOkClick}>{okLabel}</PrimaryButton>
56+
<DefaultButton startIcon={<CloseIcon />} onClick={onCancelClick}>{cancelLabel}</DefaultButton>
6857
}
58+
<PrimaryButton className='Alert-margin' startIcon={buttonIconMap[okIcon]} onClick={onOkClick} autoFocus>{okLabel}</PrimaryButton>
6959
</Box>
7060
</StyledBox>
7161
);
@@ -77,7 +67,7 @@ AlertContent.propTypes = {
7767
onCancelClick: PropTypes.func,
7868
okLabel: PropTypes.string,
7969
cancelLabel: PropTypes.string,
80-
extraButtons: PropTypes.array
70+
okIcon : PropTypes.func
8171
};
8272

8373
function alert(title, text, onOkClick, okLabel = gettext('OK')) {
@@ -93,7 +83,7 @@ function alert(title, text, onOkClick, okLabel = gettext('OK')) {
9383
});
9484
}
9585

96-
function confirm(title, text, onOkClick, onCancelClick, okLabel = gettext('Yes'), cancelLabel = gettext('No'), extras = null) {
86+
function confirm(title, text, onOkClick, onCancelClick, okLabel = gettext('Yes'), cancelLabel = gettext('No'), okIcon) {
9787
// bind the modal provider before calling
9888
this.showModal(title, (closeModal) => {
9989
const onCancelClickClose = () => {
@@ -105,12 +95,36 @@ function confirm(title, text, onOkClick, onCancelClick, okLabel = gettext('Yes')
10595
onOkClick?.();
10696
closeModal();
10797
};
108-
const extraButtons = extras?.(closeModal);
10998
return (
110-
<AlertContent text={text} confirm onOkClick={onOkClickClose} onCancelClick={onCancelClickClose} okLabel={okLabel} cancelLabel={cancelLabel} extraButtons={extraButtons} />
99+
<AlertContent text={text} confirm onOkClick={onOkClickClose} onCancelClick={onCancelClickClose} okLabel={okLabel} cancelLabel={cancelLabel} okIcon={okIcon}/>
111100
);
112101
});
113102
}
103+
104+
function confirmDelete(title, text, onDeleteClick, onCancelClick, deleteLabel = gettext('Delete'), cancelLabel = gettext('Cancel')) {
105+
this.showModal(
106+
title,
107+
(closeModal)=>{
108+
const handleOkClose = (callback) => {
109+
callback();
110+
closeModal();
111+
};
112+
return (
113+
<StyledBox display="flex" flexDirection="column" height="100%">
114+
<Box flexGrow="1" p={2}>
115+
{typeof (text) == 'string' ? HTMLReactParser(text) : text}
116+
</Box>
117+
<Box className='Alert-footer'>
118+
<DefaultButton className='Alert-margin' startIcon={<CloseIcon />} onClick={() => handleOkClose(onCancelClick)} autoFocus>{cancelLabel}</DefaultButton>
119+
<DefaultButton className='Alert-margin' color={'error'} startIcon={<DeleteIcon/> } onClick={() => handleOkClose(onDeleteClick)}>{deleteLabel}</DefaultButton>
120+
</Box>
121+
</StyledBox>
122+
);
123+
},
124+
{ isFullScreen: false, isResizeable: false, showFullScreen: false, isFullWidth: false, showTitle: true},
125+
);
126+
}
127+
114128
export default function ModalProvider({ children }) {
115129
const [modals, setModals] = React.useState([]);
116130

@@ -143,7 +157,8 @@ export default function ModalProvider({ children }) {
143157
const modalContext = React.useMemo(() => ({
144158
...modalContextBase,
145159
confirm: confirm.bind(modalContextBase),
146-
alert: alert.bind(modalContextBase)
160+
alert: alert.bind(modalContextBase),
161+
confirmDelete: confirmDelete.bind(modalContextBase)
147162
}), []);
148163
return (
149164
<ModalContext.Provider value={modalContext}>

web/pgadmin/static/js/helpers/Notifier.jsx

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -175,29 +175,14 @@ class Notifier {
175175
this.modal.alert(title, text, onOkClick, okLabel);
176176
}
177177

178-
confirm(title, text, onOkClick, onCancelClick, okLabel=gettext('Yes'), cancelLabel=gettext('No'), extras=null) {
178+
confirm(title, text, onOkClick, onCancelClick, okLabel=gettext('Yes'), cancelLabel=gettext('No'), okIcon) {
179179
/* Use this if you want to use pgAdmin global notifier.
180180
Or else, if you want to use modal inside iframe only then use ModalProvider eg- query tool */
181-
this.modal.confirm(title, text, onOkClick, onCancelClick, okLabel, cancelLabel, extras);
181+
this.modal.confirm(title, text, onOkClick, onCancelClick, okLabel, cancelLabel, okIcon);
182182
}
183183

184-
confirmDelete(title, text, onOkClick, onCancelClick,okLabel = gettext('Yes'), cancelLabel = gettext('No')){
185-
186-
const extraButtons = (closeModal) => {
187-
return [
188-
{
189-
type: 'default',
190-
icon: <CheckRoundedIcon />,
191-
label: okLabel,
192-
onClick: ()=>{
193-
onOkClick();
194-
closeModal();
195-
},
196-
color: 'error',
197-
},
198-
];
199-
};
200-
this.modal.confirm(title, text, onOkClick, onCancelClick, okLabel, cancelLabel, extraButtons);
184+
confirmDelete(title, text, onDeleteClick, onCancelClick, okLabel = gettext('Delete'), cancelLabel = gettext('Cancel')){
185+
this.modal.confirmDelete(title, text, onDeleteClick, onCancelClick, okLabel, cancelLabel);
201186
}
202187

203188
showModal(title, content, modalOptions) {

web/pgadmin/tools/erd/static/js/erd_tool/components/ConnectionBar.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import gettext from 'sources/gettext';
1313
import PropTypes from 'prop-types';
1414
import { DefaultButton, PgButtonGroup, PgIconButton } from '../../../../../../static/js/components/Buttons';
1515
import { Box, Tooltip, CircularProgress } from '@mui/material';
16-
import { ConnectedIcon, DisonnectedIcon } from '../../../../../../static/js/components/ExternalIcon';
16+
import { ConnectedIcon, DisconnectedIcon } from '../../../../../../static/js/components/ExternalIcon';
1717

1818
const StyledBox = styled(Box)(({theme}) => ({
1919
padding: '2px 4px',
@@ -45,7 +45,7 @@ function ConnectionStatusIcon({status}) {
4545
} else if(status == STATUS.CONNECTED || status == STATUS.FAILED) {
4646
return <ConnectedIcon />;
4747
} else {
48-
return <DisonnectedIcon />;
48+
return <DisconnectedIcon />;
4949
}
5050
}
5151

web/pgadmin/tools/sqleditor/static/js/components/sections/ConnectionBar.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { styled } from '@mui/material/styles';
1111
import { Box, CircularProgress, Tooltip } from '@mui/material';
1212
import { DefaultButton, PgButtonGroup, PgIconButton } from '../../../../../../static/js/components/Buttons';
1313
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
14-
import { ConnectedIcon, DisonnectedIcon, QueryToolIcon } from '../../../../../../static/js/components/ExternalIcon';
14+
import { ConnectedIcon, DisconnectedIcon, QueryToolIcon } from '../../../../../../static/js/components/ExternalIcon';
1515
import { QueryToolContext } from '../QueryToolComponent';
1616
import { CONNECTION_STATUS, CONNECTION_STATUS_MESSAGE } from '../QueryToolConstants';
1717
import HourglassEmptyRoundedIcon from '@mui/icons-material/HourglassEmptyRounded';
@@ -65,7 +65,7 @@ function ConnectionStatusIcon({connected, connecting, status}) {
6565
return <ConnectedIcon />;
6666
}
6767
} else {
68-
return <DisonnectedIcon />;
68+
return <DisconnectedIcon />;
6969
}
7070
}
7171

0 commit comments

Comments
 (0)