ui: panneau d'édition vertical par colonnes + scroll horizontal des tables BN/notes

- 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) <noreply@anthropic.com>
This commit is contained in:
Julien Balet 2026-05-10 20:32:53 +02:00
parent 43a2196150
commit e6e24e4d2d
3 changed files with 48 additions and 21 deletions

View file

@ -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; }

View file

@ -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'<div style="overflow-x:auto;margin-bottom:16px">'
f'<table style="width:100%;border-collapse:collapse;font-size:0.875em">'
f'<div style="overflow-x:auto;max-width:100%;margin-bottom:16px">'
f'<table style="min-width:560px;width:100%;border-collapse:collapse;font-size:0.875em">'
f"<thead><tr>{header}</tr></thead>"
f"<tbody>{body}</tbody>"
f"</table></div>"
@ -173,6 +173,7 @@ def _render_notes_html(notes_data: list) -> str:
f'<div class="bh{_insuf_cls}">'
f'<span class="bn">{_br_name}</span>'
f'<span class="moy">Moyenne&nbsp;: {_moy_html}</span></div>'
'<div style="overflow-x:auto;max-width:100%">'
"<table><tr><th>Date</th><th>Examen</th><th>Enseignant</th>"
"<th>Coeff</th><th>Type</th><th>Note</th></tr>"
)
@ -197,7 +198,7 @@ def _render_notes_html(notes_data: list) -> str:
f'<td style="color:#777">{_ex["type"]}</td>'
f'<td style="text-align:center">{_note_html}</td></tr>'
)
html += "</table>"
html += "</table></div>"
html += "</div>"
return html

View file

@ -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'<div style="overflow-x:auto;margin-bottom:16px">'
f'<table style="width:100%;border-collapse:collapse;font-size:0.875em">'
f'<div style="overflow-x:auto;max-width:100%;margin-bottom:16px">'
f'<table style="min-width:560px;width:100%;border-collapse:collapse;font-size:0.875em">'
f"<thead><tr>{header}</tr></thead>"
f"<tbody>{body}</tbody>"
f"</table></div>"
@ -192,7 +192,8 @@ def _render_notes_html(notes_data: list) -> str:
f'<div class="bh{_insuf_cls}">'
f'<span class="bn">{_br_name}</span>'
f'<span class="moy">Moyenne&nbsp;: {_moy_html}</span></div>'
'<table style="table-layout:fixed;width:100%">'
'<div style="overflow-x:auto;max-width:100%">'
'<table style="table-layout:fixed;min-width:520px;width:100%">'
'<colgroup>'
'<col style="width:90px">'
'<col>'
@ -225,7 +226,7 @@ def _render_notes_html(notes_data: list) -> str:
f'<td style="color:#777">{_ex["type"]}</td>'
f'<td style="text-align:center">{_note_html}</td></tr>'
)
html += "</table>"
html += "</table></div>"
html += "</div>"
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(