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,
|
disabled=True,
|
||||||
className="mt-2",
|
className="mt-2",
|
||||||
),
|
),
|
||||||
|
dcc.Input(
|
||||||
|
id="observatoire-share-url",
|
||||||
|
readOnly=True,
|
||||||
|
style={"display": "none"},
|
||||||
|
),
|
||||||
|
html.Div(id="observatoire-copy-container"),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
dbc.Col(
|
dbc.Col(
|
||||||
@@ -310,6 +316,52 @@ def restore_filters_from_url(search):
|
|||||||
return acheteur_id, titulaire_id, ""
|
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(
|
@callback(
|
||||||
Output("cards", "children"),
|
Output("cards", "children"),
|
||||||
Output("btn-download-observatoire", "disabled"),
|
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", (
|
assert acheteur_input.get_attribute("value") == "a1", (
|
||||||
"acheteur_id input should be populated from URL param"
|
"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