refactor: extrait build_view_query et le réutilise dans le partage #95

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Colin Maudry
2026-06-29 16:19:51 +02:00
parent 03023a6b8c
commit 22fc0cbab2
3 changed files with 55 additions and 13 deletions
+2 -13
View File
@@ -25,6 +25,7 @@ from src.utils import get_data_update_timestamp, logger
from src.utils.seo import META_CONTENT from src.utils.seo import META_CONTENT
from src.utils.table import ( from src.utils.table import (
COLUMNS, COLUMNS,
build_view_query,
filter_table_data, filter_table_data,
get_default_hidden_columns, get_default_hidden_columns,
invert_columns, invert_columns,
@@ -425,19 +426,7 @@ def sync_url_and_reset_button(filter_query, sort_by, hidden_columns, href):
# Extract base URL (remove existing query params) # Extract base URL (remove existing query params)
base_url = href.split("?")[0] base_url = href.split("?")[0]
params = {} query_string = build_view_query(filter_query, sort_by, hidden_columns)
if filter_query:
params["filtres"] = filter_query
if sort_by:
params["tris"] = json.dumps(sort_by)
if hidden_columns:
table_columns = invert_columns(hidden_columns)
table_columns = ",".join(table_columns)
params["colonnes"] = table_columns
query_string = urllib.parse.urlencode(params)
full_url = f"{base_url}?{query_string}" if query_string else base_url full_url = f"{base_url}?{query_string}" if query_string else base_url
copy_button = dcc.Clipboard( copy_button = dcc.Clipboard(
+19
View File
@@ -1,4 +1,6 @@
import json
import os import os
import urllib.parse
import uuid import uuid
import polars as pl import polars as pl
@@ -557,6 +559,23 @@ def invert_columns(columns):
return inverted_columns return inverted_columns
def build_view_query(filter_query, sort_by, hidden_columns) -> str:
"""
Construit la query string d'une vue Tableau (filtres + tris + colonnes),
identique à celle produite par le bouton « Partager la vue ».
hidden_columns : colonnes masquées ; on stocke les colonnes visibles.
"""
params = {}
if filter_query:
params["filtres"] = filter_query
if sort_by:
params["tris"] = json.dumps(sort_by)
if hidden_columns:
params["colonnes"] = ",".join(invert_columns(hidden_columns))
return urllib.parse.urlencode(params)
COLUMNS = schema.names() COLUMNS = schema.names()
_EXCEL_MIN_COLUMN_WIDTH = 132 # ≈ 3.5 cm à 96 DPI _EXCEL_MIN_COLUMN_WIDTH = 132 # ≈ 3.5 cm à 96 DPI
@@ -0,0 +1,34 @@
import urllib.parse
from src.utils.table import build_view_query
def test_empty_inputs_give_empty_string():
assert build_view_query(None, None, None) == ""
assert build_view_query("", [], []) == ""
def test_filter_only():
q = build_view_query("{objet} icontains route", None, None)
params = urllib.parse.parse_qs(q)
assert params["filtres"] == ["{objet} icontains route"]
assert "tris" not in params
assert "colonnes" not in params
def test_sort_is_json_encoded():
sort_by = [{"column_id": "montant", "direction": "desc"}]
q = build_view_query(None, sort_by, None)
params = urllib.parse.parse_qs(q)
import json
assert json.loads(params["tris"][0]) == sort_by
def test_hidden_columns_become_visible_csv():
# build_view_query reçoit les colonnes MASQUÉES et stocke les VISIBLES
q = build_view_query(None, None, ["objet"])
params = urllib.parse.parse_qs(q)
visible = params["colonnes"][0].split(",")
assert "objet" not in visible
assert len(visible) > 0