Verbeter anatomie en plaatsing van avataraccessoires (v0.4.46-beta) #1
4 changed files with 79 additions and 64 deletions
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
0.4.12-beta
|
||||
0.4.13-beta
|
||||
|
|
|
|||
|
|
@ -1271,11 +1271,13 @@
|
|||
sectie, dus niet boven de allereerste kop van de pagina) */
|
||||
.am-section{margin-bottom:14px;}
|
||||
.am-section + .am-h3{margin-top:22px; padding-top:16px; border-top:1px solid var(--line);}
|
||||
/* Scholen is de enige sectie die niet zelf al een omkaderde lijst heeft
|
||||
(Gebruikers heeft dat via .am-list) - een eigen paneel bindt de losse
|
||||
schoolkaarten samen tot één zichtbaar geheel i.p.v. rijen die zomaar
|
||||
overlopen in de sectie erna */
|
||||
.am-panel{background:var(--surface-2); border:1px solid var(--line); border-radius:var(--radius); padding:10px;}
|
||||
/* hiërarchie via inspringing, niet via een andere kleur per niveau: alles
|
||||
wat bij een klas hoort (Groepsleiding/Leerlingen, hun rijen en +-knoppen)
|
||||
krijgt dezelfde lichte inspringing i.p.v. een eigen kadertje - dat hield
|
||||
eerder te veel verschillende "boxstijlen" tegelijk in beeld. Specificiteit
|
||||
moet #settingsModal .am-row's eigen margin:0 kunnen verslaan, ongeacht
|
||||
bestandsvolgorde. */
|
||||
#settingsModal .am-list .am-indent{margin-left:18px;}
|
||||
.am-msg{
|
||||
min-height:20px; font-size:13.5px; font-weight:700; color:var(--green); margin:4px 0;
|
||||
display:flex; align-items:center; gap:8px; flex-wrap:wrap;
|
||||
|
|
@ -1328,10 +1330,10 @@
|
|||
/* Systeem-tab: schoolrij duidelijk zwaarder dan de beheerder-subrijen */
|
||||
.am-row-school{background:var(--accent-soft);}
|
||||
.am-row-school > .am-name{font-size:15px;}
|
||||
/* klasrij (naam + klasbeheer) onderscheidt zich van de Groepsleiding/
|
||||
Leerlingen-rijen eronder - zelfde "kop, geen lid"-taal als .am-row-school */
|
||||
.am-classhead{background:var(--accent-soft); border-left:3px solid var(--accent);}
|
||||
.am-classhead > .am-name{font-size:15px;}
|
||||
/* klasrij (naam + klasbeheer): bewust géén eigen kleur/kader - alleen de
|
||||
naam iets zwaarder, zodat klas/school/gebruiker-rijen overal dezelfde
|
||||
visuele taal spreken en de hiërarchie via .am-indent hieronder loopt */
|
||||
.am-classhead > .am-name{font-size:15px; font-weight:700;}
|
||||
.am-row-sub{
|
||||
margin-left:22px; background:var(--surface);
|
||||
border-left:3px solid var(--line); border-radius:var(--radius-s);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
database en kunnen dus samenvallen (klas 3 én gebruiker 3) - een gedeelde
|
||||
Set zou dan per ongeluk de verkeerde bewerktools open/dicht klappen */
|
||||
const openClassTools = new Set();
|
||||
const openSchoolTools = new Set(); /* zelfde reden als hierboven */
|
||||
|
||||
/* welke rollen de ingelogde gebruiker mag aanmaken: unie over hoofdrol + extra rollen */
|
||||
const creatableRoles = () =>
|
||||
|
|
@ -523,6 +524,29 @@
|
|||
return tools;
|
||||
}
|
||||
|
||||
/* herbruikbaar "Bewerken"-knopje dat een tools-blok in-/uitklapt, gekoppeld
|
||||
aan een gegeven Set + id. Gebruikers, klassen en scholen hebben elk hun
|
||||
eigen Set (openRows/openClassTools/openSchoolTools) - hun id's zijn losse
|
||||
reeksen in de database en kunnen samenvallen, dus nooit delen. Eén
|
||||
gedeelde implementatie zorgt dat elke "Bewerken"-rij er overal identiek
|
||||
uitziet en hetzelfde gedraagt, i.p.v. drie keer bijna-hetzelfde stukje
|
||||
code met kleine, ongemerkt geslopen verschillen. */
|
||||
function editToggle(tools, set, id){
|
||||
const btn = h("button","am-edit", T("amEdit"));
|
||||
btn.type = "button";
|
||||
const sync = ()=>{
|
||||
const open = set.has(id);
|
||||
tools.style.display = open ? "" : "none";
|
||||
btn.classList.toggle("on", open);
|
||||
};
|
||||
btn.addEventListener("click", ()=>{
|
||||
if(set.has(id)) set.delete(id); else set.add(id);
|
||||
sync();
|
||||
});
|
||||
sync();
|
||||
return btn;
|
||||
}
|
||||
|
||||
/* inline-variant voor het Systeem-tabblad (schoolbeheerder-subrijen):
|
||||
naam + rol met een "Bewerken"-tekstknop die het formulier uitklapt */
|
||||
function userRow(u, opts){
|
||||
|
|
@ -542,19 +566,7 @@
|
|||
const badge = resultBadge(u);
|
||||
if(badge) tools.appendChild(badge);
|
||||
tools.appendChild(userTools(u));
|
||||
const edit = h("button","am-edit", T("amEdit"));
|
||||
edit.type = "button";
|
||||
const sync = ()=>{
|
||||
const open = openRows.has(u.id);
|
||||
tools.style.display = open ? "" : "none";
|
||||
edit.classList.toggle("on", open);
|
||||
};
|
||||
edit.addEventListener("click", ()=>{
|
||||
if(openRows.has(u.id)) openRows.delete(u.id); else openRows.add(u.id);
|
||||
sync();
|
||||
});
|
||||
sync();
|
||||
row.appendChild(edit);
|
||||
row.appendChild(editToggle(tools, openRows, u.id));
|
||||
row.appendChild(tools);
|
||||
return row;
|
||||
}
|
||||
|
|
@ -562,8 +574,10 @@
|
|||
/* klasrij (naam + "Bewerken") binnen de gebruikerslijst: klasbeheer
|
||||
(verplaatsen naar een andere school, wachtwoorden resetten, verwijderen)
|
||||
staat zo letterlijk bij de klasleden eronder, i.p.v. in een los
|
||||
klassenpaneel. Zelfde opzet als userRow() hierboven, met een eigen
|
||||
openClassTools-Set (zie daar voor waarom). */
|
||||
klassenpaneel. Bewust een gewone rij (geen eigen kleur/kader) - alleen de
|
||||
naam is iets zwaarder (zie css), zodat klas/school/gebruiker-rijen overal
|
||||
dezelfde visuele taal spreken en de hiërarchie via inspringing loopt
|
||||
i.p.v. via steeds een andere kleur per niveau. */
|
||||
function classHeadRow(c, otherSchools, canManage){
|
||||
const row = h("div","am-row am-classhead");
|
||||
const pupilCount = USERS.filter(u=>u.role==="pupil" && Number(u.classId)===Number(c.id)).length;
|
||||
|
|
@ -596,19 +610,7 @@
|
|||
catch(e){ msg(e.message); }
|
||||
}));
|
||||
tools.appendChild(field("amFieldActions", acts));
|
||||
const edit = h("button","am-edit", T("amEdit"));
|
||||
edit.type = "button";
|
||||
const sync = ()=>{
|
||||
const open = openClassTools.has(c.id);
|
||||
tools.style.display = open ? "" : "none";
|
||||
edit.classList.toggle("on", open);
|
||||
};
|
||||
edit.addEventListener("click", ()=>{
|
||||
if(openClassTools.has(c.id)) openClassTools.delete(c.id); else openClassTools.add(c.id);
|
||||
sync();
|
||||
});
|
||||
sync();
|
||||
row.appendChild(edit);
|
||||
row.appendChild(editToggle(tools, openClassTools, c.id));
|
||||
row.appendChild(tools);
|
||||
return row;
|
||||
}
|
||||
|
|
@ -897,11 +899,20 @@
|
|||
niets op dit tabblad hangt van een gekozen school af. Toevoegen zit
|
||||
achter een bewuste extra stap (+-knop klapt het formulier uit, zoals
|
||||
bij gebruikers) en bevestigt daarna nog met de naam erin. */
|
||||
/* Scholen als platte rijenlijst - zelfde .am-list/.am-row-taal als de
|
||||
klassen/gebruikers-boom eronder, i.p.v. een eigen kaartenstijl. De
|
||||
beheerders van een school staan al in Gebruikers (gegroepeerd bij "alle
|
||||
scholen"); ze hier óók als inklapbare subrijen tonen was een tweede,
|
||||
overbodige plek voor dezelfde informatie en droeg bij aan het rommelige
|
||||
gevoel van te veel verschillende niveaus. */
|
||||
function renderScholenPanel(panel){
|
||||
const list = h("div","am-list");
|
||||
SCHOOLS.forEach(s=>{
|
||||
const admins = SYS_ADMINS.filter(a=>Number(a.schoolId)===Number(s.id));
|
||||
/* bewerk-gereedschap van de school zelf (hernoemen/verwijderen) */
|
||||
const tools = h("div","am-tools");
|
||||
const row = h("div","am-row");
|
||||
row.appendChild(h("span","am-name", s.name));
|
||||
row.appendChild(h("span","am-role", `${admins.length} ${(admins.length===1 ? T("amAdminOne") : T("amAdmins")).toLowerCase()}`));
|
||||
const tools = h("div","am-row-tools");
|
||||
const nameInp = h("input","am-inp");
|
||||
nameInp.value = s.name;
|
||||
nameInp.maxLength = 80;
|
||||
|
|
@ -922,16 +933,9 @@
|
|||
}catch(e){ msg(e.message); }
|
||||
}));
|
||||
tools.appendChild(field("amFieldActions", acts));
|
||||
/* éé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 })),
|
||||
}));
|
||||
row.appendChild(editToggle(tools, openSchoolTools, s.id));
|
||||
row.appendChild(tools);
|
||||
list.appendChild(row);
|
||||
});
|
||||
|
||||
const wrap = h("div","am-add-wrap");
|
||||
|
|
@ -975,7 +979,8 @@
|
|||
f.style.display = "flex";
|
||||
inp.focus();
|
||||
});
|
||||
panel.appendChild(wrap);
|
||||
list.appendChild(wrap);
|
||||
panel.appendChild(list);
|
||||
}
|
||||
|
||||
/* Klassenbeheer zit niet meer in een los paneel: klasrij (classHeadRow) +
|
||||
|
|
@ -1322,9 +1327,9 @@
|
|||
const list = h("div","am-list am-userlist");
|
||||
/* inklapbare groepskop; standaard dicht tenzij defaultOpen (dan onthoudt
|
||||
closedGroups een bewuste dichtklap). Zoeken kijkt door alle groepen heen. */
|
||||
const group = (key, label, us, defaultOpen)=>{
|
||||
const group = (key, label, us, defaultOpen, indent)=>{
|
||||
if(defaultOpen && !closedGroups.has(key)) openGroups.add(key);
|
||||
const g = h("div","am-group am-group-toggle");
|
||||
const g = h("div","am-group am-group-toggle" + (indent ? " am-indent" : ""));
|
||||
g.dataset.collapsible = "1";
|
||||
g.dataset.gkey = key;
|
||||
const sync = ()=>{ g.textContent = `${openGroups.has(key) ? "▾" : "▸"} ${label} (${us.length})`; };
|
||||
|
|
@ -1336,7 +1341,11 @@
|
|||
applyUserFilter(panel);
|
||||
});
|
||||
list.appendChild(g);
|
||||
us.forEach(u=>list.appendChild(userCells(u)));
|
||||
us.forEach(u=>{
|
||||
const row = userCells(u);
|
||||
if(indent) row.classList.add("am-indent");
|
||||
list.appendChild(row);
|
||||
});
|
||||
};
|
||||
|
||||
if(currentUser.role==="super" && !selSchool){
|
||||
|
|
@ -1377,11 +1386,19 @@
|
|||
CLASSES.forEach(c=>{
|
||||
list.appendChild(classHeadRow(c, otherSchools, canManageClasses));
|
||||
const staff = USERS.filter(u=>u.role==="teacher" && (u.classIds||[]).some(id=>Number(id)===Number(c.id)));
|
||||
if(staff.length || creatableRoles().includes("teacher")) group("classteachers:"+c.id, T("roleTeacher"), staff, true);
|
||||
if(creatableRoles().includes("teacher")) list.appendChild(addForm("teacher", c.id));
|
||||
if(staff.length || creatableRoles().includes("teacher")) group("classteachers:"+c.id, T("roleTeacher"), staff, true, true);
|
||||
if(creatableRoles().includes("teacher")){
|
||||
const w = addForm("teacher", c.id);
|
||||
w.classList.add("am-indent");
|
||||
list.appendChild(w);
|
||||
}
|
||||
const us = pupils.filter(u=>u.classId===c.id);
|
||||
if(us.length || creatableRoles().includes("pupil")) group("class:"+c.id, T("amPupils"), us, true);
|
||||
if(creatableRoles().includes("pupil")) list.appendChild(addForm("pupil", c.id));
|
||||
if(us.length || creatableRoles().includes("pupil")) group("class:"+c.id, T("amPupils"), us, true, true);
|
||||
if(creatableRoles().includes("pupil")){
|
||||
const w = addForm("pupil", c.id);
|
||||
w.classList.add("am-indent");
|
||||
list.appendChild(w);
|
||||
}
|
||||
});
|
||||
if(canManageClasses){
|
||||
const f = h("div","am-add");
|
||||
|
|
@ -1460,11 +1477,7 @@
|
|||
klassen hebben dus geen eigen kop/paneel meer hier. */
|
||||
if(currentUser.role==="super" && !selSchool){
|
||||
panel.appendChild(h("h3","am-h3", T("amSchools")));
|
||||
/* eigen kader om de hele Scholen-sectie: zonder dit oogt de lijst als
|
||||
losse rijen die zomaar overlopen in de Gebruikers-sectie eronder -
|
||||
met dezelfde schoolnaam soms letterlijk twee keer vlak onder elkaar
|
||||
(als kaart hier, als groepskop daar) */
|
||||
const sub = h("div","am-section am-panel");
|
||||
const sub = h("div","am-section");
|
||||
renderScholenPanel(sub);
|
||||
panel.appendChild(sub);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.4.12-beta";
|
||||
const VERSION = "0.4.13-beta";
|
||||
(function(){
|
||||
const tag = document.getElementById("verTag");
|
||||
tag.textContent = "v"+VERSION;
|
||||
|
|
|
|||
Loading…
Reference in a new issue