1717 BaseUpdatableDisplayModel ,
1818)
1919from simcore_service_dynamic_scheduler .api .frontend ._common .some_renderer import (
20- SomeRenderer ,
20+ UpdatableComponentList ,
2121)
2222from simcore_service_dynamic_scheduler .api .frontend ._common .updatable_component import (
2323 BaseUpdatableComponent ,
@@ -159,41 +159,42 @@ def _draw_ui(self) -> None:
159159
160160class PersonComponent (BaseUpdatableComponent [Person ]):
161161 def _draw_ui (self ) -> None :
162- # NOTE:
163- # There are 3 ways to bind the UI to the model changes:
164- # 1. using nicegui builting facilties
165- # 2. via model attribute VALE change
166- # 3. via model attribute TYPE change
167- # The model attribute changes allow to trigger re-rendering of subcomponents.
168- # This should be mainly used for chainging the UI layout based on
169- # the attribute's value or type.
170-
171- # 1. bind the label directly to the model's attribute
172- ui .label ().bind_text_from (
173- self .display_model ,
174- "name" ,
175- backward = lambda name : f"Name: { name } " ,
176- )
177-
178- # 2. use refreshable and bind to the attribute's VALUE change
179- @ui .refreshable
180- def _person_age_ui () -> None :
181- ui .label (f"Age: { self .display_model .age } " )
182-
183- _person_age_ui ()
184- self .display_model .on_value_change ("age" , _person_age_ui .refresh )
185-
186- # 3. use refreshable and bind to the attribute's TYPE change
187- @ui .refreshable
188- def _friend_or_pet_ui () -> None :
189- if isinstance (self .display_model .companion , Friend ):
190- FriendComponent (self .display_model .companion ).display ()
191-
192- elif isinstance (self .display_model .companion , Pet ):
193- PetComponent (self .display_model .companion ).display ()
194-
195- _friend_or_pet_ui ()
196- self .display_model .on_type_change ("companion" , _friend_or_pet_ui .refresh )
162+ with ui .element ().classes ("border" ):
163+ # NOTE:
164+ # There are 3 ways to bind the UI to the model changes:
165+ # 1. using nicegui builting facilties
166+ # 2. via model attribute VALE change
167+ # 3. via model attribute TYPE change
168+ # The model attribute changes allow to trigger re-rendering of subcomponents.
169+ # This should be mainly used for chainging the UI layout based on
170+ # the attribute's value or type.
171+
172+ # 1. bind the label directly to the model's attribute
173+ ui .label ().bind_text_from (
174+ self .display_model ,
175+ "name" ,
176+ backward = lambda name : f"Name: { name } " ,
177+ )
178+
179+ # 2. use refreshable and bind to the attribute's VALUE change
180+ @ui .refreshable
181+ def _person_age_ui () -> None :
182+ ui .label (f"Age: { self .display_model .age } " )
183+
184+ _person_age_ui ()
185+ self .display_model .on_value_change ("age" , _person_age_ui .refresh )
186+
187+ # 3. use refreshable and bind to the attribute's TYPE change
188+ @ui .refreshable
189+ def _friend_or_pet_ui () -> None :
190+ if isinstance (self .display_model .companion , Friend ):
191+ FriendComponent (self .display_model .companion ).display ()
192+
193+ elif isinstance (self .display_model .companion , Pet ):
194+ PetComponent (self .display_model .companion ).display ()
195+
196+ _friend_or_pet_ui ()
197+ self .display_model .on_type_change ("companion" , _friend_or_pet_ui .refresh )
197198
198199
199200async def _ensure_before_corpus (async_page : Page ) -> None :
@@ -331,13 +332,17 @@ async def test_multiple_componenets_management(
331332 ensure_page_loaded : Callable [[Callable [[], None ]], Awaitable [None ]],
332333 async_page : Page ,
333334):
334- renderer = SomeRenderer [Person ](PersonComponent )
335+ renderer = UpdatableComponentList [Person ](PersonComponent )
335336
336337 def _index_corpus () -> None :
337338 renderer .display ()
338339
339340 await ensure_page_loaded (_index_corpus )
340341
342+ from helpers import take_screenshot
343+
344+ await take_screenshot (async_page , prefix = "1.before" )
345+
341346 person_1 = Person (name = "Alice" , age = 30 , companion = Pet (name = "Fluffy" , species = "cat" ))
342347 person_2 = Person (name = "Bob" , age = 25 , companion = Friend (name = "Marta" , age = 28 ))
343348
@@ -350,10 +355,33 @@ def _index_corpus() -> None:
350355 await _ensure_person_is_present (async_page , person_1 )
351356 await _ensure_person_is_present (async_page , person_2 )
352357
358+ await take_screenshot (async_page , prefix = "2.persons-added" )
359+
353360 renderer .remove_model ("person_1" )
354361 await _ensure_person_not_present (async_page , person_1 )
355362 await _ensure_person_is_present (async_page , person_2 )
356363
364+ await take_screenshot (async_page , prefix = "3.person-1-removed" )
365+
357366 renderer .remove_model ("person_2" )
358367 await _ensure_person_not_present (async_page , person_2 )
359368 await _ensure_person_not_present (async_page , person_1 )
369+
370+ await take_screenshot (async_page , prefix = "4.person-2-removed" )
371+
372+ renderer .update_from_dict ({"person_1" : person_1 , "person_2" : person_2 })
373+ await _ensure_person_is_present (async_page , person_1 )
374+ await _ensure_person_is_present (async_page , person_2 )
375+
376+ await take_screenshot (async_page , prefix = "5.persons-added" )
377+
378+ renderer .update_from_dict ({"person_1" : person_1 })
379+ await _ensure_person_is_present (async_page , person_1 )
380+ await _ensure_person_not_present (async_page , person_2 )
381+
382+ await take_screenshot (async_page , prefix = "6.person-2-removed" )
383+
384+ renderer .update_from_dict ({})
385+ await _ensure_person_not_present (async_page , person_1 )
386+ await _ensure_person_not_present (async_page , person_2 )
387+ await take_screenshot (async_page , prefix = "7.person-1-removed" )
0 commit comments