diff --git a/LehrerApp.Desktop.Tests/LessonDialogViewModelTests.cs b/LehrerApp.Desktop.Tests/LessonDialogViewModelTests.cs index 7526680..dfb69a8 100644 --- a/LehrerApp.Desktop.Tests/LessonDialogViewModelTests.cs +++ b/LehrerApp.Desktop.Tests/LessonDialogViewModelTests.cs @@ -19,7 +19,17 @@ public sealed class LessonDialogViewModelTests FakeTimetableSlots? slots = null, PeriodScheduleService? periodSchedule = null) => new(new FakeLessons(), new FakeShorthandCodes([]), new FakeAlternativeLessonPaths([]), slots ?? new FakeTimetableSlots(), periodSchedule ?? NewPeriodSchedule(), - unitId, groupId, [], [], editing); + unitId, groupId, "10c", "Chemie", [], [], editing); + + /// Nutzer-Feedback: bei einer Klasse, die in mehreren Fächern unterrichtet wird (mehrere + /// LearningGroup-Datensätze mit gleichem Namen), war im Stunden-Dialog nicht erkennbar, + /// welche der beiden Stunden man gerade bearbeitet. + [Fact] + public void GroupSubjectDisplay_ZeigtGruppeUndFachZusammen() + { + var vm = BuildVm(Guid.NewGuid(), Guid.NewGuid()); + Assert.Equal("10c · Chemie", vm.GroupSubjectDisplay); + } [Fact] public void AddPhase_FuegtZeileMitStandardwertenHinzu() @@ -83,7 +93,7 @@ public sealed class LessonDialogViewModelTests var codes = new FakeShorthandCodes([new ShorthandCode { Code = "Tb" }, new ShorthandCode { Code = "SH" }]); var vm = new LessonDialogViewModel(new FakeLessons(), codes, new FakeAlternativeLessonPaths([]), new FakeTimetableSlots(), NewPeriodSchedule(), - Guid.NewGuid(), Guid.NewGuid(), [], ["Plenum", "LDE", "Tb"], null); // "Tb" doppelt (Katalog + Historie), soll nur einmal erscheinen + Guid.NewGuid(), Guid.NewGuid(), "10c", "Chemie", [], ["Plenum", "LDE", "Tb"], null); // "Tb" doppelt (Katalog + Historie), soll nur einmal erscheinen Assert.Equal(["LDE", "Plenum", "SH", "Tb"], vm.ShorthandSuggestions); } @@ -145,7 +155,7 @@ public sealed class LessonDialogViewModelTests var groupId = Guid.NewGuid(); var lessons = new FakeLessons(); var vm = new LessonDialogViewModel(lessons, new FakeShorthandCodes([]), new FakeAlternativeLessonPaths([]), - new FakeTimetableSlots(), NewPeriodSchedule(), unitId, groupId, [], [], null) + new FakeTimetableSlots(), NewPeriodSchedule(), unitId, groupId, "10c", "Chemie", [], [], null) { Topic = "Brechung", DateText = "01.09.2025", StartTimeText = "11:45", }; @@ -242,7 +252,7 @@ public sealed class LessonDialogViewModelTests }; var vm = new LessonDialogViewModel(new FakeLessons(), new FakeShorthandCodes([]), alternativePaths, - new FakeTimetableSlots(), NewPeriodSchedule(), Guid.NewGuid(), Guid.NewGuid(), [], [], editing); + new FakeTimetableSlots(), NewPeriodSchedule(), Guid.NewGuid(), Guid.NewGuid(), "10c", "Chemie", [], [], editing); Assert.True(vm.Phases[0].HasAlternativePath); Assert.Equal("Kurzversion", vm.Phases[0].AlternativePathName); diff --git a/LehrerApp.Desktop.Tests/UnitDialogViewModelTests.cs b/LehrerApp.Desktop.Tests/UnitDialogViewModelTests.cs new file mode 100644 index 0000000..a8d1bbd --- /dev/null +++ b/LehrerApp.Desktop.Tests/UnitDialogViewModelTests.cs @@ -0,0 +1,28 @@ +using LehrerApp.Desktop.ViewModels.Groups; +using Xunit; + +namespace LehrerApp.Desktop.Tests; + +/// Nutzer-Feedback: bei einer Klasse, die in mehreren Fächern unterrichtet wird (mehrere +/// LearningGroup-Datensätze mit gleichem Namen), war im Einheiten-Dialog nur das Fach sichtbar, +/// nicht welche Klasse gemeint ist — beides zusammen macht es eindeutig. +public sealed class UnitDialogViewModelTests +{ + [Fact] + public void GroupSubjectDisplay_ZeigtGruppeUndFachZusammen() + { + var vm = new UnitDialogViewModel(new FakeUnits(), new FakeCompetencyDomains(), + Guid.NewGuid(), Guid.NewGuid(), 10, "10c", "Chemie", editingUnit: null); + + Assert.Equal("10c · Chemie", vm.GroupSubjectDisplay); + } + + [Fact] + public void GroupSubjectDisplay_OhneFach_WeistDaraufHin() + { + var vm = new UnitDialogViewModel(new FakeUnits(), new FakeCompetencyDomains(), + Guid.NewGuid(), null, 10, "10c", "", editingUnit: null); + + Assert.Equal("10c · kein Fach hinterlegt (siehe Lerngruppe)", vm.GroupSubjectDisplay); + } +} diff --git a/LehrerApp.Desktop/ViewModels/Groups/PlanningViewModels.cs b/LehrerApp.Desktop/ViewModels/Groups/PlanningViewModels.cs index 9c813c5..7f44082 100644 --- a/LehrerApp.Desktop/ViewModels/Groups/PlanningViewModels.cs +++ b/LehrerApp.Desktop/ViewModels/Groups/PlanningViewModels.cs @@ -39,6 +39,7 @@ public partial class PlanningTabViewModel : ObservableObject public Guid? SubjectId { get; private set; } public int GradeLevel { get; private set; } public string SubjectName { get; private set; } = ""; + public string GroupLabel { get; private set; } = ""; [ObservableProperty] private UnitSummary? _selectedUnit; [ObservableProperty] private LessonSummary? _selectedLesson; @@ -88,6 +89,7 @@ public partial class PlanningTabViewModel : ObservableObject SubjectId = group?.SubjectId; GradeLevel = group?.GradeLevel ?? 0; SubjectName = SubjectId is Guid sid ? _subjects.GetById(sid)?.Name ?? "" : ""; + GroupLabel = group?.Name ?? ""; LoadUnits(); } @@ -494,21 +496,23 @@ public partial class UnitDialogViewModel : ObservableObject public string CompetencySummary => _competencyCodes.Count == 0 ? "Keine Kompetenzen" : $"{_competencyCodes.Count} Kompetenz(en)"; - /// Fach kommt von der Lerngruppe, nicht editierbar (jede Gruppe unterrichtet ein Fach). - public string SubjectDisplay { get; } + /// Gruppe + Fach kommen von der Lerngruppe, nicht editierbar (jede Gruppe unterrichtet ein + /// Fach) — beide zusammen zeigen, da dieselbe Klasse in mehreren Fächern (mehrere + /// Lerngruppen mit gleichem Namen) sonst nicht unterscheidbar wäre (Nutzer-Feedback). + public string GroupSubjectDisplay { get; } public Unit? Result { get; private set; } public string DialogTitle => _editingUnit is null ? "Neue Einheit anlegen" : "Einheit bearbeiten"; public string SaveButtonText => _editingUnit is null ? "Anlegen" : "Speichern"; public UnitDialogViewModel(IUnitRepository units, ICompetencyDomainRepository competencyDomains, - Guid groupId, Guid? subjectId, int gradeLevel, string subjectName, Unit? editingUnit) + Guid groupId, Guid? subjectId, int gradeLevel, string groupName, string subjectName, Unit? editingUnit) { _units = units; _competencyDomains = competencyDomains; _groupId = groupId; _subjectId = subjectId; _gradeLevel = gradeLevel; _editingUnit = editingUnit; - SubjectDisplay = string.IsNullOrWhiteSpace(subjectName) - ? "Kein Fach hinterlegt (siehe Lerngruppe)" : $"Fach: {subjectName}"; + GroupSubjectDisplay = string.IsNullOrWhiteSpace(subjectName) + ? $"{groupName} · kein Fach hinterlegt (siehe Lerngruppe)" : $"{groupName} · {subjectName}"; _competencyCodes = editingUnit is not null ? [.. editingUnit.Competencies] : []; BuildCompetencyTagGroups(); @@ -631,6 +635,12 @@ public partial class LessonDialogViewModel : ObservableObject public string DialogTitle => _editingLesson is null ? "Neue Stunde anlegen" : "Stunde bearbeiten"; public string SaveButtonText => _editingLesson is null ? "Anlegen" : "Speichern"; + /// Gruppe + Fach der Einheit, zu der diese Stunde gehört — nicht editierbar, nur zur + /// Einordnung. Ohne das war bei gleichnamigen Klassen in mehreren Fächern (mehrere + /// Lerngruppen mit gleichem Namen) nicht erkennbar, welche Stunde man gerade bearbeitet + /// (Nutzer-Feedback). + public string GroupSubjectDisplay { get; } + // Für die KI-Unterstützung mit Fokus auf genau diese Stunde (4.5.22) — nur für bereits // gespeicherte Stunden sinnvoll, eine gerade erst angelegte, noch ungespeicherte Stunde hat // keine echte Id, auf die sich die KI beziehen könnte. @@ -645,12 +655,14 @@ public partial class LessonDialogViewModel : ObservableObject public LessonDialogViewModel(ILessonRepository lessons, IShorthandCodeRepository shorthandCodes, IAlternativeLessonPathRepository alternativePaths, ITimetableSlotRepository timetableSlots, - PeriodScheduleService periodSchedule, Guid unitId, Guid groupId, + PeriodScheduleService periodSchedule, Guid unitId, Guid groupId, string groupName, string subjectName, List materialSuggestions, List shorthandHistorySuggestions, Lesson? editingLesson) { _lessons = lessons; _alternativePaths = alternativePaths; _timetableSlots = timetableSlots; _periodSchedule = periodSchedule; _unitId = unitId; _groupId = groupId; _editingLesson = editingLesson; + GroupSubjectDisplay = string.IsNullOrWhiteSpace(subjectName) + ? $"{groupName} · kein Fach hinterlegt (siehe Lerngruppe)" : $"{groupName} · {subjectName}"; MaterialSuggestions = [.. materialSuggestions]; // Vorschläge kommen sowohl aus dem gepflegten Kürzel-Katalog (Einstellungen) als auch aus diff --git a/LehrerApp.Desktop/Views/Groups/LessonDialog.axaml b/LehrerApp.Desktop/Views/Groups/LessonDialog.axaml index 4ef729f..6c29295 100644 --- a/LehrerApp.Desktop/Views/Groups/LessonDialog.axaml +++ b/LehrerApp.Desktop/Views/Groups/LessonDialog.axaml @@ -10,7 +10,10 @@ - + + + + diff --git a/LehrerApp.Desktop/Views/Groups/PlanningTabView.axaml.cs b/LehrerApp.Desktop/Views/Groups/PlanningTabView.axaml.cs index 8ac0786..6e73dcd 100644 --- a/LehrerApp.Desktop/Views/Groups/PlanningTabView.axaml.cs +++ b/LehrerApp.Desktop/Views/Groups/PlanningTabView.axaml.cs @@ -41,7 +41,7 @@ public partial class PlanningTabView : UserControl var dialogVm = new UnitDialogViewModel( App.Services.GetRequiredService(), App.Services.GetRequiredService(), - groupId, vm.SubjectId, vm.GradeLevel, vm.SubjectName, editingUnit); + groupId, vm.SubjectId, vm.GradeLevel, vm.GroupLabel, vm.SubjectName, editingUnit); var dialog = new UnitDialog { DataContext = dialogVm }; var owner = TopLevel.GetTopLevel(this) as Window; @@ -80,13 +80,16 @@ public partial class PlanningTabView : UserControl private async Task ShowLessonDialog(Guid unitId, Guid groupId, List materialSuggestions, List shorthandHistorySuggestions, Lesson? editingLesson) { + if (DataContext is not PlanningTabViewModel vm) return false; + var dialogVm = new LessonDialogViewModel( App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService(), - unitId, groupId, materialSuggestions, shorthandHistorySuggestions, editingLesson); + unitId, groupId, vm.GroupLabel, vm.SubjectName, + materialSuggestions, shorthandHistorySuggestions, editingLesson); var dialog = new LessonDialog { DataContext = dialogVm }; var owner = TopLevel.GetTopLevel(this) as Window; diff --git a/LehrerApp.Desktop/Views/Groups/UnitDialog.axaml b/LehrerApp.Desktop/Views/Groups/UnitDialog.axaml index b3c5773..bf39547 100644 --- a/LehrerApp.Desktop/Views/Groups/UnitDialog.axaml +++ b/LehrerApp.Desktop/Views/Groups/UnitDialog.axaml @@ -12,7 +12,7 @@ - + diff --git a/TODO.md b/TODO.md index a4079ce..c2bed21 100644 --- a/TODO.md +++ b/TODO.md @@ -286,6 +286,13 @@ gruppenspezifischen Tab "Planung" (`GroupDetailView`), siehe unten. - [x] **4.1.1** Listenansicht der Einheiten je Gruppe mit Status und Zeitraum (ersetzt den Platzhalter im Tab "Planung"). - [x] **4.1.2** Dialog Einheit anlegen/bearbeiten: Titel, Fach, Zeitraum, Status, Notizen. + + **Nachtrag (Nutzer-Feedback, im Zuge des 4.3.3-Bugfixes):** Bei einer Klasse, die in + mehreren Fächern unterrichtet wird (mehrere `LearningGroup`-Datensätze mit gleichem Namen, + z.B. zwei "10c"), zeigte der Dialog bisher nur das Fach ("Fach: Chemie"), nicht welche + Klasse gemeint ist — beides zusammen war nirgends auf einen Blick zu sehen. Jetzt zeigen + sowohl `UnitDialog` (Einheit) als auch `LessonDialog` (Stunde) direkt unter dem Dialogtitel + "Gruppe · Fach" (z.B. "10c · Chemie"), nicht editierbar, nur zur Einordnung. - [x] **4.1.3** Kompetenzen aus dem Katalog (siehe 8) einer Einheit zuordnen — Mehrfachauswahl. - [x] **4.1.4** Einheit als Vorlage speichern und in eine andere Gruppe kopieren (inkl. Stunden, ohne Datumsbezug).