From 31d037d8afd2dc06a0aa58e7cfe999937a1f808a Mon Sep 17 00:00:00 2001 From: bes-r <27369668+bes-r@users.noreply.github.com> Date: Wed, 17 Jun 2026 14:37:52 +0200 Subject: [PATCH] wizards onder roostermaker/personen + snelmenu leerplein --- ROADMAP.md | 6 ++--- backend/modules/blokwizard/apps.py | 5 ++--- backend/modules/personenwizard/apps.py | 5 ++--- frontend/src/pages.jsx | 31 ++++++++++++++++---------- frontend/src/styles.css | 2 ++ 5 files changed, 28 insertions(+), 21 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 9da0883..10dad47 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -19,9 +19,9 @@ volgt. T (deze week), Esc (paneel/sluiten); met hint. - [x] **Rol van een begeleider zichtbaar** in de Roostermaker: afkorting (LK/PO/KO) bij de begeleider in een blok en de volledige rol bij het toewijzen. -- [x] **Vak-wizard** (module `blokwizard`, default uit): stap-voor-stap vak → +- [x] **Vak-wizard** (module `blokwizard`, default uit; verschijnt als tab in de Roostermaker): stap-voor-stap vak → voor wie → wanneer/waar (+periode) → begeleiders → controle → inplannen. -- [x] **Personen-wizard + import** (module `personenwizard`, default uit): +- [x] **Personen-wizard + import** (module `personenwizard`, default uit; tab onder Personen): leerling/medewerker enkel toevoegen óf in bulk via plakken/CSV (komma, puntkomma of tab; koprij optioneel) met preview; endpoint /api/personen-import/. @@ -30,7 +30,7 @@ volgt. - [~] **Alle klassen verwerkbaar in het rooster**, overzichtelijk gemaakt — een **scope-filter** (per klas/leerplein/leerling/personeel) is toegevoegd in Rooster en Roostermaker; een vast **per-leerplein-overzicht** kan nog volgen. -- [ ] **Snelmenu** om per klas of per leerplein direct het rooster te tonen. +- [x] **Snelmenu** per klas én per bovenliggende groep (chips in Rooster én Roostermaker) om direct dat rooster te tonen. - [x] **Schooljaar uit het hoofdmenu** halen en **onder Rooster** plaatsen (tab "Schooljaar") met snelle invoer + kalenderbeheer. - [x] **Instellingenmenu** (subtiel onderaan de zijbalk) waaronder **Gebruikers** diff --git a/backend/modules/blokwizard/apps.py b/backend/modules/blokwizard/apps.py index 92a85ad..2fa6cb4 100644 --- a/backend/modules/blokwizard/apps.py +++ b/backend/modules/blokwizard/apps.py @@ -22,8 +22,7 @@ class BlokwizardConfig(AppConfig): category="Hulpmiddelen", core=False, default_enabled=False, - menu_items=( - MenuItem("Vak-wizard", "/vak-wizard", icon="puzzle", order=40), - ), + # Geen eigen menu-item: de wizard verschijnt als tab in de Roostermaker. + menu_items=(), ) ) diff --git a/backend/modules/personenwizard/apps.py b/backend/modules/personenwizard/apps.py index eba63b6..80ff5e8 100644 --- a/backend/modules/personenwizard/apps.py +++ b/backend/modules/personenwizard/apps.py @@ -22,8 +22,7 @@ class PersonenwizardConfig(AppConfig): category="Hulpmiddelen", core=False, default_enabled=False, - menu_items=( - MenuItem("Personen toevoegen", "/personen-wizard", icon="users", order=42), - ), + # Geen eigen menu-item: verschijnt als tab onder Personen. + menu_items=(), ) ) diff --git a/frontend/src/pages.jsx b/frontend/src/pages.jsx index c924c90..37005cb 100644 --- a/frontend/src/pages.jsx +++ b/frontend/src/pages.jsx @@ -344,6 +344,8 @@ export function PersonenPage() { const [editId, setEditId] = useState(null); const [filter, setFilter] = useState(""); const [nieuweFunctie, setNieuweFunctie] = useState(""); + const [wizardAan, setWizardAan] = useState(false); + const [importView, setImportView] = useState(false); async function maakFunctie() { const naam = nieuweFunctie.trim(); @@ -362,6 +364,7 @@ export function PersonenPage() { listResource("activiteiten").then(setVakken).catch(() => {}); listResource("subgroepen").then(setSubgroepen).catch(() => {}); listResource("leerpleinen").then(setLeerpleinen).catch(() => setLeerpleinen([])); + getModules().then((ms) => setWizardAan(ms.some((m) => m.key === "personenwizard" && m.enabled))).catch(() => {}); } useEffect(() => { laadHulplijsten(); }, []); @@ -445,10 +448,13 @@ export function PersonenPage() {
- - + + + {wizardAan && }
+ {importView ? : (<> +
setForm({ ...form, voornaam: e.target.value })} /> @@ -564,6 +570,7 @@ export function PersonenPage() { )} + )} ); } @@ -1892,6 +1899,7 @@ function Groepsindeling({ groepen, leerpleinen, subgroepen, medewerkers, blokken export function RoosterScherm({ mode }) { const edit = mode === "edit"; const [printAan, setPrintAan] = useState(false); + const [blokwizardAan, setBlokwizardAan] = useState(false); const [schooljaren, setSchooljaren] = useState([]); const [schooljaar, setSchooljaar] = useState(""); const [tijdsloten, setTijdsloten] = useState([]); @@ -1942,7 +1950,7 @@ export function RoosterScherm({ mode }) { listResource("leerpleinen").then(setLeerpleinen).catch(() => {}); listResource("stages", "?actief=1").then(setStages).catch(() => setStages([])); // Afdrukken alleen tonen als de print-module aanstaat. - getModules().then((ms) => setPrintAan(ms.some((m) => m.key === "printing" && m.enabled))).catch(() => {}); + getModules().then((ms) => { setPrintAan(ms.some((m) => m.key === "printing" && m.enabled)); setBlokwizardAan(ms.some((m) => m.key === "blokwizard" && m.enabled)); }).catch(() => {}); }, []); // Scope-context + gefilterde blokken (voor weergave/afdrukken). @@ -2360,18 +2368,14 @@ export function RoosterScherm({ mode }) { )} {scopeType !== "alles" && scopeId && {zichtbareBlokken.length} blok(ken)} - {edit && groepen.length > 0 && ( + {(groepen.length > 0 || leerpleinen.length > 0) && (
{groepen.map((g) => ( - + + ))} + {leerpleinen.map((lp) => ( + ))}
)} @@ -2383,6 +2387,7 @@ export function RoosterScherm({ mode }) { + {blokwizardAan && }
)} @@ -2540,6 +2545,8 @@ export function RoosterScherm({ mode }) { )} + {edit && tab === "wizard" && blokwizardAan && } + {tab === "instellingen" && (

Bouwstenen van het rooster — beheer ze hier zonder het Rooster te verlaten.

diff --git a/frontend/src/styles.css b/frontend/src/styles.css index 20a5c1b..27df053 100644 --- a/frontend/src/styles.css +++ b/frontend/src/styles.css @@ -487,3 +487,5 @@ input[type="color"] { padding: 2px; width: 44px; min-width: 44px; height: 38px; .keuze-emoji { font-size: 40px; line-height: 1; } .bulk-invoer { width: 100%; font-family: monospace; font-size: 13px; padding: 10px; border: 1px solid var(--line); border-radius: 8px; } .banner.ok { background: #ecfdf5; color: #065f46; border: 1px solid #a7f3d0; padding: 10px 14px; border-radius: 8px; } + +.chip.chip-plein { border-style: dashed; }