auto-rooster als tab onder roostermaker; code-review: imports + model-drift opgeschoond

This commit is contained in:
bes-r 2026-06-17 14:56:55 +02:00
parent 2b6a9ac47a
commit 48a72fd199
8 changed files with 65 additions and 9 deletions

View file

@ -0,0 +1,20 @@
# Generated by Django 5.2.15 on 2026-06-17 12:53
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0009_activiteit_pictogram'),
('module_accounts', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='gebruikersprofiel',
name='persoon',
field=models.ForeignKey(blank=True, help_text='Koppeling aan een leerling of medewerker uit de kern.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='gebruikers', to='core.persoon'),
),
]

View file

@ -8,7 +8,7 @@ class AutoroosterConfig(AppConfig):
verbose_name = "Module: Automatisch rooster"
def ready(self):
from plugins.registry import MenuItem, ModuleSpec, registry
from plugins.registry import ModuleSpec, registry
registry.register(
ModuleSpec(
@ -23,8 +23,7 @@ class AutoroosterConfig(AppConfig):
category="Hulpmiddelen",
core=False,
default_enabled=False,
menu_items=(
MenuItem("Auto-rooster", "/auto-rooster", icon="puzzle", order=44),
),
# Geen eigen menu-item: verschijnt als tab in de Roostermaker.
menu_items=(),
)
)

View file

@ -8,7 +8,7 @@ class BlokwizardConfig(AppConfig):
verbose_name = "Module: Vak-wizard"
def ready(self):
from plugins.registry import MenuItem, ModuleSpec, registry
from plugins.registry import ModuleSpec, registry
registry.register(
ModuleSpec(

View file

@ -0,0 +1,29 @@
# Generated by Django 5.2.15 on 2026-06-17 12:53
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0009_activiteit_pictogram'),
('module_leerplein', '0003_rename_leerplein_verbose_names'),
]
operations = [
migrations.AlterField(
model_name='leerplein',
name='groepen',
field=models.ManyToManyField(blank=True, related_name='leerpleinen', to='core.groep', verbose_name='groepen'),
),
migrations.AlterField(
model_name='leerplein',
name='leerlingen',
field=models.ManyToManyField(blank=True, limit_choices_to={'rol': 'leerling'}, related_name='leerpleinen', to='core.persoon', verbose_name='losse leerlingen'),
),
migrations.AlterField(
model_name='leerplein',
name='subgroepen',
field=models.ManyToManyField(blank=True, related_name='leerpleinen', to='core.subgroep', verbose_name='subgroepen'),
),
]

View file

@ -8,7 +8,7 @@ class PersonenwizardConfig(AppConfig):
verbose_name = "Module: Personen-wizard & import"
def ready(self):
from plugins.registry import MenuItem, ModuleSpec, registry
from plugins.registry import ModuleSpec, registry
registry.register(
ModuleSpec(

View file

@ -8,7 +8,7 @@ class PrintingConfig(AppConfig):
verbose_name = "Module: Printen/Exporteren"
def ready(self):
from plugins.registry import MenuItem, ModuleSpec, registry
from plugins.registry import ModuleSpec, registry
registry.register(
ModuleSpec(

View file

@ -1,6 +1,6 @@
from rest_framework import serializers
from .models import Dagdeel, Omvang, Stage, StageType
from .models import Omvang, Stage, StageType
class StageSerializer(serializers.ModelSerializer):

View file

@ -1900,6 +1900,7 @@ export function RoosterScherm({ mode }) {
const edit = mode === "edit";
const [printAan, setPrintAan] = useState(false);
const [blokwizardAan, setBlokwizardAan] = useState(false);
const [autoroosterAan, setAutoroosterAan] = useState(false);
const [schooljaren, setSchooljaren] = useState([]);
const [schooljaar, setSchooljaar] = useState("");
const [tijdsloten, setTijdsloten] = useState([]);
@ -1950,7 +1951,11 @@ 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)); setBlokwizardAan(ms.some((m) => m.key === "blokwizard" && m.enabled)); }).catch(() => {});
getModules().then((ms) => {
setPrintAan(ms.some((m) => m.key === "printing" && m.enabled));
setBlokwizardAan(ms.some((m) => m.key === "blokwizard" && m.enabled));
setAutoroosterAan(ms.some((m) => m.key === "autorooster" && m.enabled));
}).catch(() => {});
}, []);
// Scope-context + gefilterde blokken (voor weergave/afdrukken).
@ -2388,6 +2393,7 @@ export function RoosterScherm({ mode }) {
<button className={tab === "conflicten" ? "tab on" : "tab"} title="Conflicten" onClick={() => setTab("conflicten")}> Conflicten</button>
<button className={tab === "schooljaar" ? "tab on" : "tab"} title="Schooljaar" onClick={() => setTab("schooljaar")}> Jaar</button>
{blokwizardAan && <button className={tab === "wizard" ? "tab on" : "tab"} title="Vak-wizard" onClick={() => setTab("wizard")}> Wizard</button>}
{autoroosterAan && <button className={tab === "auto" ? "tab on" : "tab"} title="Automatisch rooster" onClick={() => setTab("auto")}>🪄 Auto-rooster</button>}
<button className={tab === "instellingen" ? "tab on" : "tab"} title="Instellingen" onClick={() => setTab("instellingen")}> Instellingen</button>
</div>
)}
@ -2547,6 +2553,8 @@ export function RoosterScherm({ mode }) {
{edit && tab === "wizard" && blokwizardAan && <VakWizardPage />}
{edit && tab === "auto" && autoroosterAan && <AutoRoosterPage />}
{tab === "instellingen" && (
<div className="instellingen">
<p className="muted">Bouwstenen van het rooster beheer ze hier zonder het Rooster te verlaten.</p>