Callback URL → filtres sur la page observatoire #65

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Colin Maudry
2026-03-18 14:55:41 +01:00
parent bf1791635f
commit 3745f6df74
3 changed files with 57 additions and 2 deletions
+32 -2
View File
@@ -1,9 +1,21 @@
import urllib.parse
from datetime import datetime, timedelta
import dash_bootstrap_components as dbc
import polars as pl
import polars.selectors as cs
from dash import ALL, Input, Output, State, callback, ctx, dcc, html, register_page
from dash import (
ALL,
Input,
Output,
State,
callback,
ctx,
dcc,
html,
no_update,
register_page,
)
from src.figures import (
get_barchart_sources,
@@ -107,7 +119,7 @@ def _apply_filters(
layout = [
dcc.Store(id="dashboard-filters"),
dcc.Location(id="dashboard_url"),
dcc.Location(id="dashboard_url", refresh="callback-nav"),
dbc.Modal(
[
dbc.ModalHeader(dbc.ModalTitle("Montants")),
@@ -280,6 +292,24 @@ Alors, on fait comment ?
]
@callback(
Output("dashboard_acheteur_id", "value"),
Output("dashboard_titulaire_id", "value"),
Output("dashboard_url", "search"),
Input("dashboard_url", "search"),
)
def restore_filters_from_url(search):
if not search:
return no_update, no_update, no_update
params = urllib.parse.parse_qs(search.lstrip("?"))
acheteur_id = params.get("acheteur_id", [None])[0] or no_update
titulaire_id = params.get("titulaire_id", [None])[0] or no_update
return acheteur_id, titulaire_id, ""
@callback(
Output("cards", "children"),
Output("btn-download-observatoire", "disabled"),
+5
View File
@@ -34,6 +34,11 @@ def test_data():
"sourceFile": "test.xml",
"sourceDataset": "test_dataset",
"datePublicationDonnees": datetime.date(2025, 1, 1),
"considerationsSociales": "",
"considerationsEnvironnementales": "",
"type": "Marché",
"acheteur_categorie": "Collectivité",
"titulaire_categorie": "PME",
}
]
path = "tests/test.parquet"
+20
View File
@@ -137,3 +137,23 @@ def test_005_add_links_observatoire_titulaire():
# titulaire_id should NOT contain observatoire link
assert "/observatoire" not in id_value
def test_006_observatoire_url_to_input(dash_duo: DashComposite):
from src.app import app
dash_duo.start_server(app)
dash_duo.wait_for_text_to_equal(".logo > h1", "decp.info", timeout=4)
# Navigate to observatoire with acheteur_id query param
dash_duo.wait_for_page(f"{dash_duo.server_url}/observatoire?acheteur_id=a1")
dash_duo.wait_for_element("#dashboard_acheteur_id", timeout=4)
import time
time.sleep(1) # Allow callback chain to complete
acheteur_input = dash_duo.find_element("#dashboard_acheteur_id")
assert acheteur_input.get_attribute("value") == "a1", (
"acheteur_id input should be populated from URL param"
)