mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Enable the start debugging button once execution is completed. Fixes #7517
This commit is contained in:
committed by
Akshay Joshi
parent
7d0ed90796
commit
9c745db413
@@ -18,3 +18,5 @@ Housekeeping
|
||||
|
||||
Bug fixes
|
||||
*********
|
||||
|
||||
| `Issue #7517 <https://redmine.postgresql.org/issues/7517>`_ - Enable the start debugging button once execution is completed.
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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'
|
||||
};
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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 <DebuggerArgumentComponent
|
||||
closeModal={closeModal}
|
||||
debuggerInfo={res.data.data.result}
|
||||
restartDebug={restart_dbg}
|
||||
isEdbProc={isEdbProc}
|
||||
transId={params.transId.toString()}
|
||||
pgData={d}
|
||||
pgTreeInfo={treeInfo}
|
||||
></DebuggerArgumentComponent>;
|
||||
}, { 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
|
||||
|
||||
@@ -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 (
|
||||
<Box className={classes.root}>
|
||||
<PgButtonGroup size="small">
|
||||
<PgIconButton data-test='step-in' title={gettext('Step into')} disabled={buttonsDisabled['step-into']} icon={<FormatIndentIncreaseIcon />} onClick={() => { stepInTODebugger(); }}
|
||||
<PgIconButton data-test='step-in' title={gettext('Step into')} disabled={buttonsDisabled[MENUS.STEPINTO]} icon={<FormatIndentIncreaseIcon />} onClick={() => { stepInTODebugger(); }}
|
||||
accesskey={shortcut_key(preferences?.btn_step_into)} />
|
||||
<PgIconButton data-test='step-over' title={gettext('Step over')} disabled={buttonsDisabled['step-over']} icon={<FormatIndentDecreaseIcon />} onClick={() => { stepOverDebugger(); }}
|
||||
<PgIconButton data-test='step-over' title={gettext('Step over')} disabled={buttonsDisabled[MENUS.STEPOVER]} icon={<FormatIndentDecreaseIcon />} onClick={() => { stepOverDebugger(); }}
|
||||
accesskey={shortcut_key(preferences?.btn_step_over)} />
|
||||
<PgIconButton data-test='debugger-contiue' title={gettext('Continue/Start')} disabled={buttonsDisabled['start']} icon={<PlayCircleFilledWhiteIcon />} onClick={() => { continueDebugger(); }}
|
||||
<PgIconButton data-test='debugger-contiue' title={gettext('Continue/Start')} disabled={buttonsDisabled[MENUS.START]} icon={<PlayCircleFilledWhiteIcon />} onClick={() => { continueDebugger(); }}
|
||||
accesskey={shortcut_key(preferences?.btn_start)} />
|
||||
</PgButtonGroup>
|
||||
<PgButtonGroup size="small">
|
||||
<PgIconButton data-test='toggle-breakpoint' title={gettext('Toggle breakpoint')} disabled={buttonsDisabled['toggle-breakpoint']} icon={<FiberManualRecordIcon style={{height: '2rem'}} />}
|
||||
<PgIconButton data-test='toggle-breakpoint' title={gettext('Toggle breakpoint')} disabled={buttonsDisabled[MENUS.TOGGLE_BREAKPOINT]} icon={<FiberManualRecordIcon style={{height: '2rem'}} />}
|
||||
accesskey={shortcut_key(preferences?.btn_toggle_breakpoint)} onClick={() => { toggleBreakpoint(); }} />
|
||||
<PgIconButton data-test='clear-breakpoint' title={gettext('Clear all breakpoints')} disabled={buttonsDisabled['clear-all-breakpoints']} icon={<NotInterestedIcon />}
|
||||
<PgIconButton data-test='clear-breakpoint' title={gettext('Clear all breakpoints')} disabled={buttonsDisabled[MENUS.CLEAR_ALL_BREAKPOINT]} icon={<NotInterestedIcon />}
|
||||
accesskey={shortcut_key(preferences?.btn_clear_breakpoints)} onClick={() => { clearAllBreakpoint(); }} />
|
||||
</PgButtonGroup>
|
||||
<PgButtonGroup size="small">
|
||||
<PgIconButton data-test='stop-debugger' title={gettext('Stop')} icon={<StopIcon style={{height: '2rem'}} />} disabled={buttonsDisabled['stop']} onClick={() => { stop(); }}
|
||||
<PgIconButton data-test='stop-debugger' title={gettext('Stop')} icon={<StopIcon style={{height: '2rem'}} />} disabled={buttonsDisabled[MENUS.STOP]} onClick={() => { stop(); }}
|
||||
accesskey={shortcut_key(preferences?.btn_stop)} />
|
||||
</PgButtonGroup>
|
||||
<PgButtonGroup size="small">
|
||||
|
||||
@@ -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 <DebuggerArgumentComponent closeModal={closeModal} debuggerInfo={debugInfo} restartDebug={restartDebug} isEdbProc={isEdbProc} transId={transId}></DebuggerArgumentComponent>;
|
||||
return <DebuggerArgumentComponent closeModal={closeModal} debuggerInfo={debugInfo} restartDebug={restartDebug} isEdbProc={isEdbProc} transId={transId} pgTreeInfo={treeInfo} pgData={d}></DebuggerArgumentComponent>;
|
||||
}, { isFullScreen: false, isResizeable: true, showFullScreen: true, isFullWidth: true, dialogWidth: pgAdmin.Browser.stdW.md, dialogHeight: pgAdmin.Browser.stdH.md });
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user