mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-01-26 00:06:47 -06:00
Fixed a button focus issue found while testing the dialog button changes. #6513
This commit is contained in:
parent
172edaa227
commit
de6fbe7725
@ -271,7 +271,8 @@ define('pgadmin.node.database', [
|
||||
},
|
||||
function() { return true;},
|
||||
gettext('Disconnect'),
|
||||
gettext('Cancel')
|
||||
gettext('Cancel'),
|
||||
'disconnect'
|
||||
);
|
||||
}
|
||||
|
||||
@ -565,7 +566,8 @@ define('pgadmin.node.database', [
|
||||
},
|
||||
function() { return true; },
|
||||
gettext('Disconnect'),
|
||||
gettext('Cancel')
|
||||
gettext('Cancel'),
|
||||
'disconnect'
|
||||
);
|
||||
} else {
|
||||
disconnect();
|
||||
|
@ -261,6 +261,7 @@ define('pgadmin.node.server', [
|
||||
function() { return true;},
|
||||
gettext('Disconnect'),
|
||||
gettext('Cancel'),
|
||||
'disconnect'
|
||||
);
|
||||
}
|
||||
return false;
|
||||
@ -868,7 +869,8 @@ define('pgadmin.node.server', [
|
||||
function() { disconnect(); },
|
||||
function() { return true;},
|
||||
gettext('Disconnect'),
|
||||
gettext('Cancel')
|
||||
gettext('Cancel'),
|
||||
'disconnect'
|
||||
);
|
||||
} else {
|
||||
disconnect();
|
||||
|
@ -15,6 +15,8 @@ import React, { useEffect, useMemo } from 'react';
|
||||
import { FileType } from 'react-aspen';
|
||||
import { Box } from '@mui/material';
|
||||
import PropTypes from 'prop-types';
|
||||
import CloseIcon from '@mui/icons-material/CloseRounded';
|
||||
import HTMLReactParser from 'html-react-parser/lib/index';
|
||||
import SchemaView from '../../../../static/js/SchemaView';
|
||||
import getApiInstance from '../../../../static/js/api_instance';
|
||||
import CloseSharpIcon from '@mui/icons-material/CloseSharp';
|
||||
@ -85,6 +87,16 @@ const StyledBox = styled(Box)(({theme}) => ({
|
||||
marginLeft: '0.5em'
|
||||
},
|
||||
},
|
||||
|
||||
},
|
||||
'& .Alert-footer': {
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
padding: '0.5rem',
|
||||
...theme.mixins.panelBorder.top,
|
||||
},
|
||||
'& .Alert-margin': {
|
||||
marginLeft: '0.25rem',
|
||||
},
|
||||
}));
|
||||
|
||||
@ -655,36 +667,31 @@ export default function PreferencesComponent({ ...props }) {
|
||||
};
|
||||
|
||||
const reset = () => {
|
||||
pgAdmin.Browser.notifier.confirm(
|
||||
const text = `${gettext('All preferences will be reset to their default values.')}<br><br>${gettext('Do you want to proceed?')}<br><br>
|
||||
${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>
|
||||
<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>`;
|
||||
|
||||
pgAdmin.Browser.notifier.showModal(
|
||||
gettext('Reset all preferences'),
|
||||
`${gettext('All preferences will be reset to their default values.')}<br><br>${gettext('Do you want to proceed?')}<br><br>
|
||||
${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>
|
||||
<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>`,
|
||||
function () {},
|
||||
function () {},
|
||||
'',
|
||||
'Cancel',
|
||||
function (closeModal) {
|
||||
return [
|
||||
{
|
||||
type: 'default',
|
||||
icon: <SaveSharpIcon />,
|
||||
label: gettext('Save & Reload'),
|
||||
onclick: () => {
|
||||
resetPrefsToDefault(true);
|
||||
closeModal();
|
||||
}
|
||||
}, {
|
||||
type: 'primary',
|
||||
icon: <SaveSharpIcon />,
|
||||
label: gettext('Save & Reload Later'),
|
||||
onclick: () => {
|
||||
resetPrefsToDefault(false);
|
||||
closeModal();
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
(closeModal)=>{
|
||||
const onClick = (reset) => {
|
||||
resetPrefsToDefault(reset);
|
||||
closeModal();
|
||||
};
|
||||
return(
|
||||
<StyledBox display="flex" flexDirection="column" height="100%">
|
||||
<Box flexGrow="1" p={2}>
|
||||
{HTMLReactParser(text)}
|
||||
</Box>
|
||||
<Box className='Alert-footer'>
|
||||
<DefaultButton className='Alert-margin' startIcon={<CloseIcon />} onClick={()=> closeModal()}>{'Cancel'}</DefaultButton>
|
||||
<DefaultButton className='Alert-margin' startIcon={<SaveSharpIcon />} onClick={() => onClick(true)} >{gettext('Save & Reload')}</DefaultButton>
|
||||
<PrimaryButton className='Alert-margin' startIcon={ <SaveSharpIcon />} onClick={()=>onClick(false)}>{gettext('Save & Reload Later')}</PrimaryButton>
|
||||
</Box>
|
||||
</StyledBox>
|
||||
);
|
||||
},
|
||||
{ isFullScreen: false, isResizeable: false, showFullScreen: false, isFullWidth: false, showTitle: true},
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -71,8 +71,8 @@ ClearIcon.propTypes = {style: PropTypes.object};
|
||||
export const ConnectedIcon = ({style})=><ExternalIcon Icon={ConnectedSvg} style={{height: '1rem', ...style}} data-label="ConnectedIcon" />;
|
||||
ConnectedIcon.propTypes = {style: PropTypes.object};
|
||||
|
||||
export const DisonnectedIcon = ({style})=><ExternalIcon Icon={DisconnectedSvg} style={{height: '1rem', ...style}} data-label="DisonnectedIcon" />;
|
||||
DisonnectedIcon.propTypes = {style: PropTypes.object};
|
||||
export const DisconnectedIcon = ({style})=><ExternalIcon Icon={DisconnectedSvg} style={{height: '1rem', ...style}} data-label="DisconnectedIcon" />;
|
||||
DisconnectedIcon.propTypes = {style: PropTypes.object};
|
||||
|
||||
export const RegexIcon = ({style})=><ExternalIcon Icon={RegexSvg} style={style} data-label="RegexIcon" />;
|
||||
RegexIcon.propTypes = {style: PropTypes.object};
|
||||
|
@ -13,13 +13,14 @@ import { getEpoch } from 'sources/utils';
|
||||
import { DefaultButton, PgIconButton, PrimaryButton } from '../components/Buttons';
|
||||
import Draggable from 'react-draggable';
|
||||
import CloseIcon from '@mui/icons-material/CloseRounded';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import CustomPropTypes from '../custom_prop_types';
|
||||
import PropTypes from 'prop-types';
|
||||
import gettext from 'sources/gettext';
|
||||
import HTMLReactParser from 'html-react-parser';
|
||||
import CheckRoundedIcon from '@mui/icons-material/CheckRounded';
|
||||
import { Rnd } from 'react-rnd';
|
||||
import { ExpandDialogIcon, MinimizeDialogIcon } from '../components/ExternalIcon';
|
||||
import { ExpandDialogIcon, MinimizeDialogIcon, DisconnectedIcon } from '../components/ExternalIcon';
|
||||
import { styled } from '@mui/material/styles';
|
||||
|
||||
export const ModalContext = React.createContext({});
|
||||
@ -37,35 +38,24 @@ const StyledBox = styled(Box)(({theme}) => ({
|
||||
},
|
||||
}));
|
||||
|
||||
const buttonIconMap = {
|
||||
disconnect: <DisconnectedIcon />,
|
||||
default: <CheckRoundedIcon />
|
||||
};
|
||||
|
||||
export function useModal() {
|
||||
return React.useContext(ModalContext);
|
||||
}
|
||||
|
||||
function renderExtraButtons(button) {
|
||||
switch(button.type) {
|
||||
case 'primary':
|
||||
return <PrimaryButton className='Alert-margin' startIcon={button.icon} onClick={button.onClick}>{button.label}</PrimaryButton>;
|
||||
case 'default':
|
||||
return <DefaultButton className='Alert-margin' startIcon={button.icon} onClick={button.onClick} color={button?.color}>{button.label}</DefaultButton>;
|
||||
default:
|
||||
return <DefaultButton className='Alert-margin' startIcon={button.icon} onClick={button.onClick}>{button.label}</DefaultButton>;
|
||||
};
|
||||
}
|
||||
|
||||
function AlertContent({ text, confirm, okLabel = gettext('OK'), cancelLabel = gettext('Cancel'), onOkClick, onCancelClick, extraButtons }) {
|
||||
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}>{typeof (text) == 'string' ? HTMLReactParser(text) : text}</Box>
|
||||
<Box className='Alert-footer'>
|
||||
{confirm &&
|
||||
<DefaultButton startIcon={<CloseIcon />} onClick={onCancelClick} autoFocus={true}>{cancelLabel}</DefaultButton>
|
||||
}
|
||||
{
|
||||
extraButtons?.length ?
|
||||
extraButtons.map(button=>renderExtraButtons(button))
|
||||
:
|
||||
<PrimaryButton className='Alert-margin' startIcon={<CheckRoundedIcon />} onClick={onOkClick}>{okLabel}</PrimaryButton>
|
||||
<DefaultButton startIcon={<CloseIcon />} onClick={onCancelClick}>{cancelLabel}</DefaultButton>
|
||||
}
|
||||
<PrimaryButton className='Alert-margin' startIcon={buttonIconMap[okIcon]} onClick={onOkClick} autoFocus>{okLabel}</PrimaryButton>
|
||||
</Box>
|
||||
</StyledBox>
|
||||
);
|
||||
@ -77,7 +67,7 @@ AlertContent.propTypes = {
|
||||
onCancelClick: PropTypes.func,
|
||||
okLabel: PropTypes.string,
|
||||
cancelLabel: PropTypes.string,
|
||||
extraButtons: PropTypes.array
|
||||
okIcon : PropTypes.string
|
||||
};
|
||||
|
||||
function alert(title, text, onOkClick, okLabel = gettext('OK')) {
|
||||
@ -93,7 +83,7 @@ function alert(title, text, onOkClick, okLabel = gettext('OK')) {
|
||||
});
|
||||
}
|
||||
|
||||
function confirm(title, text, onOkClick, onCancelClick, okLabel = gettext('Yes'), cancelLabel = gettext('No'), extras = null) {
|
||||
function confirm(title, text, onOkClick, onCancelClick, okLabel = gettext('Yes'), cancelLabel = gettext('No'), okIcon) {
|
||||
// bind the modal provider before calling
|
||||
this.showModal(title, (closeModal) => {
|
||||
const onCancelClickClose = () => {
|
||||
@ -105,12 +95,36 @@ function confirm(title, text, onOkClick, onCancelClick, okLabel = gettext('Yes')
|
||||
onOkClick?.();
|
||||
closeModal();
|
||||
};
|
||||
const extraButtons = extras?.(closeModal);
|
||||
return (
|
||||
<AlertContent text={text} confirm onOkClick={onOkClickClose} onCancelClick={onCancelClickClose} okLabel={okLabel} cancelLabel={cancelLabel} extraButtons={extraButtons} />
|
||||
<AlertContent text={text} confirm onOkClick={onOkClickClose} onCancelClick={onCancelClickClose} okLabel={okLabel} cancelLabel={cancelLabel} okIcon={okIcon}/>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function confirmDelete(title, text, onDeleteClick, onCancelClick, deleteLabel = gettext('Delete'), cancelLabel = gettext('Cancel')) {
|
||||
this.showModal(
|
||||
title,
|
||||
(closeModal)=>{
|
||||
const handleOkClose = (callback) => {
|
||||
callback();
|
||||
closeModal();
|
||||
};
|
||||
return (
|
||||
<StyledBox display="flex" flexDirection="column" height="100%">
|
||||
<Box flexGrow="1" p={2}>
|
||||
{typeof (text) == 'string' ? HTMLReactParser(text) : text}
|
||||
</Box>
|
||||
<Box className='Alert-footer'>
|
||||
<DefaultButton className='Alert-margin' startIcon={<CloseIcon />} onClick={() => handleOkClose(onCancelClick)} autoFocus>{cancelLabel}</DefaultButton>
|
||||
<DefaultButton className='Alert-margin' color={'error'} startIcon={<DeleteIcon/> } onClick={() => handleOkClose(onDeleteClick)}>{deleteLabel}</DefaultButton>
|
||||
</Box>
|
||||
</StyledBox>
|
||||
);
|
||||
},
|
||||
{ isFullScreen: false, isResizeable: false, showFullScreen: false, isFullWidth: false, showTitle: true},
|
||||
);
|
||||
}
|
||||
|
||||
export default function ModalProvider({ children }) {
|
||||
const [modals, setModals] = React.useState([]);
|
||||
|
||||
@ -143,7 +157,8 @@ export default function ModalProvider({ children }) {
|
||||
const modalContext = React.useMemo(() => ({
|
||||
...modalContextBase,
|
||||
confirm: confirm.bind(modalContextBase),
|
||||
alert: alert.bind(modalContextBase)
|
||||
alert: alert.bind(modalContextBase),
|
||||
confirmDelete: confirmDelete.bind(modalContextBase)
|
||||
}), []);
|
||||
return (
|
||||
<ModalContext.Provider value={modalContext}>
|
||||
|
@ -175,29 +175,14 @@ class Notifier {
|
||||
this.modal.alert(title, text, onOkClick, okLabel);
|
||||
}
|
||||
|
||||
confirm(title, text, onOkClick, onCancelClick, okLabel=gettext('Yes'), cancelLabel=gettext('No'), extras=null) {
|
||||
confirm(title, text, onOkClick, onCancelClick, okLabel=gettext('Yes'), cancelLabel=gettext('No'), okIcon) {
|
||||
/* Use this if you want to use pgAdmin global notifier.
|
||||
Or else, if you want to use modal inside iframe only then use ModalProvider eg- query tool */
|
||||
this.modal.confirm(title, text, onOkClick, onCancelClick, okLabel, cancelLabel, extras);
|
||||
this.modal.confirm(title, text, onOkClick, onCancelClick, okLabel, cancelLabel, okIcon);
|
||||
}
|
||||
|
||||
confirmDelete(title, text, onOkClick, onCancelClick,okLabel = gettext('Yes'), cancelLabel = gettext('No')){
|
||||
|
||||
const extraButtons = (closeModal) => {
|
||||
return [
|
||||
{
|
||||
type: 'default',
|
||||
icon: <CheckRoundedIcon />,
|
||||
label: okLabel,
|
||||
onClick: ()=>{
|
||||
onOkClick();
|
||||
closeModal();
|
||||
},
|
||||
color: 'error',
|
||||
},
|
||||
];
|
||||
};
|
||||
this.modal.confirm(title, text, onOkClick, onCancelClick, okLabel, cancelLabel, extraButtons);
|
||||
confirmDelete(title, text, onDeleteClick, onCancelClick, okLabel = gettext('Delete'), cancelLabel = gettext('Cancel')){
|
||||
this.modal.confirmDelete(title, text, onDeleteClick, onCancelClick, okLabel, cancelLabel);
|
||||
}
|
||||
|
||||
showModal(title, content, modalOptions) {
|
||||
|
@ -13,7 +13,7 @@ import gettext from 'sources/gettext';
|
||||
import PropTypes from 'prop-types';
|
||||
import { DefaultButton, PgButtonGroup, PgIconButton } from '../../../../../../static/js/components/Buttons';
|
||||
import { Box, Tooltip, CircularProgress } from '@mui/material';
|
||||
import { ConnectedIcon, DisonnectedIcon } from '../../../../../../static/js/components/ExternalIcon';
|
||||
import { ConnectedIcon, DisconnectedIcon } from '../../../../../../static/js/components/ExternalIcon';
|
||||
|
||||
const StyledBox = styled(Box)(({theme}) => ({
|
||||
padding: '2px 4px',
|
||||
@ -45,7 +45,7 @@ function ConnectionStatusIcon({status}) {
|
||||
} else if(status == STATUS.CONNECTED || status == STATUS.FAILED) {
|
||||
return <ConnectedIcon />;
|
||||
} else {
|
||||
return <DisonnectedIcon />;
|
||||
return <DisconnectedIcon />;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ import { styled } from '@mui/material/styles';
|
||||
import { Box, CircularProgress, Tooltip } from '@mui/material';
|
||||
import { DefaultButton, PgButtonGroup, PgIconButton } from '../../../../../../static/js/components/Buttons';
|
||||
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
||||
import { ConnectedIcon, DisonnectedIcon, QueryToolIcon } from '../../../../../../static/js/components/ExternalIcon';
|
||||
import { ConnectedIcon, DisconnectedIcon, QueryToolIcon } from '../../../../../../static/js/components/ExternalIcon';
|
||||
import { QueryToolContext } from '../QueryToolComponent';
|
||||
import { CONNECTION_STATUS, CONNECTION_STATUS_MESSAGE } from '../QueryToolConstants';
|
||||
import HourglassEmptyRoundedIcon from '@mui/icons-material/HourglassEmptyRounded';
|
||||
@ -65,7 +65,7 @@ function ConnectionStatusIcon({connected, connecting, status}) {
|
||||
return <ConnectedIcon />;
|
||||
}
|
||||
} else {
|
||||
return <DisonnectedIcon />;
|
||||
return <DisconnectedIcon />;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user