diff --git a/src/openflexure_microscope_server/things/camera/__init__.py b/src/openflexure_microscope_server/things/camera/__init__.py index 5a39f11c..0d61bb23 100644 --- a/src/openflexure_microscope_server/things/camera/__init__.py +++ b/src/openflexure_microscope_server/things/camera/__init__.py @@ -332,6 +332,13 @@ class BaseCamera(OFMThing, ABC): self.logger.info(f"Deleting: {capture}") os.remove(capture) + def get_gallery_bulk_actions(self) -> list[ActionButton]: + """Return the bulk gallery actions for cameras. + + By default there are no bulk actions. + """ + return [] + @lt.endpoint( "delete", "capture/{name}", diff --git a/src/openflexure_microscope_server/things/gallery.py b/src/openflexure_microscope_server/things/gallery.py index 23f4f1bd..35b0aa32 100644 --- a/src/openflexure_microscope_server/things/gallery.py +++ b/src/openflexure_microscope_server/things/gallery.py @@ -12,6 +12,7 @@ from pydantic import BaseModel import labthings_fastapi as lt from openflexure_microscope_server.things import OFMThing +from openflexure_microscope_server.ui import ActionButton @runtime_checkable @@ -38,6 +39,8 @@ class GalleryCompatibleThing(Protocol): def delete_all_gallery_items(self) -> None: ... # noqa: D102 + def get_gallery_bulk_actions(self) -> list[ActionButton]: ... # noqa: D102 + class GalleryThing(lt.Thing): """A Thing for communicating with the front end gallery.""" @@ -125,6 +128,19 @@ class GalleryThing(lt.Thing): raise RuntimeError("Cannot access card_types before server has started.") return self._card_types + # Cache result after first call. + _bulk_actions: Optional[list[ActionButton]] = None + + @lt.property + def bulk_actions(self) -> list[ActionButton]: + """All bulk actions.""" + if self._bulk_actions is None: + actions: list[ActionButton] = [] + for thing in self.gallery_providing_things.values(): + actions += thing.get_gallery_bulk_actions() + self._bulk_actions = actions + return self._bulk_actions + @lt.property def list_data(self) -> list[dict[str, Any]]: """List the data from all registered things. diff --git a/src/openflexure_microscope_server/things/smart_scan.py b/src/openflexure_microscope_server/things/smart_scan.py index d22cb55f..337c8b40 100644 --- a/src/openflexure_microscope_server/things/smart_scan.py +++ b/src/openflexure_microscope_server/things/smart_scan.py @@ -32,6 +32,7 @@ import labthings_fastapi as lt from openflexure_microscope_server import scan_directories, stitching from openflexure_microscope_server.things import OFMThing +from openflexure_microscope_server.ui import ActionButton, action_button_for from openflexure_microscope_server.utilities import coerce_thing_selector # Things @@ -199,6 +200,26 @@ class SmartScanThing(OFMThing): self.logger.info(f"Deleting: {scan_name}") self._delete_scan(scan_name) + def get_gallery_bulk_actions(self) -> list[ActionButton]: + """Return the bulk gallery actions for smart scan.""" + # Stitch all scans + return [ + action_button_for( + self, + "stitch_all_scans", + submit_label="Stitch All Unstitched Scans", + can_terminate=True, + button_primary=False, + modal_progress=True, + requires_confirmation=True, + confirmation_message=( + "