From cd08bbbbc44e98d388b7995f4637dc58071242b5 Mon Sep 17 00:00:00 2001 From: Sebastian Hedtrich Date: Thu, 27 Aug 2026 17:03:11 +0200 Subject: [PATCH] =?UTF-8?q?Stundenplan:=20Dropdown=20f=C3=BCr=20Unterricht?= =?UTF-8?q?sansicht/Sitzplan/Planung/Planungsviewer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die zwei Buttons in der "Heute"-Tagesliste mit teils vom Lesson-Status abhängiger Doppelbedeutung ("Verlaufsplan ansehen"/"Zur Lerngruppe") waren unklar. Ersetzt durch ein Dropdown mit vier ausdrücklich benannten Zielen; drei nutzen bestehende Commands, "Sitzplan" (Sitzpläne-Tab) ist neu und bisher nur indirekt über den Unterrichtsmodus erreichbar gewesen. Co-Authored-By: Claude Sonnet 5 --- .../TimetableViewModelTests.cs | 42 +++++++++++++++++++ .../ViewModels/Planning/TimetableViewModel.cs | 30 +++++++++++++ .../Views/Planning/TimetableView.axaml | 29 ++++++++----- .../Views/Planning/TimetableView.axaml.cs | 34 +++++++++++++++ TODO.md | 12 ++++++ 5 files changed, 136 insertions(+), 11 deletions(-) diff --git a/LehrerApp.Desktop.Tests/TimetableViewModelTests.cs b/LehrerApp.Desktop.Tests/TimetableViewModelTests.cs index 8a2612f..ae641f8 100644 --- a/LehrerApp.Desktop.Tests/TimetableViewModelTests.cs +++ b/LehrerApp.Desktop.Tests/TimetableViewModelTests.cs @@ -1177,3 +1177,45 @@ public sealed class TimetableViewModelTests Assert.False(vm.HasUntisMismatch); } } + +/// Nutzer-Feedback: unklar, wie man aus der "Heute"-Tagesliste zwischen Unterrichtsansicht, +/// Sitzplan, Planung und Planungsviewer wechselt — TodayLessonItem.DestinationOptions ersetzt die +/// bisherigen zwei Buttons durch ein Dropdown mit ausdrücklich benannten Zielen. +public sealed class TodayLessonItemDestinationOptionsTests +{ + [Fact] + public void MitLesson_BietetAlleVierZiele() + { + var lesson = new Lesson { Topic = "Redox" }; + var item = new TodayLessonItem(Guid.NewGuid(), 3, "Q1 Chemie", "R204", + "#4C8DFF", "Redox", null, lesson: lesson); + + Assert.True(item.HasDestinationOptions); + Assert.Equal( + [ + TimetableLessonDestination.TeachingMode, TimetableLessonDestination.Viewer, + TimetableLessonDestination.SeatingPlan, TimetableLessonDestination.Planning, + ], + item.DestinationOptions.Select(o => o.Kind)); + } + + [Fact] + public void OhneLesson_BietetNurSitzplanUndPlanung() + { + var item = new TodayLessonItem(Guid.NewGuid(), 3, "Q1 Chemie", "R204", + "#4C8DFF", null, null); + + Assert.Equal( + [TimetableLessonDestination.SeatingPlan, TimetableLessonDestination.Planning], + item.DestinationOptions.Select(o => o.Kind)); + } + + [Fact] + public void OhneGroupId_BietetKeineZiele() + { + var item = TodayLessonItem.ForSubstitution(3, new SubstitutionEntry { GroupId = null, Description = "Vertretung" }); + + Assert.False(item.HasDestinationOptions); + Assert.Empty(item.DestinationOptions); + } +} diff --git a/LehrerApp.Desktop/ViewModels/Planning/TimetableViewModel.cs b/LehrerApp.Desktop/ViewModels/Planning/TimetableViewModel.cs index 1d93148..3030e9e 100644 --- a/LehrerApp.Desktop/ViewModels/Planning/TimetableViewModel.cs +++ b/LehrerApp.Desktop/ViewModels/Planning/TimetableViewModel.cs @@ -900,6 +900,9 @@ public class UpcomingExamItem(DateOnly date, string groupName, string title) public string Title { get; } = title; } +public enum TimetableLessonDestination { TeachingMode, Viewer, SeatingPlan, Planning } +public sealed record TimetableDestinationOption(TimetableLessonDestination Kind, string Label); + public class TodayLessonItem { public Guid GroupId { get; private init; } @@ -922,6 +925,33 @@ public class TodayLessonItem public bool HasLesson => Lesson is not null; public string OpenButtonLabel => Lesson is not null ? "Verlaufsplan ansehen" : "Zur Lerngruppe"; + /// Nutzer-Feedback: es war unklar, wie man aus der "Heute"-Tagesliste zwischen + /// Unterrichtsansicht, Sitzplan, Planung und Planungsviewer wechselt — bisher zwei Buttons + /// mit unterschiedlicher, teils vom Lesson-Status abhängiger Bedeutung + /// ("Verlaufsplan ansehen"/"Zur Lerngruppe"). Ein Dropdown mit ausdrücklich benannten Zielen + /// statt dessen (Wiring/Routing in TimetableView.axaml.cs). Unterrichtsansicht/Planungsviewer + /// brauchen eine existierende Lesson, Sitzplan/Planung sind auch ohne bereits möglich (Planung + /// ist ohnehin der Ort, an dem man eine Lesson für den Slot erst anlegt). + public IReadOnlyList DestinationOptions + { + get + { + var options = new List(); + if (HasLesson) + { + options.Add(new(TimetableLessonDestination.TeachingMode, "▶ Unterrichtsansicht")); + options.Add(new(TimetableLessonDestination.Viewer, "📋 Planungsviewer")); + } + if (HasGroupId) + { + options.Add(new(TimetableLessonDestination.SeatingPlan, "🪑 Sitzplan")); + options.Add(new(TimetableLessonDestination.Planning, "✏️ Planung")); + } + return options; + } + } + public bool HasDestinationOptions => DestinationOptions.Count > 0; + public TodayLessonItem(Guid groupId, int periodNumber, string groupName, string room, string colorHex, string? lessonTopic, string? examTitle, bool hasUnhandledHomework = false, Lesson? lesson = null) diff --git a/LehrerApp.Desktop/Views/Planning/TimetableView.axaml b/LehrerApp.Desktop/Views/Planning/TimetableView.axaml index b129f6e..11ed202 100644 --- a/LehrerApp.Desktop/Views/Planning/TimetableView.axaml +++ b/LehrerApp.Desktop/Views/Planning/TimetableView.axaml @@ -111,17 +111,24 @@ Foreground="#8E6C00" FontWeight="SemiBold" IsVisible="{Binding HasUnhandledHomework}"/> - -