Don't show buttons for ongoing scans.

This commit is contained in:
Julian Stirling 2025-09-19 18:29:34 +01:00
parent 29a62a278b
commit cd6bcd196f
3 changed files with 100 additions and 56 deletions

View file

@ -17,6 +17,7 @@ from subprocess import SubprocessError
from fastapi import HTTPException
from fastapi.responses import FileResponse
import numpy as np
from pydantic import BaseModel
import labthings_fastapi as lt
@ -39,6 +40,16 @@ CSMDep = lt.deps.direct_thing_client_dependency(
AutofocusDep = lt.deps.direct_thing_client_dependency(AutofocusThing, "/autofocus/")
class ScanListData(BaseModel):
"""The data to be sent to the Scan List tab."""
scans: list[scan_directories.ScanInfo]
"""The list of scans as ScanInfo objects"""
ongoing: Optional[str]
"""The name of the ongoing scan or None"""
class JPEGBlob(lt.blob.Blob):
"""A class representing a JPEG image as a LabThings FastAPI Blob."""
@ -557,7 +568,7 @@ class SmartScanThing(lt.Thing):
"""Whether to run a final stitch at the end of a successful scan."""
@lt.thing_property
def scans(self) -> list[scan_directories.ScanInfo]:
def scans(self) -> ScanListData:
"""All the available scans.
Each scan has a name (which can be used to access it), along with
@ -566,7 +577,10 @@ class SmartScanThing(lt.Thing):
uses a regular expression, and changes to the naming scheme will
break it.
"""
return self._scan_dir_manager.all_scans_info()
return ScanListData(
scans=self._scan_dir_manager.all_scans_info(),
ongoing=None if self._ongoing_scan is None else self._ongoing_scan.name,
)
@lt.fastapi_endpoint(
"get",

View file

@ -14,61 +14,64 @@
/>
</div>
</div>
<h3 class="uk-card-title" style="text-align: center;">{{ scanData.name }}</h3>
<div class="button-container">
<div class="uk-button-group" style="width:100%">
<action-button
class="uk-width-1-2"
thing="smart_scan"
action="download_zip"
submit-label="Download All"
:can-terminate="false"
:submit-data="{ scan_name: scanData.name }"
:button-primary="true"
@response="downloadZipFile"
@error="modalError"
/>
<EndpointButton
<h3 class="uk-card-title scan-card-title">{{ scanData.name }}</h3>
<h4 class="ongoing-msg" v-if="ongoing">Scan in progress</h4>
<div class="button-container" v-if="!ongoing">
<div class="uk-button-group scan-card-buttons">
<action-button
class="uk-width-1-2"
:buttonPrimary=true
:isDisabled=!scanData.stitch_available
:URL="downloadStitchFile"
buttonLabel="Download JPEG"
thing="smart_scan"
action="download_zip"
submit-label="Download All"
:can-terminate="false"
:submit-data="{ scan_name: scanData.name }"
:button-primary="true"
@response="downloadZipFile"
@error="modalError"
/>
</div>
<button
class="uk-button uk-button-default uk-width-1-1"
@click="deleteScan"
>
Delete
</button>
<action-button
submit-label="Stitch Images"
thing="smart_scan"
action="stitch_scan"
v-if="scanData.can_stitch | (scanData.stitch_available & !scanData.dzi)"
:can-terminate="true"
:submit-data="{ scan_name: scanData.name }"
:button-primary="false"
:modal-progress="true"
@error="modalError"
/>
<button
v-if="scanData.dzi" class="uk-button uk-button-default uk-width-1-1"
@click="requestViewer"
>
Show Stitched Scan
</button>
<EndpointButton
class="uk-width-1-2"
:buttonPrimary=true
:isDisabled=!scanData.stitch_available
:URL="downloadStitchFile"
buttonLabel="Download JPEG"
/>
</div>
<button
class="uk-button uk-button-default uk-width-1-1"
@click="deleteScan"
>
Delete
</button>
<action-button
submit-label="Stitch Images"
thing="smart_scan"
action="stitch_scan"
v-if="scanData.can_stitch | (scanData.stitch_available & !scanData.dzi)"
:can-terminate="true"
:submit-data="{ scan_name: scanData.name }"
:button-primary="false"
:modal-progress="true"
@error="modalError"
/>
<button
v-if="scanData.dzi" class="uk-button uk-button-default uk-width-1-1"
@click="requestViewer"
>
Show Stitched Scan
</button>
</div>
<div>
<ul>
<li>{{ scanData.number_of_images }} images</li>
<li>created: {{ formatDate(scanData.created) }}</li>
<li>modified: {{ formatDate(scanData.modified) }}</li>
</ul>
<li v-if="scanData.number_of_images<3" class="warning-msg">Not enough images to stitch</li>
<li v-else-if="!scanData.dzi & scanData.stitch_available" class="alert-msg">Interactive preview not available</li>
<li v-else-if=!scanData.stitch_available class="alert-msg">High quality stitch not available</li>
<ul>
<li>{{ scanData.number_of_images }} images</li>
<li>created: {{ formatDate(scanData.created) }}</li>
<li>modified: {{ formatDate(scanData.modified) }}</li>
</ul>
<ul v-if="!ongoing">
<li v-if="scanData.number_of_images<3" class="warning-msg">Not enough images to stitch</li>
<li v-else-if="!scanData.dzi & scanData.stitch_available" class="alert-msg">Interactive preview not available</li>
<li v-else-if=!scanData.stitch_available class="alert-msg">High quality stitch not available</li>
</ul>
</div>
</div>
</div>
@ -92,6 +95,10 @@ export default {
scansUri: {
type: String,
required: true
},
ongoing: {
type: Boolean,
required: true
}
},
@ -124,7 +131,9 @@ export default {
},
requestViewer() {
// Notify parent that thumbnail was clicked
this.$emit('viewer-requested', this.scanData);
if (!this.ongoing) {
this.$emit('viewer-requested', this.scanData);
}
},
async deleteScan() {
try {
@ -165,9 +174,23 @@ ul {
font-weight: bold;
}
.alert-msg{
.alert-msg {
color: orange;
text-align: center;
font-weight: bold;
}
.scan-card-buttons {
width: 100%;
}
.scan-card-title {
text-align: center;
}
.ongoing-msg {
text-align: center;
padding: 2rem 0;
}
</style>

View file

@ -88,6 +88,7 @@
<scan-card
:scan-data="scanData"
:scans-uri="scansUri"
:ongoing="isOngoing(scanData.name)"
@viewer-requested="showScan"
@update-requested="updateScans"
/>
@ -112,6 +113,7 @@ export default {
data: function() {
return {
scans: [],
ongoing: null,
selectedScan: null,
osdViewer: null
};
@ -191,7 +193,9 @@ export default {
},
async updateScans() {
try {
let scans = await this.readThingProperty("smart_scan", "scans");
let scans_information = await this.readThingProperty("smart_scan", "scans");
let scans = scans_information.scans
this.ongoing = scans_information.ongoing
if (!scans | (scans.length == 0)) {
this.scans = scans;
}
@ -208,6 +212,9 @@ export default {
this.scans = [];
}
},
isOngoing(name) {
return name === this.ongoing
},
async deleteAllScans() {
try {
await this.modalConfirm(