Unterrichtsmodus: Schnellbewertung und Hausaufgabe-Kontrolle direkt im Fenster
Zwei neue Buttons ("Mitarbeit", "Anwesenheit/Hausaufgabe") öffnen die
bestehenden Schnellbewertungs-Dialoge direkt aus dem Unterrichtsmodus, ohne
zum Mitarbeit-Tab wechseln zu müssen — TeachingModeViewModel bekommt dafür
eine eigene ParticipationTabViewModel-Instanz, vorselektiert auf die zu
dieser Stunde gehörende Sitzung. Die linke Spalte zeigt jetzt zusätzlich die
Hausaufgabe der letzten Stunde mit Kontrolliert-Checkbox sowie die
Hausaufgabe dieser Stunde als editierbares Feld, statt nur lesbar.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using LehrerApp.Core.Interfaces;
|
||||
using LehrerApp.Core.Models;
|
||||
|
||||
@@ -10,24 +12,104 @@ namespace LehrerApp.Desktop.ViewModels.Groups;
|
||||
/// der "Heute"-Tagesliste heraus gestartet.
|
||||
///
|
||||
/// Bewusst keine eigene DI-Registrierung als Singleton/Transient: wie LessonViewerViewModel wird
|
||||
/// diese ViewModel direkt vom Code-Behind konstruiert, das dafür nötige SeatingPlanTabViewModel
|
||||
/// aber weiterhin über DI aufgelöst (transient, siehe AppBootstrapper) und hier per Konstruktor
|
||||
/// entgegengenommen statt selbst aus App.Services zu ziehen - ViewModels greifen in diesem Code
|
||||
/// nicht selbst auf den Service-Container zu, das bleibt Aufgabe des Code-Behind.
|
||||
/// diese ViewModel direkt vom Code-Behind konstruiert, das dafür nötige SeatingPlanTabViewModel/
|
||||
/// ParticipationTabViewModel aber weiterhin über DI aufgelöst (transient, siehe AppBootstrapper)
|
||||
/// und hier per Konstruktor entgegengenommen statt selbst aus App.Services zu ziehen -
|
||||
/// ViewModels greifen in diesem Code nicht selbst auf den Service-Container zu, das bleibt
|
||||
/// Aufgabe des Code-Behind.
|
||||
/// </summary>
|
||||
public class TeachingModeViewModel
|
||||
{
|
||||
public string GroupName { get; }
|
||||
public LessonViewerViewModel LessonInfo { get; }
|
||||
public SeatingPlanTabViewModel SeatingPlan { get; }
|
||||
/// <summary>Nutzer-Feedback: die Schnellbewertungs-Dialoge für Mitarbeit/Anwesenheit-Hausaufgabe
|
||||
/// gab es bislang nur über den Mitarbeit-Tab der Gruppe — im Unterrichtsmodus musste man dafür
|
||||
/// erst wieder raus. Hier dieselbe <see cref="ParticipationTabViewModel"/> wie im Mitarbeit-Tab,
|
||||
/// aber auf die zu dieser Stunde gehörende Sitzung vorselektiert (siehe Konstruktor), damit die
|
||||
/// über <c>OnQuickInput</c>/<c>OnStatusQuickInput</c> geöffneten Dialoge (Wiring in
|
||||
/// TeachingModeWindow.axaml.cs, gleiches Muster wie ParticipationTabView.axaml.cs) direkt auf
|
||||
/// der richtigen Sitzung starten.</summary>
|
||||
public ParticipationTabViewModel Participation { get; }
|
||||
public TeachingModeHomeworkViewModel Homework { get; }
|
||||
|
||||
public TeachingModeViewModel(Lesson lesson, LearningGroup group,
|
||||
IAlternativeLessonPathRepository alternativePaths, SeatingPlanTabViewModel seatingPlan)
|
||||
IAlternativeLessonPathRepository alternativePaths, ILessonRepository lessons,
|
||||
SeatingPlanTabViewModel seatingPlan, ParticipationTabViewModel participation)
|
||||
{
|
||||
GroupName = group.Name;
|
||||
LessonInfo = new LessonViewerViewModel(lesson, alternativePaths);
|
||||
|
||||
SeatingPlan = seatingPlan;
|
||||
SeatingPlan.Initialize(group.Id, !group.IsActive);
|
||||
SeatingPlan.SelectOrCreateSessionForLesson(lesson);
|
||||
|
||||
Participation = participation;
|
||||
Participation.Initialize(group.Id, group.SchoolYear, !group.IsActive);
|
||||
if (SeatingPlan.SelectedSession is { } linkedSession)
|
||||
Participation.SelectedSession =
|
||||
Participation.Sessions.FirstOrDefault(s => s.Id == linkedSession.Id);
|
||||
|
||||
// 4.5.4: dieselbe "letzte Stunde vor dieser"-Suche wie das Stundenplan-Badge
|
||||
// "Hausaufgabe kontrollieren" (TimetableViewModel.HasUnhandledHomework) - 120 Tage
|
||||
// Lookback deckt auch längere Ferienpausen ab, ohne unbegrenzt weit zurückzuscannen.
|
||||
var previousLesson = lessons.GetByGroupAndRange(group.Id, lesson.Date.AddDays(-120), lesson.Date.AddDays(-1))
|
||||
.OrderByDescending(l => l.Date).ThenByDescending(l => l.LessonNumber ?? 0)
|
||||
.FirstOrDefault();
|
||||
Homework = new TeachingModeHomeworkViewModel(lesson, previousLesson, lessons);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Nutzer-Feedback: im Unterrichtsmodus sollte man die Hausaufgabe aus der letzten Stunde als
|
||||
/// kontrolliert abhaken und die neue Hausaufgabe eintragen/ändern können, ohne dafür den vollen
|
||||
/// <see cref="LehrerApp.Desktop.Views.Groups.LessonDialog"/>-Editor zu öffnen (der zusätzlich Phasen/Reflexion usw. zeigt)
|
||||
/// - manchmal ergibt sich die Hausaufgabe erst während der Stunde. Bewusst eine eigene, kleine
|
||||
/// <see cref="ObservableObject"/> statt Felder direkt auf <see cref="TeachingModeViewModel"/>, da
|
||||
/// diese Klasse (wie <see cref="LessonViewerViewModel"/>) selbst keine Bindable-Basisklasse hat.
|
||||
/// </summary>
|
||||
public partial class TeachingModeHomeworkViewModel : ObservableObject
|
||||
{
|
||||
private readonly ILessonRepository _lessons;
|
||||
private readonly Lesson _lesson;
|
||||
private readonly Lesson? _previousLesson;
|
||||
|
||||
public bool HasPreviousHomework =>
|
||||
_previousLesson is not null && !string.IsNullOrWhiteSpace(_previousLesson.Homework);
|
||||
public string PreviousHomeworkText => _previousLesson?.Homework ?? "";
|
||||
public string PreviousLessonLabel => _previousLesson is null ? "" :
|
||||
$"{_previousLesson.Date:dd.MM.yyyy}" + (string.IsNullOrWhiteSpace(_previousLesson.Topic)
|
||||
? "" : $" · {_previousLesson.Topic}");
|
||||
|
||||
[ObservableProperty] private bool _previousHomeworkChecked;
|
||||
[ObservableProperty] private string _currentHomework;
|
||||
[ObservableProperty] private string _saveStatus = "";
|
||||
|
||||
public TeachingModeHomeworkViewModel(Lesson lesson, Lesson? previousLesson, ILessonRepository lessons)
|
||||
{
|
||||
_lesson = lesson;
|
||||
_previousLesson = previousLesson;
|
||||
_lessons = lessons;
|
||||
_previousHomeworkChecked = previousLesson?.HomeworkChecked ?? false;
|
||||
_currentHomework = lesson.Homework ?? "";
|
||||
}
|
||||
|
||||
/// Sofort beim Umschalten gespeichert (kein separater Speichern-Klick nötig) - dieselbe
|
||||
/// Checkbox-Semantik wie im LessonDialog (4.5.4): "kontrolliert" und "nicht kontrollieren"
|
||||
/// schließen sich aus.
|
||||
partial void OnPreviousHomeworkCheckedChanged(bool value)
|
||||
{
|
||||
if (_previousLesson is null) return;
|
||||
_previousLesson.HomeworkChecked = value;
|
||||
if (value) _previousLesson.HomeworkCheckDismissed = false;
|
||||
_lessons.Save(_previousLesson);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void SaveCurrentHomework()
|
||||
{
|
||||
_lesson.Homework = CurrentHomework;
|
||||
_lessons.Save(_lesson);
|
||||
SaveStatus = "Gespeichert.";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user