using Avalonia.Controls; using Avalonia.Interactivity; using LehrerApp.Core.Interfaces; using LehrerApp.Core.Models; using LehrerApp.Core.Services; using LehrerApp.Desktop.ViewModels; using LehrerApp.Desktop.ViewModels.Planning; using LehrerApp.Desktop.ViewModels.Groups; using LehrerApp.Desktop.Views.Groups; using LehrerApp.Desktop.Services; using Microsoft.Extensions.DependencyInjection; namespace LehrerApp.Desktop.Views.Planning; public partial class TimetableView : UserControl { public TimetableView() => InitializeComponent(); protected override void OnDataContextChanged(EventArgs e) { base.OnDataContextChanged(e); if (DataContext is TimetableViewModel vm) { vm.OnEditSlot = ShowSlotDialog; vm.OnAddSubstitution = ShowSubstitutionDialog; vm.OnImportWebUntisTimetable = ShowWebUntisTimetableDialog; vm.OnOpenLessonViewer = ShowLessonViewerDialog; vm.OnOpenTeachingMode = ShowTeachingMode; } } /// Nutzer-Feedback (zweite Runde — die erste Fassung hatte das Problem an der falschen /// Stelle gelöst, in der "Heute"-Tagesliste statt im Wochenraster): im Wochenraster oben /// führt ein Klick auf eine Stunden-Kachel bislang entweder in den Planungsviewer oder zur /// Einheitenplanung — je nachdem, ob schon eine Lesson existiert, ohne dass das von außen /// erkennbar wäre. Popup-Menü (MenuFlyout, kein ComboBox mehr) mit allen vier Zielen als /// Alternative zum Direktklick, siehe /// für den "einheitlicheren" Standard-Klick (Unterrichtsansicht bei laufender Stunde, sonst /// Planungsviewer, sonst Einheitenplanung). MenuItem.Click statt Command-Binding: ein /// $parent[ItemsControl]-Vorfahrenpfad (wie beim Zeilen-Button) funktioniert innerhalb eines /// Flyouts nicht zuverlässig, weil dessen Popup nicht im normalen visuellen Baum hängt (siehe /// TODO.md-Nachtrag zum Klassenlehrer-Bereich) — DataContext-Vererbung (kein Pfad-Suchen, /// nur der normale Eltern-Wert) funktioniert dort aber sehr wohl, deshalb liest der Handler /// die Zelle über ((MenuItem)sender).DataContext statt über eine Binding. private async void OnWeekCellMenuItemClick(object? sender, RoutedEventArgs e) { if (sender is not MenuItem { Tag: TimetableLessonDestination destination } menuItem) return; if (menuItem.DataContext is not WeekCellItem cell) return; if (DataContext is not TimetableViewModel vm) return; switch (destination) { case TimetableLessonDestination.TeachingMode: if (cell.Lesson is { } teachLesson && vm.OnOpenTeachingMode is not null) await vm.OnOpenTeachingMode(teachLesson); break; case TimetableLessonDestination.Viewer: if (cell.Lesson is { } viewLesson && vm.OnOpenLessonViewer is not null) await vm.OnOpenLessonViewer(viewLesson); break; case TimetableLessonDestination.Planning: if (cell.GroupId != Guid.Empty) App.Services.GetRequiredService().NavigateToGroupDetail(cell.GroupId, 6); break; case TimetableLessonDestination.SeatingPlan: if (cell.GroupId != Guid.Empty) App.Services.GetRequiredService().NavigateToGroupDetail(cell.GroupId, 2); break; } } private async Task ShowWebUntisTimetableDialog() { var owner = TopLevel.GetTopLevel(this) as Window; if (owner is null) return; var vm = new WebUntisTimetableImportViewModel( App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService()); var dialog = new WebUntisTimetableImportDialog { DataContext = vm }; vm.OnCreateGroup = dialog.CreateGroupAsync; await vm.InitializeAsync(); await dialog.ShowDialog(owner); } private async Task ShowTeachingMode(Lesson lesson) { var owner = TopLevel.GetTopLevel(this) as Window; var group = App.Services.GetRequiredService().GetById(lesson.GroupId); if (owner is null || group is null) return; var teachingModeVm = new TeachingModeViewModel(lesson, group, App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService()); var window = new TeachingModeWindow { DataContext = teachingModeVm }; await window.ShowDialog(owner); } private async Task ShowLessonViewerDialog(Lesson lesson) { var owner = TopLevel.GetTopLevel(this) as Window; if (owner is null) return; var viewerVm = new LessonViewerViewModel(lesson, App.Services.GetRequiredService()); var dialog = new LessonViewerDialog { DataContext = viewerVm }; await dialog.ShowDialog(owner); } private async Task ShowSlotDialog(TimetableCellItem cell) { var owner = TopLevel.GetTopLevel(this) as Window; if (owner is null || cell.Weekday is null) return; var vm = new TimetableSlotDialogViewModel( App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService(), cell.Weekday.Value, cell.PeriodNumber, cell.Slot); var dialog = new TimetableSlotDialog { DataContext = vm }; await dialog.ShowDialog(owner); } private async Task ShowSubstitutionDialog() { var owner = TopLevel.GetTopLevel(this) as Window; if (owner is null) return; var vm = new SubstitutionEntryDialogViewModel( App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService()); var dialog = new SubstitutionEntryDialog { DataContext = vm }; await dialog.ShowDialog(owner); } }