From 24e5749f50fa20224a1af447d9243e96669fb167 Mon Sep 17 00:00:00 2001
From: Julian Stirling
Date: Fri, 19 Sep 2025 15:19:37 +0100
Subject: [PATCH 1/4] Remove commented out CSS in scanListContent
---
.../tabContentComponents/scanListContent.vue | 33 -------------------
1 file changed, 33 deletions(-)
diff --git a/webapp/src/components/tabContentComponents/scanListContent.vue b/webapp/src/components/tabContentComponents/scanListContent.vue
index 65363c43..1abed3a0 100644
--- a/webapp/src/components/tabContentComponents/scanListContent.vue
+++ b/webapp/src/components/tabContentComponents/scanListContent.vue
@@ -364,39 +364,6 @@ export default {
.gallery-folder-heading {
margin-bottom: 30px;
}
-/*
-.gallery-grid {
- display: grid;
- grid-template-columns: repeat(auto-fill, 320px);
- justify-content: center;
- overflow-y: hidden;
-}
-
-.gallery-grid > div {
- display: inline-block;
- margin-bottom: 20px;
-}
-
-#openseadragon {
- width: 100%;
- height: 100%;
-}
-#info-panel {
- position: absolute;
- top: 10px;
- left: 10px;
- background-color: rgba(255, 255, 255, 0.7);
- padding: 5px;
- border-radius: 1px;
- z-index: 1000;
-}
-
-/deep/ .capture-card {
- width: 300px;
- height: 100%; // Used to have all cards in a row match their heights
- margin-left: auto;
- margin-right: auto;
-}*/
ul {
display: inline-block;
From 2fd3a8f6966d8789bc034681c52e27a9e07bc80e Mon Sep 17 00:00:00 2001
From: Julian Stirling
Date: Fri, 19 Sep 2025 16:49:47 +0100
Subject: [PATCH 2/4] Split scan cards and scan list components
---
.../scanListComponents/scanCard.vue | 173 ++++++++++++++++++
.../tabContentComponents/scanListContent.vue | 171 ++---------------
2 files changed, 190 insertions(+), 154 deletions(-)
create mode 100644 webapp/src/components/tabContentComponents/scanListComponents/scanCard.vue
diff --git a/webapp/src/components/tabContentComponents/scanListComponents/scanCard.vue b/webapp/src/components/tabContentComponents/scanListComponents/scanCard.vue
new file mode 100644
index 00000000..092da2ce
--- /dev/null
+++ b/webapp/src/components/tabContentComponents/scanListComponents/scanCard.vue
@@ -0,0 +1,173 @@
+
+
+
+
+
{{ scanData.name }}
+
+
+
+ - {{ scanData.number_of_images }} images
+ - created: {{ formatDate(scanData.created) }}
+ - modified: {{ formatDate(scanData.modified) }}
+
+
Not enough images to stitch
+
Interactive preview not available
+
High quality stitch not available
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/webapp/src/components/tabContentComponents/scanListContent.vue b/webapp/src/components/tabContentComponents/scanListContent.vue
index 1abed3a0..d4434415 100644
--- a/webapp/src/components/tabContentComponents/scanListContent.vue
+++ b/webapp/src/components/tabContentComponents/scanListContent.vue
@@ -60,12 +60,12 @@
fullscreen
-
@@ -84,97 +84,30 @@
There are no scans available to show.
-
-
-
-
-
{{ item.name }}
-
-
-
- - {{ item.number_of_images }} images
- - created: {{ formatDate(item.created) }}
- - modified: {{ formatDate(item.modified) }}
-
-
Not enough images to stitch
-
Interactive preview not available
-
High quality stitch not available
-
-
+
+
-
@@ -365,23 +247,4 @@ export default {
margin-bottom: 30px;
}
-ul {
- display: inline-block;
- text-align: center;
- list-style-type:none;
- margin: 5px 0px 10px 0px;
-}
-
-.warning-msg {
- color: red;
- text-align: center;
- font-weight: bold;
-}
-
-.alert-msg{
- color: orange;
- text-align: center;
- font-weight: bold;
-}
-
\ No newline at end of file
From 29a62a278b52a6554d19acf048ce544f0bab46f9 Mon Sep 17 00:00:00 2001
From: Julian Stirling
Date: Fri, 19 Sep 2025 17:49:28 +0100
Subject: [PATCH 3/4] Update scan card to use computed properties and request
new thumb if modified date changed
---
.../scanListComponents/scanCard.vue | 32 +++++++++----------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/webapp/src/components/tabContentComponents/scanListComponents/scanCard.vue b/webapp/src/components/tabContentComponents/scanListComponents/scanCard.vue
index 092da2ce..cef8e35b 100644
--- a/webapp/src/components/tabContentComponents/scanListComponents/scanCard.vue
+++ b/webapp/src/components/tabContentComponents/scanListComponents/scanCard.vue
@@ -8,7 +8,7 @@
@@ -32,13 +32,13 @@
class="uk-width-1-2"
:buttonPrimary=true
:isDisabled=!scanData.stitch_available
- :URL="downloadStitchFile( scanData.name )"
+ :URL="downloadStitchFile"
buttonLabel="Download JPEG"
/>
@@ -95,16 +95,16 @@ export default {
}
},
+ computed: {
+ downloadStitchFile() {
+ return `${this.$store.getters.baseUri}/smart_scan/get_stitch/${this.scanData.name}`;
+ },
+ thumbnailPath() {
+ return `${this.$store.getters.baseUri}/smart_scan/scans/stitched_thumbnail.jpg?scan_name=${this.scanData.name}&modified=${this.scanData.modified}`;
+ },
+ },
+
methods: {
- downloadStitchFile: function(name) {
- return `${this.$store.getters.baseUri}/smart_scan/get_stitch/${name}`;
- },
- thumbnailPath(scan_name) {
- return (
- `${this.$store.getters.baseUri}/smart_scan/scans/stitched_thumbnail.jpg?scan_name=` +
- scan_name
- );
- },
formatDate(timestamp) {
// Multiply by 1000 as JS uses ms not s
let d = new Date(timestamp*1000);
@@ -126,12 +126,12 @@ export default {
// Notify parent that thumbnail was clicked
this.$emit('viewer-requested', this.scanData);
},
- async deleteScan(name) {
+ async deleteScan() {
try {
- await this.modalConfirm(`Are you sure you want to delete ${name}?`);
- await axios.delete(`${this.scansUri}/${name}`);
+ await this.modalConfirm(`Are you sure you want to delete ${this.scanData.name}?`);
+ await axios.delete(`${this.scansUri}/${this.scanData.name}`);
this.$emit('update-requested');
- this.modalNotify(`Deleted ${name}`);
+ this.modalNotify(`Deleted ${this.scanData.name}`);
} catch (e) {
// if the confirmation was cancelled, it's rejected with null error
if (e) this.modalError(e);
From cd6bcd196f8062332a0fb3f9c401b34531bc886c Mon Sep 17 00:00:00 2001
From: Julian Stirling
Date: Fri, 19 Sep 2025 18:29:34 +0100
Subject: [PATCH 4/4] Don't show buttons for ongoing scans.
---
.../things/smart_scan.py | 18 ++-
.../scanListComponents/scanCard.vue | 129 +++++++++++-------
.../tabContentComponents/scanListContent.vue | 9 +-
3 files changed, 100 insertions(+), 56 deletions(-)
diff --git a/src/openflexure_microscope_server/things/smart_scan.py b/src/openflexure_microscope_server/things/smart_scan.py
index 1b760e13..44fddb61 100644
--- a/src/openflexure_microscope_server/things/smart_scan.py
+++ b/src/openflexure_microscope_server/things/smart_scan.py
@@ -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",
diff --git a/webapp/src/components/tabContentComponents/scanListComponents/scanCard.vue b/webapp/src/components/tabContentComponents/scanListComponents/scanCard.vue
index cef8e35b..a44d5406 100644
--- a/webapp/src/components/tabContentComponents/scanListComponents/scanCard.vue
+++ b/webapp/src/components/tabContentComponents/scanListComponents/scanCard.vue
@@ -14,61 +14,64 @@
/>
- {{ scanData.name }}
-
@@ -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;
+}
+
\ No newline at end of file
diff --git a/webapp/src/components/tabContentComponents/scanListContent.vue b/webapp/src/components/tabContentComponents/scanListContent.vue
index d4434415..7cf1d4dc 100644
--- a/webapp/src/components/tabContentComponents/scanListContent.vue
+++ b/webapp/src/components/tabContentComponents/scanListContent.vue
@@ -88,6 +88,7 @@
@@ -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(