From e6e24e4d2d2fc996aa2aeaa929d6ff9429fc869f Mon Sep 17 00:00:00 2001 From: Julien Balet Date: Sun, 10 May 2026 20:32:53 +0200 Subject: [PATCH] =?UTF-8?q?ui:=20panneau=20d'=C3=A9dition=20vertical=20par?= =?UTF-8?q?=20colonnes=20+=20scroll=20horizontal=20des=20tables=20BN/notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - panneau d'édition des absences : P1-5 dans la colonne gauche, P6-10 à droite (au lieu d'un grid à 2 colonnes en flux ligne par ligne). Sur mobile, les deux colonnes s'empilent. - tables BN et Notes d'examen : ajout d'un min-width forcé pour qu'elles débordent de la largeur d'un écran mobile, wrapper overflow-x:auto fonctionnel pour le swipe horizontal. - exclu les tables de la règle CSS .content-area * { min-width: 0 } pour éviter la casse caractère par caractère du contenu cellule. Co-Authored-By: Claude Opus 4.7 (1M context) --- assets/responsive.css | 14 ++++++++++ eptm_dashboard/pages/classe.py | 7 ++--- eptm_dashboard/pages/fiche.py | 48 +++++++++++++++++++++------------- 3 files changed, 48 insertions(+), 21 deletions(-) diff --git a/assets/responsive.css b/assets/responsive.css index 9107d20..29e4612 100644 --- a/assets/responsive.css +++ b/assets/responsive.css @@ -47,6 +47,20 @@ body, html { min-width: 0; } +/* Tables : restaurer le layout natif (sinon les cellules collapsent à + * 0 et le texte casse caractère par caractère sur mobile). Les tables + * sont enveloppées dans un div overflow-x:auto pour le scroll horizontal. */ +.content-area table, +.content-area thead, +.content-area tbody, +.content-area tr, +.content-area td, +.content-area th { + min-width: auto; + overflow-wrap: normal; + word-break: normal; +} + /* Mobile: hide desktop sidebar, account for fixed topbar (56px) */ @media (max-width: 767px) { .sidebar-desktop { display: none !important; } diff --git a/eptm_dashboard/pages/classe.py b/eptm_dashboard/pages/classe.py index d4364e0..11d83c3 100644 --- a/eptm_dashboard/pages/classe.py +++ b/eptm_dashboard/pages/classe.py @@ -96,8 +96,8 @@ def _bn_html_table(d: dict, sem_labels: list, groups_order: list) -> str: body += _moy_ann_row("Moyenne annuelle globale", d["globale"], f"{TD};font-weight:bold") return ( - f'
' - f'' + f'
' + f'
' f"{header}" f"{body}" f"
" @@ -173,6 +173,7 @@ def _render_notes_html(notes_data: list) -> str: f'
' f'{_br_name}' f'Moyenne : {_moy_html}
' + '
' "" "" ) @@ -197,7 +198,7 @@ def _render_notes_html(notes_data: list) -> str: f'' f'' ) - html += "
DateExamenEnseignantCoeffTypeNote
{_ex["type"]}{_note_html}
" + html += "
" html += "" return html diff --git a/eptm_dashboard/pages/fiche.py b/eptm_dashboard/pages/fiche.py index 4eb57f4..024e4ee 100644 --- a/eptm_dashboard/pages/fiche.py +++ b/eptm_dashboard/pages/fiche.py @@ -115,8 +115,8 @@ def _bn_html_table(d: dict, sem_labels: list, groups_order: list) -> str: body += _moy_ann_row("Moyenne annuelle globale", d["globale"], f"{TD};font-weight:bold") return ( - f'
' - f'' + f'
' + f'
' f"{header}" f"{body}" f"
" @@ -192,7 +192,8 @@ def _render_notes_html(notes_data: list) -> str: f'
' f'{_br_name}' f'Moyenne : {_moy_html}
' - '' + '
' + '
' '' '' '' @@ -225,7 +226,7 @@ def _render_notes_html(notes_data: list) -> str: f'' f'' ) - html += "
{_ex["type"]}{_note_html}
" + html += "" html += "" return html @@ -1292,19 +1293,25 @@ def _edit_panel() -> rx.Component: width="100%", align="center", ), rx.divider(), - rx.grid( - _period_select(1, FicheState.edit_p1, FicheState.set_edit_p1), - _period_select(2, FicheState.edit_p2, FicheState.set_edit_p2), - _period_select(3, FicheState.edit_p3, FicheState.set_edit_p3), - _period_select(4, FicheState.edit_p4, FicheState.set_edit_p4), - _period_select(5, FicheState.edit_p5, FicheState.set_edit_p5), - _period_select(6, FicheState.edit_p6, FicheState.set_edit_p6), - _period_select(7, FicheState.edit_p7, FicheState.set_edit_p7), - _period_select(8, FicheState.edit_p8, FicheState.set_edit_p8), - _period_select(9, FicheState.edit_p9, FicheState.set_edit_p9), - _period_select(10, FicheState.edit_p10, FicheState.set_edit_p10), - columns="2", - gap="0.4rem", + rx.flex( + rx.vstack( + _period_select(1, FicheState.edit_p1, FicheState.set_edit_p1), + _period_select(2, FicheState.edit_p2, FicheState.set_edit_p2), + _period_select(3, FicheState.edit_p3, FicheState.set_edit_p3), + _period_select(4, FicheState.edit_p4, FicheState.set_edit_p4), + _period_select(5, FicheState.edit_p5, FicheState.set_edit_p5), + spacing="2", flex="1 1 240px", min_width="240px", + ), + rx.vstack( + _period_select(6, FicheState.edit_p6, FicheState.set_edit_p6), + _period_select(7, FicheState.edit_p7, FicheState.set_edit_p7), + _period_select(8, FicheState.edit_p8, FicheState.set_edit_p8), + _period_select(9, FicheState.edit_p9, FicheState.set_edit_p9), + _period_select(10, FicheState.edit_p10, FicheState.set_edit_p10), + spacing="2", flex="1 1 240px", min_width="240px", + ), + gap="0.6rem", + flex_wrap="wrap", width="100%", ), rx.hstack( @@ -1609,7 +1616,12 @@ def fiche_page() -> rx.Component: FicheState.has_bn, rx.vstack( rx.text(FicheState.bn_caption, size="1", color="#9e9e9e"), - rx.html(FicheState.bn_html), + rx.box( + rx.html(FicheState.bn_html), + width="100%", + max_width="100%", + overflow_x="auto", + ), spacing="2", width="100%", ), rx.text(