From 2a36b8eee59a6d6e46f10c5f71438e455a9e9cf0 Mon Sep 17 00:00:00 2001 From: Rohit Bhati Date: Wed, 8 Jan 2025 16:07:34 +0530 Subject: [PATCH] Fix button focus issue.#6513 --- .../servers/databases/static/js/database.js | 6 +- .../server_groups/servers/static/js/server.js | 4 +- .../js/components/PreferencesComponent.jsx | 65 ++++++++++--------- .../static/js/components/ExternalIcon.jsx | 4 +- .../static/js/helpers/ModalProvider.jsx | 65 ++++++++++++------- web/pgadmin/static/js/helpers/Notifier.jsx | 23 ++----- .../js/erd_tool/components/ConnectionBar.jsx | 4 +- .../js/components/sections/ConnectionBar.jsx | 4 +- 8 files changed, 93 insertions(+), 82 deletions(-) diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js index b74483268d3..46f2e26f4b9 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js +++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js @@ -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(); diff --git a/web/pgadmin/browser/server_groups/servers/static/js/server.js b/web/pgadmin/browser/server_groups/servers/static/js/server.js index 4053089690d..8600a880693 100644 --- a/web/pgadmin/browser/server_groups/servers/static/js/server.js +++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js @@ -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(); diff --git a/web/pgadmin/preferences/static/js/components/PreferencesComponent.jsx b/web/pgadmin/preferences/static/js/components/PreferencesComponent.jsx index 2aeb3a81796..cf6864de820 100644 --- a/web/pgadmin/preferences/static/js/components/PreferencesComponent.jsx +++ b/web/pgadmin/preferences/static/js/components/PreferencesComponent.jsx @@ -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.')}

${gettext('Do you want to proceed?')}

+${gettext('Note:')}
`; + + pgAdmin.Browser.notifier.showModal( gettext('Reset all preferences'), - `${gettext('All preferences will be reset to their default values.')}

${gettext('Do you want to proceed?')}

- ${gettext('Note:')}
`, - function () {}, - function () {}, - '', - 'Cancel', - function (closeModal) { - return [ - { - type: 'default', - icon: , - label: gettext('Save & Reload'), - onclick: () => { - resetPrefsToDefault(true); - closeModal(); - } - }, { - type: 'primary', - icon: , - label: gettext('Save & Reload Later'), - onclick: () => { - resetPrefsToDefault(false); - closeModal(); - } - } - ]; - } + (closeModal)=>{ + const onClick = (reset) => { + resetPrefsToDefault(reset); + closeModal(); + }; + return( + + + {HTMLReactParser(text)} + + + } onClick={()=> closeModal()}>{'Cancel'} + } onClick={() => onClick(true)} >{gettext('Save & Reload')} + } onClick={()=>onClick(false)}>{gettext('Save & Reload Later')} + + + ); + }, + { isFullScreen: false, isResizeable: false, showFullScreen: false, isFullWidth: false, showTitle: true}, ); }; diff --git a/web/pgadmin/static/js/components/ExternalIcon.jsx b/web/pgadmin/static/js/components/ExternalIcon.jsx index c36f0bffd66..2f2889fdf1a 100644 --- a/web/pgadmin/static/js/components/ExternalIcon.jsx +++ b/web/pgadmin/static/js/components/ExternalIcon.jsx @@ -71,8 +71,8 @@ ClearIcon.propTypes = {style: PropTypes.object}; export const ConnectedIcon = ({style})=>; ConnectedIcon.propTypes = {style: PropTypes.object}; -export const DisonnectedIcon = ({style})=>; -DisonnectedIcon.propTypes = {style: PropTypes.object}; +export const DisconnectedIcon = ({style})=>; +DisconnectedIcon.propTypes = {style: PropTypes.object}; export const RegexIcon = ({style})=>; RegexIcon.propTypes = {style: PropTypes.object}; diff --git a/web/pgadmin/static/js/helpers/ModalProvider.jsx b/web/pgadmin/static/js/helpers/ModalProvider.jsx index 09c41a308c6..cff217d3bb8 100644 --- a/web/pgadmin/static/js/helpers/ModalProvider.jsx +++ b/web/pgadmin/static/js/helpers/ModalProvider.jsx @@ -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: , + default: +}; + export function useModal() { return React.useContext(ModalContext); } -function renderExtraButtons(button) { - switch(button.type) { - case 'primary': - return {button.label}; - case 'default': - return {button.label}; - default: - return {button.label}; - }; -} - -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 ( {typeof (text) == 'string' ? HTMLReactParser(text) : text} {confirm && - } onClick={onCancelClick} autoFocus={true}>{cancelLabel} - } - { - extraButtons?.length ? - extraButtons.map(button=>renderExtraButtons(button)) - : - } onClick={onOkClick}>{okLabel} + } onClick={onCancelClick}>{cancelLabel} } + {okLabel} ); @@ -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 ( - + ); }); } + +function confirmDelete(title, text, onDeleteClick, onCancelClick, deleteLabel = gettext('Delete'), cancelLabel = gettext('Cancel')) { + this.showModal( + title, + (closeModal)=>{ + const handleOkClose = (callback) => { + callback(); + closeModal(); + }; + return ( + + + {typeof (text) == 'string' ? HTMLReactParser(text) : text} + + + } onClick={() => handleOkClose(onCancelClick)} autoFocus>{cancelLabel} + } onClick={() => handleOkClose(onDeleteClick)}>{deleteLabel} + + + ); + }, + { 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 ( diff --git a/web/pgadmin/static/js/helpers/Notifier.jsx b/web/pgadmin/static/js/helpers/Notifier.jsx index 9c7a8303158..5bc59f04c38 100644 --- a/web/pgadmin/static/js/helpers/Notifier.jsx +++ b/web/pgadmin/static/js/helpers/Notifier.jsx @@ -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: , - 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) { diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/components/ConnectionBar.jsx b/web/pgadmin/tools/erd/static/js/erd_tool/components/ConnectionBar.jsx index 40af685aa20..e483d8ea82e 100644 --- a/web/pgadmin/tools/erd/static/js/erd_tool/components/ConnectionBar.jsx +++ b/web/pgadmin/tools/erd/static/js/erd_tool/components/ConnectionBar.jsx @@ -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 ; } else { - return ; + return ; } } diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/ConnectionBar.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/ConnectionBar.jsx index bbdf9c78058..284a98be828 100644 --- a/web/pgadmin/tools/sqleditor/static/js/components/sections/ConnectionBar.jsx +++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/ConnectionBar.jsx @@ -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 ; } } else { - return ; + return ; } }