From d54a0dcb96d1f7e9a8d329fd57bc02d2c7a896bf Mon Sep 17 00:00:00 2001 From: Ricardo Garcia Silva Date: Fri, 17 Jul 2026 00:07:52 +0100 Subject: [PATCH 1/3] implement initial stream handler for validation in detail page --- src/seis_lab_data/operations/projects.py | 5 +-- .../operations/surveymissions.py | 4 +- .../operations/surveyrelatedrecords.py | 2 +- src/seis_lab_data/webapp/routes/projects.py | 1 + .../webapp/routes/surveymissions.py | 1 + .../webapp/routes/surveyrelatedrecords.py | 1 + .../webapp/streamhandlers/common.py | 34 +++++++++++++++ .../webapp/templates/macros-buttons.html | 2 +- .../templates/projects/detail-component.html | 8 ++-- .../detail-component.html | 43 +++++++++---------- 10 files changed, 70 insertions(+), 31 deletions(-) diff --git a/src/seis_lab_data/operations/projects.py b/src/seis_lab_data/operations/projects.py index a29249d..d224c5a 100644 --- a/src/seis_lab_data/operations/projects.py +++ b/src/seis_lab_data/operations/projects.py @@ -1,4 +1,3 @@ -import asyncio import logging import pydantic @@ -153,8 +152,8 @@ async def validate_project( session=session, event_dispatcher=event_dispatcher, ) - await asyncio.sleep(3) - validation_schemas.ValidProject.model_validate(project) + # await asyncio.sleep(3) + validation_schemas.ValidProject.model_validate(project, from_attributes=True) except pydantic.ValidationError as err: for error in err.errors(): validation_errors.append( diff --git a/src/seis_lab_data/operations/surveymissions.py b/src/seis_lab_data/operations/surveymissions.py index 4f1060b..7a4e091 100644 --- a/src/seis_lab_data/operations/surveymissions.py +++ b/src/seis_lab_data/operations/surveymissions.py @@ -189,7 +189,9 @@ async def validate_survey_mission( event_dispatcher=event_dispatcher, ) await asyncio.sleep(3) - validation_schemas.ValidSurveyMission.model_validate(survey_mission) + validation_schemas.ValidSurveyMission.model_validate( + survey_mission, from_attributes=True + ) except pydantic.ValidationError as err: for error in err.errors(): validation_errors.append( diff --git a/src/seis_lab_data/operations/surveyrelatedrecords.py b/src/seis_lab_data/operations/surveyrelatedrecords.py index 0e473b6..2e03d5a 100644 --- a/src/seis_lab_data/operations/surveyrelatedrecords.py +++ b/src/seis_lab_data/operations/surveyrelatedrecords.py @@ -208,7 +208,7 @@ async def validate_survey_related_record( ) await asyncio.sleep(3) validation_schemas.ValidSurveyRelatedRecord.model_validate( - survey_related_record + survey_related_record, from_attributes=True ) except pydantic.ValidationError as err: for error in err.errors(): diff --git a/src/seis_lab_data/webapp/routes/projects.py b/src/seis_lab_data/webapp/routes/projects.py index d2ef358..eaa31c7 100644 --- a/src/seis_lab_data/webapp/routes/projects.py +++ b/src/seis_lab_data/webapp/routes/projects.py @@ -332,6 +332,7 @@ async def stream_to_detail_page(request: Request): ), { "resource_modified": common_handlers.handle_resource_modification_detail_page, + "validation": common_handlers.handle_resource_validation_detail_page, }, ) diff --git a/src/seis_lab_data/webapp/routes/surveymissions.py b/src/seis_lab_data/webapp/routes/surveymissions.py index d2850c5..80d3185 100644 --- a/src/seis_lab_data/webapp/routes/surveymissions.py +++ b/src/seis_lab_data/webapp/routes/surveymissions.py @@ -277,6 +277,7 @@ async def stream_to_detail_page(request: Request): message_handlers={ "resource_modified": common_handlers.handle_resource_modification_detail_page, "discovery": common_handlers.handle_discovery_detail_page, + "validation": common_handlers.handle_resource_validation_detail_page, }, ) diff --git a/src/seis_lab_data/webapp/routes/surveyrelatedrecords.py b/src/seis_lab_data/webapp/routes/surveyrelatedrecords.py index 025a08d..604637d 100644 --- a/src/seis_lab_data/webapp/routes/surveyrelatedrecords.py +++ b/src/seis_lab_data/webapp/routes/surveyrelatedrecords.py @@ -1324,6 +1324,7 @@ async def stream_to_detail_page(request: Request): ), message_handlers={ "resource_modified": common_handlers.handle_resource_modification_detail_page, + "validation": common_handlers.handle_resource_validation_detail_page, }, ) diff --git a/src/seis_lab_data/webapp/streamhandlers/common.py b/src/seis_lab_data/webapp/streamhandlers/common.py index c2d005d..3c1c06a 100644 --- a/src/seis_lab_data/webapp/streamhandlers/common.py +++ b/src/seis_lab_data/webapp/streamhandlers/common.py @@ -469,6 +469,40 @@ async def _handle_survey_mission_modification_detail_page( ) +async def handle_resource_validation_detail_page( + message: message_schemas.ValidationMessage, + context: subscribers.HandlerContext, + done: asyncio.Event | None = None, +) -> AsyncGenerator[DatastarEvent, None]: + logger.debug(f"{context=}") + logger.debug(f"{message=}") + # TODO: update the page elements too + if context.resource_id != message.resource_id: + return + if not message.succeeded and context.request_id == message.request_id: + async for event in flash_ui_message_same_page( + webui_schemas.Notification( + message=( + f"{message.resource_type.capitalize()} {message.type} " + f"{message.modification} failed: {message.details}" + ), + category="error", + ) + ): + yield event + elif message.succeeded: + async for event in flash_ui_message_same_page( + webui_schemas.Notification( + message=( + f"{message.resource_type.capitalize()} {message.type} " + f"{message.modification}" + ), + ) + ): + yield event + yield ServerSentEventGenerator.patch_signals({"validating": False}) + + async def handle_resource_modification_detail_page( message: message_schemas.ResourceModificationMessage, context: subscribers.HandlerContext, diff --git a/src/seis_lab_data/webapp/templates/macros-buttons.html b/src/seis_lab_data/webapp/templates/macros-buttons.html index f85e2ba..27b72a1 100644 --- a/src/seis_lab_data/webapp/templates/macros-buttons.html +++ b/src/seis_lab_data/webapp/templates/macros-buttons.html @@ -48,7 +48,7 @@ data-bs-target="#{{ modal_id }}" data-attr:disabled="${{ signal_name }}" > - {{ icons.delete_item }} + {{ icons.delete_item }}
{{ _("actions") | capitalize }}
-
+
{% if permissions.can_update %} - {% endif %} - {% if permissions.can_update %}
-
{{ _("actions") | capitalize }}
-
- {% if permissions.can_update %} -
+ +
+ - {% endif %} - {% if permissions.can_delete %} - {{ macros_buttons_list_items.render_delete_item_button( - deletion_url=url_for("survey_related_records:detail", survey_related_record_id=survey_related_record.id) ~ "?request_id=" ~ request_id, - signal_name="deleting", - idle_message="delete survey-related record", - running_message="deleting survey-related record...", - generated_csrf_token=csrf_token(request), - modal_dialog_title=_("delete survey-related record"), - modal_dialog_confirmation_text=_("are you sure you want to delete this survey-related record?") - ) }} - {% endif %} + {% endif %} + {% if permissions.can_delete %} + {{ macros_buttons.render_delete_item_button( + deletion_url=url_for("survey_related_records:detail", survey_related_record_id=survey_related_record.id) ~ "?request_id=" ~ request_id, + signal_name="deleting", + idle_message=_("delete..."), + running_message="deleting survey-related record...", + generated_csrf_token=csrf_token(request), + modal_dialog_title=_("delete survey-related record"), + modal_dialog_confirmation_text=_("are you sure you want to delete this survey-related record?") + ) }} + {% endif %} +
{{ _("info") | capitalize }}