Skip to content

Commit a5beb8a

Browse files
author
Andrei Neagu
committed
fixed tests
1 parent 2f05c0c commit a5beb8a

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

services/dynamic-scheduler/src/simcore_service_dynamic_scheduler/api/frontend/_common/base_display_model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def update(self, update_obj: Self) -> NonNegativeInt:
5454
def _raise_if_attribute_not_declared_in_model(self, attribute: str) -> None:
5555
if attribute not in self.__class__.model_fields:
5656
msg = f"Attribute '{attribute}' is not part of the model fields"
57-
raise RuntimeError(msg)
57+
raise ValueError(msg)
5858

5959
def on_type_change(self, attribute: str, callback: Callable) -> None:
6060
"""subscribe callback to an attribute TYPE change"""

services/dynamic-scheduler/tests/unit/api_frontend/_common/test_updatable_component.py

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,31 @@ def add_to_ui(self) -> None:
119119

120120
class PersonComponent(BaseUpdatableComponent[Person]):
121121
def add_to_ui(self) -> None:
122-
ui.label(f"Name: {self.display_model.name}")
123-
ui.label(f"Age: {self.display_model.age}")
122+
# NOTE:
123+
# There are 3 ways to bind the UI to the model changes:
124+
# 1. using nicegui builting facilties
125+
# 2. via model attribute VALE change
126+
# 3. via model attribute TYPE change
127+
# The model attribute changes allow to trigger re-rendering of subcomponents.
128+
# This should be mainly used for chainging the UI layout based on
129+
# the attribute's value or type.
130+
131+
# 1. bind the label directly to the model's attribute
132+
ui.label().bind_text_from(
133+
self.display_model,
134+
"name",
135+
backward=lambda name: f"Name: {name}",
136+
)
124137

138+
# 2. use refreshable and bind to the attribute's VALUE change
139+
@ui.refreshable
140+
def _person_age_ui() -> None:
141+
ui.label(f"Age: {self.display_model.age}")
142+
143+
_person_age_ui()
144+
self.display_model.on_value_change("age", _person_age_ui.refresh)
145+
146+
# 3. use refreshable and bind to the attribute's TYPE change
125147
@ui.refreshable
126148
def _friend_or_pet_ui() -> None:
127149
if isinstance(self.display_model.companion, Friend):
@@ -131,8 +153,6 @@ def _friend_or_pet_ui() -> None:
131153
PetComponent(self.display_model.companion).add_to_ui()
132154

133155
_friend_or_pet_ui()
134-
135-
# self.display_model.on_value_change("companion", _friend_or_pet_ui.refresh)
136156
self.display_model.on_type_change("companion", _friend_or_pet_ui.refresh)
137157

138158

@@ -191,7 +211,19 @@ async def _ensure_index_page(async_page: Page, person: Person) -> None:
191211
Person(name="Alice", age=30, companion=Pet(name="Fluffy", species="cat")),
192212
Person(name="Alice", age=30, companion=Friend(name="Marta", age=30)),
193213
1,
194-
id="update-pet-ui-rerednder",
214+
id="update-pet-ui-via-rerednder-due-to-type-change",
215+
),
216+
pytest.param(
217+
Person(name="Alice", age=30, companion=Pet(name="Fluffy", species="cat")),
218+
Person(name="Bob", age=30, companion=Pet(name="Fluffy", species="cat")),
219+
0,
220+
id="change-person-name-via-bindings",
221+
),
222+
pytest.param(
223+
Person(name="Alice", age=30, companion=Pet(name="Fluffy", species="cat")),
224+
Person(name="Alice", age=31, companion=Pet(name="Fluffy", species="cat")),
225+
1,
226+
id="change-person-age-via-rerender-due-to-value-change",
195227
),
196228
],
197229
)

0 commit comments

Comments
 (0)