URL partageable pour la page observatoire #65
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -274,6 +274,12 @@ Alors, on fait comment ?
|
||||
disabled=True,
|
||||
className="mt-2",
|
||||
),
|
||||
dcc.Input(
|
||||
id="observatoire-share-url",
|
||||
readOnly=True,
|
||||
style={"display": "none"},
|
||||
),
|
||||
html.Div(id="observatoire-copy-container"),
|
||||
],
|
||||
),
|
||||
dbc.Col(
|
||||
@@ -310,6 +316,52 @@ def restore_filters_from_url(search):
|
||||
return acheteur_id, titulaire_id, ""
|
||||
|
||||
|
||||
@callback(
|
||||
Output("observatoire-share-url", "value"),
|
||||
Output("observatoire-copy-container", "children"),
|
||||
Input("dashboard_acheteur_id", "value"),
|
||||
Input("dashboard_titulaire_id", "value"),
|
||||
State("dashboard_url", "href"),
|
||||
prevent_initial_call=True,
|
||||
)
|
||||
def sync_observatoire_share_url(acheteur_id, titulaire_id, href):
|
||||
if not href:
|
||||
return no_update, no_update
|
||||
|
||||
base_url = href.split("?")[0]
|
||||
|
||||
params = {}
|
||||
if acheteur_id:
|
||||
params["acheteur_id"] = acheteur_id
|
||||
if titulaire_id:
|
||||
params["titulaire_id"] = titulaire_id
|
||||
|
||||
query_string = urllib.parse.urlencode(params)
|
||||
full_url = f"{base_url}?{query_string}" if query_string else base_url
|
||||
|
||||
copy_button = dcc.Clipboard(
|
||||
id="btn-copy-observatoire-url",
|
||||
target_id="observatoire-share-url",
|
||||
title="Copier l'URL de cette vue",
|
||||
style={
|
||||
"display": "inline-block",
|
||||
"fontSize": 20,
|
||||
"verticalAlign": "top",
|
||||
"cursor": "pointer",
|
||||
},
|
||||
className="fa fa-link",
|
||||
children=[
|
||||
dbc.Button(
|
||||
"Partager",
|
||||
className="btn btn-primary mt-2",
|
||||
title="Copier l'adresse de cette vue filtrée pour la partager.",
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
return full_url, copy_button
|
||||
|
||||
|
||||
@callback(
|
||||
Output("cards", "children"),
|
||||
Output("btn-download-observatoire", "disabled"),
|
||||
|
||||
@@ -157,3 +157,25 @@ def test_006_observatoire_url_to_input(dash_duo: DashComposite):
|
||||
assert acheteur_input.get_attribute("value") == "a1", (
|
||||
"acheteur_id input should be populated from URL param"
|
||||
)
|
||||
|
||||
|
||||
def test_007_observatoire_share_url(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("#observatoire-share-url", timeout=4)
|
||||
|
||||
import time
|
||||
|
||||
time.sleep(1) # Allow callback chain to complete
|
||||
|
||||
share_url_input = dash_duo.find_element("#observatoire-share-url")
|
||||
share_url_value = share_url_input.get_attribute("value")
|
||||
|
||||
assert "acheteur_id=a1" in share_url_value, (
|
||||
f"Share URL should contain acheteur_id param, got: {share_url_value}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user