- Sync-Settings-Tab: neuer Bereich "Gerät koppeln" (10.3.1), nutzt den bereits vorhandenen, bisher nirgends verdrahteten SnapshotService. Ein Gerät erzeugt per CreatePairingCode einen verschlüsselten DB-Snapshot + Einmal-Code, das zweite Gerät übernimmt per RedeemPairingCode Datenbank und Sync-Schlüssel. Bestätigungsdialog vor dem Einlösen, da die lokale Datenbank dabei vollständig ersetzt wird (alter Stand wird automatisch als Backup gesichert). - Einstellungen: TabPlacement von Top auf Left umgestellt (vertikale Liste statt langem horizontalem Balken) und die 13 Tabs in drei logische Gruppen sortiert (Fachliches / Zeitplanung / System). - Neuer SettingsTab-Enum ersetzt rohe int-Tab-Indizes bei MainWindowViewModel.NavigateToSettings/ TimetableViewModel.OnNavigateToSettings. Dabei einen bestehenden Bug gefunden und mitbehoben: das Zahnrad im Stundenplan öffnete über den hartcodierten Index 7 tatsächlich "Datenschutz" statt des laut Kommentar/Tooltip beabsichtigten "Ferien & Feiertage". Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
146 lines
5.3 KiB
C#
146 lines
5.3 KiB
C#
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using CommunityToolkit.Mvvm.Input;
|
|
using LehrerApp.Core.Services;
|
|
using LehrerApp.Desktop.Services;
|
|
using LehrerApp.Desktop.ViewModels.Groups;
|
|
using LehrerApp.Desktop.ViewModels.Planning;
|
|
using LehrerApp.Desktop.ViewModels.Settings;
|
|
using LehrerApp.Desktop.ViewModels.Students;
|
|
using LehrerApp.Desktop.ViewModels.Workload;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using System.Collections.ObjectModel;
|
|
|
|
namespace LehrerApp.Desktop.ViewModels;
|
|
|
|
public partial class MainWindowViewModel : ObservableObject
|
|
{
|
|
private readonly IServiceProvider _services;
|
|
|
|
[ObservableProperty] private ObservableObject? _currentPage;
|
|
[ObservableProperty] private NavItem _activeNavItem = NavItem.Dashboard;
|
|
[ObservableProperty] private string _currentSchoolYear = "";
|
|
|
|
public SyncStatusViewModel SyncStatus { get; }
|
|
public ObservableCollection<ToastItem> Toasts { get; }
|
|
public AppLockViewModel AppLock { get; }
|
|
|
|
public bool IsDashboardActive => ActiveNavItem == NavItem.Dashboard;
|
|
public bool IsGroupsActive => ActiveNavItem == NavItem.Groups;
|
|
public bool IsStudentsActive => ActiveNavItem == NavItem.Students;
|
|
public bool IsExamsActive => ActiveNavItem == NavItem.Exams;
|
|
public bool IsPlannerActive => ActiveNavItem == NavItem.Planner;
|
|
public bool IsWorkloadActive => ActiveNavItem == NavItem.Workload;
|
|
public bool IsSettingsActive => ActiveNavItem == NavItem.Settings;
|
|
|
|
public MainWindowViewModel(IServiceProvider services,
|
|
DashboardViewModel dashboard, SchoolYearService sy,
|
|
SyncStatusViewModel syncStatus, NotificationService notifications, AppLockViewModel appLock)
|
|
{
|
|
_services = services;
|
|
SyncStatus = syncStatus;
|
|
Toasts = notifications.Toasts;
|
|
AppLock = appLock;
|
|
CurrentSchoolYear = sy.CurrentSchoolYear();
|
|
CurrentPage = dashboard;
|
|
AppLock.ApplyConfig();
|
|
}
|
|
|
|
partial void OnActiveNavItemChanged(NavItem value)
|
|
{
|
|
OnPropertyChanged(nameof(IsDashboardActive));
|
|
OnPropertyChanged(nameof(IsGroupsActive));
|
|
OnPropertyChanged(nameof(IsStudentsActive));
|
|
OnPropertyChanged(nameof(IsExamsActive));
|
|
OnPropertyChanged(nameof(IsPlannerActive));
|
|
OnPropertyChanged(nameof(IsWorkloadActive));
|
|
OnPropertyChanged(nameof(IsSettingsActive));
|
|
}
|
|
|
|
[RelayCommand]
|
|
private void NavigateTo(NavItem item)
|
|
{
|
|
ActiveNavItem = item;
|
|
CurrentPage = item switch
|
|
{
|
|
NavItem.Dashboard => GetDashboard(),
|
|
NavItem.Groups => _services.GetRequiredService<GroupListViewModel>(),
|
|
NavItem.Students => GetStudents(),
|
|
NavItem.Exams => new PlaceholderViewModel { Title = "Klausuren", Icon = "📝" },
|
|
NavItem.Planner => GetTimetable(),
|
|
NavItem.Workload => GetWorkload(),
|
|
NavItem.Settings => _services.GetRequiredService<SettingsViewModel>(),
|
|
_ => CurrentPage,
|
|
};
|
|
}
|
|
|
|
private DashboardViewModel GetDashboard()
|
|
{
|
|
var dashboard = _services.GetRequiredService<DashboardViewModel>();
|
|
dashboard.RefreshCommand.Execute(null);
|
|
return dashboard;
|
|
}
|
|
|
|
private StudentListViewModel GetStudents()
|
|
{
|
|
var students = _services.GetRequiredService<StudentListViewModel>();
|
|
students.SelectedStudent = null;
|
|
students.LoadStudents();
|
|
return students;
|
|
}
|
|
|
|
private TimetableViewModel GetTimetable()
|
|
{
|
|
var timetable = _services.GetRequiredService<TimetableViewModel>();
|
|
timetable.WeekOffset = 0;
|
|
timetable.Load();
|
|
timetable.ActiveTabIndex = 0;
|
|
return timetable;
|
|
}
|
|
|
|
private WorkloadViewModel GetWorkload()
|
|
{
|
|
var workload = _services.GetRequiredService<WorkloadViewModel>();
|
|
workload.Tasks.Load();
|
|
workload.TimeTracking.Load();
|
|
workload.Evaluation.Load();
|
|
workload.ActiveTabIndex = 0;
|
|
return workload;
|
|
}
|
|
|
|
public void NavigateToGroupDetail(Guid groupId, int initialTab = 0)
|
|
{
|
|
ActiveNavItem = NavItem.Groups;
|
|
var vm = _services.GetRequiredService<GroupDetailViewModel>();
|
|
vm.ActiveTabIndex = initialTab;
|
|
CurrentPage = vm; // View bindet zuerst → Callbacks werden registriert
|
|
vm.LoadGroup(groupId); // dann Daten laden
|
|
}
|
|
|
|
public void NavigateToSettings(SettingsTab initialTab = SettingsTab.Subjects)
|
|
{
|
|
ActiveNavItem = NavItem.Settings;
|
|
var vm = _services.GetRequiredService<SettingsViewModel>();
|
|
vm.ActiveTabIndex = (int)initialTab;
|
|
CurrentPage = vm;
|
|
}
|
|
|
|
public void NavigateToStudent(Guid studentId)
|
|
{
|
|
ActiveNavItem = NavItem.Students;
|
|
var vm = _services.GetRequiredService<StudentDetailViewModel>();
|
|
vm.OnReturnToStudentList = NavigateToStudents;
|
|
vm.LoadStudent(studentId);
|
|
CurrentPage = vm;
|
|
}
|
|
|
|
public void NavigateToStudents() => NavigateTo(NavItem.Students);
|
|
}
|
|
|
|
public enum NavItem { Dashboard, Groups, Students, Exams, Planner, Workload, Settings }
|
|
|
|
public partial class PlaceholderViewModel : ObservableObject
|
|
{
|
|
[ObservableProperty] private string _title = "";
|
|
[ObservableProperty] private string _icon = "";
|
|
}
|