Aligne la hauteur du bouton de recherche sur l'input (débordement en bas)
Le bouton utilisait height:auto, dépendant du padding/line-height par défaut de .btn (~38px), plus haut que l'input fixé à 34px. Fixe la hauteur du bouton à 34px pour qu'il s'aligne avec l'input. Inclut aussi les changements en cours sur recherche.py (tagline dynamique avec stats, home_intro, layout en fonction).
This commit is contained in:
+96
-61
@@ -1,15 +1,47 @@
|
|||||||
|
import math
|
||||||
|
|
||||||
import dash_bootstrap_components as dbc
|
import dash_bootstrap_components as dbc
|
||||||
from dash import Input, Output, State, callback, dcc, html, register_page
|
from dash import Input, Output, State, callback, dcc, html, register_page
|
||||||
|
|
||||||
|
from src.db import count_unique_marches
|
||||||
from src.figures import DataTable
|
from src.figures import DataTable
|
||||||
from src.pages.a_propos.abonnement import abonnement_features
|
from src.pages.a_propos.abonnement import abonnement_features
|
||||||
|
from src.utils.cache import cache
|
||||||
from src.utils.data import DF_ACHETEURS, DF_TITULAIRES
|
from src.utils.data import DF_ACHETEURS, DF_TITULAIRES
|
||||||
from src.utils.search import search_org
|
from src.utils.search import search_org
|
||||||
from src.utils.seo import META_CONTENT
|
from src.utils.seo import META_CONTENT
|
||||||
from src.utils.table import setup_table_columns
|
from src.utils.table import format_number, setup_table_columns
|
||||||
|
|
||||||
NAME = "Recherche"
|
NAME = "Recherche"
|
||||||
|
|
||||||
|
_STAT_STYLE = {"fontWeight": "bold", "color": "var(--primary-color-text)"}
|
||||||
|
|
||||||
|
|
||||||
|
@cache.memoize(timeout=12 * 60 * 60)
|
||||||
|
def _tagline_stats() -> tuple[str, str, str]:
|
||||||
|
nb_acheteurs = format_number(round(DF_ACHETEURS.height, -3))
|
||||||
|
nb_titulaires = format_number(round(DF_TITULAIRES.height, -3))
|
||||||
|
nb_marches_millions = math.floor(count_unique_marches() / 100_000) / 10
|
||||||
|
unite_marches = "million" if nb_marches_millions < 2 else "millions"
|
||||||
|
nb_marches = f"{nb_marches_millions:.1f}".replace(".", ",") + " " + unite_marches
|
||||||
|
return nb_acheteurs, nb_titulaires, nb_marches
|
||||||
|
|
||||||
|
|
||||||
|
def _tagline() -> html.P:
|
||||||
|
nb_acheteurs, nb_titulaires, nb_marches = _tagline_stats()
|
||||||
|
return html.P(
|
||||||
|
[
|
||||||
|
"Recherchez parmi ",
|
||||||
|
html.Span(nb_acheteurs, style=_STAT_STYLE),
|
||||||
|
" acheteurs et ",
|
||||||
|
html.Span(nb_titulaires, style=_STAT_STYLE),
|
||||||
|
" titulaires dans une base de données de plus de ",
|
||||||
|
html.Span(nb_marches, style=_STAT_STYLE),
|
||||||
|
" de marchés publics",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
_features_gratuites = dcc.Markdown("""
|
_features_gratuites = dcc.Markdown("""
|
||||||
- Recherche d'acheteurs et de titulaires
|
- Recherche d'acheteurs et de titulaires
|
||||||
- [Tableau](/tableau) filtrable et personnalisable sur des dizaines de colonnes et exports Excel
|
- [Tableau](/tableau) filtrable et personnalisable sur des dizaines de colonnes et exports Excel
|
||||||
@@ -52,6 +84,7 @@ home_intro = html.Div(
|
|||||||
dcc.Link(
|
dcc.Link(
|
||||||
"En savoir plus et s'abonner",
|
"En savoir plus et s'abonner",
|
||||||
href="/a-propos/abonnement",
|
href="/a-propos/abonnement",
|
||||||
|
style={"marginLeft": "20px"},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
md=6,
|
md=6,
|
||||||
@@ -73,66 +106,68 @@ register_page(
|
|||||||
order=0,
|
order=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
layout = html.Div(
|
|
||||||
className="container",
|
def layout(**_):
|
||||||
children=[
|
return html.Div(
|
||||||
html.Div(
|
className="container",
|
||||||
className="tagline",
|
children=[
|
||||||
children=html.P("Recherchez un acheteur ou un titulaire de marché public"),
|
html.Div(
|
||||||
),
|
className="tagline",
|
||||||
html.Div(
|
children=_tagline(),
|
||||||
style={
|
),
|
||||||
"display": "flex",
|
html.Div(
|
||||||
"justifyContent": "center",
|
style={
|
||||||
"marginTop": "30px",
|
"display": "flex",
|
||||||
"marginBottom": "30px",
|
"justifyContent": "center",
|
||||||
},
|
"marginTop": "30px",
|
||||||
children=[
|
"marginBottom": "30px",
|
||||||
dcc.Input(
|
},
|
||||||
id="search",
|
children=[
|
||||||
type="text",
|
dcc.Input(
|
||||||
placeholder="Nom d'acheteur/entreprise, SIREN/SIRET, code département",
|
id="search",
|
||||||
autoFocus=True,
|
type="text",
|
||||||
style={
|
placeholder="Nom d'acheteur/entreprise, SIREN/SIRET, code département",
|
||||||
"margin": "0",
|
autoFocus=True,
|
||||||
"width": "500px",
|
style={
|
||||||
"border": "1px solid #ccc",
|
"margin": "0",
|
||||||
"borderRight": "none",
|
"width": "500px",
|
||||||
"borderRadius": "3px 0 0 3px",
|
"border": "1px solid #ccc",
|
||||||
"padding": "5px 10px",
|
"borderRight": "none",
|
||||||
"outline": "none",
|
"borderRadius": "3px 0 0 3px",
|
||||||
"height": "34px",
|
"padding": "5px 10px",
|
||||||
},
|
"outline": "none",
|
||||||
),
|
"height": "34px",
|
||||||
html.Button(
|
},
|
||||||
"=>",
|
),
|
||||||
id="search-button",
|
html.Button(
|
||||||
className="btn btn-secondary",
|
"=>",
|
||||||
style={
|
id="search-button",
|
||||||
"border": "1px solid #ccc",
|
className="btn btn-secondary",
|
||||||
"borderRadius": "0 3px 3px 0",
|
style={
|
||||||
"marginLeft": "0",
|
"border": "1px solid #ccc",
|
||||||
"height": "auto", # Ensure it matches input height if necessary, often relying on padding/line-height
|
"borderRadius": "0 3px 3px 0",
|
||||||
},
|
"marginLeft": "0",
|
||||||
),
|
"height": "34px",
|
||||||
],
|
},
|
||||||
),
|
),
|
||||||
html.P(
|
],
|
||||||
[
|
),
|
||||||
"...ou bien filtrez les marchés publics dans la vue ",
|
html.P(
|
||||||
dcc.Link("Tableau", href="/tableau"),
|
[
|
||||||
],
|
"...ou bien filtrez les marchés publics dans la vue ",
|
||||||
style={"textAlign": "center"},
|
dcc.Link("Tableau", href="/tableau"),
|
||||||
id="mention_tableau",
|
],
|
||||||
),
|
style={"textAlign": "center"},
|
||||||
home_intro,
|
id="mention_tableau",
|
||||||
# html.Div(
|
),
|
||||||
# className="search_options",
|
home_intro,
|
||||||
# children=[dcc.RadioItems(options=["Acheteur(s)"])],
|
# html.Div(
|
||||||
# ),
|
# className="search_options",
|
||||||
dbc.Row(id="search_results"),
|
# children=[dcc.RadioItems(options=["Acheteur(s)"])],
|
||||||
],
|
# ),
|
||||||
)
|
dbc.Row(id="search_results"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@callback(
|
@callback(
|
||||||
|
|||||||
@@ -402,3 +402,16 @@ def test_015_org_pages_filter_date(dash_duo: DashComposite):
|
|||||||
# la mise à jour de la grille plutôt que de lire les lignes immédiatement
|
# la mise à jour de la grille plutôt que de lire les lignes immédiatement
|
||||||
# (sinon on lit l'état pré-filtre).
|
# (sinon on lit l'état pré-filtre).
|
||||||
dash_duo.wait_for_no_elements(filter_cell_result, timeout=4)
|
dash_duo.wait_for_no_elements(filter_cell_result, timeout=4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_016_search_button_matches_input_height():
|
||||||
|
# Import app first to initialize Dash
|
||||||
|
from src.app import app # noqa: F401
|
||||||
|
from src.pages.recherche import layout
|
||||||
|
|
||||||
|
search_input, search_button = layout().children[1].children
|
||||||
|
|
||||||
|
assert search_input.style["height"] == search_button.style["height"], (
|
||||||
|
"Le bouton de recherche doit avoir la même hauteur que le champ de "
|
||||||
|
"recherche pour ne pas déborder en bas"
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user