diff --git a/src/aki_prj23_transparenzregister/ui/pages/home.py b/src/aki_prj23_transparenzregister/ui/pages/home.py index 7939bc7..5ced1f6 100644 --- a/src/aki_prj23_transparenzregister/ui/pages/home.py +++ b/src/aki_prj23_transparenzregister/ui/pages/home.py @@ -1,4 +1,5 @@ """Content of home page.""" +import os from functools import lru_cache import dash @@ -10,6 +11,7 @@ from cachetools import TTLCache, cached from dash import Input, Output, callback, dash_table, dcc, html from loguru import logger +from aki_prj23_transparenzregister.ui.session_handler import SessionHandler from aki_prj23_transparenzregister.utils.networkx.network_2d import ( create_2d_graph, ) @@ -26,6 +28,7 @@ from aki_prj23_transparenzregister.utils.networkx.networkx_data import ( get_all_company_relations, get_all_person_relations, ) +from aki_prj23_transparenzregister.utils.sql import entities dash.register_page( __name__, @@ -363,6 +366,39 @@ def update_graph_data( return graph, metrics, nodes_tmp, edges_tmp +@callback(Output("url", "href"), [Input("my-graph", "clickData")]) +def redirect(click_data: dict) -> str: + """Redirects on clicking on an entity to that entity.""" + if not click_data: + return dash.no_update + logger.debug(click_data) + db = SessionHandler.session + if not db: + raise ValueError("No SQL session defined.") + home_path = os.getenv("DASH_URL_BASE_PATHNAME", "") + id = ( + db.query(entities.Company.id) + .filter(entities.Company.name == click_data["points"][0]["text"]) + .first() + ) + if id: + url = f"{home_path}/unternehmensdetails/{id[0]}" + logger.info("Redirecting to detail page: url") + return url + concatenated_name = entities.Person.firstname + " " + entities.Person.lastname + id = ( + db.query(entities.Person.id) + .filter(concatenated_name == click_data["points"][0]["text"]) + .first() + ) + if id: + url = f"{home_path}/personendetails/{id[0]}" + logger.info("Redirecting to detail page: url") + return url + return dash.no_update + # Prevent update if no data point was clicked + + @callback( [ Output("metric_table", "data"), diff --git a/tests/ui/home_page_test.py b/tests/ui/home_page_test.py index e00d118..2309a12 100644 --- a/tests/ui/home_page_test.py +++ b/tests/ui/home_page_test.py @@ -1,8 +1,10 @@ """Test for the Home Page.""" import datetime from collections.abc import Generator +from typing import Any from unittest.mock import patch +import dash import pandas as pd import pytest from sqlalchemy.orm import Session @@ -205,3 +207,33 @@ def _set_session(full_db: Session) -> Generator[None, None, None]: def test_layout() -> None: """Checks if layout can be executed.""" home.layout() + + +@pytest.mark.usefixtures("_set_session") +@pytest.mark.parametrize("empty", ["", None, {}]) +def test_redirect_empty(empty: Any) -> None: + """Tests the redirection on clicking on the plot with an empty argument.""" + assert home.redirect(empty) == dash.no_update # type: ignore + + +def test_redirect_content_without_db() -> None: + """Tests the error when no SQL session is defined.""" + with pytest.raises(ValueError, match="No SQL session defined."): + assert home.redirect({"empty": ""}) + + +@pytest.mark.usefixtures("_set_session") +@pytest.mark.parametrize( + ("click_on", "redirect_to"), + [ + ( + {"text": "Some Company GmbH"}, + "/unternehmensdetails/1", + ), + ({"text": "Max Mustermann"}, "/personendetails/1"), + ({"text": "I do not exist"}, dash.no_update), + ], +) +def test_redirect(click_on: dict, redirect_to: Any) -> None: + """Tests the redirection when clicking on a plot.""" + assert home.redirect({"points": [click_on]}) == redirect_to