Voeg 28 herkenbare kleurplaten en creatieve niveaus toe (v0.4.66-beta) #4
4 changed files with 51 additions and 50 deletions
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
0.3.88-beta
|
||||
0.3.89-beta
|
||||
|
|
|
|||
|
|
@ -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;}
|
||||
|
|
|
|||
|
|
@ -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})` : "")));
|
||||
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();
|
||||
/* éé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 })),
|
||||
}));
|
||||
});
|
||||
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 })));
|
||||
});
|
||||
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 <select> met leerlingen gegroepeerd per klas (optgroup), gedeeld
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"use strict";
|
||||
/* version — shown until /api/version resolves (or if the fetch fails, e.g. offline).
|
||||
Kept in sync by hand with the VERSION file at the repo root on every release. */
|
||||
const VERSION = "0.3.88-beta";
|
||||
const VERSION = "0.3.89-beta";
|
||||
(function(){
|
||||
const tag = document.getElementById("verTag");
|
||||
tag.textContent = "v"+VERSION;
|
||||
|
|
@ -278,7 +278,7 @@ const I18N = {
|
|||
amNewCodeWarn:"Maakt een nieuwe koppelcode aan. Het huidige wachtwoord vervalt direct; de gebruiker moet opnieuw activeren.",
|
||||
amDeleteWarn:"Verwijdert dit account definitief, inclusief borden en woorden.",
|
||||
amResultPw:"Nieuw wachtwoord", amResultCode:"Nieuwe koppelcode",
|
||||
amColStatus:"Status", amNeverLoggedIn:"nog niet ingelogd", amFieldSchool:"School",
|
||||
amColStatus:"Status", amNeverLoggedIn:"nog niet ingelogd", amFieldSchool:"School", amStatusActive:"actief",
|
||||
amDetailEmpty:"Selecteer links een gebruiker om te bewerken, of maak een nieuwe aan.",
|
||||
amNewUser:"Nieuwe gebruiker", amRequestOne:"Aanmelding", amReqNew:"nieuw",
|
||||
amParents:"Ouders",
|
||||
|
|
@ -572,7 +572,7 @@ const I18N = {
|
|||
amNewCodeWarn:"Generates a new link code. The current password stops working immediately; the user must re-activate.",
|
||||
amDeleteWarn:"Deletes this account permanently, including boards and words.",
|
||||
amResultPw:"New password", amResultCode:"New link code",
|
||||
amColStatus:"Status", amNeverLoggedIn:"not signed in yet", amFieldSchool:"School",
|
||||
amColStatus:"Status", amNeverLoggedIn:"not signed in yet", amFieldSchool:"School", amStatusActive:"active",
|
||||
amDetailEmpty:"Select a user on the left to edit, or create a new one.",
|
||||
amNewUser:"New user", amRequestOne:"Enrolment", amReqNew:"new",
|
||||
amParents:"Parents",
|
||||
|
|
|
|||
Loading…
Reference in a new issue