Skip to content

Commit 45c2fd4

Browse files
Ensure duplicate modal dialogs are not triggered.#8316
1 parent f25cde8 commit 45c2fd4

File tree

15 files changed

+74
-51
lines changed

15 files changed

+74
-51
lines changed

runtime/src/js/pgadmin.js

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ let startPageUrl = null;
3131
let serverCheckUrl = null;
3232
let pgAdminMainScreen = null;
3333

34+
let configureWindow = null,
35+
viewLogWindow = null;
36+
3437
let serverPort = 5050;
3538
let appStartTime = (new Date()).getTime();
3639
const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -77,7 +80,8 @@ contextMenu({
7780
Menu.setApplicationMenu(null);
7881

7982
function openConfigure() {
80-
const win = new BrowserWindow({
83+
if (configureWindow === null){
84+
configureWindow = new BrowserWindow({
8185
show: false,
8286
width: 600,
8387
height: 580,
@@ -88,11 +92,12 @@ function openConfigure() {
8892
preload: path.join(__dirname, 'other_preload.js'),
8993
},
9094
});
91-
win.loadFile('./src/html/configure.html');
92-
win.once('ready-to-show', ()=>{
93-
win.show();
95+
configureWindow.loadFile('./src/html/configure.html');
96+
configureWindow.once('ready-to-show', ()=>{
97+
configureWindow.show();
9498
});
9599
}
100+
}
96101

97102
function showErrorDialog(intervalID) {
98103
if(!splashWindow.isVisible()) {
@@ -304,21 +309,23 @@ function launchPgAdminWindow() {
304309

305310
setupMenu(pgAdminMainScreen, {
306311
'view_logs': ()=>{
307-
const win = new BrowserWindow({
308-
show: false,
309-
width: 800,
310-
height: 460,
311-
position: 'center',
312-
resizable: false,
313-
icon: '../../assets/pgAdmin4.png',
314-
webPreferences: {
315-
preload: path.join(__dirname, 'other_preload.js'),
316-
},
317-
});
318-
win.loadFile('./src/html/view_log.html');
319-
win.once('ready-to-show', ()=>{
320-
win.show();
321-
});
312+
if(viewLogWindow === null){
313+
viewLogWindow = new BrowserWindow({
314+
show: false,
315+
width: 800,
316+
height: 460,
317+
position: 'center',
318+
resizable: false,
319+
icon: '../../assets/pgAdmin4.png',
320+
webPreferences: {
321+
preload: path.join(__dirname, 'other_preload.js'),
322+
},
323+
});
324+
viewLogWindow.loadFile('./src/html/view_log.html');
325+
viewLogWindow.once('ready-to-show', ()=>{
326+
viewLogWindow.show();
327+
});
328+
}
322329
},
323330
'configure': openConfigure,
324331
'reloadApp': reloadApp,

web/pgadmin/about/static/js/about.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class About {
4343
pgAdmin.Browser.notifier.showModal(gettext('About %s', pgAdmin.Browser.utils.app_name), () => {
4444
return <AboutComponent />;
4545
}, { isFullScreen: false, isResizeable: true, showFullScreen: true,
46-
isFullWidth: true, dialogWidth: dlgWidth, dialogHeight: dlgHeight, minHeight: dlgHeight
46+
isFullWidth: true, dialogWidth: dlgWidth, dialogHeight: dlgHeight, minHeight: dlgHeight, id:'id-about'
4747
});
4848
}
4949
}

web/pgadmin/browser/static/js/constants.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ export const BROWSER_PANELS = {
4646
WELCOME_PSQL_TOOL: 'id-welcome-psql'
4747
};
4848

49+
export const MODAL_DIALOGS = {
50+
QT_CONFIRMATIONS: 'id-qt-close-confirmation',
51+
};
52+
4953
export const WORKSPACES = {
5054
DEFAULT: 'default_workspace',
5155
QUERY_TOOL: 'query_tool_workspace',

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,6 @@ export default function PreferencesComponent({ ...props }) {
689689
const text = `${gettext('All preferences will be reset to their default values.')}<br><br>${gettext('Do you want to proceed?')}<br><br>
690690
${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>
691691
<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>`;
692-
693692
pgAdmin.Browser.notifier.showModal(
694693
gettext('Reset all preferences'),
695694
(closeModal)=>{
@@ -710,7 +709,7 @@ ${gettext('Note:')}<br> <ul style="padding-left:20px"><li style="list-style-type
710709
</StyledBox>
711710
);
712711
},
713-
{ isFullScreen: false, isResizeable: false, showFullScreen: false, isFullWidth: false, showTitle: true},
712+
{ isFullScreen: false, isResizeable: false, showFullScreen: false, isFullWidth: false, showTitle: true, id: 'id-reset-preferences'},
714713
);
715714
};
716715

web/pgadmin/preferences/static/js/preferences.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,13 @@ export default class Preferences {
4848

4949
// This is a callback function to show preferences.
5050
show() {
51-
5251
// Render Preferences component
5352
pgAdmin.Browser.notifier.showModal(gettext('Preferences'), (closeModal) => {
5453
return <PreferencesComponent
5554
renderTree={(prefTreeData) => {
5655
// Render preferences tree component
5756
return <PreferencesTree pgBrowser={this.pgBrowser} data={prefTreeData} />;
5857
}} closeModal={closeModal} />;
59-
}, { isFullScreen: false, isResizeable: true, showFullScreen: true, isFullWidth: true, dialogWidth: 900, dialogHeight: 550 });
58+
}, { isFullScreen: false, isResizeable: true, showFullScreen: true, isFullWidth: true, dialogWidth: 900, dialogHeight: 550, id: 'id-preferences' });
6059
}
6160
}

web/pgadmin/static/js/BrowserComponent.jsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,15 +151,18 @@ export default function BrowserComponent({pgAdmin}) {
151151
let { name: browser } = useMemo(()=>getBrowser(), []);
152152
const [uiReady, setUiReady] = useState(false);
153153
const confirmOnClose = getPreferencesForModule('browser').confirm_on_refresh_close;
154-
155154
useBeforeUnload({
156155
enabled: confirmOnClose,
157156
beforeClose: (forceClose)=>{
158157
pgAdmin.Browser.notifier.confirm(
159158
gettext('Quit pgAdmin 4'),
160159
gettext('Are you sure you want to quit the application?'),
161160
function() { forceClose(); },
162-
function() { return true;},
161+
function() { return true; },
162+
gettext('Yes'),
163+
gettext('No'),
164+
'default',
165+
'id-app-quit'
163166
);
164167
},
165168
isNewTab: true,

web/pgadmin/static/js/Dialogs/index.jsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export function showServerPassword() {
6767
}}
6868
/>
6969
);
70-
});
70+
}, {id: 'id-connect-server'});
7171
}
7272

7373
function masterPassCallbacks(masterpass_callback_queue) {
@@ -176,7 +176,7 @@ export function showMasterPassword(isPWDPresent, errmsg, masterpass_callback_que
176176
}}
177177
/>
178178
);
179-
});
179+
}, {id: 'id-master-password'});
180180
}
181181
}
182182

@@ -275,7 +275,7 @@ export function showChangeUserPassword(url) {
275275
/>;
276276
},
277277
{ isFullScreen: false, isResizeable: true, showFullScreen: false, isFullWidth: true,
278-
dialogWidth: pgAdmin.Browser.stdW.md, dialogHeight: pgAdmin.Browser.stdH.md});
278+
dialogWidth: pgAdmin.Browser.stdW.md, dialogHeight: pgAdmin.Browser.stdH.md, id: 'id-change-password'});
279279
}
280280

281281
export function showNamedRestorePoint() {
@@ -351,7 +351,7 @@ export function showChangeOwnership() {
351351
/>;
352352
},
353353
{ isFullScreen: false, isResizeable: true, showFullScreen: true, isFullWidth: true,
354-
dialogWidth: pgAdmin.Browser.stdW.md, dialogHeight: pgAdmin.Browser.stdH.md});
354+
dialogWidth: pgAdmin.Browser.stdW.md, dialogHeight: pgAdmin.Browser.stdH.md, id: 'id-change-owner' });
355355
}
356356

357357
export function showUrlDialog() {
@@ -388,6 +388,6 @@ export function showQuickSearch() {
388388
pgAdmin.Browser.notifier.showModal(gettext('Quick Search'), (closeModal) => {
389389
return <QuickSearch closeModal={closeModal}/>;
390390
},
391-
{ isFullScreen: false, isResizeable: false, showFullScreen: false, isFullWidth: false, showTitle: false}
391+
{ isFullScreen: false, isResizeable: false, showFullScreen: false, isFullWidth: false, showTitle: false, id: 'id-quick-search'}
392392
);
393393
}

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

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ function alert(title, text, onOkClick, okLabel = gettext('OK')) {
8383
});
8484
}
8585

86-
function confirm(title, text, onOkClick, onCancelClick, okLabel = gettext('Yes'), cancelLabel = gettext('No'), okIcon = 'default') {
86+
function confirm(title, text, onOkClick, onCancelClick, okLabel = gettext('Yes'), cancelLabel = gettext('No'), okIcon = 'default', modalId=null) {
8787
// bind the modal provider before calling
8888
this.showModal(title, (closeModal) => {
8989
const onCancelClickClose = () => {
@@ -98,7 +98,7 @@ function confirm(title, text, onOkClick, onCancelClick, okLabel = gettext('Yes')
9898
return (
9999
<AlertContent text={text} confirm onOkClick={onOkClickClose} onCancelClick={onCancelClickClose} okLabel={okLabel} cancelLabel={cancelLabel} okIcon={okIcon}/>
100100
);
101-
});
101+
}, {modalId: modalId});
102102
}
103103

104104
function confirmDelete(title, text, onDeleteClick, onCancelClick, deleteLabel = gettext('Delete'), cancelLabel = gettext('Cancel')) {
@@ -127,16 +127,23 @@ function confirmDelete(title, text, onDeleteClick, onCancelClick, deleteLabel =
127127

128128
export default function ModalProvider({ children }) {
129129
const [modals, setModals] = React.useState([]);
130-
131130
const showModal = (title, content, modalOptions) => {
132131
let id = getEpoch().toString() + crypto.getRandomValues(new Uint8Array(4));
133-
setModals((prev) => [...prev, {
134-
id: id,
135-
title: title,
136-
content: content,
137-
...modalOptions,
138-
}]);
132+
if(modalOptions?.id){
133+
id = modalOptions.id;
134+
}
135+
setModals((prev) => {
136+
if(prev?.find(modal=> modal.id === modalOptions?.id)){
137+
return prev;
138+
}
139+
return [...prev, {
140+
id: id,
141+
title: title,
142+
content: content,
143+
...modalOptions,
144+
}];});
139145
};
146+
140147
const closeModal = (id) => {
141148
setModals((prev) => {
142149
return prev.filter((o) => o.id != id);

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

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

178-
confirm(title, text, onOkClick, onCancelClick, okLabel=gettext('Yes'), cancelLabel=gettext('No'), okIcon='default') {
178+
confirm(title, text, onOkClick, onCancelClick, okLabel=gettext('Yes'), cancelLabel=gettext('No'), okIcon='default', modalId=null) {
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, okIcon);
181+
this.modal.confirm(title, text, onOkClick, onCancelClick, okLabel, cancelLabel, okIcon, modalId);
182182
}
183183

184184
confirmDelete(title, text, onDeleteClick, onCancelClick, okLabel = gettext('Delete'), cancelLabel = gettext('Cancel')){

web/pgadmin/tools/debugger/static/js/debugger_ui.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import React from 'react';
1111

1212
import gettext from 'sources/gettext';
1313
import pgAdmin from 'sources/pgadmin';
14-
1514
import DebuggerArgumentComponent from './components/DebuggerArgumentComponent';
1615

1716
export default class FunctionArguments {
@@ -28,6 +27,6 @@ export default class FunctionArguments {
2827
// Render Debugger argument component
2928
pgAdmin.Browser.notifier.showModal(gettext('Debugger'), (closeModal) => {
3029
return <DebuggerArgumentComponent closeModal={closeModal} debuggerInfo={debugInfo} restartDebug={restartDebug} isEdbProc={isEdbProc} transId={transId} pgTreeInfo={treeInfo} pgData={d}></DebuggerArgumentComponent>;
31-
}, { isFullScreen: false, isResizeable: true, showFullScreen: true, isFullWidth: true, dialogWidth: pgAdmin.Browser.stdW.md, dialogHeight: pgAdmin.Browser.stdH.md });
30+
}, { isFullScreen: false, isResizeable: true, showFullScreen: true, isFullWidth: true, dialogWidth: pgAdmin.Browser.stdW.md, dialogHeight: pgAdmin.Browser.stdH.md, id:'id-debugger'});
3231
}
3332
}

0 commit comments

Comments
 (0)