-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature/mx-1702 resolve types in edit view (#158)
# PR Context - this PR only resolves Links, Texts and Enums, but does not resolve Identifiers yet - additionally cleans up the user interface and code structure a bit - needs robert-koch-institut/mex-backend#187 and robert-koch-institut/mex-backend#189 # Changes - upgrade mex-common and model dependencies to v3 - overhaul and simplify margins and spaces - move transform_models_to_fields from State to transform module - use dedicated backend connector methods for edit and search - use same rendering components for edit and search pages - pop toasts when backend connector encounters errors - scroll to top when pagination is triggered # Fixed - fix routing issues by moving the refresh handlers section.from on_mount to page.on_load --------- Signed-off-by: Nicolas Drebenstedt <[email protected]> Co-authored-by: Franziska Diehr <[email protected]> Co-authored-by: RKI | Metadata Exchange <[email protected]> Co-authored-by: rababerladuseladim <[email protected]>
- Loading branch information
1 parent
7ea1271
commit b025472
Showing
30 changed files
with
1,202 additions
and
475 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import reflex as rx | ||
|
||
from mex.editor.edit.models import FixedValue | ||
|
||
|
||
def fixed_internal_link(value: FixedValue) -> rx.Component: | ||
"""Render a fixed value as a clickable internal link that reloads the edit page.""" | ||
return rx.link( | ||
value.text, | ||
href=value.href, | ||
high_contrast=True, | ||
role="link", | ||
) | ||
|
||
|
||
def fixed_external_link(value: FixedValue) -> rx.Component: | ||
"""Render a fixed value as a clickable external link that opens in a new window.""" | ||
return rx.link( | ||
value.text, | ||
href=value.href, | ||
high_contrast=True, | ||
is_external=True, | ||
role="link", | ||
) | ||
|
||
|
||
def fixed_link(value: FixedValue) -> rx.Component: | ||
"""Render a fixed value as a clickable link that reloads the edit page.""" | ||
return rx.cond( | ||
value.external, | ||
fixed_external_link(value), | ||
fixed_internal_link(value), | ||
) | ||
|
||
|
||
def fixed_text(value: FixedValue) -> rx.Component: | ||
"""Render a fixed value as a text span.""" | ||
return rx.text( | ||
value.text, | ||
as_="span", | ||
) | ||
|
||
|
||
def postfix_badge(value: FixedValue) -> rx.Component: | ||
"""Render a generic badge after the fixed value.""" | ||
return rx.badge( | ||
value.badge, | ||
radius="full", | ||
variant="surface", | ||
style={"margin": "auto 0"}, | ||
) | ||
|
||
|
||
def fixed_value(value: FixedValue) -> rx.Component: | ||
"""Return a single fixed value.""" | ||
return rx.hstack( | ||
rx.cond( | ||
value.href, | ||
fixed_link(value), | ||
fixed_text(value), | ||
), | ||
rx.cond( | ||
value.badge, | ||
postfix_badge(value), | ||
), | ||
spacing="1", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,48 @@ | ||
from pydantic import BaseModel | ||
import reflex as rx | ||
from reflex.event import EventSpec | ||
from requests import HTTPError | ||
|
||
from mex.common.backend_api.connector import BackendApiConnector | ||
from mex.common.models import AnyExtractedModel | ||
from mex.editor.edit.models import EditableField, EditablePrimarySource | ||
from mex.common.logging import logger | ||
from mex.editor.edit.models import EditableField | ||
from mex.editor.edit.transform import transform_models_to_fields | ||
from mex.editor.models import FixedValue | ||
from mex.editor.state import State | ||
from mex.editor.transform import render_any_value, render_model_title | ||
|
||
|
||
class _BackendSearchResponse(BaseModel): | ||
total: int | ||
items: list[AnyExtractedModel] | ||
from mex.editor.transform import transform_models_to_title | ||
|
||
|
||
class EditState(State): | ||
"""State for the edit component.""" | ||
|
||
fields: list[EditableField] = [] | ||
item_title: str = "" | ||
item_title: list[FixedValue] = [] | ||
|
||
def refresh(self) -> None: | ||
"""Refresh the search results.""" | ||
def refresh(self) -> EventSpec | None: | ||
"""Refresh the edit page.""" | ||
self.reset() | ||
# TODO(ND): use the user auth for backend requests (stop-gap MX-1616) | ||
connector = BackendApiConnector.get() | ||
|
||
# TODO(ND): use a specialized extracted-item search method | ||
response = connector.request( | ||
"GET", f"extracted-item?stableTargetId={self.item_id}" | ||
) | ||
items = _BackendSearchResponse.model_validate(response).items | ||
self.fields = self.extracted_to_fields(items) | ||
|
||
# TODO(ND): use title of merged item instead of title of first item | ||
self.item_title = render_model_title(items[0]) | ||
|
||
@staticmethod | ||
def extracted_to_fields(models: list[AnyExtractedModel]) -> list[EditableField]: | ||
"""Convert a list of extracted models into editable field models.""" | ||
fields_by_name: dict[str, EditableField] = {} | ||
for model in models: | ||
model_dump = model.model_dump() | ||
for field_name in model.model_fields: | ||
editable_field = fields_by_name.setdefault( | ||
field_name, EditableField(name=field_name, primary_sources=[]) | ||
) | ||
value = model_dump[field_name] | ||
if not value: | ||
continue | ||
if not isinstance(value, list): | ||
value = [value] | ||
editable_field.primary_sources.append( | ||
EditablePrimarySource( | ||
name=model.hadPrimarySource, | ||
editable_values=[render_any_value(v) for v in value], | ||
) | ||
) | ||
return list(fields_by_name.values()) | ||
try: | ||
response = connector.fetch_extracted_items( | ||
None, | ||
self.item_id, | ||
None, | ||
0, | ||
100, | ||
) | ||
except HTTPError as exc: | ||
self.reset() | ||
logger.error( | ||
"backend error fetching extracted items: %s", | ||
exc.response.text, | ||
exc_info=False, | ||
) | ||
return rx.toast.error( | ||
exc.response.text, | ||
duration=5000, | ||
close_button=True, | ||
dismissible=True, | ||
) | ||
self.item_title = transform_models_to_title(response.items) | ||
self.fields = transform_models_to_fields(response.items) | ||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
from collections.abc import Iterable | ||
|
||
from mex.common.exceptions import MExError | ||
from mex.common.models import ( | ||
MEX_PRIMARY_SOURCE_STABLE_TARGET_ID, | ||
AnyExtractedModel, | ||
AnyRuleModel, | ||
) | ||
from mex.common.types import Identifier | ||
from mex.editor.edit.models import EditableField, EditablePrimarySource | ||
from mex.editor.transform import transform_value, transform_values | ||
|
||
|
||
def transform_models_to_fields( | ||
models: Iterable[AnyExtractedModel | AnyRuleModel], | ||
) -> list[EditableField]: | ||
"""Convert a list of extracted models into editable field models.""" | ||
fields_by_name: dict[str, EditableField] = {} | ||
for model in models: | ||
if isinstance(model, AnyExtractedModel): | ||
primary_source_name = transform_value(Identifier(model.hadPrimarySource)) | ||
elif isinstance(model, AnyRuleModel): | ||
primary_source_name = transform_value(MEX_PRIMARY_SOURCE_STABLE_TARGET_ID) | ||
else: | ||
msg = ( | ||
"cannot transform model, expected extracted ExtractedData or " | ||
f"RuleItem, got {type(model).__name__}" | ||
) | ||
raise MExError(msg) | ||
for field_name in model.model_fields: | ||
editable_field = EditableField(name=field_name, primary_sources=[]) | ||
fields_by_name.setdefault(field_name, editable_field) | ||
if values := transform_values(getattr(model, field_name)): | ||
editable_field.primary_sources.append( | ||
EditablePrimarySource( | ||
name=primary_source_name, editor_values=values | ||
) | ||
) | ||
return list(fields_by_name.values()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.