Tableaux de bord et interfaces d’administration

Panneau de rétention groupée du registre de garde de serre

Dans le contexte d’un registre de service en serre, réaliser un panneau de rétention groupée : il comprend du contenu réel, des contrôles exploitables, un retour d’état clair et une mise en page adaptée à plusieurs tailles.

Tableaux de bord et interfaces d’administrationTableau de rétention de groupeHTML TableCSSJavaScript
Après activation de JavaScript, ce cas peut être modifié, exécuté et enregistré. Code source fixe ci-dessous :
<!doctype html>
<html lang="fr" dir="ltr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Panneau de rétention groupée du registre de garde de serre</title>
  <style>
    :root { --ink:#252525; --paper:#f7f2e8; --accent:#247ba0; --secondary:#f4b942; --line:color-mix(in srgb, var(--ink) 18%, transparent); --shadow:0 24px 60px color-mix(in srgb, var(--ink) 16%, transparent); color-scheme:light; }
    * { box-sizing:border-box; }
    html { min-width:320px; background:var(--paper); }
    body { min-height:100vh; margin:0; overflow-x:hidden; color:var(--ink); font-family:"IBM Plex Sans","PingFang SC",sans-serif; background:linear-gradient(color-mix(in srgb,var(--ink) 5%,transparent) 1px,transparent 1px),var(--paper);background-size:100% 36px; }
    button,input,select,textarea { color:inherit; font:inherit; }
    button,[role="button"],input,select,textarea { accent-color:var(--accent); }
    button { cursor:pointer; }
    button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible { outline:3px solid var(--accent); outline-offset:3px; }
    [hidden] { display:none !important; }
    @media (max-width:700px) { .mast h1 { line-height:1.08 !important; letter-spacing:-.035em !important; overflow-wrap:anywhere; } }
    @media (prefers-reduced-motion:reduce) { *,*::before,*::after { scroll-behavior:auto !important; animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; } }
    .page{width:min(1280px,calc(100% - 24px));margin:auto;padding:28px 0 64px}.mast{display:flex;justify-content:space-between;padding:18px;border:1px solid var(--line);background:color-mix(in srgb,#fff 60%,transparent);gap:18px;margin-bottom:14px}.mast h1{font-family:"IBM Plex Sans","PingFang SC",sans-serif;font-weight:800;font-size:clamp(34px,6vw,66px);letter-spacing:-.045em;margin:0;line-height:1}.eyebrow{display:block;margin-bottom:6px;color:var(--accent);font:800 10px/1 ui-monospace,monospace;letter-spacing:.16em}.intro{max-width:720px;margin:10px 0 0;font-size:14px;line-height:1.6}.scenario{padding:7px 10px;border:1px solid var(--line);border-radius:8px;background:var(--paper);font-size:12px}.demo{border-radius:14px;box-shadow:0 14px 40px color-mix(in srgb,var(--ink) 11%,transparent);position:relative;min-height:390px;overflow:hidden;padding:24px;background:color-mix(in srgb,var(--paper) 90%,#fff)}@media(max-width:700px){.page{width:calc(100% - 12px);padding-top:12px}.mast{display:grid}.demo{padding:12px}}
    .panel{padding:26px;border:1px solid var(--line);border-radius:2px;background:var(--paper)}.stack{display:grid;gap:28px}.row{display:flex;gap:20px;flex-wrap:wrap}.action{padding:9px 2px;border:0;border-bottom:2px solid var(--line);background:transparent}.action.primary,.action.is-active{border-color:var(--accent);color:var(--accent)}.muted{font-size:14px;line-height:1.9}.status{min-height:20px;margin-top:28px;font-size:13px}.metric{font-size:clamp(40px,9vw,88px);font-weight:500;letter-spacing:-.06em}.meter{height:2px;background:var(--line)}.meter>i{display:block;height:100%;background:var(--accent)}.chip{font-size:11px;letter-spacing:.12em;text-transform:uppercase}
    .composition-deck{display:grid;grid-template-rows:auto 1fr;border:1px solid var(--line);border-radius:24px;overflow:hidden;background:color-mix(in srgb,var(--ink) 4%,var(--paper))}.deck-bar{display:flex;justify-content:space-between;gap:18px;align-items:center;padding:12px 18px;color:var(--paper);background:var(--ink);font:700 12px/1 ui-monospace,monospace}.deck-lights{display:flex;gap:7px}.deck-lights i{width:10px;height:10px;border-radius:50%;background:var(--accent)}.deck-lights i:nth-child(2){background:var(--secondary)}.deck-lights i:nth-child(3){background:color-mix(in srgb,var(--paper) 55%,transparent)}.composition-deck .demo{border:0;border-radius:0;box-shadow:none}
    .cohort-studio{display:grid;gap:16px}.cohort-studio header{display:flex;justify-content:space-between;gap:18px;align-items:end}.cohort-studio h2{margin:.3em 0}.cohort-board{display:grid;grid-template-columns:minmax(0,1.2fr) 220px;gap:14px}.cohort-table{width:100%;border-collapse:separate;border-spacing:5px}.cohort-table caption{text-align:left;font-weight:800}.cohort-table th,.cohort-table td{padding:13px;text-align:center}.cohort-table td{background:color-mix(in srgb,var(--accent) calc(var(--retention)*.75%),var(--paper))}.cohort-table tbody th{text-align:left}.cohort-table [data-cohort="100"]{--retention:100}.cohort-board aside{display:grid;align-content:start;gap:10px;padding:18px;border-left:4px solid var(--accent);background:color-mix(in srgb,var(--secondary) 10%,transparent)}.cohort-board aside ol{display:grid;gap:8px;padding-left:18px;margin:0}@media(max-width:760px){.cohort-studio header{align-items:stretch;flex-direction:column}.cohort-board{grid-template-columns:1fr}.cohort-table th,.cohort-table td{padding:9px;font-size:12px}}.workflow-guide{display:grid;grid-template-columns:190px minmax(0,1fr);grid-template-areas:"rail core" "rail evidence";gap:14px 18px}.guide-rail{grid-area:rail;display:grid;align-content:start;gap:15px;padding:18px;border-right:1px solid var(--line)}.guide-rail ol{display:grid;gap:8px;padding:0;margin:0;list-style:none}.guide-rail li{display:grid;grid-template-columns:30px 1fr;gap:8px;align-items:center;padding:9px;opacity:.5}.guide-rail li[aria-current="step"]{opacity:1;color:var(--paper);background:var(--ink)}.guide-rail li.is-complete{opacity:1;color:var(--accent)}.guide-actions{display:grid;grid-template-columns:1fr 1fr;gap:7px}.guide-actions .action{padding-inline:8px}#workflowGuideProgress{height:6px;background:var(--line)}#workflowGuideProgress i{display:block;width:0;height:100%;background:var(--accent)}.guide-core{grid-area:core;min-width:0;padding:16px;border:1px solid var(--line)}.guide-core>p{margin:0 0 14px;padding:10px;border-left:4px solid var(--accent);background:color-mix(in srgb,var(--secondary) 12%,transparent)}.guide-core[data-guide-step="1"]{border-radius:28px}.guide-core[data-guide-step="2"]{box-shadow:inset 0 0 0 4px color-mix(in srgb,var(--accent) 35%,transparent)}.guide-evidence{grid-area:evidence;display:grid;grid-template-columns:1fr 1fr auto;gap:12px;align-items:start}.guide-evidence details,.guide-evidence form{padding:12px;border:1px solid var(--line)}.guide-evidence label{display:grid;gap:7px}.guide-evidence textarea{width:100%;padding:9px;border:1px solid var(--line);background:var(--paper)}@media(max-width:900px){.workflow-guide{grid-template-columns:1fr;grid-template-areas:"core" "rail" "evidence"}.guide-rail{border-right:0;border-bottom:1px solid var(--line)}.guide-rail ol{grid-template-columns:repeat(3,1fr)}.guide-evidence{grid-template-columns:1fr}}
  </style>
</head>
<body data-aesthetic="dashboard" data-composition="control-deck">
  <main class="page">
    <header class="mast"><div><span class="eyebrow">dashboard / panneau de rétention par cohorte / INTERMEDIATE</span><h1>Panneau de rétention groupée du registre de garde de serre</h1><p class="intro">Dans le contexte d’un registre de service en serre, réaliser un panneau de rétention groupée : il comprend du contenu réel, des contrôles exploitables, un retour d’état clair et une mise en page adaptée à plusieurs tailles.</p></div><span class="scenario">Registre de service de serre</span></header>
    <div class="composition-deck"><div class="deck-bar"><span>CONTROL DECK · 04</span><span>Tableau de rétention de groupe</span><span class="deck-lights" aria-hidden="true"><i></i><i></i><i></i></span></div><section class="demo" aria-label="Zone interactive du panneau de rétention groupée du cahier de service de la serre"><div class="workflow-guide"><nav class="guide-rail" aria-label="Guide du registre de service de serre"><span class="eyebrow">GUIDE du carnet de service de la serre</span><ol><li data-workflow-guide-step="0" aria-current="step"><b>1</b><span>Vue de surveillance du registre de garde de la serre</span></li><li data-workflow-guide-step="1"><b>2</b><span>Vue de traitement du registre de service de la serre</span></li><li data-workflow-guide-step="2"><b>3</b><span>Vue de rétrospective du registre de garde de la serre</span></li></ol><div class="guide-actions"><button id="workflowGuideBack" class="action" type="button" disabled>Étape précédente</button><button id="workflowGuideNext" class="action primary" type="button">Terminer cette étape</button></div><div id="workflowGuideProgress" role="progressbar" aria-label="Avancement du registre de service de serre" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><i></i></div></nav><section id="workflowCore" class="workflow-core guide-core" data-guide-step="0" aria-describedby="workflowGuideInstruction"><p id="workflowGuideInstruction">Veuillez effectuer les actions liées à « Vue de surveillance du carnet de service de la serre » dans le cas principal.</p><!-- 11DZ_CORE_START:dashboards-admin-cohort-panel --><div class="cohort-studio"><header><span class="eyebrow">COHORT RETENTION</span><h2>Tableau de suivi des groupes de rétention de la serre</h2><label>Afficher le pourcentage <input id="cohortPercent" type="checkbox" checked data-core-bridge="dashboards-admin-cohort-panel"></label></header><div class="cohort-board"><div class="special-table-shell"><table class="special-table cohort-table"><caption>Registre de service de la serre matrice de conservation sur quatre côtés</caption><thead><tr><th>groupe</th><th>Semaine 0</th><th>Semaine 1</th><th>Semaine 2</th><th>Semaine 3</th></tr></thead><tbody><tr><th>Rejoindre cette semaine</th><td data-cohort="100">100%</td><td data-cohort="83">83%</td><td data-cohort="66">66%</td><td data-cohort="49">49%</td></tr><tr><th>rejoint la semaine dernière</th><td data-cohort="94">94%</td><td data-cohort="77">77%</td><td data-cohort="60">60%</td><td data-cohort="43">43%</td></tr><tr><th>Il y a deux semaines</th><td data-cohort="88">88%</td><td data-cohort="71">71%</td><td data-cohort="54">54%</td><td data-cohort="37">37%</td></tr><tr><th>Adhéré il y a trois semaines</th><td data-cohort="82">82%</td><td data-cohort="65">65%</td><td data-cohort="48">48%</td><td data-cohort="31">31%</td></tr></tbody></table></div><aside><strong id="cohortTopWeek">Meilleure plage : semaine 0</strong><p id="cohortModeHint">En ce moment, visualisation des variations de rétention en pourcentage.</p><ol id="cohortSummaryList"></ol></aside></div></div><!-- 11DZ_CORE_END --></section><aside class="guide-evidence"><details id="workflowGuideDetails"><summary>Voir les exigences d’acceptation</summary><ul><li>La vue de surveillance du registre de service de la serre nécessite un changement d’état visible</li><li>La vue de traitement du registre de garde de la serre nécessite un changement d’état visible unique</li><li>La vue récapitulative du registre de service de la serre nécessite un changement d’état visible à la fois.</li></ul></details><form id="workflowGuideEvidenceForm"><label>Preuve de cette étape<textarea id="workflowGuideEvidence" rows="3" placeholder="Enregistrer l’état observé"></textarea></label><input class="action" type="submit" value="Enregistrer la preuve"></form><output id="workflowGuideSummary">0 / 3 étapes terminées</output></aside></div><p id="status" class="status" role="status" aria-live="polite"></p></section></div>
  </main>
  <script>
    'use strict';
    const statusOutput = document.querySelector('#status');
    const announce = message => { statusOutput.textContent = message; };
    /* 11DZ_CORE_SCRIPT_START:dashboards-admin-cohort-panel */
const cohortCells=[...document.querySelectorAll('[data-cohort]')];const cohortLabels=["Rejoindre cette semaine","rejoint la semaine dernière","Il y a deux semaines","Adhéré il y a trois semaines"];function renderCohortStudio(asPercent){const weeks=[0,1,2,3].map(column=>cohortCells.filter((_,index)=>index%4===column).reduce((sum,cell)=>sum+Number(cell.dataset.cohort),0));const bestWeek=weeks.indexOf(Math.max(...weeks));document.querySelector('#cohortTopWeek').textContent='Meilleure plage : numéro '+bestWeek+' semaine';document.querySelector('#cohortModeHint').textContent=asPercent?'En ce moment, visualisation des variations de rétention en pourcentage.':'Observations actuelles de l’évolution de la rétention à partir d’un effectif estimé.';document.querySelector('#cohortSummaryList').replaceChildren(...weeks.map((value,index)=>{const item=document.createElement('li');item.textContent='Deuxième '+index+' Semaine · '+(asPercent?Math.round(value/cohortLabels.length)+'%':Math.round(value*2.4/cohortLabels.length)+' personne');return item;}));}cohortCells.forEach(cell=>cell.style.setProperty('--retention',cell.dataset.cohort));document.querySelector('#cohortPercent').addEventListener('change',event=>{cohortCells.forEach(cell=>{cell.textContent=event.currentTarget.checked?cell.dataset.cohort+'%':Math.round(Number(cell.dataset.cohort)*2.4)+' personne';});renderCohortStudio(event.currentTarget.checked);announce(event.currentTarget.checked?'Pourcentage de rétention affiché':'Nombre estimé affiché');});renderCohortStudio(true);
/* 11DZ_CORE_SCRIPT_END */
const workflowBridgeSpec={"name":"dashboards-admin-cohort-panel","selector":"[data-core-bridge=\"dashboards-admin-cohort-panel\"]","mode":"toggle","key":" "};const workflowBridgeCore=document.querySelector('#workflowCore');const workflowBridgeControl=workflowBridgeCore.querySelector(workflowBridgeSpec.selector);if(!workflowBridgeControl)throw new Error('Missing core bridge: '+workflowBridgeSpec.name);const workflowBridgeControlledId=workflowBridgeControl.getAttribute('aria-controls');const workflowBridgeControlled=workflowBridgeControlledId?document.getElementById(workflowBridgeControlledId):null;workflowBridgeCore.dataset.workflowBridge=workflowBridgeSpec.name;workflowBridgeCore.dataset.workflowVersion='0';function workflowBridgeSerialize(){const visualNode=workflowBridgeCore.firstElementChild||workflowBridgeCore;const visual=getComputedStyle(visualNode);const outputs=[...workflowBridgeCore.querySelectorAll('output,[role="status"],[aria-live],meter,progress')].map(node=>node.textContent.trim()+'|'+node.getAttribute('aria-valuenow')+'|'+node.getAttribute('value'));const canvas=[...workflowBridgeCore.querySelectorAll('canvas')].map(node=>{try{return node.toDataURL().slice(-160);}catch{return 'canvas-unavailable';}});return JSON.stringify({html:workflowBridgeCore.innerHTML,status:statusOutput.textContent,outputs,canvas,visual:[visual.display,visual.visibility,visual.opacity,visual.transform,visual.filter,visual.backgroundColor,visual.width,visual.height],scroll:workflowBridgeSpec.mode==='scroll'?workflowBridgeControl.scrollTop:null});}let workflowBridgeLastEffect=workflowBridgeSerialize();function workflowBridgeSummary(){const label=(workflowBridgeControl.getAttribute('aria-label')||workflowBridgeControl.textContent||workflowBridgeControl.value||workflowBridgeSpec.name).trim().replace(/\s+/g,' ').slice(0,72);return label+' · Version de base '+workflowBridgeCore.dataset.workflowVersion;}function workflowBridgeCommit(){const effect=workflowBridgeSerialize();if(effect===workflowBridgeLastEffect)return {changed:false,summary:workflowBridgeSummary()};workflowBridgeLastEffect=effect;workflowBridgeCore.dataset.workflowVersion=String(Number(workflowBridgeCore.dataset.workflowVersion||0)+1);return {changed:true,summary:workflowBridgeSummary()};}function workflowBridgeScheduleCommit(){queueMicrotask(workflowBridgeCommit);setTimeout(workflowBridgeCommit,0);}workflowBridgeControl.setAttribute('aria-keyshortcuts',workflowBridgeSpec.key===' '?'Space':workflowBridgeSpec.key);const workflowBridgeToggleKeyMatches=event=>event.key===workflowBridgeSpec.key||event.key==='Spacebar'||event.code==='Space';workflowBridgeControl.addEventListener('keydown',event=>{if(!workflowBridgeToggleKeyMatches(event))return;event.preventDefault();});workflowBridgeControl.addEventListener('keyup',event=>{if(!workflowBridgeToggleKeyMatches(event))return;event.preventDefault();workflowBridgeControl.click();});workflowBridgeControl.addEventListener("change",workflowBridgeScheduleCommit);const workflowBridgeStateTargets=new Set(workflowBridgeCore.querySelectorAll('dialog'));if(workflowBridgeControlled&&workflowBridgeCore.contains(workflowBridgeControlled))workflowBridgeStateTargets.add(workflowBridgeControlled);workflowBridgeStateTargets.forEach(target=>['close','cancel','toggle'].forEach(eventName=>target.addEventListener(eventName,workflowBridgeScheduleCommit)));function workflowBridgeActivate(){workflowBridgeControl.focus();workflowBridgeControl.click();const result=workflowBridgeCommit();setTimeout(workflowBridgeCommit,0);return result;}function workflowBridgeReset(){workflowBridgeCore.dataset.workflowVersion='0';workflowBridgeLastEffect=workflowBridgeSerialize();}
const workflowGuideCore=document.querySelector('#workflowCore');const workflowGuideStages=["Vue de surveillance du registre de garde de la serre","Vue de traitement du registre de service de la serre","Vue de rétrospective du registre de garde de la serre"];const workflowGuideState={step:0,completed:new Set(),evidence:new Map(),consumedVersion:0};function workflowGuideDrive(){const step=workflowGuideState.step;workflowGuideCore.dataset.guideStep=String(step);document.querySelector('#workflowGuideInstruction').textContent='Veuillez terminer «'+workflowGuideStages[step]+'Opérations associées à « ».';document.querySelectorAll('[data-workflow-guide-step]').forEach((item,index)=>{item.classList.toggle('is-complete',workflowGuideState.completed.has(index));if(index===step)item.setAttribute('aria-current','step');else item.removeAttribute('aria-current');});document.querySelector('#workflowGuideBack').disabled=step===0;document.querySelector('#workflowGuideNext').textContent=step===workflowGuideStages.length-1?'Panneau d’application':'Terminer cette étape';const percent=Math.round(workflowGuideState.completed.size/workflowGuideStages.length*100);const progress=document.querySelector('#workflowGuideProgress');progress.setAttribute('aria-valuenow',String(percent));progress.querySelector('i').style.width=percent+'%';document.querySelector('#workflowGuideSummary').textContent=workflowGuideState.completed.size+' / '+workflowGuideStages.length+' Étapes complétées · '+workflowBridgeSummary();announce('Journal de service de la serre, étape actuelle :'+workflowGuideStages[step]);}function workflowGuideAdvance(direction){if(direction>0){const bridge=workflowBridgeActivate();const version=Number(workflowGuideCore.dataset.workflowVersion||0);if(version<=workflowGuideState.consumedVersion){announce('Veuillez d’abord effectuer la modification d’état visible du cas principal');return;}workflowGuideState.consumedVersion=version;workflowGuideState.completed.add(workflowGuideState.step);announce('Variation du cas principal enregistrée · '+bridge.summary);}workflowGuideState.step=Math.max(0,Math.min(workflowGuideStages.length-1,workflowGuideState.step+direction));workflowGuideDrive();}document.querySelector('#workflowGuideBack').addEventListener('click',()=>workflowGuideAdvance(-1));document.querySelector('#workflowGuideNext').addEventListener('click',()=>workflowGuideAdvance(1));document.querySelector('#workflowGuideEvidenceForm').addEventListener('submit',event=>{event.preventDefault();const version=Number(workflowGuideCore.dataset.workflowVersion||0);if(version<=workflowGuideState.consumedVersion){announce('La preuve n’a pas été enregistrée : le cas principal n’a encore subi aucun changement nouveau');return;}const text=document.querySelector('#workflowGuideEvidence').value.trim();workflowGuideState.evidence.set(workflowGuideState.step,text||'Vérification de l’état visible terminée');workflowGuideState.completed.add(workflowGuideState.step);workflowGuideState.consumedVersion=version;workflowGuideDrive();announce('Les preuves de cette étape ont été enregistrées · '+workflowBridgeSummary());});document.querySelector('#workflowGuideDetails').addEventListener('toggle',event=>announce(event.currentTarget.open?'Exigences d’acceptation développées':'Exigences d’acceptation repliées'));workflowGuideDrive();
workflowBridgeReset();
  </script>
</body>
</html>
Commentaires sur la pageVous avez découvert un problème ou avez une suggestion d’amélioration ?
Les fonctions de retour nécessitent l’utilisation de la version en ligne

Veuillez activer JavaScript dans la version en ligne avant de soumettre ; les fonctionnalités locales de l’outil ou du cas ne sont pas affectées.

Aller vers la version en ligne pour envoyer des commentaires