refactor(tableau): barre d'outils compacte sur une ligne + légende d'aide
Barre d'outils repensée au-dessus du tableau : - boutons compacts (size=sm) sur une seule rangée + ligne d'infos discrète en dessous (2 lignes au total sur desktop) - libellés explicites (Sauvegarder la vue, Partager la vue, Télécharger (Excel)), espacement homogène, couleurs conformes à la charte (neutre=secondary, Réinitialiser=danger outline) - Mode d'emploi rejeté en fin de barre via CSS order (DOM/callbacks intacts) - .table-menu (3 autres pages) laissée intacte Téléchargement bloqué (>65 000 lignes) : la raison s'affiche en clair dans la ligne d'infos (fiable cross-browser) plutôt que dans une infobulle sur bouton désactivé. Override scopé au tableau via update_table ; acheteur/ titulaire non touchés. Mode d'emploi : légende en tête listant chaque bouton reproduit (inerte) en face de sa fonction. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -320,6 +320,55 @@ input[type="email"] {
|
|||||||
margin: 8px 16px 8px 0;
|
margin: 8px 16px 8px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Barre d'outils du tableau (/tableau) : une rangée d'actions compactes
|
||||||
|
au-dessus d'une ligne d'infos discrète. .table-menu (autres pages) intacte. */
|
||||||
|
.table-toolbar {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
margin: 14px 0 6px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-toolbar > * {
|
||||||
|
margin: 0 12px 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mode d'emploi : aide auxiliaire, rejetée en fin de barre sans toucher au DOM */
|
||||||
|
.table-toolbar #tableau_help_open {
|
||||||
|
order: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-meta {
|
||||||
|
margin: 0 0 16px 0;
|
||||||
|
color: #666;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Raison du téléchargement bloqué : visible (pas une infobulle), mise en avant
|
||||||
|
sobrement avec la couleur terracotta de la marque. */
|
||||||
|
.table-meta .dl-hint {
|
||||||
|
color: #b33821;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Légende des boutons en tête du mode d'emploi : boutons reproduits à
|
||||||
|
l'identique mais inertes, alignés en face de leur fonction. */
|
||||||
|
.help-legend-table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.help-legend-table td {
|
||||||
|
padding: 4px 16px 4px 0;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.help-legend-btn {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.help-legend .btn {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
#source_table {
|
#source_table {
|
||||||
margin-bottom: 25px;
|
margin-bottom: 25px;
|
||||||
}
|
}
|
||||||
|
|||||||
+120
-19
@@ -78,6 +78,62 @@ DATATABLE = html.Div(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _help_button_legend():
|
||||||
|
"""Légende en tête du mode d'emploi : chaque bouton de la barre d'outils,
|
||||||
|
reproduit à l'identique (mais inerte), en face de sa fonction."""
|
||||||
|
rows = [
|
||||||
|
(
|
||||||
|
dbc.Button("Colonnes", color="secondary", size="sm"),
|
||||||
|
"Choisir les colonnes affichées.",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
dbc.Button("Sauvegarder la vue", color="secondary", size="sm"),
|
||||||
|
"Enregistrer les filtres, tris et colonnes actuels sous un nom (abonnés).",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
dbc.Button("Mes vues ▾", color="secondary", size="sm"),
|
||||||
|
"Rouvrir une vue que vous avez enregistrée (abonnés).",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
dbc.Button("Partager la vue", color="secondary", size="sm"),
|
||||||
|
"Copier l'adresse de la vue actuelle pour la partager ou la conserver.",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
dbc.Button("Télécharger (Excel)", color="secondary", size="sm"),
|
||||||
|
"Télécharger les données filtrées et triées au format Excel.",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
dbc.Button("Réinitialiser", color="danger", outline=True, size="sm"),
|
||||||
|
"Supprimer tous les filtres et tris.",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
dbc.Button("Mode d'emploi", color="secondary", outline=True, size="sm"),
|
||||||
|
"Ouvrir cette aide.",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
return html.Div(
|
||||||
|
className="help-legend",
|
||||||
|
children=[
|
||||||
|
html.P("Les boutons de la barre d'outils", className="fw-bold mb-2"),
|
||||||
|
html.Table(
|
||||||
|
className="help-legend-table",
|
||||||
|
children=html.Tbody(
|
||||||
|
[
|
||||||
|
html.Tr(
|
||||||
|
[
|
||||||
|
html.Td(btn, className="help-legend-btn"),
|
||||||
|
html.Td(desc, className="help-legend-desc"),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
for btn, desc in rows
|
||||||
|
]
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
layout = [
|
layout = [
|
||||||
dcc.Location(id="tableau_url", refresh=False),
|
dcc.Location(id="tableau_url", refresh=False),
|
||||||
dcc.Store(id="filter-cleanup-trigger-tableau"),
|
dcc.Store(id="filter-cleanup-trigger-tableau"),
|
||||||
@@ -160,14 +216,23 @@ layout = [
|
|||||||
html.Div(
|
html.Div(
|
||||||
[
|
[
|
||||||
# Modal du mode d'emploi
|
# Modal du mode d'emploi
|
||||||
dbc.Button("Mode d'emploi", id="tableau_help_open"),
|
dbc.Button(
|
||||||
|
"Mode d'emploi",
|
||||||
|
id="tableau_help_open",
|
||||||
|
color="secondary",
|
||||||
|
outline=True,
|
||||||
|
size="sm",
|
||||||
|
),
|
||||||
dbc.Modal(
|
dbc.Modal(
|
||||||
[
|
[
|
||||||
dbc.ModalHeader(dbc.ModalTitle("Mode d'emploi")),
|
dbc.ModalHeader(dbc.ModalTitle("Mode d'emploi")),
|
||||||
dbc.ModalBody(
|
dbc.ModalBody(
|
||||||
dcc.Markdown(
|
[
|
||||||
dangerously_allow_html=True,
|
_help_button_legend(),
|
||||||
children=f"""
|
html.Hr(),
|
||||||
|
dcc.Markdown(
|
||||||
|
dangerously_allow_html=True,
|
||||||
|
children=f"""
|
||||||
##### Définition des colonnes
|
##### Définition des colonnes
|
||||||
|
|
||||||
Pour voir la définition d'une colonne, passez votre souris sur son en-tête.
|
Pour voir la définition d'une colonne, passez votre souris sur son en-tête.
|
||||||
@@ -226,7 +291,8 @@ layout = [
|
|||||||
(informations, marchés attribués/remportés, etc.)
|
(informations, marchés attribués/remportés, etc.)
|
||||||
|
|
||||||
""",
|
""",
|
||||||
),
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
dbc.ModalFooter(
|
dbc.ModalFooter(
|
||||||
dbc.Button(
|
dbc.Button(
|
||||||
@@ -245,8 +311,10 @@ layout = [
|
|||||||
),
|
),
|
||||||
# Bouton modal des colonnes affichées
|
# Bouton modal des colonnes affichées
|
||||||
dbc.Button(
|
dbc.Button(
|
||||||
"Choisir les colonnes",
|
"Colonnes",
|
||||||
id="tableau_columns_open",
|
id="tableau_columns_open",
|
||||||
|
color="secondary",
|
||||||
|
size="sm",
|
||||||
className="column_list",
|
className="column_list",
|
||||||
title="Choisir les colonnes à afficher et masquer",
|
title="Choisir les colonnes à afficher et masquer",
|
||||||
),
|
),
|
||||||
@@ -258,11 +326,15 @@ layout = [
|
|||||||
dbc.Button(
|
dbc.Button(
|
||||||
"Sauvegarder la vue",
|
"Sauvegarder la vue",
|
||||||
id="btn-save-view",
|
id="btn-save-view",
|
||||||
|
color="secondary",
|
||||||
|
size="sm",
|
||||||
title="Enregistrer les filtres, tris et colonnes actuels sous un nom",
|
title="Enregistrer les filtres, tris et colonnes actuels sous un nom",
|
||||||
),
|
),
|
||||||
dbc.DropdownMenu(
|
dbc.DropdownMenu(
|
||||||
id="saved-views-menu",
|
id="saved-views-menu",
|
||||||
label="Mes vues",
|
label="Mes vues",
|
||||||
|
color="secondary",
|
||||||
|
size="sm",
|
||||||
children=[],
|
children=[],
|
||||||
className="d-inline-block",
|
className="d-inline-block",
|
||||||
),
|
),
|
||||||
@@ -294,24 +366,35 @@ layout = [
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
html.P("lignes", id="nb_rows"),
|
|
||||||
html.Div(id="copy-container"),
|
html.Div(id="copy-container"),
|
||||||
dcc.Input(id="share-url", readOnly=True, style={"display": "none"}),
|
dcc.Input(id="share-url", readOnly=True, style={"display": "none"}),
|
||||||
dbc.Button(
|
dbc.Button(
|
||||||
"Téléchargement désactivé au-delà de 65 000 lignes",
|
"Télécharger (Excel)",
|
||||||
id="btn-download-data",
|
id="btn-download-data",
|
||||||
|
color="secondary",
|
||||||
|
size="sm",
|
||||||
disabled=True,
|
disabled=True,
|
||||||
),
|
),
|
||||||
dcc.Download(id="download-data"),
|
dcc.Download(id="download-data"),
|
||||||
dcc.Store(id="filtered_data", storage_type="memory"),
|
dcc.Store(id="filtered_data", storage_type="memory"),
|
||||||
html.P("Données mises à jour le " + str(update_date)),
|
|
||||||
dbc.Button(
|
dbc.Button(
|
||||||
"Remettre à zéro",
|
"Réinitialiser",
|
||||||
title="Supprime tous les filtres et les tris. Autrement ils sont conservés même si vous fermez la page.",
|
|
||||||
id="btn-tableau-reset",
|
id="btn-tableau-reset",
|
||||||
|
color="danger",
|
||||||
|
outline=True,
|
||||||
|
size="sm",
|
||||||
|
title="Supprime tous les filtres et les tris. Autrement ils sont conservés même si vous fermez la page.",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
className="table-menu",
|
className="table-toolbar",
|
||||||
|
),
|
||||||
|
html.Div(
|
||||||
|
className="table-meta",
|
||||||
|
children=[
|
||||||
|
html.Span(id="nb_rows"),
|
||||||
|
html.Span(" · Données mises à jour le " + str(update_date)),
|
||||||
|
html.Span(id="download-hint", className="dl-hint"),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
dbc.Modal(
|
dbc.Modal(
|
||||||
[
|
[
|
||||||
@@ -351,6 +434,7 @@ layout = [
|
|||||||
Output("btn-download-data", "children"),
|
Output("btn-download-data", "children"),
|
||||||
Output("btn-download-data", "title"),
|
Output("btn-download-data", "title"),
|
||||||
Output("filter-cleanup-trigger-tableau", "data", allow_duplicate=True),
|
Output("filter-cleanup-trigger-tableau", "data", allow_duplicate=True),
|
||||||
|
Output("download-hint", "children"),
|
||||||
Input("tableau_url", "href"),
|
Input("tableau_url", "href"),
|
||||||
Input("tableau_datatable", "page_current"),
|
Input("tableau_datatable", "page_current"),
|
||||||
Input("tableau_datatable", "page_size"),
|
Input("tableau_datatable", "page_size"),
|
||||||
@@ -360,13 +444,29 @@ layout = [
|
|||||||
prevent_initial_call=True,
|
prevent_initial_call=True,
|
||||||
)
|
)
|
||||||
def update_table(href, page_current, page_size, filter_query, sort_by, data_timestamp):
|
def update_table(href, page_current, page_size, filter_query, sort_by, data_timestamp):
|
||||||
# if ctx.triggered_id != "url":
|
result = list(
|
||||||
# search_params = None
|
prepare_table_data(
|
||||||
# else:
|
None,
|
||||||
# search_params = urllib.parse.parse_qs(search_params.lstrip("?"))
|
data_timestamp,
|
||||||
return prepare_table_data(
|
filter_query,
|
||||||
None, data_timestamp, filter_query, page_current, page_size, sort_by, "tableau"
|
page_current,
|
||||||
|
page_size,
|
||||||
|
sort_by,
|
||||||
|
"tableau",
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
# Libellé court et constant ; la raison d'un éventuel blocage est affichée
|
||||||
|
# en clair dans la ligne d'infos (fiable cross-browser, contrairement à une
|
||||||
|
# infobulle sur bouton désactivé). index 5 = disabled, 6 = children, 7 = title.
|
||||||
|
result[6] = "Télécharger (Excel)"
|
||||||
|
download_blocked_too_many = result[5] and result[7]
|
||||||
|
download_hint = (
|
||||||
|
" · Filtrez sous 65 000 lignes pour activer le téléchargement"
|
||||||
|
if download_blocked_too_many
|
||||||
|
else ""
|
||||||
|
)
|
||||||
|
result.append(download_hint)
|
||||||
|
return tuple(result)
|
||||||
|
|
||||||
|
|
||||||
@callback(
|
@callback(
|
||||||
@@ -491,7 +591,8 @@ def sync_url_and_reset_button(filter_query, sort_by, hidden_columns, href):
|
|||||||
children=[
|
children=[
|
||||||
dbc.Button(
|
dbc.Button(
|
||||||
"Partager la vue",
|
"Partager la vue",
|
||||||
className="btn btn-primary",
|
color="secondary",
|
||||||
|
size="sm",
|
||||||
title="Copier l'adresse de cette vue (filtres, tris, choix de colonnes) pour la partager.",
|
title="Copier l'adresse de cette vue (filtres, tris, choix de colonnes) pour la partager.",
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user