Merge branch 'v3-webapp-modal-action-progress' into 'v3'

Modal progress dialog for TaskSubmitter

See merge request openflexure/openflexure-microscope-server!164
This commit is contained in:
Richard Bowman 2024-01-04 01:09:50 +00:00
commit 62957e53e8
3 changed files with 112 additions and 57 deletions

View file

@ -34,11 +34,43 @@
{{ submitLabel }} {{ submitLabel }}
</button> </button>
</div> </div>
<div id="modal-center" ref="statusModal" class="" uk-modal>
<div class="uk-modal-dialog uk-modal-body uk-margin-auto-vertical">
<div id="log-container" ref="logContainer">
<div v-for="(item, index) in log" :key="`log_entry_${index}`">
{{ item.message }}
</div>
</div>
<div id="progress-and-cancel-row">
<div class="stretchy">
<div class="progress uk-margin-small">
<div
v-if="progress"
class="determinate"
:style="barWidthFromProgress"
></div>
<div v-else class="indeterminate"></div>
</div>
</div>
<button
v-if="canTerminate && taskRunning"
type="button"
class="uk-button uk-button-danger not-stretchy"
@click="terminateTask()"
>
Cancel
</button>
</div>
</div>
</div>
</div> </div>
</template> </template>
<script> <script>
import axios from "axios"; import axios from "axios";
import UIkit from "uikit";
export default { export default {
name: "TaskSubmitter", name: "TaskSubmitter",
@ -87,6 +119,11 @@ export default {
type: String, type: String,
required: false, required: false,
default: null default: null
},
modalProgress: {
type: Boolean,
required: false,
default: false
} }
}, },
@ -96,7 +133,8 @@ export default {
taskUrl: null, taskUrl: null,
progress: null, progress: null,
taskStarted: false, taskStarted: false,
taskRunning: false taskRunning: false,
log: []
}; };
}, },
@ -108,7 +146,14 @@ export default {
} }
}, },
created() {}, watch: {
log: function() {
this.$nextTick(function() {
let viewer = this.$refs.logContainer;
viewer.scrollTop = viewer.scrollHeight;
});
}
},
mounted() { mounted() {
// Check for already running tasks // Check for already running tasks
@ -165,7 +210,7 @@ export default {
} }
}, },
startTask: function() { async startTask() {
// Starts a new Action task // Starts a new Action task
this.$emit("submit", this.submitData); this.$emit("submit", this.submitData);
@ -173,36 +218,32 @@ export default {
this.taskStarted = true; this.taskStarted = true;
this.$emit("taskStarted", this.taskId); this.$emit("taskStarted", this.taskId);
axios try {
.post(this.submitUrl, this.submitData) let response = await axios.post(this.submitUrl, this.submitData);
// Get the returned Task ID if (this.modalProgress) {
.then(response => { UIkit.modal(this.$refs.statusModal).show();
// Start the store polling TaskId for success }
return this.startPolling(response.data.id, response.data.href); // Start the store polling TaskId for success
}) response = await this.startPolling(
.then(response => { response.data.id,
// Do something with the final response response.data.href
);
this.$emit("response", response); this.$emit("response", response);
this.$emit("finished"); this.$emit("finished");
}) } catch (error) {
.catch(error => { this.$emit("error", error | Error("Unknown error"));
if (!error) { this.$emit("finished");
error = Error("Unknown error"); } finally {
} // Reset taskRunning and taskId
this.$emit("error", error); this.taskRunning = false;
this.$emit("finished"); this.taskStarted = false;
}) this.taskId = null;
.finally(() => { // Update the form data if we're self-updating
// Reset taskRunning and taskId if (this.selfUpdate) {
this.taskRunning = false; this.getFormData();
this.taskStarted = false; }
this.taskId = null; UIkit.modal(this.$refs.statusModal).hide();
// Update the form data if we're self-updating }
if (this.selfUpdate) {
this.getFormData();
}
});
}, },
startPolling: function(taskId, taskUrl) { startPolling: function(taskId, taskUrl) {
@ -244,6 +285,7 @@ export default {
} else { } else {
// Since the task is still running, we can update the progress bar // Since the task is still running, we can update the progress bar
this.progress = response.data.progress; this.progress = response.data.progress;
this.log = response.data.log;
// Check again after timeout // Check again after timeout
setTimeout(checkCondition, interval, resolve, reject); setTimeout(checkCondition, interval, resolve, reject);
} }
@ -269,6 +311,32 @@ export default {
<style lang="less" scoped> <style lang="less" scoped>
@import "../../assets/less/theme.less"; @import "../../assets/less/theme.less";
#log-container {
position: relative;
height: 6em;
overflow-y: scroll;
overflow-x: auto;
}
#progress-and-cancel-row {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
align-content: stretch;
align-items: center;
width: 100%;
}
#progress-and-cancel-row .stretchy {
flex-grow: 1;
margin-left: 5px;
margin-right: 5px;
}
#progress-and-cancel-row .not-stretchy {
flex-grow: 0;
margin-left: 5px;
margin-right: 5px;
}
.progress { .progress {
position: relative; position: relative;
height: 5px; height: 5px;

View file

@ -1,9 +1,9 @@
<template> <template>
<div class="uk-padding-small"> <div class="uk-padding-small">
<div v-show="!thingAvailable" class="ui-alert-error" uk-alert> <div v-show="!backendOK" class="uk-alert-danger">
The background detect Thing seems to be missing or incompatible. The background detect Thing seems to be missing or incompatible.
</div> </div>
<div v-show="thingAvailable"> <div v-show="backendOK">
<div class="uk-margin"> <div class="uk-margin">
<taskSubmitter <taskSubmitter
:submit-url="setBackgroundUri" :submit-url="setBackgroundUri"
@ -42,40 +42,26 @@ export default {
propertyControl propertyControl
}, },
data: function() {
return {
};
},
computed: { computed: {
backgroundFractionUri() { backgroundFractionUri() {
return this.thingActionUrl("background_detect", "background_fraction"); return this.thingActionUrl("background_detect", "background_fraction");
}, },
setBackgroundUri() { setBackgroundUri() {
return this.thingActionUrl("background_detect", "set_background"); return this.thingActionUrl("background_detect", "set_background");
},
backendOK() {
return (
(this.backgroundFractionUri != null) & (this.setBackgroundUri != null)
);
} }
}, },
methods: { methods: {
alertBackgroundFraction(r) { alertBackgroundFraction(r) {
let fraction = r.output let fraction = r.output;
let percentage = (fraction * 100).toFixed(1) let percentage = (fraction * 100).toFixed(1);
this.modalNotify(`Current image is ${percentage}% background.`) this.modalNotify(`Current image is ${percentage}% background.`);
} }
} }
}; };
</script> </script>
<style>
.grid-container {
display: grid;
grid-template-columns: auto auto;
grid-column-gap: 10px;
}
.warning {
color: #c11;
font-weight: bold;
text-align: center;
}
</style>

View file

@ -11,6 +11,7 @@
" "
:submit-url="calibrateXYUri" :submit-url="calibrateXYUri"
:submit-label="'Auto-Calibrate using camera'" :submit-label="'Auto-Calibrate using camera'"
:modal-progress="true"
@response="onRecalibrateResponse" @response="onRecalibrateResponse"
@error="modalError" @error="modalError"
/> />