Files
LehrerApp/LehrerApp.Desktop/Views/Planning/TimetableView.axaml
T
adminandClaude Sonnet 5 d9d007cd4b feat: Unterrichtsmodus - konsolidierte Ansicht für die laufende Stunde
Verlaufsplan und Sitzplan bisher über mehrere Tabs verteilt, obwohl im Unterricht selbst beides
gleichzeitig gebraucht wird. Neuer Button "▶ Unterricht" in der "Heute"-Tagesliste des
Stundenplans (nur bei vorhandener Lesson) öffnet ein maximiertes Fenster: links der
schreibgeschützte Verlaufsplan als kompakte Kartenliste, rechts der volle, unverändert
wiederverwendete SeatingPlanTabView (Drag&Drop, Schnellbewertung, Situations-Tags, PDF-Export).
TeachingModeViewModel baut auf dem bestehenden LessonViewerViewModel auf, dadurch kommen "Zur
Mitarbeit"/"Zu den Noten" ohne Duplizierung mit.

Neue SeatingPlanTabViewModel.SelectOrCreateSessionForLesson verknüpft die Mitarbeitssitzung
automatisch mit der konkreten Stunde - anders als die bestehende EnsureTodaySession darf das hier
sofort beim Start passieren, da durch den expliziten Klick für genau diese Stunde eindeutig
feststeht, worum es geht (keine Geistersitzungs-Gefahr wie beim bloßen Tab-Öffnen).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 14:53:16 +02:00

335 lines
22 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels.Planning"
xmlns:shared="clr-namespace:LehrerApp.Desktop.Views.Shared"
x:Class="LehrerApp.Desktop.Views.Planning.TimetableView"
x:DataType="vm:TimetableViewModel">
<UserControl.Styles>
<Style Selector="Border.timetablecell">
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundBaseLowBrush}"/>
</Style>
<Style Selector="Border.timetablecell.assigned">
<Setter Property="Background" Value="Transparent"/>
</Style>
<Style Selector="Border.weekheader.today">
<Setter Property="Background" Value="{DynamicResource SystemAccentColor}"/>
</Style>
<Style Selector="Border.supervisioncell">
<Setter Property="Background" Value="#616161"/>
</Style>
<Style Selector="Border.supervisioncell.substitution">
<Setter Property="Background" Value="#8E24AA"/>
</Style>
</UserControl.Styles>
<Grid RowDefinitions="Auto,*">
<shared:PageHeader Grid.Row="0" Margin="32,28,32,0" Title="Stundenplan"
Subtitle="Wiederkehrendes wöchentliches Muster, keine konkreten Termine"/>
<TabbedPage Grid.Row="1" TabPlacement="Top" SelectedIndex="{Binding ActiveTabIndex}">
<!-- Tab: Heute (Standardansicht) -->
<ContentPage Header="Heute">
<DockPanel Margin="32,20,32,20">
<!-- Unten angedockt: heutige Stunden im Detail -->
<Border DockPanel.Dock="Bottom" Margin="0,16,0,0"
Background="{DynamicResource SystemControlBackgroundAltHighBrush}"
CornerRadius="8" Padding="16" MaxHeight="240">
<DockPanel>
<TextBlock DockPanel.Dock="Top" Text="{Binding TodayLabel}" FontSize="15" FontWeight="SemiBold" Margin="0,0,0,8"/>
<ItemsControl DockPanel.Dock="Top" ItemsSource="{Binding TodaySupervisions}" Margin="0,0,0,6"
IsVisible="{Binding TodaySupervisions.Count}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:TodaySupervisionItem">
<Grid ColumnDefinitions="Auto,*" Margin="0,2">
<Border Grid.Column="0" Classes="supervisioncell" Classes.substitution="{Binding IsSubstitution}"
CornerRadius="4" Padding="6,2" Margin="0,0,8,0">
<TextBlock Text="👁" FontSize="11" Foreground="White"/>
</Border>
<TextBlock Grid.Column="1" FontSize="12" VerticalAlignment="Center">
<Run Text="{Binding PeriodLabel}"/><Run Text=" — "/><Run Text="{Binding Description}"/>
</TextBlock>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl DockPanel.Dock="Top" ItemsSource="{Binding TodaySpecialAssignments}" Margin="0,0,0,6"
IsVisible="{Binding TodaySpecialAssignments.Count}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:TodaySpecialAssignmentItem">
<Grid ColumnDefinitions="Auto,*" Margin="0,2">
<Border Grid.Column="0" Background="#00838F" CornerRadius="4" Padding="6,2" Margin="0,0,8,0">
<TextBlock Text="📌" FontSize="11" Foreground="White"/>
</Border>
<TextBlock Grid.Column="1" FontSize="12" VerticalAlignment="Center" TextWrapping="Wrap"
Text="{Binding DisplayText}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ScrollViewer>
<ItemsControl ItemsSource="{Binding TodayItems}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:TodayLessonItem">
<Border BorderBrush="{DynamicResource SystemControlForegroundBaseLowBrush}"
BorderThickness="0,0,0,1" Padding="0,8">
<Grid ColumnDefinitions="6,Auto,*,Auto">
<Rectangle Grid.Column="0" Fill="{Binding ColorHex}" Width="5" HorizontalAlignment="Left"/>
<TextBlock Grid.Column="1" Text="{Binding PeriodNumber}" FontSize="17" FontWeight="Bold"
Width="30" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="8,0"/>
<StackPanel Grid.Column="2" Spacing="2">
<StackPanel Orientation="Horizontal" Spacing="6">
<TextBlock Text="{Binding GroupName}" FontSize="14" FontWeight="SemiBold"/>
<Border Background="#8E24AA" CornerRadius="7" Padding="5,0" IsVisible="{Binding IsSubstitution}">
<TextBlock Text="Vertretung" FontSize="10" Foreground="White"/>
</Border>
<Border Background="#757575" CornerRadius="7" Padding="5,0" IsVisible="{Binding IsCancelled}">
<TextBlock Text="Ausfall" FontSize="10" Foreground="White"/>
</Border>
</StackPanel>
<TextBlock FontSize="11" Opacity="0.6" IsVisible="{Binding HasRoom}">
<Run Text="Raum "/><Run Text="{Binding Room}"/>
</TextBlock>
<TextBlock Text="{Binding LessonTopic}" FontSize="11" Opacity="0.75"
TextWrapping="Wrap" IsVisible="{Binding HasLessonTopic}"/>
<TextBlock Text="{Binding ExamTitle}" FontSize="11" Foreground="#D85A30" FontWeight="SemiBold"
IsVisible="{Binding HasExam}"/>
<TextBlock Text="📓 Hausaufgabe aus letzter Stunde noch nicht kontrolliert" FontSize="11"
Foreground="#8E6C00" FontWeight="SemiBold"
IsVisible="{Binding HasUnhandledHomework}"/>
</StackPanel>
<StackPanel Grid.Column="3" Orientation="Horizontal" Spacing="6" VerticalAlignment="Center">
<Button Content="▶ Unterricht" FontSize="11" Padding="9,4"
IsVisible="{Binding HasLesson}"
ToolTip.Tip="Unterrichtsmodus: Verlaufsplan und Sitzplan mit Schnellbewertung auf einem Bildschirm."
Command="{Binding $parent[ItemsControl].((vm:TimetableViewModel)DataContext).StartTeachingModeCommand}"
CommandParameter="{Binding}"/>
<Button Content="{Binding OpenButtonLabel}" FontSize="11" Padding="9,4"
IsVisible="{Binding HasGroupId}"
Command="{Binding $parent[ItemsControl].((vm:TimetableViewModel)DataContext).OpenTodayLessonCommand}"
CommandParameter="{Binding}"/>
</StackPanel>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
</Border>
<TextBlock DockPanel.Dock="Bottom" Text="Heute sind keine Stunden im Stundenplan eingetragen." Classes="emptyhint"
IsVisible="{Binding !TodayItems.Count}" Margin="0,8,0,0"/>
<!-- Rest: Wochenüberblick (nicht editierbar) -->
<ScrollViewer>
<StackPanel Spacing="14">
<Grid ColumnDefinitions="Auto,Auto,*,Auto,Auto,Auto">
<Button Grid.Column="0" Content="" FontWeight="Bold" Padding="10,4"
Command="{Binding PreviousWeekCommand}" ToolTip.Tip="Vorherige Woche"/>
<Button Grid.Column="1" Content="" FontWeight="Bold" Padding="10,4" Margin="4,0,0,0"
Command="{Binding NextWeekCommand}" ToolTip.Tip="Nächste Woche"/>
<TextBlock Grid.Column="2" FontSize="16" FontWeight="SemiBold"
VerticalAlignment="Center" Margin="12,0,0,0">
<Run Text="Woche "/><Run Text="{Binding WeekRangeLabel}"/>
</TextBlock>
<Button Grid.Column="3" Content="Diese Woche" Margin="0,0,8,0"
Command="{Binding CurrentWeekCommand}" IsVisible="{Binding !IsCurrentWeek}"/>
<Button Grid.Column="4" Content="Ausnahme eintragen" Margin="0,0,8,0"
Command="{Binding AddSubstitutionCommand}"/>
<Button Grid.Column="5" Content="⚙️" Command="{Binding OpenSettingsCommand}"
ToolTip.Tip="Einstellungen (Ferien, Aufsichten, Stundenraster)"/>
</Grid>
<!-- Zeilenweise (WeekRows) statt eines einzigen flachen UniformGrid: so kann jede
Zeile ihre eigene Höhe haben (RowHeight je WeekRowItem) - Aufsicht-Zeilen
deutlich schmaler als Stunden-/Kopfzeilen. Grid.RowDefinitions lässt sich in
Avalonia nicht per {Binding} setzen (AVLN3000 "Unable to find suitable setter
or adder"), daher dieser Umweg statt eines einzelnen Grids mit dynamischer
RowDefinitions-Bindung. Die innere UniformGrid Columns="6" bleibt unverändert
für die Spaltenaufteilung innerhalb je einer Zeile. -->
<ItemsControl ItemsSource="{Binding WeekRows}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:WeekRowItem">
<ItemsControl ItemsSource="{Binding Cells}" Height="{Binding RowHeight}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate><UniformGrid Columns="6"/></ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:WeekCellItem">
<Grid Margin="2">
<Border Classes="weekheader" Classes.today="{Binding IsToday}" CornerRadius="4"
IsVisible="{Binding IsHeader}">
<TextBlock Text="{Binding Text}" FontWeight="SemiBold" FontSize="12" Opacity="0.75"
HorizontalAlignment="Center" VerticalAlignment="Center" Margin="4"/>
</Border>
<TextBlock Text="{Binding Text}" IsVisible="{Binding IsPeriodLabel}"
FontWeight="SemiBold" FontSize="13"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock Text="{Binding Text}" IsVisible="{Binding IsSupervisionRow}"
FontSize="10" FontWeight="SemiBold" Opacity="0.55" TextWrapping="Wrap"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Border Classes="supervisioncell" Classes.substitution="{Binding IsSubstitutionSupervision}"
CornerRadius="4" Padding="4,1" IsVisible="{Binding IsSupervisionCell}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TextBlock Text="{Binding SupervisionLocation}" FontSize="9" Foreground="White"
HorizontalAlignment="Center" VerticalAlignment="Center"
TextWrapping="NoWrap" TextTrimming="CharacterEllipsis"
IsVisible="{Binding HasSupervision}"/>
</Border>
<Border Classes="timetablecell" Classes.assigned="{Binding IsAssigned}"
CornerRadius="6" IsVisible="{Binding IsSlotCell}">
<Button Background="{Binding ColorHex}" IsVisible="{Binding IsAssigned}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
HorizontalContentAlignment="Stretch" CornerRadius="6" Padding="6"
Command="{Binding $parent[ItemsControl;1].((vm:TimetableViewModel)DataContext).OpenWeekCellCommand}"
CommandParameter="{Binding}">
<StackPanel Spacing="1">
<TextBlock FontSize="11" FontWeight="Bold" Foreground="White" TextWrapping="Wrap">
<Run Text="{Binding SubjectLabel}"/><Run Text=" · "/><Run Text="{Binding GroupName}"/>
</TextBlock>
<TextBlock Text="{Binding Room}" FontSize="10" Foreground="White" Opacity="0.9"
IsVisible="{Binding HasRoom}"/>
<TextBlock Text="{Binding Topic}" FontSize="10" Foreground="White" Opacity="0.8"
TextWrapping="Wrap" IsVisible="{Binding HasTopic}"/>
<TextBlock Text="Ferien" FontSize="10" Foreground="White" FontWeight="SemiBold"
Opacity="0.9" IsVisible="{Binding IsHoliday}" Margin="0,2,0,0"/>
<TextBlock Text="Ausfall" FontSize="10" Foreground="White" FontWeight="SemiBold"
Opacity="0.9" IsVisible="{Binding IsCancelled}" Margin="0,2,0,0"/>
<StackPanel Orientation="Horizontal" Spacing="3" Margin="0,2,0,0"
IsVisible="{Binding !IsHoliday}">
<Border Background="#B71C1C" CornerRadius="7" Padding="4,0" IsVisible="{Binding HasHolidayBadge}">
<TextBlock Text="{Binding HolidayBadge}" FontSize="9" FontWeight="Bold" Foreground="White"/>
</Border>
<TextBlock Text="📝" FontSize="11" IsVisible="{Binding HasExam}" ToolTip.Tip="Klausur"/>
<TextBlock Text="⏰" FontSize="11" IsVisible="{Binding IsLastBeforeExam}" ToolTip.Tip="Letzte Stunde vor der Klausur"/>
<TextBlock Text="🧪" FontSize="11" IsVisible="{Binding HasExperiment}" ToolTip.Tip="Experiment geplant"/>
<TextBlock Text="📓" FontSize="11" IsVisible="{Binding HasUnhandledHomework}"
ToolTip.Tip="Hausaufgabe aus letzter Stunde noch nicht kontrolliert"/>
</StackPanel>
</StackPanel>
</Button>
</Border>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Border Background="{DynamicResource SystemControlBackgroundAltHighBrush}"
CornerRadius="8" Padding="16" IsVisible="{Binding HoursWarnings.Count}">
<StackPanel Spacing="8">
<TextBlock Text="ABWEICHENDE WOCHENSTUNDEN" FontSize="11" FontWeight="Bold" Opacity="0.5"/>
<ItemsControl ItemsSource="{Binding HoursWarnings}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:HoursWarningItem">
<TextBlock Text="{Binding Text}" FontSize="12" Foreground="#FB8C00"
TextWrapping="Wrap" Margin="0,3"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Border>
<Border Background="{DynamicResource SystemControlBackgroundAltHighBrush}"
CornerRadius="8" Padding="16" IsVisible="{Binding UpcomingExams.Count}">
<StackPanel Spacing="8">
<TextBlock Text="ANSTEHENDE KLAUSUREN" FontSize="11" FontWeight="Bold" Opacity="0.5"/>
<ItemsControl ItemsSource="{Binding UpcomingExams}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:UpcomingExamItem">
<Grid ColumnDefinitions="90,*" Margin="0,3">
<TextBlock Grid.Column="0" Text="{Binding DateDisplay}" FontSize="12" Opacity="0.6"/>
<TextBlock Grid.Column="1" FontSize="12">
<Run Text="{Binding GroupName}"/><Run Text=" — "/><Run Text="{Binding Title}"/>
</TextBlock>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Border>
</StackPanel>
</ScrollViewer>
</DockPanel>
</ContentPage>
<!-- Tab: Bearbeiten (Raster) -->
<ContentPage Header="Bearbeiten">
<ScrollViewer>
<StackPanel Margin="32,20,32,28" Spacing="10">
<!-- Zeilenweise (GridRows) statt eines flachen UniformGrid, siehe Kommentar im
Wochenraster oben (Heute-Tab) - gleicher Grund (Grid.RowDefinitions lässt sich
nicht per {Binding} setzen). -->
<ItemsControl ItemsSource="{Binding GridRows}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:TimetableRowItem">
<ItemsControl ItemsSource="{Binding Cells}" Height="{Binding RowHeight}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate><UniformGrid Columns="6"/></ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:TimetableCellItem">
<Grid Margin="2">
<TextBlock Text="{Binding Text}" IsVisible="{Binding IsHeader}"
FontWeight="SemiBold" FontSize="12" Opacity="0.6"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock Text="{Binding Text}" IsVisible="{Binding IsPeriodLabel}"
FontWeight="SemiBold" FontSize="13"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock Text="{Binding Text}" IsVisible="{Binding IsSupervisionRow}"
FontSize="10" FontWeight="SemiBold" Opacity="0.55" TextWrapping="Wrap"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Border Classes="supervisioncell" CornerRadius="4" Padding="4,1"
IsVisible="{Binding IsSupervisionCell}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TextBlock Text="{Binding SupervisionLocation}" FontSize="9" Foreground="White"
HorizontalAlignment="Center" VerticalAlignment="Center"
TextWrapping="NoWrap" TextTrimming="CharacterEllipsis"
IsVisible="{Binding HasSupervision}"/>
</Border>
<Border Classes="timetablecell" Classes.assigned="{Binding IsAssigned}"
CornerRadius="6" IsVisible="{Binding IsSlotCell}">
<Panel>
<Button Background="{Binding ColorHex}"
IsVisible="{Binding IsAssigned}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
HorizontalContentAlignment="Center" CornerRadius="6"
Command="{Binding $parent[ItemsControl;1].((vm:TimetableViewModel)DataContext).EditCellCommand}"
CommandParameter="{Binding}">
<TextBlock Text="{Binding Text}" FontSize="11" Foreground="White"
TextWrapping="Wrap" TextAlignment="Center"/>
</Button>
<Button Content="+" Opacity="0.35"
IsVisible="{Binding !IsAssigned}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
HorizontalContentAlignment="Center" Background="Transparent"
Command="{Binding $parent[ItemsControl;1].((vm:TimetableViewModel)DataContext).EditCellCommand}"
CommandParameter="{Binding}"/>
<Border Background="#D85A30" CornerRadius="8" Padding="5,1"
IsVisible="{Binding HasBadge}"
HorizontalAlignment="Right" VerticalAlignment="Top" Margin="2">
<TextBlock Text="{Binding BadgeText}" FontSize="10" FontWeight="Bold" Foreground="White"/>
</Border>
</Panel>
</Border>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
</ContentPage>
</TabbedPage>
</Grid>
</UserControl>