diff --git a/web/pgadmin/browser/register_browser_preferences.py b/web/pgadmin/browser/register_browser_preferences.py
index 86eae07b1..cfd9bca1a 100644
--- a/web/pgadmin/browser/register_browser_preferences.py
+++ b/web/pgadmin/browser/register_browser_preferences.py
@@ -133,6 +133,7 @@ def register_browser_preferences(self):
self.table_row_count_threshold = self.preference.register(
'processes', 'process_retain_days',
gettext("Process details/logs retention days"), 'integer', 5,
+ min_val=1,
category_label=gettext('Processes'),
help_str=gettext(
'After this many days, the process info and logs '
diff --git a/web/pgadmin/misc/bgprocess/processes.py b/web/pgadmin/misc/bgprocess/processes.py
index 7d8acd9df..81dfcc9f2 100644
--- a/web/pgadmin/misc/bgprocess/processes.py
+++ b/web/pgadmin/misc/bgprocess/processes.py
@@ -545,7 +545,8 @@ class BatchProcess(object):
cloud_instance['instance']['status'] = True
cloud_instance['instance']['pid'] = _pid
return update_server(cloud_instance)
- elif err_completed and _process.exit_code > 0:
+ elif err_completed and _process.exit_code is not None and \
+ _process.exit_code > 0:
cloud_instance = {'instance': {}}
cloud_instance['instance']['sid'] = _process.server_id
cloud_instance['instance']['status'] = False
diff --git a/web/pgadmin/misc/bgprocess/static/js/BgProcessManager.js b/web/pgadmin/misc/bgprocess/static/js/BgProcessManager.js
index 13a4ef9c2..fabaf6fa5 100644
--- a/web/pgadmin/misc/bgprocess/static/js/BgProcessManager.js
+++ b/web/pgadmin/misc/bgprocess/static/js/BgProcessManager.js
@@ -140,7 +140,7 @@ export default class BgProcessManager {
stopProcess(jobId) {
this.procList.find((p)=>p.id == jobId).process_state = BgProcessManagerProcessState.PROCESS_TERMINATING;
this._eventManager.fireEvent(BgProcessManagerEvents.LIST_UPDATED);
- this.api.put(url_for('bgprocess.stop_process', {
+ return this.api.put(url_for('bgprocess.stop_process', {
pid: jobId,
}))
.then(()=>{
diff --git a/web/pgadmin/misc/bgprocess/static/js/BgProcessNotify.jsx b/web/pgadmin/misc/bgprocess/static/js/BgProcessNotify.jsx
index 368ed67a0..6d72b302d 100644
--- a/web/pgadmin/misc/bgprocess/static/js/BgProcessNotify.jsx
+++ b/web/pgadmin/misc/bgprocess/static/js/BgProcessNotify.jsx
@@ -56,7 +56,10 @@ function ProcessNotifyMessage({title, desc, onClose, onViewProcess, success=true
{desc}
- } onClick={onViewProcess}>View Processes
+ } onClick={()=>{
+ onViewProcess();
+ onClose();
+ }}>View Processes
diff --git a/web/pgadmin/misc/bgprocess/static/js/ProcessDetails.jsx b/web/pgadmin/misc/bgprocess/static/js/ProcessDetails.jsx
index 6e582a89f..0b38811da 100644
--- a/web/pgadmin/misc/bgprocess/static/js/ProcessDetails.jsx
+++ b/web/pgadmin/misc/bgprocess/static/js/ProcessDetails.jsx
@@ -86,15 +86,23 @@ export default function ProcessDetails({data}) {
const [[outPos, errPos], setOutErrPos] = useState([0, 0]);
const [exitCode, setExitCode] = useState(data.exit_code);
const [timeTaken, setTimeTaken] = useState(data.execution_time);
+ const [stopping, setStopping] = useState(false);
let notifyType = MESSAGE_TYPE.INFO;
let notifyText = gettext('Not started');
- const process_state = pgAdmin.Browser.BgProcessManager.evaluateProcessState({
+ let process_state = pgAdmin.Browser.BgProcessManager.evaluateProcessState({
...data,
exit_code: exitCode,
});
+ if(process_state == BgProcessManagerProcessState.PROCESS_STARTED && stopping) {
+ process_state = BgProcessManagerProcessState.PROCESS_TERMINATING;
+ }
+ if(process_state == BgProcessManagerProcessState.PROCESS_FAILED && stopping) {
+ process_state = BgProcessManagerProcessState.PROCESS_TERMINATED;
+ }
+
if(process_state == BgProcessManagerProcessState.PROCESS_STARTED) {
notifyText = gettext('Running...');
} else if(process_state == BgProcessManagerProcessState.PROCESS_FINISHED) {
@@ -133,6 +141,11 @@ export default function ProcessDetails({data}) {
}, completed ? -1 : 1000);
+ const onStopProcess = ()=>{
+ setStopping(true);
+ pgAdmin.Browser.BgProcessManager.stopProcess(data.id);
+ };
+
const errRe = new RegExp(': (' + gettext('error') + '|' + gettext('fatal') + '):', 'i');
return (
@@ -153,7 +166,10 @@ export default function ProcessDetails({data}) {
pgAdmin.Tools.FileManager.openStorageManager(data.current_storage_dir);
}} style={{marginRight: '4px'}} />}
} className={classes.terminateBtn}>Stop Process
+ startIcon={} className={classes.terminateBtn} onClick={onStopProcess}>
+ Stop Process
+
+
{logs == null && {gettext('Loading process logs...')}}
diff --git a/web/pgadmin/misc/bgprocess/static/js/Processes.jsx b/web/pgadmin/misc/bgprocess/static/js/Processes.jsx
index 65545ab4c..860ace469 100644
--- a/web/pgadmin/misc/bgprocess/static/js/Processes.jsx
+++ b/web/pgadmin/misc/bgprocess/static/js/Processes.jsx
@@ -218,7 +218,7 @@ export default function Processes() {
},
},
{
- Header: gettext('Time Taken'),
+ Header: gettext('Time Taken (sec)'),
accessor: 'execution_time',
sortable: true,
resizable: true,
diff --git a/web/pgadmin/static/js/SchemaView/FormView.jsx b/web/pgadmin/static/js/SchemaView/FormView.jsx
index bf9ece18a..f03be592d 100644
--- a/web/pgadmin/static/js/SchemaView/FormView.jsx
+++ b/web/pgadmin/static/js/SchemaView/FormView.jsx
@@ -40,8 +40,8 @@ const useStyles = makeStyles((theme)=>({
height: 'unset',
},
errorMargin: {
- /* Error footer margin */
- marginBottom: '36px',
+ /* Error footer space */
+ paddingBottom: '36px',
},
sqlTabInput: {
border: 0,
@@ -382,13 +382,13 @@ export default function FormView({
{Object.keys(finalTabs).map((tabName, i)=>{
- let contentClassName = null;
+ let contentClassName = [stateUtils.formErr.message ? classes.errorMargin : null];
if(fullTabs.indexOf(tabName) == -1) {
- contentClassName = clsx(classes.nestedControl, stateUtils.formErr.message ? classes.errorMargin : null);
+ contentClassName.push(classes.nestedControl);
}
return (
+ className={clsx(contentClassName)}>
{finalTabs[tabName]}
);