Tableau de choix des colonnes aussi sur les pages acheteur et titulaire
This commit is contained in:
@@ -354,15 +354,17 @@ table.cell-table th {
|
|||||||
position: relative;
|
position: relative;
|
||||||
width: 180px;
|
width: 180px;
|
||||||
margin: 0 0 10px 0;
|
margin: 0 0 10px 0;
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
.show-hide::before {
|
.show-hide::before {
|
||||||
background: inherit;
|
background: inherit;
|
||||||
content: "Colonnes affichées";
|
content: "Colonnes affichées";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 5px;
|
left: 5px;
|
||||||
right: 5px;
|
right: 5px;
|
||||||
}
|
|
||||||
|
|
||||||
#column_list .show-hide,
|
#column_list .show-hide,
|
||||||
#table .show-hide {
|
#table .show-hide {
|
||||||
@@ -371,7 +373,7 @@ table.cell-table th {
|
|||||||
|
|
||||||
.show-hide-menu-item > input {
|
.show-hide-menu-item > input {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
} */
|
||||||
|
|
||||||
/* Tooltips */
|
/* Tooltips */
|
||||||
.dash-tooltip,
|
.dash-tooltip,
|
||||||
|
|||||||
+59
-5
@@ -6,10 +6,10 @@ import plotly.graph_objects as go
|
|||||||
import polars as pl
|
import polars as pl
|
||||||
from dash import dash_table, dcc, html
|
from dash import dash_table, dcc, html
|
||||||
|
|
||||||
from src.utils import data_schema, format_number
|
from src.utils import data_schema, df, format_number
|
||||||
|
|
||||||
|
|
||||||
def get_map_count_marches(df: pl.DataFrame):
|
def get_map_count_marches():
|
||||||
lf = df.lazy()
|
lf = df.lazy()
|
||||||
lf = lf.with_columns(
|
lf = lf.with_columns(
|
||||||
pl.col("lieuExecution_code").str.head(2).str.zfill(2).alias("Département")
|
pl.col("lieuExecution_code").str.head(2).str.zfill(2).alias("Département")
|
||||||
@@ -31,16 +31,16 @@ def get_map_count_marches(df: pl.DataFrame):
|
|||||||
for f in departements["features"]:
|
for f in departements["features"]:
|
||||||
f["id"] = f["properties"]["code"]
|
f["id"] = f["properties"]["code"]
|
||||||
|
|
||||||
df = lf.collect(engine="streaming")
|
df_map = lf.collect(engine="streaming")
|
||||||
|
|
||||||
fig = px.choropleth(
|
fig = px.choropleth(
|
||||||
df,
|
df_map,
|
||||||
geojson=departements,
|
geojson=departements,
|
||||||
locations="Département",
|
locations="Département",
|
||||||
color="uid",
|
color="uid",
|
||||||
color_continuous_scale="Reds",
|
color_continuous_scale="Reds",
|
||||||
title="Nombres de marchés attribués par département (lieu d'exécution)",
|
title="Nombres de marchés attribués par département (lieu d'exécution)",
|
||||||
range_color=(df["uid"].min(), df["uid"].max()),
|
range_color=(df_map["uid"].min(), df_map["uid"].max()),
|
||||||
labels={"uid": "Marchés attribués"},
|
labels={"uid": "Marchés attribués"},
|
||||||
scope="europe",
|
scope="europe",
|
||||||
width=900,
|
width=900,
|
||||||
@@ -414,3 +414,57 @@ def get_duplicate_matrix() -> html.Div:
|
|||||||
dcc.Graph(figure=fig),
|
dcc.Graph(figure=fig),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def make_column_picker(page: str):
|
||||||
|
table_data = []
|
||||||
|
table_columns = [
|
||||||
|
{
|
||||||
|
"id": col,
|
||||||
|
"name": data_schema[col]["title"],
|
||||||
|
"description": data_schema[col]["description"],
|
||||||
|
}
|
||||||
|
for col in df.columns
|
||||||
|
]
|
||||||
|
for column in table_columns:
|
||||||
|
new_column = {
|
||||||
|
"id": column["id"],
|
||||||
|
"name": column["name"],
|
||||||
|
"description": data_schema[column["id"]]["description"],
|
||||||
|
}
|
||||||
|
table_data.append(new_column)
|
||||||
|
|
||||||
|
table = (
|
||||||
|
DataTable(
|
||||||
|
row_selectable="multi",
|
||||||
|
data=table_data,
|
||||||
|
filter_action="native",
|
||||||
|
sort_action="none",
|
||||||
|
style_cell={
|
||||||
|
"textAlign": "left",
|
||||||
|
},
|
||||||
|
columns=[
|
||||||
|
{
|
||||||
|
"name": "Nom",
|
||||||
|
"id": "name",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Description",
|
||||||
|
"id": "description",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
style_cell_conditional=[
|
||||||
|
{
|
||||||
|
"if": {"column_id": "description"},
|
||||||
|
"minWidth": "450px",
|
||||||
|
"overflow": "hidden",
|
||||||
|
"lineHeight": "18px",
|
||||||
|
"whiteSpace": "normal",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
page_action="none",
|
||||||
|
dtid=f"{page}_column_list",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
return table
|
||||||
|
|||||||
+83
-1
@@ -1,11 +1,13 @@
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
import dash_bootstrap_components as dbc
|
||||||
import polars as pl
|
import polars as pl
|
||||||
from dash import Input, Output, State, callback, dcc, html, register_page
|
from dash import Input, Output, State, callback, dcc, html, register_page
|
||||||
|
|
||||||
from src.callbacks import get_top_org_table
|
from src.callbacks import get_top_org_table
|
||||||
from src.figures import DataTable, point_on_map
|
from src.figures import DataTable, make_column_picker, point_on_map
|
||||||
from src.utils import (
|
from src.utils import (
|
||||||
|
columns,
|
||||||
df,
|
df,
|
||||||
df_acheteurs,
|
df_acheteurs,
|
||||||
filter_table_data,
|
filter_table_data,
|
||||||
@@ -53,6 +55,7 @@ datatable = html.Div(
|
|||||||
|
|
||||||
layout = [
|
layout = [
|
||||||
dcc.Store(id="acheteur_data", storage_type="memory"),
|
dcc.Store(id="acheteur_data", storage_type="memory"),
|
||||||
|
dcc.Store(id="acheteur-hidden-columns", storage_type="memory"),
|
||||||
dcc.Location(id="acheteur_url", refresh="callback-nav"),
|
dcc.Location(id="acheteur_url", refresh="callback-nav"),
|
||||||
html.Div(
|
html.Div(
|
||||||
children=[
|
children=[
|
||||||
@@ -133,6 +136,12 @@ layout = [
|
|||||||
children=[
|
children=[
|
||||||
html.Div(
|
html.Div(
|
||||||
[
|
[
|
||||||
|
# Bouton modal des colonnes affichées
|
||||||
|
dbc.Button(
|
||||||
|
"Colonnes affichées",
|
||||||
|
id="acheteur_columns_open",
|
||||||
|
className="column_list",
|
||||||
|
),
|
||||||
html.P("lignes", id="acheteur_nb_rows"),
|
html.P("lignes", id="acheteur_nb_rows"),
|
||||||
html.Button(
|
html.Button(
|
||||||
"Téléchargement désactivé au-delà de 65 000 lignes",
|
"Téléchargement désactivé au-delà de 65 000 lignes",
|
||||||
@@ -144,6 +153,30 @@ layout = [
|
|||||||
],
|
],
|
||||||
className="table-menu",
|
className="table-menu",
|
||||||
),
|
),
|
||||||
|
dbc.Modal(
|
||||||
|
[
|
||||||
|
dbc.ModalHeader(
|
||||||
|
dbc.ModalTitle("Choix des colonnes à afficher")
|
||||||
|
),
|
||||||
|
dbc.ModalBody(
|
||||||
|
id="acheteur_columns_body",
|
||||||
|
children=make_column_picker("acheteur"),
|
||||||
|
),
|
||||||
|
dbc.ModalFooter(
|
||||||
|
dbc.Button(
|
||||||
|
"Fermer",
|
||||||
|
id="acheteur_columns_close",
|
||||||
|
className="ms-auto",
|
||||||
|
n_clicks=0,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
],
|
||||||
|
id="acheteur_columns",
|
||||||
|
is_open=False,
|
||||||
|
fullscreen="md-down",
|
||||||
|
scrollable=True,
|
||||||
|
size="xl",
|
||||||
|
),
|
||||||
datatable,
|
datatable,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -333,3 +366,52 @@ def download_filtered_acheteur_data(
|
|||||||
return dcc.send_bytes(
|
return dcc.send_bytes(
|
||||||
to_bytes, filename=f"decp_filtrées_{acheteur_nom}_{date}.xlsx"
|
to_bytes, filename=f"decp_filtrées_{acheteur_nom}_{date}.xlsx"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@callback(
|
||||||
|
Output("acheteur-hidden-columns", "data", allow_duplicate=True),
|
||||||
|
Input("acheteur_column_list", "selected_rows"),
|
||||||
|
prevent_initial_call=True,
|
||||||
|
)
|
||||||
|
def update_hidden_columns_from_checkboxes(selected_columns):
|
||||||
|
if selected_columns:
|
||||||
|
selected_columns = [columns[i] for i in selected_columns]
|
||||||
|
hidden_columns = [col for col in columns if col not in selected_columns]
|
||||||
|
return hidden_columns
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
@callback(
|
||||||
|
Output("acheteur_datatable", "hidden_columns", allow_duplicate=True),
|
||||||
|
Input(
|
||||||
|
"acheteur-hidden-columns",
|
||||||
|
"data",
|
||||||
|
),
|
||||||
|
prevent_initial_call=True,
|
||||||
|
)
|
||||||
|
def store_hidden_columns(hidden_columns):
|
||||||
|
return hidden_columns
|
||||||
|
|
||||||
|
|
||||||
|
@callback(
|
||||||
|
Output("acheteur_column_list", "selected_rows"),
|
||||||
|
Input("acheteur_datatable", "hidden_columns"),
|
||||||
|
State("acheteur_column_list", "selected_rows"), # pour éviter la boucle infinie
|
||||||
|
)
|
||||||
|
def update_checkboxes_from_hidden_columns(hidden_cols, current_checkboxes):
|
||||||
|
# Show all columns that are NOT hidden
|
||||||
|
visible_cols = [columns.index(col) for col in columns if col not in hidden_cols]
|
||||||
|
return visible_cols
|
||||||
|
|
||||||
|
|
||||||
|
@callback(
|
||||||
|
Output("acheteur_columns", "is_open"),
|
||||||
|
Input("acheteur_columns_open", "n_clicks"),
|
||||||
|
Input("acheteur_columns_close", "n_clicks"),
|
||||||
|
State("acheteur_columns", "is_open"),
|
||||||
|
)
|
||||||
|
def toggle_acheteur_columns(click_open, click_close, is_open):
|
||||||
|
if click_open or click_close:
|
||||||
|
return not is_open
|
||||||
|
return is_open
|
||||||
|
|||||||
+9
-66
@@ -19,10 +19,10 @@ from dash import (
|
|||||||
register_page,
|
register_page,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from figures import make_column_picker
|
||||||
from src.figures import DataTable
|
from src.figures import DataTable
|
||||||
from src.utils import (
|
from src.utils import (
|
||||||
columns,
|
columns,
|
||||||
data_schema,
|
|
||||||
df,
|
df,
|
||||||
filter_table_data,
|
filter_table_data,
|
||||||
get_default_hidden_columns,
|
get_default_hidden_columns,
|
||||||
@@ -63,66 +63,6 @@ datatable = html.Div(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def make_tableau_columns_table():
|
|
||||||
table_data = []
|
|
||||||
table_columns = [
|
|
||||||
{
|
|
||||||
"id": col,
|
|
||||||
"name": data_schema[col]["title"],
|
|
||||||
"description": data_schema[col]["description"],
|
|
||||||
}
|
|
||||||
for col in df.columns
|
|
||||||
]
|
|
||||||
for column in table_columns:
|
|
||||||
new_column = {
|
|
||||||
"id": column["id"],
|
|
||||||
"name": column["name"],
|
|
||||||
"description": data_schema[column["id"]]["description"],
|
|
||||||
}
|
|
||||||
table_data.append(new_column)
|
|
||||||
|
|
||||||
table = (
|
|
||||||
DataTable(
|
|
||||||
row_selectable="multi",
|
|
||||||
data=table_data,
|
|
||||||
filter_action="native",
|
|
||||||
sort_action="none",
|
|
||||||
style_cell={
|
|
||||||
"textAlign": "left",
|
|
||||||
},
|
|
||||||
columns=[
|
|
||||||
{
|
|
||||||
"name": "Nom",
|
|
||||||
"id": "name",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Description",
|
|
||||||
"id": "description",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "column_id",
|
|
||||||
"id": "id",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
hidden_columns=["id"],
|
|
||||||
style_cell_conditional=[
|
|
||||||
{
|
|
||||||
"if": {"column_id": "description"},
|
|
||||||
"minWidth": "450px",
|
|
||||||
"overflow": "hidden",
|
|
||||||
"lineHeight": "18px",
|
|
||||||
"whiteSpace": "normal",
|
|
||||||
}
|
|
||||||
],
|
|
||||||
page_action="none",
|
|
||||||
dtid="column_list",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
return table
|
|
||||||
|
|
||||||
|
|
||||||
layout = [
|
layout = [
|
||||||
dcc.Location(id="tableau_url", refresh=False),
|
dcc.Location(id="tableau_url", refresh=False),
|
||||||
dcc.Store(id="filter-cleanup-trigger"),
|
dcc.Store(id="filter-cleanup-trigger"),
|
||||||
@@ -199,6 +139,7 @@ layout = [
|
|||||||
children=[
|
children=[
|
||||||
html.Div(
|
html.Div(
|
||||||
[
|
[
|
||||||
|
# Modal du mode d'emploi
|
||||||
dbc.Button("Mode d'emploi", id="tableau_help_open"),
|
dbc.Button("Mode d'emploi", id="tableau_help_open"),
|
||||||
dbc.Modal(
|
dbc.Modal(
|
||||||
[
|
[
|
||||||
@@ -246,7 +187,7 @@ layout = [
|
|||||||
|
|
||||||
##### Partager une vue
|
##### Partager une vue
|
||||||
|
|
||||||
Une vue est un ensemble de filtres, de tris et de choix de colonnes que vous avez appliqué. Cliquez sur l'icône <img src="/assets/copy.svg" alt="drawing" width="20"/> pour copier une adresse Web qui reproduit la vue courante à l'identique : en la collant dans la barre d'adresse d'un navigateur, vous ouvrez la vue Tableau avec les mêmes paramètres.
|
Une vue est un ensemble de filtres, de tris et de choix de colonnes que vous avez appliqués. Cliquez sur l'icône <img src="/assets/copy.svg" alt="drawing" width="20"/> pour copier une adresse Web qui reproduit la vue courante à l'identique : en la collant dans la barre d'adresse d'un navigateur, vous ouvrez la vue Tableau avec les mêmes paramètres.
|
||||||
|
|
||||||
Pratique pour partager une vue avec un·e collègue, sur les réseaux sociaux, ou la sauvegarder pour plus tard.
|
Pratique pour partager une vue avec un·e collègue, sur les réseaux sociaux, ou la sauvegarder pour plus tard.
|
||||||
|
|
||||||
@@ -277,6 +218,7 @@ layout = [
|
|||||||
scrollable=True,
|
scrollable=True,
|
||||||
size="lg",
|
size="lg",
|
||||||
),
|
),
|
||||||
|
# Bouton modal des colonnes affichées
|
||||||
dbc.Button(
|
dbc.Button(
|
||||||
"Colonnes affichées",
|
"Colonnes affichées",
|
||||||
id="tableau_columns_open",
|
id="tableau_columns_open",
|
||||||
@@ -300,7 +242,8 @@ layout = [
|
|||||||
[
|
[
|
||||||
dbc.ModalHeader(dbc.ModalTitle("Choix des colonnes à afficher")),
|
dbc.ModalHeader(dbc.ModalTitle("Choix des colonnes à afficher")),
|
||||||
dbc.ModalBody(
|
dbc.ModalBody(
|
||||||
id="tableau_columns_body", children=make_tableau_columns_table()
|
id="tableau_columns_body",
|
||||||
|
children=make_column_picker("tableau"),
|
||||||
),
|
),
|
||||||
dbc.ModalFooter(
|
dbc.ModalFooter(
|
||||||
dbc.Button(
|
dbc.Button(
|
||||||
@@ -502,7 +445,7 @@ def toggle_tableau_help(click_open, click_close, is_open):
|
|||||||
|
|
||||||
@callback(
|
@callback(
|
||||||
Output("tableau-hidden-columns", "data", allow_duplicate=True),
|
Output("tableau-hidden-columns", "data", allow_duplicate=True),
|
||||||
Input("column_list", "selected_rows"),
|
Input("tableau_column_list", "selected_rows"),
|
||||||
prevent_initial_call=True,
|
prevent_initial_call=True,
|
||||||
)
|
)
|
||||||
def update_hidden_columns_from_checkboxes(selected_columns):
|
def update_hidden_columns_from_checkboxes(selected_columns):
|
||||||
@@ -527,9 +470,9 @@ def store_hidden_columns(hidden_columns):
|
|||||||
|
|
||||||
|
|
||||||
@callback(
|
@callback(
|
||||||
Output("column_list", "selected_rows"),
|
Output("tableau_column_list", "selected_rows"),
|
||||||
Input("table", "hidden_columns"),
|
Input("table", "hidden_columns"),
|
||||||
State("column_list", "selected_rows"), # pour éviter la boucle infinie
|
State("tableau_column_list", "selected_rows"), # pour éviter la boucle infinie
|
||||||
)
|
)
|
||||||
def update_checkboxes_from_hidden_columns(hidden_cols, current_checkboxes):
|
def update_checkboxes_from_hidden_columns(hidden_cols, current_checkboxes):
|
||||||
# Show all columns that are NOT hidden
|
# Show all columns that are NOT hidden
|
||||||
|
|||||||
+83
-1
@@ -1,11 +1,13 @@
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
import dash_bootstrap_components as dbc
|
||||||
import polars as pl
|
import polars as pl
|
||||||
from dash import Input, Output, State, callback, dcc, html, register_page
|
from dash import Input, Output, State, callback, dcc, html, register_page
|
||||||
|
|
||||||
from src.callbacks import get_top_org_table
|
from src.callbacks import get_top_org_table
|
||||||
from src.figures import DataTable, point_on_map
|
from src.figures import DataTable, make_column_picker, point_on_map
|
||||||
from src.utils import (
|
from src.utils import (
|
||||||
|
columns,
|
||||||
df,
|
df,
|
||||||
df_titulaires,
|
df_titulaires,
|
||||||
filter_table_data,
|
filter_table_data,
|
||||||
@@ -53,6 +55,7 @@ datatable = html.Div(
|
|||||||
|
|
||||||
layout = [
|
layout = [
|
||||||
dcc.Store(id="titulaire_data", storage_type="memory"),
|
dcc.Store(id="titulaire_data", storage_type="memory"),
|
||||||
|
dcc.Store(id="titulaire-hidden-columns", storage_type="memory"),
|
||||||
dcc.Location(id="titulaire_url", refresh="callback-nav"),
|
dcc.Location(id="titulaire_url", refresh="callback-nav"),
|
||||||
html.Div(
|
html.Div(
|
||||||
children=[
|
children=[
|
||||||
@@ -132,6 +135,12 @@ layout = [
|
|||||||
children=[
|
children=[
|
||||||
html.Div(
|
html.Div(
|
||||||
[
|
[
|
||||||
|
# Bouton modal des colonnes affichées
|
||||||
|
dbc.Button(
|
||||||
|
"Colonnes affichées",
|
||||||
|
id="titulaire_columns_open",
|
||||||
|
className="column_list",
|
||||||
|
),
|
||||||
html.P("lignes", id="titulaire_nb_rows"),
|
html.P("lignes", id="titulaire_nb_rows"),
|
||||||
html.Button(
|
html.Button(
|
||||||
"Téléchargement désactivé au-delà de 65 000 lignes",
|
"Téléchargement désactivé au-delà de 65 000 lignes",
|
||||||
@@ -142,6 +151,30 @@ layout = [
|
|||||||
],
|
],
|
||||||
className="table-menu",
|
className="table-menu",
|
||||||
),
|
),
|
||||||
|
dbc.Modal(
|
||||||
|
[
|
||||||
|
dbc.ModalHeader(
|
||||||
|
dbc.ModalTitle("Choix des colonnes à afficher")
|
||||||
|
),
|
||||||
|
dbc.ModalBody(
|
||||||
|
id="titulaire_columns_body",
|
||||||
|
children=make_column_picker("titulaire"),
|
||||||
|
),
|
||||||
|
dbc.ModalFooter(
|
||||||
|
dbc.Button(
|
||||||
|
"Fermer",
|
||||||
|
id="titulaire_columns_close",
|
||||||
|
className="ms-auto",
|
||||||
|
n_clicks=0,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
],
|
||||||
|
id="titulaire_columns",
|
||||||
|
is_open=False,
|
||||||
|
fullscreen="md-down",
|
||||||
|
scrollable=True,
|
||||||
|
size="xl",
|
||||||
|
),
|
||||||
datatable,
|
datatable,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -346,3 +379,52 @@ def download_filtered_titulaire_data(
|
|||||||
return dcc.send_bytes(
|
return dcc.send_bytes(
|
||||||
to_bytes, filename=f"decp_filtrées_{titulaire_nom}_{date}.xlsx"
|
to_bytes, filename=f"decp_filtrées_{titulaire_nom}_{date}.xlsx"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@callback(
|
||||||
|
Output("titulaire-hidden-columns", "data", allow_duplicate=True),
|
||||||
|
Input("titulaire_column_list", "selected_rows"),
|
||||||
|
prevent_initial_call=True,
|
||||||
|
)
|
||||||
|
def update_hidden_columns_from_checkboxes(selected_columns):
|
||||||
|
if selected_columns:
|
||||||
|
selected_columns = [columns[i] for i in selected_columns]
|
||||||
|
hidden_columns = [col for col in columns if col not in selected_columns]
|
||||||
|
return hidden_columns
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
@callback(
|
||||||
|
Output("titulaire_datatable", "hidden_columns", allow_duplicate=True),
|
||||||
|
Input(
|
||||||
|
"titulaire-hidden-columns",
|
||||||
|
"data",
|
||||||
|
),
|
||||||
|
prevent_initial_call=True,
|
||||||
|
)
|
||||||
|
def store_hidden_columns(hidden_columns):
|
||||||
|
return hidden_columns
|
||||||
|
|
||||||
|
|
||||||
|
@callback(
|
||||||
|
Output("titulaire_column_list", "selected_rows"),
|
||||||
|
Input("titulaire_datatable", "hidden_columns"),
|
||||||
|
State("titulaire_column_list", "selected_rows"), # pour éviter la boucle infinie
|
||||||
|
)
|
||||||
|
def update_checkboxes_from_hidden_columns(hidden_cols, current_checkboxes):
|
||||||
|
# Show all columns that are NOT hidden
|
||||||
|
visible_cols = [columns.index(col) for col in columns if col not in hidden_cols]
|
||||||
|
return visible_cols
|
||||||
|
|
||||||
|
|
||||||
|
@callback(
|
||||||
|
Output("titulaire_columns", "is_open"),
|
||||||
|
Input("titulaire_columns_open", "n_clicks"),
|
||||||
|
Input("titulaire_columns_close", "n_clicks"),
|
||||||
|
State("titulaire_columns", "is_open"),
|
||||||
|
)
|
||||||
|
def toggle_titulaire_columns(click_open, click_close, is_open):
|
||||||
|
if click_open or click_close:
|
||||||
|
return not is_open
|
||||||
|
return is_open
|
||||||
|
|||||||
Reference in New Issue
Block a user