style: tekstknoppen en consistente secties in het beheer - emoji-sweep afgerond (v0.3.87-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 45s

- Alle resterende emoji uit het beheer: kopieerknoppen zijn tekstknoppen ("kopieer"), wachtwoord-genereerknop heet "genereer", "alles kopiëren" zonder klembord-icoon, schoolrijen zonder 🏫, contextbalk-label is het woord "School", bevestiging is "zeker?" (de rode armed-stijl is het signaal), kopieer-feedback een net vinkje
- Scholen-tabblad: "Bewerken"-tekstknoppen i.p.v. het ✏-potlood; zoek-placeholders zonder vergrootglas-emoji
- CMS-widgetkeuze zonder emoji-prefix in de opties
- Playwright-emoji-scan over alle vijf beheersecties (knoppen/labels/groepen schoon, ▸▾✕✓+ toegestaan) + volledige master-detail-regressie (19 checks) groen

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149FgUQvuwxKKEdvQGmNngF
This commit is contained in:
Ramon 2026-07-17 07:08:17 +02:00
parent af86ff5c47
commit ebe622588f
4 changed files with 20 additions and 23 deletions

View file

@ -1 +1 @@
0.3.86-beta
0.3.87-beta

View file

@ -49,13 +49,12 @@
document.body.removeChild(ta);
}
const orig = btn.textContent;
btn.textContent = "";
btn.textContent = "";
setTimeout(()=>{ btn.textContent = orig; }, 1200);
}
function copyBtn(text, cls){
const b = h("button", cls || "am-copy", "📋");
const b = h("button", cls || "am-btn", T("amCopy"));
b.type = "button";
b.title = T("amCopy");
b.addEventListener("click", e=>{ e.preventDefault(); if(text) copyText(b, text); });
return b;
}
@ -92,7 +91,7 @@
b.addEventListener("click", async ()=>{
if(!timer){
b.classList.add("armed");
b.textContent = "⚠ " + T("amSure");
b.textContent = T("amSure");
timer = setTimeout(()=>{ timer = null; b.classList.remove("armed"); b.textContent = label; }, 4000);
return;
}
@ -527,9 +526,8 @@
pwInp.placeholder = T("amPwOptional");
pwInp.addEventListener("keydown", ev=>ev.stopPropagation());
pwWrap.appendChild(pwInp);
const gen = h("button","am-btn","🎲");
const gen = h("button","am-btn", T("amGenerate"));
gen.type = "button";
gen.title = T("amGenerate");
gen.addEventListener("click", async ()=>{
try{
const { password } = await api("/admin/genpw");
@ -677,7 +675,7 @@
return box;
}
const all = resetResults.entries.map(en=>`${en.displayName}\t${en.password}`).join("\n");
const copyAll = h("button","am-btn","📋 "+T("amCopyAll"));
const copyAll = h("button","am-btn", T("amCopyAll"));
copyAll.type = "button";
copyAll.addEventListener("click", e=>{ e.preventDefault(); copyText(copyAll, all); });
box.appendChild(copyAll);
@ -703,7 +701,7 @@
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-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
@ -729,9 +727,8 @@
}catch(e){ msg(e.message); }
}));
tools.appendChild(field("amFieldActions", acts));
const edit = h("button","am-edit","✏");
const edit = h("button","am-edit", T("amEdit"));
edit.type = "button";
edit.title = T("amEdit");
const key = "school:"+s.id;
const sync = ()=>{
const open = openRows.has(key);
@ -747,7 +744,7 @@
row.appendChild(tools);
list.appendChild(row);
/* de schoolbeheerders van deze school, duidelijk onderscheiden van de
schoolrij (🛡-icoon, ingesprongen) maar met hetzelfde -gereedschap */
schoolrij (ingesprongen) maar met hetzelfde bewerk-gereedschap */
admins.forEach(a=>list.appendChild(userRow(a, { sub:true })));
});
panel.appendChild(list);
@ -1247,7 +1244,7 @@
function schoolContextBar(){
if(currentUser.role !== "super") return null;
const bar = h("div","am-schoolbar");
bar.appendChild(h("span","am-schoolbar-lbl","🏫"));
bar.appendChild(h("span","am-schoolbar-lbl", T("amFieldSchool")));
const sel = h("select","am-sel");
sel.appendChild(new Option(T("amAllSchools"), ""));
SCHOOLS.forEach(s=>sel.appendChild(new Option(s.name, s.id)));

View file

@ -151,7 +151,7 @@ let CMS = {};
const pick = document.createElement("select");
pick.className = "am-sel";
pick.appendChild(new Option(T("cmsWidgetPick"), ""));
REGISTRY.forEach(def=>pick.appendChild(new Option(def.icon + " " + T("wg_"+def.id), def.id)));
REGISTRY.forEach(def=>pick.appendChild(new Option(T("wg_"+def.id), def.id)));
const editor = cmsEl("div");
editor.style.display = "none";
pick.addEventListener("change", ()=>{

View file

@ -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.86-beta";
const VERSION = "0.3.87-beta";
(function(){
const tag = document.getElementById("verTag");
tag.textContent = "v"+VERSION;
@ -200,7 +200,7 @@ const I18N = {
login:"Inloggen", loginBtn:"Inloggen", registerBtn:"Account maken", logout:"Uitloggen",
settingsTitle:"Instellingen", tabLogin:"Inloggen", tabLinkCode:"Koppelcode", busy:"Bezig…",
stAccount:"Account", stPassword:"Wachtwoord", stSession:"Sessie",
stSearchPh:"🔎 Zoeken in instellingen…", stNoResults:"Niets gevonden.",
stSearchPh:"Zoeken in instellingen…", stNoResults:"Niets gevonden.",
stOpenSection:"open dit onderdeel",
stGroupPersonal:"Persoonlijk", stGroupSchool:"School", stGroupSystem:"Systeem",
stAccountSub:"Je gegevens, wachtwoord en reservekopieën.",
@ -265,7 +265,7 @@ const I18N = {
pupilEmpty:"Je leerkracht heeft nog niets voor je klaargezet.",
pupilWatching:"meekijken",
amUsers:"Gebruikers", amClasses:"Klassen", amSchools:"Scholen", amOverarching:"Systeem",
amPickSchoolHint:"Kies hierboven eerst een school (🏫).", amPickSchool:"Kies een school",
amPickSchoolHint:"Kies hierboven eerst een school.", amPickSchool:"Kies een school",
amPupils:"Leerlingen", amPupilOne:"Leerling", amEdit:"Bewerken",
amAdmins:"Schoolbeheerders", amAdminOne:"Schoolbeheerder",
amClassAdd:"— voeg toe aan klas… —", amClassRemove:"Uit deze klas halen",
@ -276,7 +276,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",
amColStatus:"Status", amNeverLoggedIn:"nog niet ingelogd", amFieldSchool:"School",
amDetailEmpty:"Selecteer links een gebruiker om te bewerken, of maak een nieuwe aan.",
amNewUser:"Nieuwe gebruiker", amRequestOne:"Aanmelding", amReqNew:"nieuw",
amParents:"Ouders",
@ -293,7 +293,7 @@ const I18N = {
amNewSchool:" School", amNewClass:" Klas", amNewTeacher:" Groepsleiding",
amNewAdmin:" Schoolbeheerder", amNewSuper:" Systeemmanager",
amNewPupil:" Leerling", amUserPh:"gebruikersnaam…", amNamePh:"naam…",
amSearchPh:"🔎 zoek op naam…",
amSearchPh:"zoek op naam…",
amCode:"koppelcode", amNewCode:"nieuwe code", amPw:"wachtwoord",
amNoClass:"— geen klas —", amPending:"nog niet geactiveerd",
amCouple:"koppel leerkracht", amAllSchools:"— alle scholen —", amSuperGroup:"Systeem",
@ -492,7 +492,7 @@ const I18N = {
login:"Log in", loginBtn:"Log in", registerBtn:"Create account", logout:"Log out",
settingsTitle:"Settings", tabLogin:"Log in", tabLinkCode:"Link code", busy:"Please wait…",
stAccount:"Account", stPassword:"Password", stSession:"Session",
stSearchPh:"🔎 Search settings…", stNoResults:"Nothing found.",
stSearchPh:"Search settings…", stNoResults:"Nothing found.",
stOpenSection:"open this section",
stGroupPersonal:"Personal", stGroupSchool:"School", stGroupSystem:"System",
stAccountSub:"Your details, password and backups.",
@ -557,7 +557,7 @@ const I18N = {
pupilEmpty:"Your teacher hasn't set up anything for you yet.",
pupilWatching:"watching",
amUsers:"Users", amClasses:"Classes", amSchools:"Schools", amOverarching:"System",
amPickSchoolHint:"First pick a school above (🏫).", amPickSchool:"Pick a school",
amPickSchoolHint:"First pick a school above.", amPickSchool:"Pick a school",
amPupils:"Pupils", amPupilOne:"Pupil", amEdit:"Edit",
amAdmins:"School admins", amAdminOne:"School admin",
amClassAdd:"— add to class… —", amClassRemove:"Remove from this class",
@ -568,7 +568,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",
amColStatus:"Status", amNeverLoggedIn:"not signed in yet", amFieldSchool:"School",
amDetailEmpty:"Select a user on the left to edit, or create a new one.",
amNewUser:"New user", amRequestOne:"Enrolment", amReqNew:"new",
amParents:"Parents",
@ -585,7 +585,7 @@ const I18N = {
amNewSchool:" School", amNewClass:" Class", amNewTeacher:" Group leader",
amNewAdmin:" School admin", amNewSuper:" System manager",
amNewPupil:" Pupil", amUserPh:"username…", amNamePh:"name…",
amSearchPh:"🔎 search by name…",
amSearchPh:"search by name…",
amCode:"link code", amNewCode:"new code", amPw:"password",
amNoClass:"— no class —", amPending:"not yet activated",
amCouple:"link teacher", amAllSchools:"— all schools —", amSuperGroup:"System",