Dynamically create lists of tasks for Calibration Wizard

This commit is contained in:
Julian Stirling 2025-10-23 00:06:01 +01:00
parent 5860b9be97
commit 958b28aa94
3 changed files with 51 additions and 194 deletions

View file

@ -34,7 +34,7 @@ export default {
data: function() {
return {
isNeeded: undefined,
calibrateableThings: [],
availableCalibrationTasks: {},
tasks: [],
taskIndex: 0,
movingBackward: false
@ -56,46 +56,42 @@ export default {
mounted() {
this.$refs["calibrationModalEl"].addEventListener("hidden", this.onHide);
// Check which Things are available on mount.
const thingsToCheck = [
"camera",
"camera_stage_mapping"
];
this.calibrateableThings = thingsToCheck.filter(name => this.thingAvailable(name));
this.tasks = [
{component: singleStepTask, props: {stepComponent: welcomeStep}},
{component: cameraCalibrationTask},
{component: cameraStageMappingTask},
{component: singleStepTask, props: {stepComponent: finalStep}},
]
const allCalibrationTasks = {
camera: cameraCalibrationTask,
camera_stage_mapping: cameraStageMappingTask
};
this.availableCalibrationTasks = Object.fromEntries(
Object.entries(allCalibrationTasks)
.filter(([thing]) => this.thingAvailable(thing))
);
},
methods: {
/**
* Check all calibratable Things to see if any require calibration.
* Check all calibratable Things to see which require calibration.
*
* Iterates over `this.calibrateableThings` (set during mounted()) and reads the
* Iterates over `this.availableCalibrationTasks` (set during mounted()) and reads the
* `calibration_required` property.
*
* Returns `true` if any Thing reports that calibration is required.
*
* Returns a list of thing names that report calibration is required.
*/
async check_if_needed() {
let wizardNeeded = false;
let thingNeedsCal = false;
async check_things_needing_calibration() {
const needsCalibration = [];
const calibrateableThings = Object.keys(this.availableCalibrationTasks);
for (const name of this.calibrateableThings) {
for (const name of calibrateableThings) {
try {
thingNeedsCal = await this.readThingProperty(name, "calibration_required");
const thingNeedsCal = await this.readThingProperty(name, "calibration_required");
if (thingNeedsCal) {
needsCalibration.push(name);
}
} catch (e) {
console.error(`${name}: missing calibration_required property`, e);
thingNeedsCal = false;
}
// OR it into the function-level flag
wizardNeeded = wizardNeeded || thingNeedsCal;
}
return wizardNeeded;
return needsCalibration;
},
resetData: function() {
@ -103,13 +99,38 @@ export default {
this.taskIndex = 0;
},
/**
* Create the calibration wizard task list dynamically.
*/
create_task_list: function(thingsToCal, includeWelcome=true) {
const tasks = [];
// Optionally include the welcome screen
if (includeWelcome) {
tasks.push({ component: singleStepTask, props: { stepComponent: welcomeStep } });
}
// Add calibration task for each thing
for (const thing of thingsToCal) {
const taskComponent = this.availableCalibrationTasks[thing];
tasks.push({ component: taskComponent });
}
// Always include the final step
tasks.push({ component: singleStepTask, props: { stepComponent: finalStep } });
this.tasks = tasks;
},
show_if_needed: async function() {
// Check if the calibration modal is needed, and only show it if it is.
let needed = await this.check_if_needed()
let thingsToCal = await this. check_things_needing_calibration()
const needed = thingsToCal.length > 0;
// Check if this calibration wizard can actually do anything useful
if (needed) {
this.resetData();
this.create_task_list(thingsToCal);
this.show();
} else {
// If not needed, we just return the onClose event immediately
@ -119,7 +140,10 @@ export default {
// Forces modal to show on button press
force_show: function() {
const allThings = Object.keys(this.availableCalibrationTasks);
this.resetData();
this.create_task_list(allThings, false);
this.show();
},

View file

@ -1,166 +0,0 @@
<!--
This is a temporary holidng file for content that needs to be put into the new
structure
-->
<div v-show="stepValue == 0">
</div>
<div v-show="stepValue == 1">
<h3>Lens-shading</h3>
<div v-if="isLSTCalibrated">
<p>
<b
>Your lens-shading table has already been calibrated. Click Next
to move on.</b
>
</p>
</div>
<div v-else>
<miniStreamDisplay
v-if="stepValue == 1"
class="mini-preview"
></miniStreamDisplay>
<p>Once you're ready, click auto-calibrate.</p>
<cameraCalibrationSettings
:show-extra-settings="false"
:camera-uri="cameraUri"
></cameraCalibrationSettings>
</div>
</div>
<div v-show="stepValue == 2">
<h3>Adjust z height</h3>
<p>
Insert a sample and adjust the z position of
the stage using the buttons below, until the
sample is in focus.
</p>
<p>
You may also adjust the z position with <b>page up</b> and <b>page down</b>.
</p>
<miniStreamDisplay
v-if="stepValue == 2"
class="mini-preview"
></miniStreamDisplay>
<div class="action-button-container">
<action-button
class="moveZ"
thing="stage"
action="move_relative"
:button-primary="false"
:submit-data="{ x: 0, y: 0, z: -100}"
:submit-label="' - '"
:hideOnRun="false"
:can-terminate="false"
/>
<action-button
class="moveZ"
thing="stage"
action="move_relative"
:button-primary="false"
:submit-data="{ x: 0, y: 0, z: 100}"
:submit-label="'+'"
:can-terminate="false"
:hideOnRun="false"
/>
</div>
</div>
<div v-show="stepValue == 3">
<h3>Camera-stage mapping</h3>
<div v-if="isCSMCalibrated">
<p>
<b
>Your camera-stage mapping has already been calibrated. Click Next
to move on.</b
>
</p>
</div>
<div v-else-if="!canCSMCalibrated">
<p>
<b
>No stage connected. Please skip this step, or connect a valid
stage, then reboot your microscope.</b
>
</p>
</div>
<div v-else>
<p>
<b
>Follow the important steps below before starting camera-stage
mapping calibration!</b
>
</p>
<ul class="uk-list uk-list-bullet">
<li>Insert a clearly visible sample to the microscope</li>
<li>
Ensure the sample is reasonably well centered on the microscope
camera
</li>
</ul>
<miniStreamDisplay
v-if="stepValue == 3"
class="mini-preview"
></miniStreamDisplay>
<p>Once you're ready, click auto-calibrate.</p>
<CSMCalibrationSettings
:show-extra-settings="false"
></CSMCalibrationSettings>
</div>
</div>
<div v-show="stepValue == 4">
<p>
<b>Calibration complete</b>
</p>
<p>
Click Finish to return to your microscope, or Restart to re-run the
calibration routine
</p>
</div>
<script>
import cameraCalibrationSettings from "../tabContentComponents/settingsComponents/cameraSettingsComponents/cameraCalibrationSettings.vue";
import CSMCalibrationSettings from "../tabContentComponents/settingsComponents/CSMSettingsComponents/CSMCalibrationSettings.vue";
import miniStreamDisplay from "../genericComponents/miniStreamDisplay.vue";
export default {
name: "calibrationWizard",
components: {
cameraCalibrationSettings,
CSMCalibrationSettings,
miniStreamDisplay,
ActionButton
},
}
</script>
<style scoped>
.action-button-container {
display: flex;
flex-direction: row; /* Stack vertically */
justify-content: center; /* Left align */
gap: 8px; /* Small space between buttons */
margin-top: 4px; /* Gap from image */
}
>>> .moveZ .uk-button.uk-width-1-1 {
line-height: 50px;
font-size: 50px !important;
height: 60px;
padding-bottom: 46px;
margin: 0; /* Remove default margin */
width: 120px;
min-width: 80px;
}
</style>

View file

@ -16,7 +16,6 @@
</template>
<script>
export default {
name: "csmExplanation"
}