Live/Vergleich an Klassenaufgabe gekoppelt
- aktive Klassenaufgabe wird automatisch als Vergleichs-Modul vorgewaehlt (Chip mit 📋 markiert, immer vorne) - Aufgaben-Banner: begonnen X/N (aus matrix) · gerade aktiv A · Oe Fortschritt - zeigt Aufgabe auch wenn noch niemand aktiv ist (mit Hinweis) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+62
-14
@@ -1464,10 +1464,21 @@ function _compareGroupLabel(g) {
|
||||
async function renderLiveCompare() {
|
||||
var host = document.getElementById('tab-live');
|
||||
if (!host) return;
|
||||
var sessions = await api('live?class_id=' + currentClassId);
|
||||
var res = await Promise.all([
|
||||
api('live?class_id=' + currentClassId),
|
||||
api('assignments?class_id=' + currentClassId),
|
||||
api('results?class_id=' + currentClassId + '&view=matrix'),
|
||||
]);
|
||||
var sessions = res[0], assignments = res[1], matrix = res[2];
|
||||
if (sessions.error) { host.innerHTML = _liveToggleHtml() + '<p style="color:#c07a6b">'+esc(sessions.error)+'</p>'; return; }
|
||||
if (!Array.isArray(assignments)) assignments = [];
|
||||
if (!matrix || matrix.error) matrix = { students:[], modules:[], cells:{} };
|
||||
|
||||
// Sim-Filter-Chips: alle aktiven Sims zählen, gruppiert
|
||||
// Aktive Klassenaufgabe (erste aktive) → Fokus-Modul für den Vergleich
|
||||
var activeAssign = assignments.filter(function(a){ return a.active; })[0] || null;
|
||||
var assignGroup = activeAssign ? _compareSimGroup(activeAssign.module_id) : null;
|
||||
|
||||
// Online-Sessions nach Sim gruppieren
|
||||
var byGroup = {};
|
||||
(sessions || []).forEach(function(ls){
|
||||
var g = _compareSimGroup(ls.module_id);
|
||||
@@ -1477,38 +1488,75 @@ async function renderLiveCompare() {
|
||||
});
|
||||
var groups = Object.keys(byGroup).sort(function(a,b){ return byGroup[b].count - byGroup[a].count; });
|
||||
|
||||
if (!groups.length) {
|
||||
// Chips = Online-Gruppen, Aufgabe immer vorne (auch wenn noch niemand aktiv)
|
||||
var chipGroups = groups.slice();
|
||||
if (assignGroup) chipGroups = [assignGroup].concat(chipGroups.filter(function(g){ return g !== assignGroup; }));
|
||||
|
||||
if (!chipGroups.length) {
|
||||
host.innerHTML = _liveToggleHtml()
|
||||
+ '<div class="card"><div class="card-h">Vergleich</div>'
|
||||
+ '<p style="font-size:.78rem;color:#8a8a8a">Gerade niemand online — sobald Schüler*innen eine Simulation öffnen, kannst du hier vergleichen.</p>'
|
||||
+ '<p style="font-size:.78rem;color:#8a8a8a">Gerade niemand online und keine aktive Klassenaufgabe — sobald Schüler*innen eine Simulation öffnen (oder du eine Aufgabe freigibst), kannst du hier vergleichen.</p>'
|
||||
+ '</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Aktive Sim wählen — User-Wahl, sonst die mit den meisten Schüler*innen
|
||||
var sim = _liveCompareSim && byGroup[_liveCompareSim] ? _liveCompareSim : groups[0];
|
||||
// Sim wählen: explizite User-Wahl > aktive Aufgabe > meiste Online
|
||||
var sim;
|
||||
if (_liveCompareSim && chipGroups.indexOf(_liveCompareSim) >= 0) sim = _liveCompareSim;
|
||||
else if (assignGroup) sim = assignGroup;
|
||||
else sim = groups[0];
|
||||
_liveCompareSim = sim;
|
||||
|
||||
// Header mit Toggle + Sim-Filter-Chips
|
||||
var html = _liveToggleHtml();
|
||||
|
||||
// Aufgaben-Banner, wenn eine Klassenaufgabe aktiv ist
|
||||
if (activeAssign) {
|
||||
var modId = activeAssign.module_id;
|
||||
var N = (matrix.students || []).length;
|
||||
var begun = 0;
|
||||
(matrix.students || []).forEach(function(s){
|
||||
var c = (matrix.cells && matrix.cells[s.id]) ? matrix.cells[s.id][modId] : null;
|
||||
if (c && c.plays > 0) begun++;
|
||||
});
|
||||
var onlineNow = byGroup[assignGroup] ? byGroup[assignGroup].sessions : [];
|
||||
var progVals = onlineNow.map(function(ls){ return _liveProgressPct(ls.module_id, ls.state); }).filter(function(v){ return v != null; });
|
||||
var avgProg = progVals.length ? Math.round(progVals.reduce(function(a,b){return a+b;},0)/progVals.length) : null;
|
||||
var due = activeAssign.ends_at ? ' · bis ' + new Date(activeAssign.ends_at).toLocaleDateString('de-AT',{day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'}) : '';
|
||||
html += '<div style="background:#f0f5f1;border:1px solid #cfe0d4;border-left:4px solid #3a6a3e;border-radius:10px;padding:.6rem .9rem;margin-bottom:.7rem">'
|
||||
+ '<div style="font-size:.82rem;font-weight:800;color:#2a5a2e">📋 Aufgabe: '+esc(_compareGroupLabel(assignGroup))+'<span style="font-weight:500;color:#6a8a6e;font-size:.7rem"> · Level '+esc(activeAssign.level)+due+'</span></div>'
|
||||
+ '<div style="display:flex;gap:1.2rem;flex-wrap:wrap;margin-top:.35rem;font-size:.74rem;color:#3a3a3a">'
|
||||
+ '<span>begonnen <b>'+begun+'</b> / '+N+'</span>'
|
||||
+ '<span>gerade aktiv <b>'+onlineNow.length+'</b></span>'
|
||||
+ '<span>Ø Fortschritt <b>'+(avgProg!=null?avgProg+' %':'–')+'</b></span>'
|
||||
+ '</div></div>';
|
||||
}
|
||||
|
||||
// Sim-Filter-Chips
|
||||
html += '<div style="display:flex;gap:.4rem;flex-wrap:wrap;margin-bottom:.6rem;padding:.3rem 0">';
|
||||
groups.forEach(function(g){
|
||||
chipGroups.forEach(function(g){
|
||||
var active = g === sim;
|
||||
var isAssign = (g === assignGroup);
|
||||
var bg = active ? '#1f4b37' : '#fff';
|
||||
var col = active ? '#fff' : '#3d5165';
|
||||
var border = active ? '#1f4b37' : 'rgba(0,0,0,.12)';
|
||||
var border = active ? '#1f4b37' : (isAssign ? '#3a6a3e' : 'rgba(0,0,0,.12)');
|
||||
var cnt = byGroup[g] ? byGroup[g].count : 0;
|
||||
html += '<button onclick="setCompareSim(\''+g+'\')" style="padding:.35rem .7rem;border:1.5px solid '+border+';background:'+bg+';color:'+col+';border-radius:18px;font-size:.74rem;font-weight:700;cursor:pointer;display:inline-flex;align-items:center;gap:.4rem">'
|
||||
+ (isAssign ? '<span title="aktive Klassenaufgabe">📋</span>' : '')
|
||||
+ '<span>'+esc(_compareGroupLabel(g))+'</span>'
|
||||
+ '<span style="background:'+(active?'rgba(255,255,255,.25)':'rgba(0,0,0,.07)')+';padding:0 .4rem;border-radius:8px;font-size:.66rem;font-weight:800">'+byGroup[g].count+'</span>'
|
||||
+ '<span style="background:'+(active?'rgba(255,255,255,.25)':'rgba(0,0,0,.07)')+';padding:0 .4rem;border-radius:8px;font-size:.66rem;font-weight:800">'+cnt+'</span>'
|
||||
+ '</button>';
|
||||
});
|
||||
html += '</div>';
|
||||
|
||||
// Sim-spezifisch rendern
|
||||
if (sim === 'klima') {
|
||||
html += _renderKlimaCompareBody(byGroup.klima.sessions);
|
||||
// Körper
|
||||
var simSessions = byGroup[sim] ? byGroup[sim].sessions : [];
|
||||
if (!simSessions.length) {
|
||||
html += '<div class="card"><div class="card-h">'+esc(_compareGroupLabel(sim))+' · Vergleich</div>'
|
||||
+ '<p style="font-size:.78rem;color:#8a8a8a">Noch niemand arbeitet gerade an dieser Simulation. Sobald Kinder starten, erscheinen sie hier im Vergleich.</p></div>';
|
||||
} else if (sim === 'klima') {
|
||||
html += _renderKlimaCompareBody(simSessions);
|
||||
} else {
|
||||
html += _renderGenericCompareBody(byGroup[sim].sessions, sim);
|
||||
html += _renderGenericCompareBody(simSessions, sim);
|
||||
}
|
||||
host.innerHTML = html;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user