Remplace les onglets texte de pages par de vraies vignettes miniatures
Build and deploy / test-python (push) Successful in 7m23s
Build and deploy / test-js (push) Successful in 1m24s
Build and deploy / lint-python (push) Successful in 6m29s
Build and deploy / lint-js (push) Failing after 1m31s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 5m18s

Les vignettes réutilisent le HTML réellement rendu de chaque page
(CSS scale trick) et sont centrées dans le conteneur du milieu, au
lieu d'une barre pleine largeur.

Corrige au passage deux bugs réels trouvés en écrivant les tests :
- une page contenant un mini-jeu (bouton Suivant/Recommencer) cassait
  le parsing HTML car .docPageThumbCard était un <button> englobant
  un autre <button> ; passage en div role="button" + équivalent
  clavier, contenu copié rendu inert.
- le renommage d'une page par double-clic ne fonctionnait plus du
  tout (sélecteur .docPageTab oublié lors du renommage des classes).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
william
2026-09-21 13:50:05 +02:00
co-authored by Claude Sonnet 5
parent ecd483f352
commit 57c4de3d8a
5 changed files with 273 additions and 125 deletions
+126 -70
View File
@@ -366,7 +366,8 @@ body.objectEditBody > main.content {
padding: 36px 40px;
overflow: auto;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
position: relative;
}
@@ -1212,102 +1213,157 @@ img.docImage {
white-space: nowrap;
}
/* ---- Bande d'onglets des PAGES (au-dessus du canevas, jamais un
panneau latéral — voir retour utilisateur du 21/09/2026). Masquée en
Mode Aperçu (voir la règle .docEditor3--preview plus bas), qui a sa
propre navigation via .docPageNavPill ci-dessus. ---- */
.docPageTabs {
/* ---- Bande de VIGNETTES MINIATURES des pages, au-dessus de la page
ET centrée dans le conteneur du milieu (.docCanvasArea, jamais toute
la largeur de l'éditeur par-dessus les panneaux latéraux — retour
utilisateur du 21/09/2026 : "je préfère avoir des miniatures ...
centré dans le conteneur du milieu"). Chaque vignette affiche un
VRAI rendu réduit du contenu de sa page (voir .docPageThumbInner plus
bas, et rendered_pages côté serveur dans routes/document/
document_edit.py) — jamais une carte générique numéro/titre. Masquée
en Mode Aperçu (voir la règle .docEditor3--preview plus bas), qui a
sa propre navigation via .docPageNavPill ci-dessus. ---- */
.docPageThumbs {
width: 100%;
display: flex;
align-items: center;
gap: 4px;
padding: 8px 20px 0;
background: var(--doc-bg-2);
border-bottom: 1px solid var(--doc-border);
overflow-x: auto;
justify-content: center;
align-items: flex-end;
flex-wrap: wrap;
gap: 16px;
padding: 4px 20px 28px;
flex-shrink: 0;
}
.docPageTab {
.docPageThumbCard {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
padding: 7px 10px 7px 14px;
border: 1px solid var(--doc-border);
border-bottom: none;
border-radius: 8px 8px 0 0;
background: transparent;
color: var(--doc-muted);
font-size: 13px;
font-weight: 600;
gap: 6px;
flex-shrink: 0;
border: none;
background: none;
padding: 0;
cursor: pointer;
white-space: nowrap;
flex-shrink: 0;
font-family: inherit;
}
.docPageTab:hover {
color: var(--doc-text);
border-color: var(--doc-accent);
}
.docPageTab.is-active {
background: var(--doc-bg);
color: var(--doc-text);
}
.docPageTab.is-dragging {
.docPageThumbCard.is-dragging {
opacity: 0.4;
}
.docPageTabTitle {
max-width: 160px;
overflow: hidden;
text-overflow: ellipsis;
.docPageThumbCard:focus-visible {
outline: 2px solid var(--doc-accent);
outline-offset: 2px;
border-radius: 10px;
}
.docPageTabTitle[contenteditable="true"] {
.docPageThumbFrame {
/* <span> (jamais <div>, invalide comme enfant direct d'un <button> —
voir templates/document/document_edit.html) : display:block requis
pour que width/aspect-ratio s'appliquent normalement. */
display: block;
position: relative;
width: 132px;
aspect-ratio: 4 / 3;
border: 2px solid var(--doc-border);
border-radius: 10px;
overflow: hidden;
background: var(--doc-card);
box-shadow: 0 2px 6px rgb(0 0 0 / 20%);
transition: border-color 0.15s ease, transform 0.15s ease;
}
.docPageThumbCard:hover .docPageThumbFrame {
border-color: var(--doc-accent);
transform: translateY(-2px);
}
.docPageThumbCard.is-active .docPageThumbFrame {
border-color: var(--doc-accent);
box-shadow: 0 0 0 2px var(--doc-accent);
}
/* Astuce "scale inverse" pour une vraie vignette : le contenu est rendu
à sa largeur RÉELLE (voir .docPage, 760px) puis réduit visuellement —
jamais un second moteur de rendu séparé pour les miniatures, c'est le
MÊME rendu que le canevas principal, juste redimensionné en CSS. Le
cadre (.docPageThumbFrame) le rogne verticalement s'il dépasse — un
support de formation "page" est proche d'un format diapositive, ce
recadrage reste représentatif. */
.docPageThumbInner {
position: absolute;
top: 0;
left: 0;
width: 760px;
transform: scale(0.1737);
transform-origin: top left;
pointer-events: none;
}
.docPageThumbDelete {
position: absolute;
top: 4px;
right: 4px;
display: none;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
border-radius: 50%;
border: none;
background: rgb(11 14 20 / 65%);
color: #fff;
font-size: 10px;
cursor: pointer;
}
.docPageThumbCard:hover .docPageThumbDelete {
display: flex;
}
.docPageThumbDelete:hover {
background: var(--doc-quiz-danger-border);
}
.docPageThumbs.docPageTabs--single .docPageThumbDelete {
display: none;
}
.docPageThumbLabel {
max-width: 132px;
font-size: 12px;
font-weight: 600;
color: var(--doc-muted);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.docPageThumbCard.is-active .docPageThumbLabel {
color: var(--doc-text);
}
.docPageThumbLabel[contenteditable="true"] {
outline: none;
border-bottom: 1px solid var(--doc-accent);
cursor: text;
user-select: text;
color: var(--doc-text);
}
.docPageTabDelete {
.docPageThumbAddCard .docPageThumbFrame {
display: flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;
border-radius: 50%;
font-size: 10px;
border-style: dashed;
color: var(--doc-muted);
}
.docPageTabDelete:hover {
background: var(--doc-quiz-danger-bg);
color: var(--doc-quiz-danger-text);
}
.docPageTabs.docPageTabs--single .docPageTabDelete {
visibility: hidden;
}
.docPageTabAdd {
flex-shrink: 0;
width: 28px;
height: 28px;
margin-bottom: 6px;
border-radius: 8px;
border: 1px dashed var(--doc-border);
background: transparent;
color: var(--doc-muted);
font-size: 16px;
font-size: 24px;
font-weight: 700;
cursor: pointer;
box-shadow: none;
}
.docPageTabAdd:hover {
.docPageThumbAddCard:hover .docPageThumbFrame {
color: var(--doc-text);
border-color: var(--doc-accent);
}
/* ---- RIGHT SIDEBAR : Propriétés ---- */
@@ -1551,7 +1607,7 @@ img.docImage {
.docEditor3.docEditor3--preview .docSidebarRight,
.docEditor3.docEditor3--preview .docBottomNav,
.docEditor3.docEditor3--preview .docZoomPill,
.docEditor3.docEditor3--preview .docPageTabs {
.docEditor3.docEditor3--preview .docPageThumbs {
display: none;
}