Skip to content

Commit

Permalink
Fix issues found during Electron testing. pgadmin-org#7494
Browse files Browse the repository at this point in the history
Fix application crash when using users dialog. pgadmin-org#7607
  • Loading branch information
adityatoshniwal committed Jul 8, 2024
1 parent dcfef15 commit 760e382
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 107 deletions.
6 changes: 3 additions & 3 deletions runtime/src/js/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//
//////////////////////////////////////////////////////////////

import { app, Menu, ipcMain } from 'electron';
import { app, Menu, ipcMain, BrowserWindow } from 'electron';

const isMac = process.platform == 'darwin';
let mainMenu;
Expand Down Expand Up @@ -72,8 +72,8 @@ function buildMenu(pgadminMenus, pgAdminMainScreen, callbacks) {
{
label: 'View',
submenu: [
{ label: 'Reload', click: ()=>pgAdminMainScreen.webContents.reload()},
{ label: 'Toggle Developer Tools', click: ()=>pgAdminMainScreen.webContents.openDevTools({ mode: 'bottom' })},
{ label: 'Reload', click: ()=>BrowserWindow.getFocusedWindow().webContents.reload()},
{ label: 'Toggle Developer Tools', click: ()=>BrowserWindow.getFocusedWindow().webContents.openDevTools({ mode: 'bottom' })},
{ type: 'separator' },
{ role: 'resetZoom' },
{ role: 'zoomIn' },
Expand Down
13 changes: 5 additions & 8 deletions runtime/src/js/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import fs from 'fs';
import path from 'path';
import net from 'net';
import {platform} from 'os';
import { app } from 'electron';
import { app, session } from 'electron';

let pgadminServerProcess = null;

Expand Down Expand Up @@ -141,7 +141,7 @@ export const getServerLogFile = () => {

// This function is used to kill the server process, remove the log files
// and quit the application.
export const cleanupAndQuitApp = (pgAdminWindowObject) => {
export const cleanupAndQuitApp = () => {
// Remove the server log file on exit
removeLogFile();

Expand All @@ -155,10 +155,7 @@ export const cleanupAndQuitApp = (pgAdminWindowObject) => {
}
}

if (pgAdminWindowObject != null) {
const ses = pgAdminWindowObject.webContents.session;
ses.clearStorageData({
storages: ['cookies'],
});
}
session.defaultSession.clearStorageData({
storages: ['cookies', 'localstorage'],
});
};
15 changes: 9 additions & 6 deletions runtime/src/js/pgadmin.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function openConfigure() {
const win = new BrowserWindow({
show: false,
width: 600,
height: 600,
height: 620,
position: 'center',
resizable: false,
icon: '../../assets/pgAdmin4.png',
Expand All @@ -81,8 +81,8 @@ function showErrorDialog(intervalID) {

new BrowserWindow({
'frame': true,
'width': 790,
'height': 430,
'width': 800,
'height': 450,
'position': 'center',
'resizable': false,
'focus': true,
Expand Down Expand Up @@ -251,8 +251,8 @@ function launchPgAdminWindow() {
'view_logs': ()=>{
const win = new BrowserWindow({
show: false,
width: 790,
height: 425,
width: 800,
height: 460,
position: 'center',
resizable: false,
icon: '../../assets/pgAdmin4.png',
Expand Down Expand Up @@ -302,9 +302,12 @@ function launchPgAdminWindow() {
}
});

pgAdminMainScreen.on('closed', ()=>{
misc.cleanupAndQuitApp();
});

pgAdminMainScreen.on('close', () => {
configStore.set('bounds', pgAdminMainScreen.getBounds());
misc.cleanupAndQuitApp(pgAdminMainScreen);
pgAdminMainScreen.removeAllListeners('close');
pgAdminMainScreen.close();
});
Expand Down
2 changes: 1 addition & 1 deletion web/pgadmin/browser/static/js/MainMenuFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export default class MainMenuFactory {
return {
...sm.serialize(),
submenu: sm.getMenuItems()?.map((smsm)=>{
MainMenuFactory.electronCallbacks[`${smName}_${smsm.name}`] = sm.callback;
MainMenuFactory.electronCallbacks[`${smName}_${smsm.name}`] = smsm.callback;
return {
...smsm.serialize(),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export default class FileManagerModule {
if(res.canceled) {
onCancel?.();
} else {
onOK?.(res.filePaths[0]);
onOK?.(res.filePath ? res.filePath : res.filePaths[0]);
}
}

Expand Down
45 changes: 45 additions & 0 deletions web/pgadmin/static/js/custom_hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import React, {useRef, useEffect, useState, useCallback, useLayoutEffect} from 'react';
import moment from 'moment';
import { isMac } from './keyboard_shortcuts';
import { getBrowser } from './utils';

/* React hook for setInterval */
export function useInterval(callback, delay) {
Expand Down Expand Up @@ -209,3 +210,47 @@ export function useWindowSize() {
export function useForceUpdate() {
return React.useReducer(() => ({}), {})[1];
}

export function useBeforeUnload({enabled, isNewTab, beforeClose, closePanel }) {
const onBeforeUnload = useCallback((e)=>{
e.preventDefault();
e.returnValue = 'prevent';
}, []);

const onBeforeUnloadElectron = useCallback((e)=>{
e.preventDefault();
e.returnValue = 'prevent';
beforeClose?.();
}, []);

useEffect(()=>{
if(getBrowser().name == 'Electron') {
window.addEventListener('beforeunload', onBeforeUnloadElectron);
} else {
if(enabled){
window.addEventListener('beforeunload', onBeforeUnload);
} else {
window.removeEventListener('beforeunload', onBeforeUnload);
}
}

return () => {
window.removeEventListener('beforeunload', onBeforeUnloadElectron);
window.removeEventListener('beforeunload', onBeforeUnload);
};
}, [enabled]);


function forceClose() {
if(getBrowser().name == 'Electron' && isNewTab) {
window.removeEventListener('beforeunload', onBeforeUnloadElectron);
// somehow window.close was not working may becuase the removeEventListener
// was not completely executed. Add timeout.
setTimeout(()=>window.close(), 50);
} else {
closePanel?.();
}
}

return {forceClose};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import PropTypes from 'prop-types';
import { useBeforeUnload } from '../../../../../../static/js/custom_hooks';

export default function BeforeUnload({enabled, isNewTab, beforeClose, closePanel, getForceClose}) {
const {forceClose} = useBeforeUnload(
{enabled, isNewTab, beforeClose, closePanel}
);

getForceClose(forceClose);

return <></>;
}

BeforeUnload.propTypes = {
enabled: PropTypes.bool,
isNewTab: PropTypes.bool,
beforeClose: PropTypes.func,
closePanel: PropTypes.func,
getForceClose: PropTypes.func,
};
80 changes: 32 additions & 48 deletions web/pgadmin/tools/erd/static/js/erd_tool/components/ERDTool.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { LAYOUT_EVENTS } from '../../../../../../static/js/helpers/Layout';
import usePreferences from '../../../../../../preferences/static/js/store';
import pgAdmin from 'sources/pgadmin';
import { styled } from '@mui/material/styles';
import BeforeUnload from './BeforeUnload';

/* Custom react-diagram action for keyboard events */
export class KeyboardShortcutAction extends Action {
Expand Down Expand Up @@ -144,12 +145,13 @@ export default class ERDTool extends React.Component {
_.bindAll(this, ['onLoadDiagram', 'onSaveDiagram', 'onSQLClick',
'onImageClick', 'onAddNewNode', 'onEditTable', 'onCloneNode', 'onDeleteNode', 'onNoteClick',
'onNoteClose', 'onOneToManyClick', 'onManyToManyClick', 'onAutoDistribute', 'onDetailsToggle',
'onChangeColors', 'onDropNode', 'onBeforeUnload', 'onNotationChange',
'onChangeColors', 'onDropNode', 'onNotationChange', 'closePanel'
]);

this.diagram.zoomToFit = this.diagram.zoomToFit.bind(this.diagram);
this.diagram.zoomIn = this.diagram.zoomIn.bind(this.diagram);
this.diagram.zoomOut = this.diagram.zoomOut.bind(this.diagram);
this.forceClose = this.closePanel;
}

registerModelEvents() {
Expand Down Expand Up @@ -315,14 +317,7 @@ export default class ERDTool extends React.Component {

this.props.panelDocker.eventBus.registerListener(LAYOUT_EVENTS.CLOSING, (id)=>{
if(this.props.panelId == id) {
window.removeEventListener('beforeunload', this.onBeforeUnload);
if(this.state.dirty) {
this.closeOnSave = false;
this.confirmBeforeClose();
return false;
}
this.closePanel();
return true;
this.confirmBeforeClose();
}
});

Expand Down Expand Up @@ -354,45 +349,34 @@ export default class ERDTool extends React.Component {
if(this.props.params.gen) {
await this.loadTablesData();
}

if(this.state.is_close_tab_warning) {
window.addEventListener('beforeunload', this.onBeforeUnload);
} else {
window.removeEventListener('beforeunload', this.onBeforeUnload);
}
}

componentWillUnmount() {
window.removeEventListener('beforeunload', this.onBeforeUnload);
}

componentDidUpdate() {
if(this.state.dirty) {
this.setTitle(this.state.current_file, true);
}
// Add beforeunload event if "Confirm on close or refresh" option is enabled in the preferences.
if(this.state.is_close_tab_warning){
window.addEventListener('beforeunload', this.onBeforeUnload);
} else {
window.removeEventListener('beforeunload', this.onBeforeUnload);
}
}

confirmBeforeClose() {
let bodyObj = this;
this.context.showModal(gettext('Save changes?'), (closeModal)=>(
<ConfirmSaveContent
closeModal={closeModal}
text={gettext('The diagram has changed. Do you want to save changes?')}
onDontSave={()=>{
bodyObj.closePanel();
}}
onSave={()=>{
bodyObj.onSaveDiagram(false, true);
}}
/>
));
return false;
if(this.state.dirty) {
this.closeOnSave = false;
this.context.showModal(gettext('Save changes?'), (closeModal)=>(
<ConfirmSaveContent
closeModal={closeModal}
text={gettext('The diagram has changed. Do you want to save changes?')}
onDontSave={()=>{
bodyObj.forceClose();
}}
onSave={()=>{
bodyObj.onSaveDiagram(false, true);
}}
/>
));
return false;
} else {
this.forceClose();
}
}

closePanel() {
Expand Down Expand Up @@ -463,15 +447,6 @@ export default class ERDTool extends React.Component {
}
}

onBeforeUnload(e) {
if(this.state.dirty) {
e.preventDefault();
e.returnValue = 'prevent';
} else {
delete e['returnValue'];
}
}

onDropNode(e) {
let nodeDropData = JSON.parse(e.dataTransfer.getData('text'));
if(nodeDropData.objUrl && nodeDropData.nodeType === 'table') {
Expand Down Expand Up @@ -627,7 +602,7 @@ export default class ERDTool extends React.Component {
this.setTitle(fileName);
this.setLoading(null);
if(this.closeOnSave) {
this.closePanel();
this.forceClose();
}
}).catch((err)=>{
this.setLoading(null);
Expand Down Expand Up @@ -910,6 +885,15 @@ export default class ERDTool extends React.Component {

return (
<StyledBox ref={this.containerRef} height="100%" display="flex" flexDirection="column">
<BeforeUnload
enabled={this.state.is_close_tab_warning}
isNewTab={this.state.is_new_tab}
beforeClose={()=>{
this.confirmBeforeClose();
}}
closePanel={this.closePanel}
getForceClose={(fn)=>this.forceClose = fn}
/>
<ConnectionBar status={this.state.conn_status} bgcolor={this.props.params.bgcolor}
fgcolor={this.props.params.fgcolor} title={_.unescape(this.props.params.title)}/>
<MainToolBar preferences={this.state.preferences} eventBus={this.eventBus}
Expand Down
Loading

0 comments on commit 760e382

Please sign in to comment.