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);
}
}