Association et Memory restent affiches une fois termines, seul Recommencer bascule
Build and deploy / test-python (push) Failing after 59s
Build and deploy / test-js (push) Failing after 52s
Build and deploy / lint-python (push) Failing after 59s
Build and deploy / lint-js (push) Failing after 1m1s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 1m4s

Les deux mini-jeux gardaient jusqu'ici un ecran de resultat separe qui
remplacait le plateau de jeu (comme le Quiz). Le plateau reste desormais
visible en permanence ; seule une barre partagee .docMinigameRestartBar
apparait/disparait. Le Quiz garde son propre comportement (ecran de
resultat separe), inchange.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
william
2026-09-20 14:43:26 +02:00
co-authored by Claude Sonnet 5
parent a34a95a3b4
commit 1b1307bb85
4 changed files with 49 additions and 43 deletions
@@ -221,11 +221,15 @@ def _render_association_player(config: dict[str, Any]) -> str:
f'<div class="docAssocColumn docAssocColumnRight"></div>' f'<div class="docAssocColumn docAssocColumnRight"></div>'
f"</div>" f"</div>"
f'<div class="docAssocFeedback"></div>' f'<div class="docAssocFeedback"></div>'
f"</div>" # Le plateau reste affiché une fois toutes les paires trouvées
f'<div class="docAssocResultCard" style="display:none;">' # (voir docs/plan/PLAN.md, retour utilisateur du 20/09/2026) —
f'<div class="docAssocResultBig">✓</div>' # seul ce bouton apparaît (.is-visible posé par
f'<div class="docAssocResultSub">Toutes les paires sont associées !</div>' # forgeDocAssociationMatchResult), jamais un écran de résultat
# séparé qui remplacerait le plateau (ça reste le comportement du
# Quiz, seul mini-jeu concerné par un écran de fin distinct).
f'<div class="docMinigameRestartBar">'
f'<button type="button" class="docAssocRestartBtn">Recommencer</button>' f'<button type="button" class="docAssocRestartBtn">Recommencer</button>'
f"</div>"
f"</div></div>" f"</div></div>"
) )
@@ -277,11 +281,11 @@ def _render_memory_player(config: dict[str, Any]) -> str:
f'<div class="docAssocTitle docMemoryTitle"></div>' f'<div class="docAssocTitle docMemoryTitle"></div>'
f'<div class="docAssocMeta"><span class="docMemoryProg"></span></div>' f'<div class="docAssocMeta"><span class="docMemoryProg"></span></div>'
f'<div class="docMemoryGrid"></div>' f'<div class="docMemoryGrid"></div>'
# Même choix que l'Association ci-dessus : le plateau reste
# affiché une fois le jeu terminé, seul ce bouton apparaît.
f'<div class="docMinigameRestartBar">'
f'<button type="button" class="docMemoryRestartBtn">Recommencer</button>'
f"</div>" f"</div>"
f'<div class="docAssocResultCard docMemoryResultCard" style="display:none;">'
f'<div class="docAssocResultBig">✓</div>'
f'<div class="docAssocResultSub docMemoryResultSub"></div>'
f'<button type="button" class="docAssocRestartBtn docMemoryRestartBtn">Recommencer</button>'
f"</div></div>" f"</div></div>"
) )
+8 -1
View File
@@ -57,7 +57,11 @@ regroupement à chaque appel.
mélangées INDÉPENDAMMENT (`random.shuffle`, mélange d'affichage — voir mélangées INDÉPENDAMMENT (`random.shuffle`, mélange d'affichage — voir
`CODE_QUALITY.md`) puis embarquées en JSON dans un attribut `CODE_QUALITY.md`) puis embarquées en JSON dans un attribut
`data-assoc-config`, échappé pour l'HTML — même principe que le Quiz, `data-assoc-config`, échappé pour l'HTML — même principe que le Quiz,
aucun aller-retour serveur pendant qu'on joue. aucun aller-retour serveur pendant qu'on joue. Contrairement au Quiz,
le plateau reste affiché en permanence une fois la partie terminée :
seul le bouton "Recommencer" (`.docMinigameRestartBar`, partagé avec
Memory) apparaît, jamais d'écran de résultat séparé qui le
remplacerait.
- **Memory** : toujours une carte résumant la config réelle (nombre de - **Memory** : toujours une carte résumant la config réelle (nombre de
cartes définies, mode paire/simple) — sanitizée cartes définies, mode paire/simple) — sanitizée
(`sanitize_memory_config`) avant lecture. Si au moins une carte existe, (`sanitize_memory_config`) avant lecture. Si au moins une carte existe,
@@ -70,6 +74,9 @@ regroupement à chaque appel.
d'affichage — voir `CODE_QUALITY.md`) puis embarquées en JSON dans un d'affichage — voir `CODE_QUALITY.md`) puis embarquées en JSON dans un
attribut `data-memory-config`, échappé pour l'HTML — même principe que attribut `data-memory-config`, échappé pour l'HTML — même principe que
le Quiz/l'Association, aucun aller-retour serveur pendant qu'on joue. le Quiz/l'Association, aucun aller-retour serveur pendant qu'on joue.
Comme l'Association, le plateau reste affiché une fois toutes les
paires trouvées (ou toutes les cartes révélées en mode `"single"`) :
seul le bouton "Recommencer" (`.docMinigameRestartBar`) apparaît.
- **Autres mini-jeux** (`mots`/`scenario`/`zones`) : carte placeholder - **Autres mini-jeux** (`mots`/`scenario`/`zones`) : carte placeholder
portant le libellé du type (voir portant le libellé du type (voir
`document_engine/labels/element_kind_labels.py`) — emplacement réservé, `document_engine/labels/element_kind_labels.py`) — emplacement réservé,
+17 -22
View File
@@ -747,18 +747,13 @@ img.docImage {
"relier visuellement deux éléments qui vont ensemble"). Réutilise "relier visuellement deux éléments qui vont ensemble"). Réutilise
.docQuizFeedback/.docQuizKicker (même rôle visuel) plutôt que de .docQuizFeedback/.docQuizKicker (même rôle visuel) plutôt que de
dupliquer ces règles. ---- */ dupliquer ces règles. ---- */
.docAssocCard, .docAssocCard {
.docAssocResultCard {
background: linear-gradient(180deg, var(--doc-card), var(--doc-bg-2)); background: linear-gradient(180deg, var(--doc-card), var(--doc-bg-2));
border: 1px solid var(--doc-border); border: 1px solid var(--doc-border);
border-radius: 16px; border-radius: 16px;
padding: 1.8rem; padding: 1.8rem;
} }
.docAssocResultCard {
text-align: center;
}
.docAssocTitle { .docAssocTitle {
font-size: 1.15rem; font-size: 1.15rem;
font-weight: 700; font-weight: 700;
@@ -826,8 +821,21 @@ img.docImage {
background: var(--doc-quiz-danger-bg); background: var(--doc-quiz-danger-bg);
} }
.docAssocRestartBtn { /* ---- Barre de bouton "Recommencer" partagée par tous les mini-jeux SAUF
le Quiz (qui garde son propre écran de résultat séparé) : le plateau de
jeu reste affiché en permanence une fois terminé, seul ce bouton
apparaît/disparaît (voir retour utilisateur du 20/09/2026). ---- */
.docMinigameRestartBar {
display: none;
margin-top: 20px; margin-top: 20px;
text-align: center;
}
.docMinigameRestartBar.is-visible {
display: block;
}
.docMinigameRestartBar button {
padding: 0.7rem 1.5rem; padding: 0.7rem 1.5rem;
border-radius: 10px; border-radius: 10px;
background: transparent; background: transparent;
@@ -838,19 +846,6 @@ img.docImage {
cursor: pointer; cursor: pointer;
} }
.docAssocResultBig {
font-size: 40px;
line-height: 1;
color: var(--doc-quiz-success-border);
}
.docAssocResultSub {
margin-top: 10px;
margin-bottom: 4px;
font-size: 14px;
color: var(--doc-text);
}
/* ---- Association : panneau Propriétés — paires reliées visuellement par /* ---- Association : panneau Propriétés — paires reliées visuellement par
un glyphe entre les deux champs (voir forgeDocRenderAssociationPairHtml, un glyphe entre les deux champs (voir forgeDocRenderAssociationPairHtml,
static/document/js/document-editor.js). Empilement VERTICAL (pas côte à static/document/js/document-editor.js). Empilement VERTICAL (pas côte à
@@ -902,8 +897,8 @@ img.docImage {
/* ---- Memory : plateau de jeu (voir docs/plan/PLAN.md, "retourner des /* ---- Memory : plateau de jeu (voir docs/plan/PLAN.md, "retourner des
cartes pour constituer des paires d'images identiques"). Réutilise cartes pour constituer des paires d'images identiques"). Réutilise
.docAssocTitle/.docAssocMeta/.docAssocResultCard (mêmes rôles visuels, .docAssocTitle/.docAssocMeta/.docMinigameRestartBar (mêmes rôles
voir forgeDocRenderMemoryProps ci-dessus). ---- */ visuels, voir forgeDocRenderMemoryProps ci-dessus). ---- */
.docMemoryCardWrap { .docMemoryCardWrap {
background: linear-gradient(180deg, var(--doc-card), var(--doc-bg-2)); background: linear-gradient(180deg, var(--doc-card), var(--doc-bg-2));
border: 1px solid var(--doc-border); border: 1px solid var(--doc-border);
+12 -12
View File
@@ -653,8 +653,12 @@ function forgeDocAssociationMatchResult(playerEl, state, pairIndex, itemEl, slot
feedbackEl.textContent = 'Bonne association !'; feedbackEl.textContent = 'Bonne association !';
playerEl.querySelector('.docAssocProg').textContent = `${state.matched.size} / ${state.total} associées`; playerEl.querySelector('.docAssocProg').textContent = `${state.matched.size} / ${state.total} associées`;
if (state.matched.size >= state.total) { if (state.matched.size >= state.total) {
playerEl.querySelector('.docAssocCard').style.display = 'none'; // Le plateau reste affiché une fois le jeu terminé (voir retour
playerEl.querySelector('.docAssocResultCard').style.display = 'block'; // utilisateur du 20/09/2026 : "tous les mini-jeux à part le quiz
// doivent continuer à s'afficher même une fois terminé") — seul le
// bouton Recommencer apparaît, jamais un écran de résultat séparé qui
// remplacerait le plateau (ça reste le comportement du Quiz).
playerEl.querySelector('.docMinigameRestartBar').classList.add('is-visible');
} }
} }
@@ -728,8 +732,7 @@ function forgeDocAssociationRestart(playerEl) {
selected: null, selected: null,
selectedPairIndex: null, selectedPairIndex: null,
}; };
playerEl.querySelector('.docAssocResultCard').style.display = 'none'; playerEl.querySelector('.docMinigameRestartBar').classList.remove('is-visible');
playerEl.querySelector('.docAssocCard').style.display = 'block';
playerEl.querySelector('.docAssocFeedback').className = 'docAssocFeedback docQuizFeedback'; playerEl.querySelector('.docAssocFeedback').className = 'docAssocFeedback docQuizFeedback';
playerEl.querySelector('.docAssocProg').textContent = `0 / ${state.total} associées`; playerEl.querySelector('.docAssocProg').textContent = `0 / ${state.total} associées`;
forgeDocRenderAssociationBoard(playerEl, state); forgeDocRenderAssociationBoard(playerEl, state);
@@ -830,12 +833,10 @@ function forgeDocMemoryUpdateProgress(playerEl, state) {
function forgeDocMemoryCheckComplete(playerEl, state) { function forgeDocMemoryCheckComplete(playerEl, state) {
const done = state.mode === 'single' ? state.revealed >= state.total : state.matched >= state.totalPairs; const done = state.mode === 'single' ? state.revealed >= state.total : state.matched >= state.totalPairs;
if (!done) return; if (!done) return;
playerEl.querySelector('.docMemoryCardWrap').style.display = 'none'; // Le plateau reste affiché une fois le jeu terminé (voir retour
const resultCard = playerEl.querySelector('.docMemoryResultCard'); // utilisateur du 20/09/2026) — seul le bouton Recommencer apparaît,
resultCard.style.display = 'block'; // jamais un écran de résultat séparé (ça reste le comportement du Quiz).
playerEl.querySelector('.docMemoryResultSub').textContent = state.mode === 'single' playerEl.querySelector('.docMinigameRestartBar').classList.add('is-visible');
? 'Toutes les cartes ont été retournées !'
: 'Toutes les paires ont été trouvées !';
} }
function forgeDocMemoryFlip(playerEl, state, cardEl) { function forgeDocMemoryFlip(playerEl, state, cardEl) {
@@ -885,8 +886,7 @@ function forgeDocMemoryRestart(playerEl) {
flippedCards: [], flippedCards: [],
busy: false, busy: false,
}; };
playerEl.querySelector('.docMemoryResultCard').style.display = 'none'; playerEl.querySelector('.docMinigameRestartBar').classList.remove('is-visible');
playerEl.querySelector('.docMemoryCardWrap').style.display = 'block';
playerEl.querySelector('.docMemoryTitle').textContent = state.mode === 'single' playerEl.querySelector('.docMemoryTitle').textContent = state.mode === 'single'
? 'Retournez chaque carte' ? 'Retournez chaque carte'
: 'Retrouvez les paires'; : 'Retrouvez les paires';