codekingpro/portable-devtools
114k
1/////////////////////////////////////////////////////////////2//3// pgAdmin 4 - PostgreSQL Tools4//5// Copyright (C) 2013 - 2024, The pgAdmin Development Team6// This software is released under the PostgreSQL Licence7//8//////////////////////////////////////////////////////////////9 10import PropTypes from 'prop-types';11 12import React, { useEffect, useRef } from 'react';13 14import DeleteSweepIcon from '@mui/icons-material/DeleteSweep';15import { Box } from '@mui/material';16import { makeStyles } from '@mui/styles';17import BugReportRoundedIcon from '@mui/icons-material/BugReportRounded';18import CloseSharpIcon from '@mui/icons-material/CloseSharp';19 20import url_for from 'sources/url_for';21import gettext from 'sources/gettext';22import pgAdmin from 'sources/pgadmin';23import Loader from 'sources/components/Loader';24 25import SchemaView from '../../../../../static/js/SchemaView';26import getApiInstance, { parseApiError } from '../../../../../static/js/api_instance';27import { DefaultButton, PrimaryButton } from '../../../../../static/js/components/Buttons';28import { getAppropriateLabel, getDebuggerTitle } from '../debugger_utils';29import { DebuggerArgumentSchema } from './DebuggerArgs.ui';30import { DEBUGGER_ARGS } from '../DebuggerConstants';31import { BROWSER_PANELS } from '../../../../../browser/static/js/constants';32import usePreferences from '../../../../../preferences/static/js/store';33 34 35const useStyles = makeStyles((theme) =>36 ({37 root: {38 display: 'flex',39 flexDirection: 'column',40 flexGrow: 1,41 height: '100%',42 backgroundColor: theme.palette.background.default,43 overflow: 'hidden',44 },45 body: {46 display: 'flex',47 flexDirection: 'column',48 height: '100%',49 minHeight: 0,50 },51 actionBtn: {52 alignItems: 'flex-start',53 },54 buttonMargin: {55 marginLeft: '0.5em'56 },57 debugBtn: {58 fontSize: '1.12rem !important',59 },60 footer: {61 borderTop: `1px solid ${theme.otherVars.inputBorderColor} !important`,62 padding: '0.5rem',63 display: 'flex',64 width: '100%',65 background: theme.otherVars.headerBg,66 }67 }),68);69 70 71export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug, isEdbProc, transId, pgTreeInfo, pgData, ...props }) {72 const classes = useStyles();73 const debuggerArgsSchema = useRef(new DebuggerArgumentSchema());74 const api = getApiInstance();75 const debuggerArgsData = useRef([]);76 const [loadArgs, setLoadArgs] = React.useState(0);77 const [isDisableDebug, setIsDisableDebug] = React.useState(true);78 const [loaderText, setLoaderText] = React.useState('');79 const debuggerFinalArgs = useRef([]);80 const InputArgIds = useRef([]);81 const browserPreferences = usePreferences().getPreferencesForModule('browser');82 83 function getURL() {84 let _Url = null;85 86 if (restartDebug == 0) {87 88 if (!pgData)89 return;90 91 let treeInfo = pgTreeInfo;92 93 if (pgData._type == 'function') {94 // Get the existing function parameters available from sqlite database95 _Url = url_for('debugger.get_arguments', {96 'sid': treeInfo.server._id,97 'did': treeInfo.database._id,98 'scid': treeInfo.schema._id,99 'func_id': treeInfo.function._id,100 });101 } else if (pgData._type == 'procedure') {102 // Get the existing function parameters available from sqlite database103 _Url = url_for('debugger.get_arguments', {104 'sid': treeInfo.server._id,105 'did': treeInfo.database._id,106 'scid': treeInfo.schema._id,107 'func_id': treeInfo.procedure._id,108 });109 } else if (pgData._type == 'edbfunc') {110 // Get the existing function parameters available from sqlite database111 _Url = url_for('debugger.get_arguments', {112 'sid': treeInfo.server._id,113 'did': treeInfo.database._id,114 'scid': treeInfo.schema._id,115 'func_id': treeInfo.edbfunc._id,116 });117 } else if (pgData._type == 'edbproc') {118 // Get the existing function parameters available from sqlite database119 _Url = url_for('debugger.get_arguments', {120 'sid': treeInfo.server._id,121 'did': treeInfo.database._id,122 'scid': treeInfo.schema._id,123 'func_id': treeInfo.edbproc._id,124 });125 }126 } else {127 // Get the existing function parameters available from sqlite database128 _Url = url_for('debugger.get_arguments', {129 'sid': debuggerInfo.server_id,130 'did': debuggerInfo.database_id,131 'scid': debuggerInfo.schema_id,132 'func_id': debuggerInfo.function_id,133 });134 }135 return _Url;136 }137 138 function setArgs(res) {139 let funcArgsData = [];140 if (res.data.data.args_count != 0) {141 setIsDisableDebug(false);142 for (const i of res.data.data.result) {143 // Below will format the data to be stored in sqlite database144 funcArgsData.push({145 'arg_id': i['arg_id'],146 'is_null': i['is_null'],147 'is_expression': i['is_expression'],148 'use_default': i['use_default'],149 'value': i['value'],150 });151 }152 }153 return funcArgsData;154 }155 156 function checkModesAndTypes() {157 // Check modes and type in the arguments.158 if (debuggerInfo['proargmodes'] != null) {159 let argmodes = debuggerInfo['proargmodes'].split(',');160 argmodes.forEach((NULL, indx) => {161 if (argmodes[indx] == 'i' || argmodes[indx] == 'b' ||162 (isEdbProc && argmodes[indx] == 'o')) {163 InputArgIds.current.push(indx);164 }165 });166 } else {167 let argtypes = debuggerInfo['proargtypenames'].split(',');168 argtypes.forEach((NULL, indx) => {169 InputArgIds.current.push(indx);170 });171 }172 173 // Get argument types174 let argType = debuggerInfo['proargtypenames'].split(',');175 let argMode, defaultArgs, argCnt;176 177 if (debuggerInfo['proargmodes'] != null) {178 argMode = debuggerInfo['proargmodes'].split(',');179 }180 181 if (debuggerInfo['pronargdefaults']) {182 let defaultArgsCount = debuggerInfo['pronargdefaults'];183 defaultArgs = debuggerInfo['proargdefaults'].split(',');184 argCnt = defaultArgsCount;185 }186 187 return [argType, argMode, argCnt, defaultArgs];188 }189 190 function setDefaultValues(defValList, argCnt, argName, argMode, defaultArgs) {191 for (let j = (argName.length - 1); j >= 0; j--) {192 if (debuggerInfo['proargmodes'] != null) {193 if (argMode && (argMode[j] == 'i' || argMode[j] == 'b' ||194 (isEdbProc && argMode[j] == 'o'))) {195 defValList[j] = DEBUGGER_ARGS.NO_DEFAULT;196 if (argCnt) {197 argCnt = argCnt - 1;198 defValList[j] = defaultArgs[argCnt];199 }200 }201 } else if (argCnt) {202 argCnt = argCnt - 1;203 defValList[j] = defaultArgs[argCnt];204 } else {205 defValList[j] = DEBUGGER_ARGS.NO_DEFAULT;206 }207 }208 }209 210 function addArg(argtype, defvalList, argname, useDefValue) {211 let myObj = {};212 if (defvalList != DEBUGGER_ARGS.NO_DEFAULT) {213 useDefValue = true;214 }215 myObj = {216 'name': argname,217 'type': argtype,218 'use_default': useDefValue,219 'default_value': defvalList,220 'disable_use_default': defvalList == DEBUGGER_ARGS.NO_DEFAULT221 };222 223 return myObj;224 }225 226 function getArgsList(argType, argMode, defValList, argName, useDefValue) {227 let myObj = [];228 if (argType.length != 0) {229 for (let i = 0; i < argType.length; i++) {230 if (debuggerInfo['proargmodes'] != null) {231 if (argMode && (argMode[i] == 'i' || argMode[i] == 'b' ||232 (isEdbProc && argMode[i] == 'o'))) {233 useDefValue = false;234 myObj.push(addArg(argType[i], defValList[i], argName[i], useDefValue));235 }236 } else {237 useDefValue = false;238 myObj.push(addArg(argType[i], defValList[i], argName[i], useDefValue));239 }240 }241 }242 return myObj;243 }244 245 function getFormattedArgsValues(argType, index, argData) {246 let values = [];247 if (argType[index].indexOf('[]') != -1 && argData['value'].length > 0) {248 values = `{${argData['value']}}`;249 } else {250 values = argData['value'];251 }252 253 return values;254 }255 256 function setFuncObj(funcArgsData, argMode, argType, argName, defValList, isUnnamedParam = false) {257 let index, values, funcObj = [];258 for (const argData of funcArgsData) {259 index = argData['arg_id'];260 if (debuggerInfo['proargmodes'] != null &&261 (argMode && argMode[index] == 'o' && !isEdbProc) && !isUnnamedParam) {262 continue;263 }264 // Get formated values for argument.265 values = getFormattedArgsValues(argType, index, argData);266 267 funcObj.push({268 'name': argName[index],269 'type': argType[index],270 'is_null': argData['is_null'],271 'expr': argData['is_expression'],272 'value': values,273 'use_default': argData['use_default'],274 'default_value': defValList[index],275 'disable_use_default': isUnnamedParam ? defValList[index] == DEBUGGER_ARGS.NO_DEFAULT_VALUE : defValList[index] == DEBUGGER_ARGS.NO_DEFAULT,276 });277 }278 279 return funcObj;280 }281 282 function setUnnamedParamNonDefVal(argType, defValList, myargname) {283 let myObj = [];284 for (let i = 0; i < argType.length; i++) {285 myObj.push({286 'name': myargname[i],287 'type': argType[i],288 'use_default': false,289 'default_value': DEBUGGER_ARGS.NO_DEFAULT_VALUE,290 'disable_use_default': true291 });292 defValList[i] = DEBUGGER_ARGS.NO_DEFAULT_VALUE;293 }294 return myObj;295 }296 297 function setUnnamedParamDefVal(myargname, argCnt, defValList, defaultArgs) {298 for (let j = (myargname.length - 1); j >= 0; j--) {299 if (argCnt) {300 argCnt = argCnt - 1;301 defValList[j] = defaultArgs[argCnt];302 } else {303 defValList[j] = DEBUGGER_ARGS.NO_DEFAULT_VALUE;304 }305 }306 307 }308 309 function checkIsDefault(defValList) {310 let useDefValue = false;311 if (defValList != DEBUGGER_ARGS.NO_DEFAULT_VALUE) {312 useDefValue = true;313 }314 315 return useDefValue;316 }317 function setUnnamedArgs(argType, argMode, useDefValue, defValList, myargname) {318 let myObj = [];319 for (let i = 0; i < argType.length; i++) {320 let useDefValue = checkIsDefault(defValList[i]);321 if (debuggerInfo['proargmodes'] == null) {322 myObj.push({323 'name': myargname[i],324 'type': argType[i],325 'use_default': useDefValue,326 'default_value': defValList[i],327 'disable_use_default': defValList[i] == DEBUGGER_ARGS.NO_DEFAULT_VALUE,328 });329 } else if (argMode && (argMode[i] == 'i' || argMode[i] == 'b' ||330 (isEdbProc && argMode[i] == 'o'))) {331 myObj.push({332 'name': myargname[i],333 'type': argType[i],334 'use_default': useDefValue,335 'default_value': defValList[i],336 'disable_use_default': defValList[i] == DEBUGGER_ARGS.NO_DEFAULT_VALUE,337 });338 }339 }340 return myObj;341 }342 343 function generateArgsNames(argType) {344 let myargname = [];345 for (let i = 0; i < argType.length; i++) {346 myargname[i] = 'dbgparam' + (i + 1);347 }348 349 return myargname;350 }351 352 function setDebuggerArgs(funcArgsData, funcObj, myObj) {353 // Check if the arguments already available in the sqlite database354 // then we should use the existing arguments355 let initVal = { 'aregsCollection': [] };356 if (funcArgsData.length == 0) {357 initVal = { 'aregsCollection': myObj };358 debuggerArgsData.current = initVal;359 } else {360 initVal = { 'aregsCollection': funcObj };361 debuggerArgsData.current = initVal;362 }363 }364 365 function getDebuggerArgsSchema() {366 // Variables to store the data sent from sqlite database367 let funcArgsData = [];368 369 // As we are not getting Browser.tree when we debug again370 // so tree info will be updated from the server data371 let baseURL = getURL();372 373 api({374 url: baseURL,375 method: 'GET',376 })377 .then(function (res) {378 funcArgsData = setArgs(res);379 let argName;380 381 let defValList = [];382 let myObj = [];383 let funcObj = [];384 385 let [argType, argMode, argCnt, defaultArgs] = checkModesAndTypes();386 387 let useDefValue;388 389 if (debuggerInfo['proargnames'] != null) {390 argName = debuggerInfo['proargnames'].split(',');391 392 // It will assign default values to "Default value" column393 setDefaultValues(defValList, argCnt, argName, argMode, defaultArgs);394 // It wil check and add args in myObj list.395 myObj = getArgsList(argType, argMode, defValList, argName, useDefValue);396 397 // Need to update the funcObj variable from sqlite database if available398 if (funcArgsData.length != 0) {399 funcObj = setFuncObj(funcArgsData, argMode, argType, argName, defValList);400 }401 }402 else {403 /* Generate the name parameter if function do not have arguments name404 like dbgparam1, dbgparam2 etc. */405 let myargname = generateArgsNames(argType);406 407 // If there is no default arguments408 if (!debuggerInfo['pronargdefaults']) {409 myObj = setUnnamedParamNonDefVal(argType, defValList, myargname);410 } else {411 // If there is default arguments412 //Below logic will assign default values to "Default value" column413 setUnnamedParamDefVal(myargname, argCnt, defValList, defaultArgs);414 415 myObj = setUnnamedArgs(argType, argMode, useDefValue, defValList, myargname);416 }417 418 // Need to update the funcObj variable from sqlite database if available419 if (funcArgsData.length != 0) {420 funcObj = setFuncObj(funcArgsData, argMode, argType, myargname, defValList, true);421 }422 }423 424 setDebuggerArgs(funcArgsData, funcObj, myObj);425 debuggerArgsSchema.current = new DebuggerArgumentSchema();426 setLoadArgs(crypto.getRandomValues(new Uint16Array(1)));427 })428 .catch(() => {429 pgAdmin.Browser.notifier.alert(430 gettext('Debugger Error'),431 gettext('Unable to fetch the arguments from server')432 );433 });434 }435 436 useEffect(() => {437 getDebuggerArgsSchema();438 }, []);439 440 let initData = () => new Promise((resolve, reject) => {441 try {442 resolve(debuggerArgsData.current);443 } catch (error) {444 reject(error);445 }446 });447 448 function clearArgs() {449 setLoaderText('Loading...');450 setLoadArgs(0);451 let base_url = null;452 453 if (restartDebug == 0) {454 if (!pgData)455 return;456 457 let treeInfo = pgTreeInfo;458 459 base_url = url_for('debugger.clear_arguments', {460 'sid': treeInfo.server._id,461 'did': treeInfo.database._id,462 'scid': treeInfo.schema._id,463 'func_id': pgData._id,464 });465 } else {466 base_url = url_for('debugger.clear_arguments', {467 'sid': debuggerInfo.server_id,468 'did': debuggerInfo.database_id,469 'scid': debuggerInfo.schema_id,470 'func_id': debuggerInfo.function_id,471 });472 }473 api({474 url: base_url,475 method: 'POST',476 data: {},477 }).then(function () {478 /* Get updated debugger arguments */479 getDebuggerArgsSchema();480 /* setTimeout required to get updated argruments as 'Clear All' will delete all saved arguments form sqlite db. */481 setTimeout(() => {482 /* Reload the debugger arguments */483 setLoaderText('');484 setLoadArgs(crypto.getRandomValues(new Uint16Array(1)));485 /* Disable debug button */486 setIsDisableDebug(true);487 }, 100);488 }).catch(function (er) {489 setLoaderText('');490 pgAdmin.Browser.notifier.alert(491 gettext('Clear failed'),492 er.responseJSON.errormsg493 );494 });495 }496 497 function setDebuggingArgs(argsList, argSet) {498 if (argsList.length === 0) {499 // Add all parameters500 debuggerArgsData.current.aregsCollection.forEach(arg => {501 if (!argSet.includes(arg.name)) {502 argSet.push(arg.name);503 argsList.push(arg);504 }505 });506 507 // Update values if any change in the args.508 if (debuggerFinalArgs.current) {509 debuggerFinalArgs.current.changed.forEach(changedArg => {510 argsList.forEach((el, _index) => {511 if (changedArg.name == el.name) {512 argsList[_index] = changedArg;513 }514 });515 });516 }517 518 }519 }520 521 function checkArgsVal(arg, argsValueList) {522 // Check if value is set to NULL then we should ignore the value field523 if (arg.is_null) {524 argsValueList.push({525 'name': arg.name,526 'type': arg.type,527 'value': 'NULL',528 });529 } else if (arg.use_default) {530 // Check if default value to be used or not531 argsValueList.push({532 'name': arg.name,533 'type': arg.type,534 'value': arg.default_value,535 });536 } else {537 argsValueList.push({538 'name': arg.name,539 'type': arg.type,540 'value': arg.value,541 });542 }543 }544 function getFunctionID(d, treeInfo) {545 let functionId;546 if (d._type == 'function') {547 functionId = treeInfo.function._id;548 } else if (d._type == 'procedure') {549 functionId = treeInfo.procedure._id;550 } else if (d._type == 'edbfunc') {551 functionId = treeInfo.edbfunc._id;552 } else if (d._type == 'edbproc') {553 functionId = treeInfo.edbproc._id;554 }555 return functionId;556 }557 558 function setSqliteFuncArgs(d, treeInfo, arg, intCount, sqliteFuncArgsList) {559 if (restartDebug == 0) {560 let functionId = getFunctionID(d, treeInfo);561 // Below will format the data to be stored in sqlite database562 sqliteFuncArgsList.push({563 'server_id': treeInfo.server._id,564 'database_id': treeInfo.database._id,565 'schema_id': treeInfo.schema._id,566 'function_id': functionId,567 'arg_id': InputArgIds.current[intCount],568 'is_null': arg.is_null ? 1 : 0,569 'is_expression': arg.expr ? 1 : 0,570 'use_default': arg.use_default ? 1 : 0,571 'value': arg.value,572 'is_array_value': arg?.isArrayType,573 });574 } else {575 // Below will format the data to be stored in sqlite database576 sqliteFuncArgsList.push({577 'server_id': debuggerInfo.server_id,578 'database_id': debuggerInfo.database_id,579 'schema_id': debuggerInfo.schema_id,580 'function_id': debuggerInfo.function_id,581 'arg_id': InputArgIds.current[intCount],582 'is_null': arg.is_null ? 1 : 0,583 'is_expression': arg.expr ? 1 : 0,584 'use_default': arg.use_default ? 1 : 0,585 'value': arg.value,586 'is_array_value': arg?.isArrayType,587 });588 }589 590 return sqliteFuncArgsList;591 }592 593 function checkTypeAndGetUrl(d, treeInfo) {594 let baseUrl;595 if (d?._type == 'function') {596 baseUrl = url_for('debugger.initialize_target_for_function', {597 'debug_type': 'direct',598 'trans_id': transId,599 'sid': treeInfo.server._id,600 'did': treeInfo.database._id,601 'scid': treeInfo.schema._id,602 'func_id': treeInfo.function._id,603 });604 } else if (d?._type == 'procedure') {605 baseUrl = url_for('debugger.initialize_target_for_function', {606 'debug_type': 'direct',607 'trans_id': transId,608 'sid': treeInfo.server._id,609 'did': treeInfo.database._id,610 'scid': treeInfo.schema._id,611 'func_id': treeInfo.procedure._id,612 });613 } else if (d?._type == 'edbfunc') {614 baseUrl = url_for('debugger.initialize_target_for_function', {615 'debug_type': 'direct',616 'trans_id': transId,617 'sid': treeInfo.server._id,618 'did': treeInfo.database._id,619 'scid': treeInfo.schema._id,620 'func_id': treeInfo.edbfunc._id,621 });622 } else if (d?._type == 'edbproc') {623 baseUrl = url_for('debugger.initialize_target_for_function', {624 'debug_type': 'direct',625 'trans_id': transId,626 'sid': treeInfo.server._id,627 'did': treeInfo.database._id,628 'scid': treeInfo.schema._id,629 'func_id': treeInfo.edbproc._id,630 });631 }632 633 return baseUrl;634 }635 636 function getSetArgsUrl(d, treeInfo) {637 let baseUrl;638 if (d._type == 'function') {639 baseUrl = url_for('debugger.set_arguments', {640 'sid': treeInfo.server._id,641 'did': treeInfo.database._id,642 'scid': treeInfo.schema._id,643 'func_id': treeInfo.function._id,644 });645 } else if (d._type == 'procedure') {646 baseUrl = url_for('debugger.set_arguments', {647 'sid': treeInfo.server._id,648 'did': treeInfo.database._id,649 'scid': treeInfo.schema._id,650 'func_id': treeInfo.procedure._id,651 });652 } else if (d._type == 'edbfunc') {653 // Get the existing function parameters available from sqlite database654 baseUrl = url_for('debugger.set_arguments', {655 'sid': treeInfo.server._id,656 'did': treeInfo.database._id,657 'scid': treeInfo.schema._id,658 'func_id': treeInfo.edbfunc._id,659 });660 } else if (d._type == 'edbproc') {661 // Get the existing function parameters available from sqlite database662 baseUrl = url_for('debugger.set_arguments', {663 'sid': treeInfo.server._id,664 'did': treeInfo.database._id,665 'scid': treeInfo.schema._id,666 'func_id': treeInfo.edbproc._id,667 });668 }669 670 return baseUrl;671 }672 673 function startDebugging() {674 setLoaderText('Starting debugger...');675 try {676 /* Initialize the target once the debug button is clicked and create asynchronous connection677 and unique transaction ID If the debugging is started again then treeInfo is already stored. */678 let treeInfo = pgTreeInfo;679 if (!pgData) return;680 681 let argsValueList = [];682 let sqliteFuncArgsList = [];683 let intCount = 0;684 685 let argsList = [];686 let argSet = [];687 688 setDebuggingArgs(argsList, argSet);689 690 argsList.forEach(arg => {691 checkArgsVal(arg, argsValueList);692 setSqliteFuncArgs(pgData, treeInfo, arg, intCount, sqliteFuncArgsList);693 intCount = intCount + 1;694 });695 696 let baseUrl;697 698 /* If debugging is not started again then we should initialize the target otherwise not */699 if (restartDebug == 0) {700 baseUrl = checkTypeAndGetUrl(pgData, treeInfo);701 702 api({703 url: baseUrl,704 method: 'POST',705 data: JSON.stringify(argsValueList),706 })707 .then(function (res_post) {708 709 let url = url_for(710 'debugger.direct', {711 'trans_id': res_post.data.data.debuggerTransId,712 }713 );714 715 let open_new_tab = browserPreferences.new_browser_tab_open;716 let label = getAppropriateLabel(treeInfo);717 718 pgAdmin.Browser.Events.trigger(719 'pgadmin:tool:show',720 `${BROWSER_PANELS.DEBUGGER_TOOL}_${res_post.data.data.debuggerTransId}`,721 url,722 null,723 {title: getDebuggerTitle(browserPreferences, label, treeInfo.schema.label, treeInfo.database.label, null, pgAdmin.Browser),724 icon: 'fa fa-bug', manualClose: false, renamable: true},725 Boolean(open_new_tab?.includes('debugger'))726 );727 728 let _url = getSetArgsUrl(pgData, treeInfo);729 730 api({731 url: _url,732 method: 'POST',733 data: JSON.stringify(sqliteFuncArgsList),734 })735 .then(function () {/*This is intentional (SonarQube)*/ })736 .catch((error) => {737 setLoaderText('');738 pgAdmin.Browser.notifier.alert(739 gettext('Error occured: '),740 parseApiError(error)741 );742 });743 /* Close the debugger modal dialog */744 props.closeModal();745 setLoaderText('');746 })747 .catch(function (error) {748 setLoaderText('');749 pgAdmin.Browser.notifier.alert(750 gettext('Debugger Target Initialization Error'),751 parseApiError(error)752 );753 });754 755 }756 else {757 // If the debugging is started again then we should only set the758 // arguments and start the listener again759 baseUrl = url_for('debugger.start_listener', {760 'trans_id': transId,761 });762 763 api({764 url: baseUrl,765 method: 'POST',766 data: JSON.stringify(argsValueList),767 })768 .catch(function (error) {769 props.closeModal();770 pgAdmin.Browser.notifier.alert(771 gettext('Debugger Listener Startup Error'),772 parseApiError(error)773 );774 });775 setLoaderText('');776 // Set the new input arguments given by the user during debugging777 let _Url = url_for('debugger.set_arguments', {778 'sid': debuggerInfo.server_id,779 'did': debuggerInfo.database_id,780 'scid': debuggerInfo.schema_id,781 'func_id': debuggerInfo.function_id,782 });783 api({784 url: _Url,785 method: 'POST',786 data: JSON.stringify(sqliteFuncArgsList),787 })788 .then(function () {789 /*This is intentional (SonarQube)*/790 props.closeModal();791 })792 .catch(function (error) {793 setLoaderText('');794 pgAdmin.Browser.notifier.alert(795 gettext('Debugger Listener Startup Set Arguments Error'),796 parseApiError(error)797 );798 });799 }800 } catch (err) {801 setLoaderText('');802 pgAdmin.Browser.notifier.alert(803 gettext('Debugger Error'),804 gettext(err.message)805 );806 }807 808 }809 810 return (811 <Box className={classes.root}>812 <Box className={classes.body}>813 {814 loadArgs > 0 &&815 <>816 <Loader message={loaderText} />817 <SchemaView818 formType={'dialog'}819 getInitData={initData}820 viewHelperProps={{ mode: 'edit' }}821 schema={debuggerArgsSchema.current}822 showFooter={false}823 isTabView={false}824 Notifier={pgAdmin.Browser.notifier}825 onDataChange={(isChanged, changedData) => {826 let isValid = false;827 let skipStep = false;828 if ('_sessData' in debuggerArgsSchema.current) {829 isValid = true;830 debuggerArgsSchema.current._sessData.aregsCollection.forEach((data) => {831 832 if (skipStep) { return; }833 834 if ((data.is_null || data.use_default || data?.value?.toString()?.length > 0) && isValid) {835 isValid = true;836 } else {837 isValid = false;838 skipStep = true;839 }840 841 if (!data.isValid) {842 isValid = false;843 skipStep = true;844 }845 846 });847 }848 setIsDisableDebug(!isValid);849 debuggerFinalArgs.current = changedData.aregsCollection;850 }}851 />852 </>853 }854 </Box>855 <Box className={classes.footer}>856 <Box>857 <DefaultButton className={classes.buttonMargin} onClick={() => { clearArgs(); }} startIcon={<DeleteSweepIcon onClick={() => { clearArgs(); }} />}>858 {gettext('Clear All')}859 </DefaultButton>860 </Box>861 <Box className={classes.actionBtn} marginLeft="auto">862 <DefaultButton className={classes.buttonMargin} onClick={() => { props.closeModal(); }} startIcon={<CloseSharpIcon onClick={() => { props.closeModal(); }} />}>863 {gettext('Cancel')}864 </DefaultButton>865 <PrimaryButton className={classes.buttonMargin} startIcon={<BugReportRoundedIcon className={classes.debugBtn} />}866 disabled={isDisableDebug}867 onClick={() => { startDebugging(); }}>868 {gettext('Debug')}869 </PrimaryButton>870 </Box>871 </Box>872 </Box>873 874 );875}876 877DebuggerArgumentComponent.propTypes = {878 debuggerInfo: PropTypes.object,879 restartDebug: PropTypes.number,880 isEdbProc: PropTypes.bool,881 transId: PropTypes.string,882 closeModal: PropTypes.func,883 pgTreeInfo: PropTypes.object,884 pgData: PropTypes.object,885};886 