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-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-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-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{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-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;}
|
#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):
|
/* inline-variant voor het Systeem-tabblad (schoolbeheerder-subrijen):
|
||||||
naam + rol met een "Bewerken"-tekstknop die het formulier uitklapt */
|
naam + rol met een "Bewerken"-tekstknop die het formulier uitklapt */
|
||||||
function userRow(u, opts){
|
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-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")}` : "")));
|
row.appendChild(h("span","am-role", T(roleKey(u.role)) + (u.pending ? ` · ${T("amPending")}` : "")));
|
||||||
|
}
|
||||||
const tools = h("div","am-row-tools");
|
const tools = h("div","am-row-tools");
|
||||||
const badge = resultBadge(u);
|
const badge = resultBadge(u);
|
||||||
if(badge) tools.appendChild(badge);
|
if(badge) tools.appendChild(badge);
|
||||||
|
|
@ -754,16 +763,10 @@
|
||||||
achter een bewuste extra stap (+-knop klapt het formulier uit, zoals
|
achter een bewuste extra stap (+-knop klapt het formulier uit, zoals
|
||||||
bij gebruikers) en bevestigt daarna nog met de naam erin. */
|
bij gebruikers) en bevestigt daarna nog met de naam erin. */
|
||||||
function renderScholenPanel(panel){
|
function renderScholenPanel(panel){
|
||||||
const list = h("div","am-list");
|
|
||||||
SCHOOLS.forEach(s=>{
|
SCHOOLS.forEach(s=>{
|
||||||
const admins = SYS_ADMINS.filter(a=>Number(a.schoolId)===Number(s.id));
|
const admins = SYS_ADMINS.filter(a=>Number(a.schoolId)===Number(s.id));
|
||||||
const row = h("div","am-row am-row-school");
|
/* bewerk-gereedschap van de school zelf (hernoemen/verwijderen) */
|
||||||
row.appendChild(h("span","am-name", s.name));
|
const tools = h("div","am-tools");
|
||||||
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");
|
|
||||||
const nameInp = h("input","am-inp");
|
const nameInp = h("input","am-inp");
|
||||||
nameInp.value = s.name;
|
nameInp.value = s.name;
|
||||||
nameInp.maxLength = 80;
|
nameInp.maxLength = 80;
|
||||||
|
|
@ -784,27 +787,17 @@
|
||||||
}catch(e){ msg(e.message); }
|
}catch(e){ msg(e.message); }
|
||||||
}));
|
}));
|
||||||
tools.appendChild(field("amFieldActions", acts));
|
tools.appendChild(field("amFieldActions", acts));
|
||||||
const edit = h("button","am-edit", T("amEdit"));
|
/* één kader om de school en haar beheerders; beheerders standaard
|
||||||
edit.type = "button";
|
ingeklapt achter de teller, als compacte subrijen */
|
||||||
const key = "school:"+s.id;
|
panel.appendChild(groupCard({
|
||||||
const sync = ()=>{
|
icon:"🏫",
|
||||||
const open = openRows.has(key);
|
title:s.name,
|
||||||
tools.style.display = open ? "" : "none";
|
summary:`${admins.length} ${(admins.length===1 ? T("amAdminOne") : T("amAdmins")).toLowerCase()}`,
|
||||||
edit.classList.toggle("on", open);
|
key:"schooladmins:"+s.id,
|
||||||
};
|
edit:{ key:"school:"+s.id, tools },
|
||||||
edit.addEventListener("click", ()=>{
|
subs: admins.map(a=>userRow(a, { sub:true, compact:true })),
|
||||||
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 })));
|
|
||||||
});
|
|
||||||
panel.appendChild(list);
|
|
||||||
|
|
||||||
const wrap = h("div","am-add-wrap");
|
const wrap = h("div","am-add-wrap");
|
||||||
const toggle = h("button","tbtn ghost", T("amNewSchool"));
|
const toggle = h("button","tbtn ghost", T("amNewSchool"));
|
||||||
|
|
@ -864,12 +857,9 @@
|
||||||
const canResetPw = can("schools.resetPasswords");
|
const canResetPw = can("schools.resetPasswords");
|
||||||
/* klassen als volwaardige rijen (zelfde maat als de gebruikersvakken),
|
/* klassen als volwaardige rijen (zelfde maat als de gebruikersvakken),
|
||||||
met de gevaarlijke acties als aparte, bevestigde knoppen */
|
met de gevaarlijke acties als aparte, bevestigde knoppen */
|
||||||
const list = h("div","am-list");
|
|
||||||
CLASSES.forEach(c=>{
|
CLASSES.forEach(c=>{
|
||||||
const row = h("div","am-row");
|
|
||||||
const pupilCount = USERS.filter(u=>u.role==="pupil" && Number(u.classId)===Number(c.id)).length;
|
const pupilCount = USERS.filter(u=>u.role==="pupil" && Number(u.classId)===Number(c.id)).length;
|
||||||
row.appendChild(h("span","am-name", c.name));
|
let edit = null;
|
||||||
row.appendChild(h("span","am-role", `${pupilCount} ${(pupilCount===1 ? T("amPupilOne") : T("amPupils")).toLowerCase()}`));
|
|
||||||
if(canResetPw){
|
if(canResetPw){
|
||||||
const acts = h("div","am-actions");
|
const acts = h("div","am-actions");
|
||||||
acts.appendChild(dangerBtn(T("amResetClass"), "amConfirmReset", async ()=>{
|
acts.appendChild(dangerBtn(T("amResetClass"), "amConfirmReset", async ()=>{
|
||||||
|
|
@ -884,11 +874,16 @@
|
||||||
try{ await api("/admin/classes/"+c.id, {method:"DELETE"}); reload(); }
|
try{ await api("/admin/classes/"+c.id, {method:"DELETE"}); reload(); }
|
||||||
catch(e){ msg(e.message); }
|
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){
|
if(canResetPw){
|
||||||
const f = h("div","am-add");
|
const f = h("div","am-add");
|
||||||
const inp = h("input","am-inp");
|
const inp = h("input","am-inp");
|
||||||
|
|
@ -947,8 +942,6 @@
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
function assignmentRow(target, boardOptions, current){
|
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");
|
const sel = h("select","am-sel");
|
||||||
sel.appendChild(new Option(T("amNoAssignment"), ""));
|
sel.appendChild(new Option(T("amNoAssignment"), ""));
|
||||||
boardOptions.forEach(b=>sel.appendChild(new Option(b.label, b.id)));
|
boardOptions.forEach(b=>sel.appendChild(new Option(b.label, b.id)));
|
||||||
|
|
@ -971,10 +964,6 @@
|
||||||
sel.addEventListener("change", syncWidgetSel);
|
sel.addEventListener("change", syncWidgetSel);
|
||||||
widgetSel.addEventListener("change", syncModeSel);
|
widgetSel.addEventListener("change", syncModeSel);
|
||||||
const info = h("span","am-code", describeCurrent(current));
|
const info = h("span","am-code", describeCurrent(current));
|
||||||
row.appendChild(sel);
|
|
||||||
row.appendChild(widgetSel);
|
|
||||||
row.appendChild(modeSel);
|
|
||||||
row.appendChild(info);
|
|
||||||
syncWidgetSel();
|
syncWidgetSel();
|
||||||
const apply = h("button","am-btn", T("amAssign"));
|
const apply = h("button","am-btn", T("amAssign"));
|
||||||
apply.type = "button";
|
apply.type = "button";
|
||||||
|
|
@ -994,8 +983,20 @@
|
||||||
}
|
}
|
||||||
}catch(e){ msg(e.message); }
|
}catch(e){ msg(e.message); }
|
||||||
});
|
});
|
||||||
row.appendChild(apply);
|
/* kop toont compact de huidige stand; de keuzes klappen uit via Bewerken */
|
||||||
return row;
|
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
|
/* vult een <select> met leerlingen gegroepeerd per klas (optgroup), gedeeld
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
/* version — shown until /api/version resolves (or if the fetch fails, e.g. offline).
|
/* 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. */
|
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(){
|
(function(){
|
||||||
const tag = document.getElementById("verTag");
|
const tag = document.getElementById("verTag");
|
||||||
tag.textContent = "v"+VERSION;
|
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.",
|
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.",
|
amDeleteWarn:"Verwijdert dit account definitief, inclusief borden en woorden.",
|
||||||
amResultPw:"Nieuw wachtwoord", amResultCode:"Nieuwe koppelcode",
|
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.",
|
amDetailEmpty:"Selecteer links een gebruiker om te bewerken, of maak een nieuwe aan.",
|
||||||
amNewUser:"Nieuwe gebruiker", amRequestOne:"Aanmelding", amReqNew:"nieuw",
|
amNewUser:"Nieuwe gebruiker", amRequestOne:"Aanmelding", amReqNew:"nieuw",
|
||||||
amParents:"Ouders",
|
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.",
|
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.",
|
amDeleteWarn:"Deletes this account permanently, including boards and words.",
|
||||||
amResultPw:"New password", amResultCode:"New link code",
|
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.",
|
amDetailEmpty:"Select a user on the left to edit, or create a new one.",
|
||||||
amNewUser:"New user", amRequestOne:"Enrolment", amReqNew:"new",
|
amNewUser:"New user", amRequestOne:"Enrolment", amReqNew:"new",
|
||||||
amParents:"Parents",
|
amParents:"Parents",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue