From 9c745db413ffa702b2b7861b7465b47873ee3b15 Mon Sep 17 00:00:00 2001 From: Nikhil Mohite Date: Fri, 1 Jul 2022 12:41:06 +0530 Subject: [PATCH] =?UTF-8?q?Enable=20the=20start=20debugging=20button=20onc?= =?UTF-8?q?e=20execution=C2=A0is=20completed.=20Fixes=20#7517?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en_US/release_notes_6_12.rst | 2 + web/pgadmin/tools/debugger/__init__.py | 2 +- .../debugger/static/js/DebuggerConstants.js | 4 +- .../components/DebuggerArgumentComponent.jsx | 67 ++++++++----------- .../js/components/DebuggerComponent.jsx | 32 +++++++-- .../debugger/static/js/components/ToolBar.jsx | 40 +++++------ .../tools/debugger/static/js/debugger_ui.js | 10 ++- 7 files changed, 89 insertions(+), 68 deletions(-) diff --git a/docs/en_US/release_notes_6_12.rst b/docs/en_US/release_notes_6_12.rst index 9449f8fcf..0a9768cd3 100644 --- a/docs/en_US/release_notes_6_12.rst +++ b/docs/en_US/release_notes_6_12.rst @@ -18,3 +18,5 @@ Housekeeping Bug fixes ********* + + | `Issue #7517 `_ - Enable the start debugging button once execution is completed. diff --git a/web/pgadmin/tools/debugger/__init__.py b/web/pgadmin/tools/debugger/__init__.py index 087c8e7a1..23ff9e6b6 100644 --- a/web/pgadmin/tools/debugger/__init__.py +++ b/web/pgadmin/tools/debugger/__init__.py @@ -985,7 +985,7 @@ def start_debugger_listener(trans_id): # If user again start the same debug function with different arguments # then we need to save that values to session variable and database. if request.method == 'POST': - data = json.loads(request.values['data'], encoding='utf-8') + data = json.loads(request.data, encoding='utf-8') if data: de_inst.function_data['args_value'] = data de_inst.update_session() diff --git a/web/pgadmin/tools/debugger/static/js/DebuggerConstants.js b/web/pgadmin/tools/debugger/static/js/DebuggerConstants.js index 379409f73..cb95acf47 100644 --- a/web/pgadmin/tools/debugger/static/js/DebuggerConstants.js +++ b/web/pgadmin/tools/debugger/static/js/DebuggerConstants.js @@ -47,8 +47,8 @@ export const MENUS = { STEPINTO: 'step-into', STEPOVER: 'step-over', STOP: 'stop', - CONTINUE: 'continue', - CLEAR_ALL_BREAKPOINT: 'clear-al-breakpoint', + START: 'start', + CLEAR_ALL_BREAKPOINT: 'clear-all-breakpoint', TOGGLE_BREAKPOINT: 'toggle-breakpoint' }; diff --git a/web/pgadmin/tools/debugger/static/js/components/DebuggerArgumentComponent.jsx b/web/pgadmin/tools/debugger/static/js/components/DebuggerArgumentComponent.jsx index dda9fbc50..19fe4750c 100644 --- a/web/pgadmin/tools/debugger/static/js/components/DebuggerArgumentComponent.jsx +++ b/web/pgadmin/tools/debugger/static/js/components/DebuggerArgumentComponent.jsx @@ -69,7 +69,7 @@ const useStyles = makeStyles((theme) => ); -export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug, isEdbProc, transId, ...props }) { +export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug, isEdbProc, transId, pgTreeInfo, pgData, ...props }) { const classes = useStyles(); const debuggerArgsSchema = useRef(new DebuggerArgumentSchema()); const api = getApiInstance(); @@ -85,16 +85,13 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug, var _Url = null; if (restartDebug == 0) { - var t = pgAdmin.Browser.tree, - i = t.selected(), - d = i ? t.itemData(i) : undefined; - if (!d) + if (!pgData) return; - var treeInfo = t.getTreeNodeHierarchy(i); + var treeInfo = pgTreeInfo; - if (d._type == 'function') { + if (pgData._type == 'function') { // Get the existing function parameters available from sqlite database _Url = url_for('debugger.get_arguments', { 'sid': treeInfo.server._id, @@ -102,7 +99,7 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug, 'scid': treeInfo.schema._id, 'func_id': treeInfo.function._id, }); - } else if (d._type == 'procedure') { + } else if (pgData._type == 'procedure') { // Get the existing function parameters available from sqlite database _Url = url_for('debugger.get_arguments', { 'sid': treeInfo.server._id, @@ -110,7 +107,7 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug, 'scid': treeInfo.schema._id, 'func_id': treeInfo.procedure._id, }); - } else if (d._type == 'edbfunc') { + } else if (pgData._type == 'edbfunc') { // Get the existing function parameters available from sqlite database _Url = url_for('debugger.get_arguments', { 'sid': treeInfo.server._id, @@ -118,7 +115,7 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug, 'scid': treeInfo.schema._id, 'func_id': treeInfo.edbfunc._id, }); - } else if (d._type == 'edbproc') { + } else if (pgData._type == 'edbproc') { // Get the existing function parameters available from sqlite database _Url = url_for('debugger.get_arguments', { 'sid': treeInfo.server._id, @@ -452,18 +449,16 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug, let base_url = null; if (restartDebug == 0) { - let selectedItem = pgAdmin.Browser.tree.selected(); - let itemData = pgAdmin.Browser.tree.itemData(selectedItem); - if (!itemData) + if (!pgData) return; - let treeInfo = pgAdmin.Browser.tree.getTreeNodeHierarchy(selectedItem); + let treeInfo = pgTreeInfo; base_url = url_for('debugger.clear_arguments', { 'sid': treeInfo.server._id, 'did': treeInfo.database._id, 'scid': treeInfo.schema._id, - 'func_id': itemData._id, + 'func_id': pgData._id, }); } else { base_url = url_for('debugger.clear_arguments', { @@ -587,7 +582,7 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug, 'is_null': arg.is_null ? 1 : 0, 'is_expression': arg.expr ? 1 : 0, 'use_default': arg.use_default ? 1 : 0, - 'value': debuggerInfo.value, + 'value': arg.value, 'is_array_value': arg?.isArrayType, }); } @@ -675,43 +670,27 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug, return baseUrl; } - function getSelectedNodeData() { - var treeInfo, d; - if (restartDebug == 0) { - var t = pgAdmin.Browser.tree, - i = t.selected(); - - d = i ? t.itemData(i) : undefined; - - if (!d) - return; - - treeInfo = t.getTreeNodeHierarchy(i); - } - return [treeInfo, d]; - } - function startDebugging() { var self = this; setLoaderText('Starting debugger.'); try { /* Initialize the target once the debug button is clicked and create asynchronous connection and unique transaction ID If the debugging is started again then treeInfo is already stored. */ - var [treeInfo, d] = getSelectedNodeData(); - if (!d) return; + var treeInfo = pgTreeInfo; + if (!pgData) return; var argsValueList = []; var sqliteFuncArgsList = []; var intCount = 0; - let argsList = []; //debuggerFinalArgs.current?.changed ? [] : debuggerArgsData.current.aregsCollection; + let argsList = []; let argSet = []; setDebuggingArgs(argsList, argSet); argsList.forEach(arg => { checkArgsVal(arg, argsValueList); - setSqliteFuncArgs(d, treeInfo, arg, intCount, sqliteFuncArgsList); + setSqliteFuncArgs(pgData, treeInfo, arg, intCount, sqliteFuncArgsList); intCount = intCount + 1; }); @@ -719,7 +698,7 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug, /* If debugging is not started again then we should initialize the target otherwise not */ if (restartDebug == 0) { - baseUrl = checkTypeAndGetUrl(d, treeInfo); + baseUrl = checkTypeAndGetUrl(pgData, treeInfo); api({ url: baseUrl, @@ -791,7 +770,7 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug, }); } - var _url = getSetArgsUrl(d, treeInfo); + var _url = getSetArgsUrl(pgData, treeInfo); api({ url: _url, @@ -831,8 +810,12 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug, method: 'POST', data: JSON.stringify(argsValueList), }) - .then(function () {/*This is intentional (SonarQube)*/ }) + .then(function () { + /* Close the debugger modal dialog */ + props.closeModal(); + }) .catch(function (error) { + props.closeModal(); Notify.alert( gettext('Debugger Listener Startup Error'), gettext(error.response.data) @@ -851,7 +834,9 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug, method: 'POST', data: JSON.stringify(sqliteFuncArgsList), }) - .then(function () {/*This is intentional (SonarQube)*/ }) + .then(function () { + /*This is intentional (SonarQube)*/ + }) .catch(function (error) { setLoaderText(''); Notify.alert( @@ -942,5 +927,7 @@ DebuggerArgumentComponent.propTypes = { isEdbProc: PropTypes.bool, transId: PropTypes.string, closeModal: PropTypes.func, + pgTreeInfo: PropTypes.object, + pgData: PropTypes.object, }; diff --git a/web/pgadmin/tools/debugger/static/js/components/DebuggerComponent.jsx b/web/pgadmin/tools/debugger/static/js/components/DebuggerComponent.jsx index acef3964d..879758893 100644 --- a/web/pgadmin/tools/debugger/static/js/components/DebuggerComponent.jsx +++ b/web/pgadmin/tools/debugger/static/js/components/DebuggerComponent.jsx @@ -31,6 +31,7 @@ import { ToolBar } from './ToolBar'; import { Stack } from './Stack'; import { Results } from './Results'; import { LocalVariablesAndParams } from './LocalVariablesAndParams'; +import DebuggerArgumentComponent from './DebuggerArgumentComponent'; export const DebuggerContext = React.createContext(); export const DebuggerEventsContext = React.createContext(); @@ -524,7 +525,7 @@ export default function DebuggerComponent({ pgAdmin, selectedNodeInfo, panel, ev // Restarting debugging in the same transaction do not work // We will give same behaviour as pgAdmin3 and disable all buttons - enableToolbarButtons(MENUS.CONTINUE); + disableToolbarButtons(); // Set the Alertify message to inform the user that execution // is completed. @@ -571,7 +572,26 @@ export default function DebuggerComponent({ pgAdmin, selectedNodeInfo, panel, ev listener. */ if (res.data.data.result.require_input) { - params.funcArgsInstance.show(res.data.data.result, restart_dbg); + let t = pgAdmin.Browser.tree, + i = t.selected(), + d = i ? t.itemData(i) : undefined; + + let treeInfo = t.getTreeNodeHierarchy(i); + + if (d) { + let isEdbProc = d._type == 'edbproc'; + modal.showModal(gettext('Debugger'), (closeModal) => { + return ; + }, { isFullScreen: false, isResizeable: true, showFullScreen: true, isFullWidth: true, dialogWidth: pgAdmin.Browser.stdW.md, dialogHeight: pgAdmin.Browser.stdH.md }); + } } else { // Debugging of void function is started again so we need to start // the listener again @@ -612,7 +632,7 @@ export default function DebuggerComponent({ pgAdmin, selectedNodeInfo, panel, ev // If debugging is stopped by user then do not enable // continue/restart button if (!params.directDebugger.is_user_aborted_debugging) { - enableToolbarButtons(MENUS.CONTINUE); + enableToolbarButtons(); params.directDebugger.is_user_aborted_debugging = false; } @@ -620,7 +640,7 @@ export default function DebuggerComponent({ pgAdmin, selectedNodeInfo, panel, ev params.directDebugger.is_polling_required = false; }; - const updateResultAnsMessages = (res) => { + const updateResultAndMessages = (res) => { if (res.data.data.result != null) { setActiveLine(-1); // Call function to update results information and set result panel focus @@ -640,6 +660,7 @@ export default function DebuggerComponent({ pgAdmin, selectedNodeInfo, panel, ev // "Continue/Start" button because user can still // start the same execution again. disableToolbarButtons(); + enableToolbarButtons(MENUS.START); // Stop further pooling params.directDebugger.is_polling_required = false; @@ -706,11 +727,12 @@ export default function DebuggerComponent({ pgAdmin, selectedNodeInfo, panel, ev // "Continue/Start" button because user can still // start the same execution again. disableToolbarButtons(); + enableToolbarButtons(MENUS.START); // Stop further polling params.directDebugger.is_polling_required = false; } else { - updateResultAnsMessages(res); + updateResultAndMessages(res); } } else if (res.data.data.status === 'Busy') { // If status is Busy then poll the result by recursive call to diff --git a/web/pgadmin/tools/debugger/static/js/components/ToolBar.jsx b/web/pgadmin/tools/debugger/static/js/components/ToolBar.jsx index 6718a0541..caca9e399 100644 --- a/web/pgadmin/tools/debugger/static/js/components/ToolBar.jsx +++ b/web/pgadmin/tools/debugger/static/js/components/ToolBar.jsx @@ -25,7 +25,7 @@ import url_for from 'sources/url_for'; import { PgButtonGroup, PgIconButton } from '../../../../../static/js/components/Buttons'; import { DebuggerContext, DebuggerEventsContext } from './DebuggerComponent'; -import { DEBUGGER_EVENTS } from '../DebuggerConstants'; +import { DEBUGGER_EVENTS, MENUS } from '../DebuggerConstants'; const useStyles = makeStyles((theme) => ({ root: { @@ -45,6 +45,8 @@ export function ToolBar() { const eventBus = useContext(DebuggerEventsContext); let preferences = debuggerCtx.preferences.debugger; + // JS not allowing to use constants as key hence unable to use MENUS constants, + // If required any changes in key update MENUS constans as well form DebuggerConstans file. const [buttonsDisabled, setButtonsDisabled] = useState({ 'stop': true, 'clear-all-breakpoints': true, @@ -94,21 +96,21 @@ export function ToolBar() { useEffect(() => { eventBus.registerListener(DEBUGGER_EVENTS.DISABLE_MENU, () => { - setDisableButton('start', true); - setDisableButton('step-into', true); - setDisableButton('step-over', true); - setDisableButton('clear-all-breakpoints', true); - setDisableButton('toggle-breakpoint', true); - setDisableButton('stop', true); + setDisableButton(MENUS.START, true); + setDisableButton(MENUS.STEPINTO, true); + setDisableButton(MENUS.STEPOVER, true); + setDisableButton(MENUS.CLEAR_ALL_BREAKPOINT, true); + setDisableButton(MENUS.TOGGLE_BREAKPOINT, true); + setDisableButton(MENUS.STOP, true); }); eventBus.registerListener(DEBUGGER_EVENTS.ENABLE_MENU, () => { - setDisableButton('start', false); - setDisableButton('step-into', false); - setDisableButton('step-over', false); - setDisableButton('clear-all-breakpoints', false); - setDisableButton('toggle-breakpoint', false); - setDisableButton('stop', false); + setDisableButton(MENUS.START, false); + setDisableButton(MENUS.STEPINTO, false); + setDisableButton(MENUS.STEPOVER, false); + setDisableButton(MENUS.CLEAR_ALL_BREAKPOINT, false); + setDisableButton(MENUS.TOGGLE_BREAKPOINT, false); + setDisableButton(MENUS.STOP, false); }); eventBus.registerListener(DEBUGGER_EVENTS.ENABLE_SPECIFIC_MENU, (key) => { @@ -120,21 +122,21 @@ export function ToolBar() { return ( - } onClick={() => { stepInTODebugger(); }} + } onClick={() => { stepInTODebugger(); }} accesskey={shortcut_key(preferences?.btn_step_into)} /> - } onClick={() => { stepOverDebugger(); }} + } onClick={() => { stepOverDebugger(); }} accesskey={shortcut_key(preferences?.btn_step_over)} /> - } onClick={() => { continueDebugger(); }} + } onClick={() => { continueDebugger(); }} accesskey={shortcut_key(preferences?.btn_start)} /> - } + } accesskey={shortcut_key(preferences?.btn_toggle_breakpoint)} onClick={() => { toggleBreakpoint(); }} /> - } + } accesskey={shortcut_key(preferences?.btn_clear_breakpoints)} onClick={() => { clearAllBreakpoint(); }} /> - } disabled={buttonsDisabled['stop']} onClick={() => { stop(); }} + } disabled={buttonsDisabled[MENUS.STOP]} onClick={() => { stop(); }} accesskey={shortcut_key(preferences?.btn_stop)} /> diff --git a/web/pgadmin/tools/debugger/static/js/debugger_ui.js b/web/pgadmin/tools/debugger/static/js/debugger_ui.js index 5ad628de0..9ac0a9ca0 100644 --- a/web/pgadmin/tools/debugger/static/js/debugger_ui.js +++ b/web/pgadmin/tools/debugger/static/js/debugger_ui.js @@ -18,9 +18,17 @@ import DebuggerArgumentComponent from './components/DebuggerArgumentComponent'; export default class FunctionArguments { show(debugInfo, restartDebug, isEdbProc, transId) { + var t = pgAdmin.Browser.tree, + i = t.selected(), + d = i ? t.itemData(i) : undefined; + + if (!d) + return; + + let treeInfo = t.getTreeNodeHierarchy(i); // Render Debugger argument component Notify.showModal(gettext('Debugger'), (closeModal) => { - return ; + return ; }, { isFullScreen: false, isResizeable: true, showFullScreen: true, isFullWidth: true, dialogWidth: pgAdmin.Browser.stdW.md, dialogHeight: pgAdmin.Browser.stdH.md }); } }