From c0158a7a6c4d16a1e7fa9d38e8fa53d65f9425e6 Mon Sep 17 00:00:00 2001 From: Julian Stirling Date: Fri, 15 May 2026 14:30:14 +0100 Subject: [PATCH] Provide feeback to user on broken UI components. --- src/openflexure_microscope_server/ui.py | 12 +++++++++-- webapp/src/App.vue | 12 +++++++++++ .../labThingsComponents/actionButton.vue | 20 ++++++++++++++++--- .../labThingsComponents/propertyControl.vue | 14 +++++++++++++ .../serverSpecifiedActionButton.vue | 1 + .../serverSpecifiedPropertyControl.vue | 1 + 6 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/openflexure_microscope_server/ui.py b/src/openflexure_microscope_server/ui.py index 33134247..420a7b9e 100644 --- a/src/openflexure_microscope_server/ui.py +++ b/src/openflexure_microscope_server/ui.py @@ -214,6 +214,9 @@ class ActionButton(BaseModel): Downstream components can subscribe to this and request an update. """ + broken: bool = False + """If True the action button is broken. There is no corresponding action.""" + def action_button_for(thing: lt.Thing, action_name: str, **kwargs: Any) -> ActionButton: """Create a ActionButton data for the specified Thing Action. @@ -225,7 +228,8 @@ def action_button_for(thing: lt.Thing, action_name: str, **kwargs: Any) -> Actio webapp needs to create the action button. """ if action_name not in thing.actions: - raise AttributeError(f"{thing.name} has no action {action_name}") + thing.logger.error(f"{thing.name} has no action {action_name}") + kwargs["broken"] = True return ActionButton(thing=thing.name, action=action_name, **kwargs) @@ -272,6 +276,9 @@ class PropertyControl(BaseModel): used. """ + broken: bool = False + """If True the property control is broken. There is no corresponding property.""" + def property_control_for( thing: lt.Thing, property_name: str, **kwargs: Any @@ -286,7 +293,8 @@ def property_control_for( if "label" not in kwargs: kwargs["label"] = property_name if property_name not in thing.properties: - raise AttributeError(f"{thing.name} has no property {property_name}") + thing.logger.error(f"{thing.name} has no property {property_name}") + kwargs["broken"] = True return PropertyControl(thing=thing.name, property_name=property_name, **kwargs) diff --git a/webapp/src/App.vue b/webapp/src/App.vue index c603d280..c8f0e830 100644 --- a/webapp/src/App.vue +++ b/webapp/src/App.vue @@ -387,4 +387,16 @@ html { padding: 0; height: 100%; } + +.ui-element-error-icon { + vertical-align: middle; + padding-right: 10px; + color: #a00; +} + +.ui-element-broken { + border-color: #a00 !important; + color: #a00 !important; + cursor: not-allowed; +} diff --git a/webapp/src/components/labThingsComponents/actionButton.vue b/webapp/src/components/labThingsComponents/actionButton.vue index 6b173d62..6f1df1a9 100644 --- a/webapp/src/components/labThingsComponents/actionButton.vue +++ b/webapp/src/components/labThingsComponents/actionButton.vue @@ -3,13 +3,15 @@ +
+ error {{ label }} +