diff --git a/src/openflexure_microscope_server/things/scan_workflows.py b/src/openflexure_microscope_server/things/scan_workflows.py index 7679207a..1bf5b826 100644 --- a/src/openflexure_microscope_server/things/scan_workflows.py +++ b/src/openflexure_microscope_server/things/scan_workflows.py @@ -42,7 +42,8 @@ from openflexure_microscope_server.things.stage import BaseStage from openflexure_microscope_server.ui import ( UI_ELEMENT_RESPONSE, Accordion, - HTMLBlock, + HeaderBlock, + TextBlock, UIElementList, action_button_for, property_control_for, @@ -642,7 +643,8 @@ class HistoScanWorkflow(RectGridWorkflow[HistoScanSettingsModel]): return UIElementList( [ - HTMLBlock(html=f"
{self.ui_blurb}
"), + HeaderBlock(text=self.display_name, level=4), + TextBlock(text=self.ui_blurb), Accordion(title="Background Detect", children=background_ui), Accordion( title="Scan Settings", @@ -750,7 +752,8 @@ class RegularGridWorkflow(RectGridWorkflow[RegularGridSettingsModel]): ) return UIElementList( [ - HTMLBlock(html=f"
{self.ui_blurb}
"), + HeaderBlock(text=self.display_name, level=4), + TextBlock(text=self.ui_blurb), Accordion( title="Scan Settings", children=scan_settings, diff --git a/src/openflexure_microscope_server/ui.py b/src/openflexure_microscope_server/ui.py index b6692785..2524515e 100644 --- a/src/openflexure_microscope_server/ui.py +++ b/src/openflexure_microscope_server/ui.py @@ -5,24 +5,12 @@ from html.parser import HTMLParser from typing import Annotated, Any, Literal, Optional from urllib.parse import urlparse -from pydantic import BaseModel, BeforeValidator, RootModel +from pydantic import BaseModel, BeforeValidator, Field, RootModel import labthings_fastapi as lt -ALLOWED_TAGS = { - "p", - "i", - "b", - "h1", - "h2", - "h3", - "h4", - "h5", - "h6", - "ul", - "li", - "a", -} +# Only allowed tags are italic, bold, and link. Also allows self closing br tags. +ALLOWED_TAGS = {"i", "b", "a"} ALLOWED_SCHEMES = {"http", "https"} @@ -116,8 +104,7 @@ class SafeHTMLParser(HTMLParser): def sanitise_html(html: str) -> str: """Santitise HTML to only have a small list of allowed tags. - Tags allowed without attrs: ``
, , , Hello,
,
,
,
,
,``
- ``
,
line.
+```
+### Result
+```html
+This is bold italic and on a new
line.
```
\ No newline at end of file
diff --git a/tests/unit_tests/test_scan_workflows.py b/tests/unit_tests/test_scan_workflows.py
index b9f0fa07..0ffa4a00 100644
--- a/tests/unit_tests/test_scan_workflows.py
+++ b/tests/unit_tests/test_scan_workflows.py
@@ -21,8 +21,9 @@ from openflexure_microscope_server.things.scan_workflows import (
from openflexure_microscope_server.ui import (
Accordion,
ActionButton,
- HTMLBlock,
+ HeaderBlock,
PropertyControl,
+ TextBlock,
UIElementList,
)
@@ -385,20 +386,24 @@ def test_histo_workflow_settings_ui(histo_workflow, mocker):
ui = histo_workflow.settings_ui().root
- # The UI is in 3 blocks
- assert len(ui) == 3
- # The top HTML block
- assert isinstance(ui[0], HTMLBlock)
- assert "Histo Scan
" in ui[0].html
+ # The UI is in 4 blocks
+ assert len(ui) == 4
+ # The top is a header
+ assert isinstance(ui[0], HeaderBlock)
+ assert ui[0].text == "Histo Scan"
+ # The then some text (note the & is escaped)
+ assert isinstance(ui[1], TextBlock)
+ fragment = "This scan workflow is optimised for scanning H&E stained biopsies."
+ assert fragment in ui[1].text
# Followed by a background detect accordion
- assert isinstance(ui[1], Accordion)
- assert ui[1].title == "Background Detect"
- # And a Scan Settings accordion
assert isinstance(ui[2], Accordion)
- assert ui[2].title == "Scan Settings"
+ assert ui[2].title == "Background Detect"
+ # And a Scan Settings accordion
+ assert isinstance(ui[3], Accordion)
+ assert ui[3].title == "Scan Settings"
# Background UI is ...
- background_ui = ui[1].children.root
+ background_ui = ui[2].children.root
# what the detector specifies as it settings ...
assert background_ui[0] is mock_prop_control
# plus 2 action buttons
@@ -409,7 +414,7 @@ def test_histo_workflow_settings_ui(histo_workflow, mocker):
assert background_ui[2].action == "check_background"
# Finally check the contents of the scan settings accordion
- scan_settings = ui[2].children.root
+ scan_settings = ui[3].children.root
assert len(scan_settings) == 8
for element in scan_settings:
assert isinstance(element, PropertyControl)
diff --git a/webapp/src/components/labThingsComponents/serverSpecifiedInterface.vue b/webapp/src/components/labThingsComponents/serverSpecifiedInterface.vue
index 10aa5636..f69ae102 100644
--- a/webapp/src/components/labThingsComponents/serverSpecifiedInterface.vue
+++ b/webapp/src/components/labThingsComponents/serverSpecifiedInterface.vue
@@ -1,7 +1,17 @@
+
+