Callback URL → filtres sur la page observatoire #65
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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"),
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user