diff --git a/VERSION b/VERSION index e510274..76418e2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.88-beta +0.3.89-beta diff --git a/public/css/teach.css b/public/css/teach.css index 530daea..57ded36 100644 --- a/public/css/teach.css +++ b/public/css/teach.css @@ -2017,7 +2017,7 @@ body.hc #settingsModal .am-inp, body.hc #settingsModal .am-sel{border-color:#000 #settingsModal .am-card:has(.am-card-subs[style*="none"]):not(:has(.am-card-tools:not([style*="none"]))) .am-card-head{border-bottom:none;} #settingsModal .am-ico{filter:grayscale(1); opacity:.55; font-size:13px; flex:none;} #settingsModal .am-card-title{font-weight:650; font-size:13.5px; flex:1; min-width:80px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;} -#settingsModal .am-card-sum{margin-left:auto; flex:none; font-size:12px; color:var(--muted);} +#settingsModal .am-card-sum{margin-left:auto; flex:0 1 auto; min-width:0; font-size:12px; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;} #settingsModal .am-card-toggle{cursor:pointer; user-select:none; padding:4px 6px; border-radius:5px;} #settingsModal .am-card-toggle:hover{background:var(--surface-3); color:var(--ink);} #settingsModal .am-card-tools{padding:10px 12px; border-bottom:1px solid var(--line); display:flex; flex-wrap:wrap; gap:10px;} diff --git a/public/js/admin.js b/public/js/admin.js index c859c1a..42a2660 100644 --- a/public/js/admin.js +++ b/public/js/admin.js @@ -478,9 +478,18 @@ /* inline-variant voor het Systeem-tabblad (schoolbeheerder-subrijen): naam + rol met een "Bewerken"-tekstknop die het formulier uitklapt */ function userRow(u, opts){ - const row = h("div","am-row" + (opts && opts.sub ? " am-row-sub" : "")); + const compact = !!(opts && opts.compact); + const row = h("div","am-row" + (opts && opts.sub ? " am-row-sub" : "") + (compact ? " am-card-sub" : "")); row.appendChild(h("span","am-name", u.displayName + (u.displayName!==u.username ? ` (${u.username})` : ""))); - row.appendChild(h("span","am-role", T(roleKey(u.role)) + (u.pending ? ` · ${T("amPending")}` : ""))); + if(compact){ + /* compacte kaart-subrij: status als glyph met uitleg-title i.p.v. tekst */ + row.appendChild(h("span","am-role", T(roleKey(u.role)))); + const glyph = h("span","am-glyph" + (u.pending ? "" : " ok"), u.pending ? "○" : "●"); + glyph.title = u.pending ? T("amPending") : T("amStatusActive"); + row.appendChild(glyph); + }else{ + row.appendChild(h("span","am-role", T(roleKey(u.role)) + (u.pending ? ` · ${T("amPending")}` : ""))); + } const tools = h("div","am-row-tools"); const badge = resultBadge(u); if(badge) tools.appendChild(badge); @@ -754,16 +763,10 @@ achter een bewuste extra stap (+-knop klapt het formulier uit, zoals bij gebruikers) en bevestigt daarna nog met de naam erin. */ function renderScholenPanel(panel){ - const list = h("div","am-list"); SCHOOLS.forEach(s=>{ const admins = SYS_ADMINS.filter(a=>Number(a.schoolId)===Number(s.id)); - const row = h("div","am-row am-row-school"); - row.appendChild(h("span","am-name", s.name)); - row.appendChild(h("span","am-role", - `${admins.length} ${(admins.length===1 ? T("amAdminOne") : T("amAdmins")).toLowerCase()}`)); - /* zelfde ✏-systeem als bij gebruikers: hernoemen en verwijderen - zitten achter het gereedschapsblok, de rij zelf blijft rustig */ - const tools = h("div","am-row-tools"); + /* bewerk-gereedschap van de school zelf (hernoemen/verwijderen) */ + const tools = h("div","am-tools"); const nameInp = h("input","am-inp"); nameInp.value = s.name; nameInp.maxLength = 80; @@ -784,27 +787,17 @@ }catch(e){ msg(e.message); } })); tools.appendChild(field("amFieldActions", acts)); - const edit = h("button","am-edit", T("amEdit")); - edit.type = "button"; - const key = "school:"+s.id; - const sync = ()=>{ - const open = openRows.has(key); - tools.style.display = open ? "" : "none"; - edit.classList.toggle("on", open); - }; - edit.addEventListener("click", ()=>{ - if(openRows.has(key)) openRows.delete(key); else openRows.add(key); - sync(); - }); - sync(); - row.appendChild(edit); - row.appendChild(tools); - list.appendChild(row); - /* de schoolbeheerders van deze school, duidelijk onderscheiden van de - schoolrij (ingesprongen) maar met hetzelfde bewerk-gereedschap */ - admins.forEach(a=>list.appendChild(userRow(a, { sub:true }))); + /* één kader om de school en haar beheerders; beheerders standaard + ingeklapt achter de teller, als compacte subrijen */ + panel.appendChild(groupCard({ + icon:"🏫", + title:s.name, + summary:`${admins.length} ${(admins.length===1 ? T("amAdminOne") : T("amAdmins")).toLowerCase()}`, + key:"schooladmins:"+s.id, + edit:{ key:"school:"+s.id, tools }, + subs: admins.map(a=>userRow(a, { sub:true, compact:true })), + })); }); - panel.appendChild(list); const wrap = h("div","am-add-wrap"); const toggle = h("button","tbtn ghost", T("amNewSchool")); @@ -864,12 +857,9 @@ const canResetPw = can("schools.resetPasswords"); /* klassen als volwaardige rijen (zelfde maat als de gebruikersvakken), met de gevaarlijke acties als aparte, bevestigde knoppen */ - const list = h("div","am-list"); CLASSES.forEach(c=>{ - const row = h("div","am-row"); const pupilCount = USERS.filter(u=>u.role==="pupil" && Number(u.classId)===Number(c.id)).length; - row.appendChild(h("span","am-name", c.name)); - row.appendChild(h("span","am-role", `${pupilCount} ${(pupilCount===1 ? T("amPupilOne") : T("amPupils")).toLowerCase()}`)); + let edit = null; if(canResetPw){ const acts = h("div","am-actions"); acts.appendChild(dangerBtn(T("amResetClass"), "amConfirmReset", async ()=>{ @@ -884,11 +874,16 @@ try{ await api("/admin/classes/"+c.id, {method:"DELETE"}); reload(); } catch(e){ msg(e.message); } })); - row.appendChild(acts); + const tools = h("div","am-tools"); + tools.appendChild(field("amFieldActions", acts)); + edit = { key:"klas:"+c.id, tools }; } - list.appendChild(row); + panel.appendChild(groupCard({ + title:c.name, + summary:`${pupilCount} ${(pupilCount===1 ? T("amPupilOne") : T("amPupils")).toLowerCase()}`, + edit, + })); }); - panel.appendChild(list); if(canResetPw){ const f = h("div","am-add"); const inp = h("input","am-inp"); @@ -947,8 +942,6 @@ return s; } function assignmentRow(target, boardOptions, current){ - const row = h("div","am-row"); - row.appendChild(h("span","am-name", target.label)); const sel = h("select","am-sel"); sel.appendChild(new Option(T("amNoAssignment"), "")); boardOptions.forEach(b=>sel.appendChild(new Option(b.label, b.id))); @@ -971,10 +964,6 @@ sel.addEventListener("change", syncWidgetSel); widgetSel.addEventListener("change", syncModeSel); const info = h("span","am-code", describeCurrent(current)); - row.appendChild(sel); - row.appendChild(widgetSel); - row.appendChild(modeSel); - row.appendChild(info); syncWidgetSel(); const apply = h("button","am-btn", T("amAssign")); apply.type = "button"; @@ -994,8 +983,20 @@ } }catch(e){ msg(e.message); } }); - row.appendChild(apply); - return row; + /* kop toont compact de huidige stand; de keuzes klappen uit via Bewerken */ + const tools = h("div","am-tools"); + const inline = h("div","am-inline"); + inline.appendChild(sel); + inline.appendChild(widgetSel); + inline.appendChild(modeSel); + inline.appendChild(apply); + tools.appendChild(inline); + tools.appendChild(info); + return groupCard({ + title: target.label, + summary: describeCurrent(current) || T("amNoAssignment"), + edit: { key: "assign:"+target.type+":"+target.id, tools }, + }); } /* vult een