Ajout d'un menu de navigation
This commit is contained in:
+2
-1
@@ -10,7 +10,8 @@ dependencies = [
|
|||||||
"dash",
|
"dash",
|
||||||
"polars",
|
"polars",
|
||||||
"gunicorn",
|
"gunicorn",
|
||||||
"dash-bootstrap-components"
|
"dash-bootstrap-components",
|
||||||
|
"python-dotenv"
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
|
|||||||
+19
-85
@@ -1,101 +1,35 @@
|
|||||||
from dash import Dash, html, dcc, callback, Output, Input, dash_table
|
from dash import Dash, html, page_container, page_registry, dcc
|
||||||
import polars as pl
|
|
||||||
import dash_bootstrap_components as dbc
|
import dash_bootstrap_components as dbc
|
||||||
|
|
||||||
df = pl.read_parquet("/home/colin/git/decp-processing/dist/2025-04-21/decp.parquet")
|
app = Dash(external_stylesheets=[dbc.themes.UNITED], title="decp.info", use_pages=True)
|
||||||
|
|
||||||
app = Dash(external_stylesheets=[dbc.themes.UNITED], title="decp.info")
|
|
||||||
server = app.server
|
server = app.server
|
||||||
|
|
||||||
datatable = dash_table.DataTable(
|
|
||||||
cell_selectable=False,
|
|
||||||
id="table",
|
|
||||||
data=df.to_dicts(),
|
|
||||||
page_size=20,
|
|
||||||
page_current=0,
|
|
||||||
page_action="native",
|
|
||||||
filter_action="native",
|
|
||||||
filter_options={"case": "insensitive", "placeholder_text": "Filtrer..."},
|
|
||||||
columns=[
|
|
||||||
{"name": i, "id": i, "deletable": True, "selectable": False} for i in df.columns
|
|
||||||
],
|
|
||||||
selected_columns=[],
|
|
||||||
selected_rows=[],
|
|
||||||
sort_action="native",
|
|
||||||
sort_mode="multi",
|
|
||||||
export_format="xlsx",
|
|
||||||
export_columns="visible",
|
|
||||||
export_headers="ids",
|
|
||||||
style_cell_conditional=[
|
|
||||||
{
|
|
||||||
"if": {"column_id": "objet"},
|
|
||||||
"minWidth": "300px",
|
|
||||||
"textAlign": "left",
|
|
||||||
"overflow": "hidden",
|
|
||||||
"lineHeight": "14px",
|
|
||||||
"whiteSpace": "normal",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
app.layout = [
|
app.layout = [
|
||||||
html.H1(children="decp.info"),
|
|
||||||
html.Details(
|
|
||||||
children=[
|
|
||||||
html.Summary("Utilisation"),
|
|
||||||
dcc.Markdown(
|
|
||||||
"""
|
|
||||||
|
|
||||||
**Filtres**
|
|
||||||
|
|
||||||
Vous pouvez appliquer un filtre pour chaque colonne en entrant du texte sous le nom de la colonne, puis en tapant sur `Entrée`.
|
|
||||||
|
|
||||||
- Champs textuels : la recherche est insensible à la casse (majuscules/minuscules).
|
|
||||||
- Champs numériques : possibilité d'ajouter < ou > devant le chiffre recherché pour chercher des valeurs inférieures ou supérieur.
|
|
||||||
|
|
||||||
**Télécharger le résultat**
|
|
||||||
|
|
||||||
Vous pouvez télécharger le résultat de vos filtres et tris en cliquant sur Télécharger au format Excel.
|
|
||||||
|
|
||||||
Les colonnes supprimées seront absentes du fichier téléchargé.
|
|
||||||
|
|
||||||
Si vous téléchargez un volume important de données, il se peut que vous attendiez quelques minutes avant le début du téléchargement.
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
],
|
|
||||||
id="instructions",
|
|
||||||
),
|
|
||||||
html.Div(
|
html.Div(
|
||||||
[
|
[
|
||||||
"Recherche dans objet : ",
|
html.H1("decp.info"),
|
||||||
dcc.Input(id="search", value="", type="text"),
|
html.Div(
|
||||||
]
|
[
|
||||||
),
|
dcc.Link(page["name"], href=page["relative_path"], className="nav")
|
||||||
dcc.Loading(
|
for page in page_registry.values()
|
||||||
overlay_style={"visibility": "visible", "filter": "blur(2px)"},
|
]
|
||||||
id="loading-1",
|
),
|
||||||
type="default",
|
],
|
||||||
children=datatable,
|
className="navbar",
|
||||||
),
|
),
|
||||||
|
page_container,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@callback(
|
|
||||||
Output(component_id="table", component_property="data", allow_duplicate=True),
|
|
||||||
Input(component_id="search", component_property="value"),
|
|
||||||
prevent_initial_call=True,
|
|
||||||
)
|
|
||||||
def global_search(text):
|
|
||||||
new_df = df
|
|
||||||
new_df = new_df.filter(pl.col("objet").str.contains("(?i)" + text))
|
|
||||||
return new_df.to_dicts()
|
|
||||||
|
|
||||||
|
|
||||||
# @callback(
|
# @callback(
|
||||||
# Output("table", "data"), Input("table", "page_current"), Input("table", "page_size")
|
# Output(component_id="table", component_property="data", allow_duplicate=True),
|
||||||
|
# Input(component_id="search", component_property="value"),
|
||||||
|
# prevent_initial_call=True,
|
||||||
# )
|
# )
|
||||||
# def update_table(page_current, page_size):
|
# def global_search(text):
|
||||||
# return df[page_current * page_size : (page_current + 1) * page_size].to_dicts()
|
# new_df = df
|
||||||
|
# new_df = new_df.filter(pl.col("objet").str.contains("(?i)" + text))
|
||||||
|
# return new_df.to_dicts()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -17,3 +17,44 @@ input.dash-filter--case {
|
|||||||
td[data-dash-column="objet"] {
|
td[data-dash-column="objet"] {
|
||||||
font-size: 85%;
|
font-size: 85%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dash-table-container
|
||||||
|
.dash-spreadsheet-container
|
||||||
|
.dash-spreadsheet-inner
|
||||||
|
th.dash-header {
|
||||||
|
background-color: #666986;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dash-table-container
|
||||||
|
.dash-spreadsheet-container
|
||||||
|
.dash-spreadsheet-inner
|
||||||
|
th.dash-filter {
|
||||||
|
background-color: #d0d2e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header > *,
|
||||||
|
.dash-spreadsheet-menu button.export {
|
||||||
|
margin: 0 0 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
width: 100%;
|
||||||
|
height: 100px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.nav {
|
||||||
|
float: left;
|
||||||
|
margin-right: 40px;
|
||||||
|
font-size: 120%;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
float: left;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
from dash import register_page, html, page_registry
|
||||||
|
|
||||||
|
title = "À propos"
|
||||||
|
|
||||||
|
register_page(
|
||||||
|
__name__, path="/a-propos", title=f"decp.info - {title}", name=title, order=3
|
||||||
|
)
|
||||||
|
|
||||||
|
layout = [html.H2(title)]
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
from dash import (
|
||||||
|
Dash,
|
||||||
|
html,
|
||||||
|
dcc,
|
||||||
|
callback,
|
||||||
|
Output,
|
||||||
|
Input,
|
||||||
|
dash_table,
|
||||||
|
page_container,
|
||||||
|
register_page,
|
||||||
|
)
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
import os
|
||||||
|
import polars as pl
|
||||||
|
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
df = pl.read_parquet(os.getenv("DATA_FILE_PARQUET_PATH"))
|
||||||
|
|
||||||
|
title = "Tableau"
|
||||||
|
register_page(__name__, path="/", title=f"decp.info - {title}", name=title, order=1)
|
||||||
|
|
||||||
|
datatable = dash_table.DataTable(
|
||||||
|
cell_selectable=False,
|
||||||
|
id="table",
|
||||||
|
data=df.to_dicts(),
|
||||||
|
page_size=20,
|
||||||
|
page_current=0,
|
||||||
|
page_action="native",
|
||||||
|
filter_action="native",
|
||||||
|
filter_options={"case": "insensitive", "placeholder_text": "Filtrer..."},
|
||||||
|
columns=[
|
||||||
|
{"name": i, "id": i, "deletable": True, "selectable": False} for i in df.columns
|
||||||
|
],
|
||||||
|
selected_columns=[],
|
||||||
|
selected_rows=[],
|
||||||
|
sort_action="native",
|
||||||
|
sort_mode="multi",
|
||||||
|
export_format="xlsx",
|
||||||
|
export_columns="visible",
|
||||||
|
export_headers="ids",
|
||||||
|
style_cell_conditional=[
|
||||||
|
{
|
||||||
|
"if": {"column_id": "objet"},
|
||||||
|
"minWidth": "300px",
|
||||||
|
"textAlign": "left",
|
||||||
|
"overflow": "hidden",
|
||||||
|
"lineHeight": "14px",
|
||||||
|
"whiteSpace": "normal",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
layout = [
|
||||||
|
html.Div(
|
||||||
|
html.Details(
|
||||||
|
children=[
|
||||||
|
html.Summary(html.H3("Utilisation")),
|
||||||
|
dcc.Markdown(
|
||||||
|
"""
|
||||||
|
|
||||||
|
**Filtres**
|
||||||
|
|
||||||
|
Vous pouvez appliquer un filtre pour chaque colonne en entrant du texte sous le nom de la colonne, puis en tapant sur `Entrée`.
|
||||||
|
|
||||||
|
- Champs textuels : la recherche est insensible à la casse (majuscules/minuscules).
|
||||||
|
- Champs numériques : possibilité d'ajouter < ou > devant le chiffre recherché pour chercher des valeurs inférieures ou supérieur.
|
||||||
|
|
||||||
|
**Télécharger le résultat**
|
||||||
|
|
||||||
|
Vous pouvez télécharger le résultat de vos filtres et tris en cliquant sur Télécharger au format Excel.
|
||||||
|
|
||||||
|
Les colonnes supprimées seront absentes du fichier téléchargé.
|
||||||
|
|
||||||
|
Si vous téléchargez un volume important de données, il se peut que vous attendiez quelques minutes avant le début du téléchargement.
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
],
|
||||||
|
id="instructions",
|
||||||
|
),
|
||||||
|
id="header",
|
||||||
|
),
|
||||||
|
# html.Div(
|
||||||
|
# [
|
||||||
|
# "Recherche dans objet : ",
|
||||||
|
# dcc.Input(id="search", value="", type="text"),
|
||||||
|
# ]
|
||||||
|
# )]),
|
||||||
|
dcc.Loading(
|
||||||
|
overlay_style={"visibility": "visible", "filter": "blur(2px)"},
|
||||||
|
id="loading-1",
|
||||||
|
type="default",
|
||||||
|
children=datatable,
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
from dash import register_page, html
|
||||||
|
|
||||||
|
title = "Statistiques"
|
||||||
|
|
||||||
|
register_page(
|
||||||
|
__name__, path="/statistiques", title=f"decp.info - {title}", name=title, order=2
|
||||||
|
)
|
||||||
|
|
||||||
|
layout = [html.H2(title)]
|
||||||
Reference in New Issue
Block a user