Zeigt die Fälligkeit der vier bestehenden, manuell ausgelösten WebUntis-Abgleiche (Fehlzeiten je Lerngruppe, offene Stunden, Klassenbuch-, Hausaufgabenabgleich) in einem neuen Hub-Fenster, ohne selbst WebUntis anzufragen - nur gespeicherte Zeitstempel werden ausgewertet. Konsolidiert die bisher verstreuten Einstiegspunkte (Sidebar-Button, Dashboard-Buttons) in ein neues WebUntis-Menü plus einen kompakten Gesundheits-Indikator auf dem Dashboard. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -38,6 +38,8 @@ public partial class DashboardViewModel : ObservableObject
|
||||
private readonly ITimeEntryRepository _timeEntries;
|
||||
private readonly IAnnualPlanEventRepository? _annualPlanEvents;
|
||||
private readonly SchoolWeatherService? _schoolWeather;
|
||||
private readonly UntisHubService _untisHub;
|
||||
private readonly WebUntisIntegrationService _webUntis;
|
||||
|
||||
private const int OpenExcuseMaxAgeDays = 21;
|
||||
private const int SupportPlanDueWithinDays = 14;
|
||||
@@ -143,6 +145,10 @@ public partial class DashboardViewModel : ObservableObject
|
||||
public string AttentionSummary => AttentionCount == 1 ? "1 offener Punkt" : $"{AttentionCount} offene Punkte";
|
||||
public string UpcomingSummary => UpcomingCount == 1 ? "1 Termin" : $"{UpcomingCount} Termine";
|
||||
|
||||
[ObservableProperty] private string _webUntisHealthLabel = "";
|
||||
[ObservableProperty] private bool _isWebUntisHealthWarning;
|
||||
[ObservableProperty] private bool _isWebUntisHealthVisible;
|
||||
|
||||
public DashboardViewModel(IGroupRepository groups, ISubjectRepository subjects, ILessonRepository lessons,
|
||||
IExamRepository exams, IExamResultRepository examResults, IGradeRepository grades,
|
||||
IReportGradeRepository reportGrades, IGroupMembershipRepository memberships,
|
||||
@@ -153,6 +159,7 @@ public partial class DashboardViewModel : ObservableObject
|
||||
DashboardSettingsService dashboardSettings, ISchoolHolidayRepository schoolHolidays,
|
||||
PublicHolidayService publicHolidays, SchoolCalendarSettingsService calendarSettings,
|
||||
ISubstitutionEntryRepository substitutions, ITimeEntryRepository timeEntries,
|
||||
UntisHubService untisHub, WebUntisIntegrationService webUntis,
|
||||
IAnnualPlanEventRepository? annualPlanEvents = null,
|
||||
AnnualPlanSyncService? annualPlanSync = null, SchoolWeatherService? schoolWeather = null)
|
||||
{
|
||||
@@ -167,12 +174,28 @@ public partial class DashboardViewModel : ObservableObject
|
||||
_substitutions = substitutions;
|
||||
_annualPlanEvents = annualPlanEvents;
|
||||
_schoolWeather = schoolWeather;
|
||||
_untisHub = untisHub;
|
||||
_webUntis = webUntis;
|
||||
if (annualPlanSync is not null)
|
||||
{
|
||||
annualPlanSync.DataChanged += () => Avalonia.Threading.Dispatcher.UIThread.Post(LoadCalendar);
|
||||
}
|
||||
LoadDashboardCards();
|
||||
Load();
|
||||
RefreshWebUntisHealth();
|
||||
}
|
||||
|
||||
/// <summary>Liest nur den gespeicherten Fälligkeitsstand der Untis-Hub-Jobs (kein
|
||||
/// WebUntis-Zugriff, siehe <see cref="UntisHubService.GetRows"/>) - aufgerufen bei jedem
|
||||
/// Dashboard-Refresh und erneut, nachdem der Nutzer den Hub geöffnet/einen Abgleich gemacht hat.</summary>
|
||||
public void RefreshWebUntisHealth()
|
||||
{
|
||||
IsWebUntisHealthVisible = _webUntis.IsAvailable;
|
||||
if (!IsWebUntisHealthVisible) return;
|
||||
var rows = _untisHub.GetRows();
|
||||
var due = rows.Count(r => r.DueState != UntisHubDueState.Ok);
|
||||
IsWebUntisHealthWarning = due > 0;
|
||||
WebUntisHealthLabel = due > 0 ? $"WebUntis ⚠ {due} fällig" : "WebUntis ✓";
|
||||
}
|
||||
|
||||
private DashboardCardOption Card(string key) => DashboardCards.First(c => c.Key == key);
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using LehrerApp.Core.Interfaces;
|
||||
using LehrerApp.Core.Models;
|
||||
using LehrerApp.Desktop.Services;
|
||||
|
||||
namespace LehrerApp.Desktop.ViewModels.UntisHub;
|
||||
|
||||
/// <summary>Eine Zeile im Untis-Hub-Fenster - reine Anzeige-Projektion von
|
||||
/// <see cref="UntisHubJobRow"/>, neu aufgebaut bei jedem <see cref="UntisHubViewModel.Load"/>.</summary>
|
||||
public sealed class UntisHubRowViewModel
|
||||
{
|
||||
public UntisHubJobKind Kind { get; }
|
||||
public Guid? GroupId { get; }
|
||||
public string GroupName { get; }
|
||||
public string JobLabel { get; }
|
||||
public string DueLabel { get; }
|
||||
public string? LastResultSummary { get; }
|
||||
public bool IsWarning { get; }
|
||||
public bool IsDanger { get; }
|
||||
|
||||
public UntisHubRowViewModel(UntisHubJobRow row)
|
||||
{
|
||||
Kind = row.Kind; GroupId = row.GroupId; GroupName = row.GroupName;
|
||||
JobLabel = Label(row.Kind); DueLabel = row.DueLabel; LastResultSummary = row.LastResultSummary;
|
||||
IsWarning = row.DueState == UntisHubDueState.Due;
|
||||
IsDanger = row.DueState == UntisHubDueState.Overdue;
|
||||
}
|
||||
|
||||
private static string Label(UntisHubJobKind kind) => kind switch
|
||||
{
|
||||
UntisHubJobKind.FehlzeitenKurz => "Fehlzeiten (kurzfristig)",
|
||||
UntisHubJobKind.FehlzeitenLang => "Fehlzeiten (seit Schuljahresbeginn)",
|
||||
UntisHubJobKind.OffenePeriods => "Offene Stunden",
|
||||
UntisHubJobKind.Klassenbuchabgleich => "Klassenbuchabgleich",
|
||||
UntisHubJobKind.Hausaufgabenabgleich => "Hausaufgabenabgleich",
|
||||
_ => kind.ToString(),
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>ViewModel des Untis-Hub-Fensters (siehe TODO.md) - zeigt nur den gespeicherten
|
||||
/// Fälligkeitsstand an (<see cref="UntisHubService.GetRows"/>, rein lesend aus LiteDB). Das
|
||||
/// tatsächliche Ausführen eines Jobs (inkl. WebUntis-Anfrage) übernimmt die Code-Behind-Klasse über
|
||||
/// <see cref="UntisHubActions"/>, weil dafür ein Fenster-Owner für <c>ShowDialog</c> gebraucht wird.</summary>
|
||||
public partial class UntisHubViewModel : ObservableObject
|
||||
{
|
||||
private readonly UntisHubService _hub;
|
||||
private readonly IGroupRepository _groups;
|
||||
|
||||
public ObservableCollection<UntisHubRowViewModel> Rows { get; } = [];
|
||||
[ObservableProperty] private bool _isAvailable;
|
||||
[ObservableProperty] private string _status = "";
|
||||
|
||||
public UntisHubViewModel(UntisHubService hub, IGroupRepository groups, WebUntisIntegrationService untis)
|
||||
{
|
||||
_hub = hub; _groups = groups;
|
||||
IsAvailable = untis.IsAvailable;
|
||||
Load();
|
||||
}
|
||||
|
||||
public void Load()
|
||||
{
|
||||
Rows.Clear();
|
||||
if (!IsAvailable)
|
||||
{
|
||||
Status = "WebUntis ist nicht konfiguriert (siehe Einstellungen).";
|
||||
return;
|
||||
}
|
||||
foreach (var row in _hub.GetRows()) Rows.Add(new UntisHubRowViewModel(row));
|
||||
var overdue = Rows.Count(r => r.IsDanger);
|
||||
var due = Rows.Count(r => r.IsWarning);
|
||||
Status = overdue > 0 || due > 0
|
||||
? $"{overdue + due} von {Rows.Count} Prüfungen fällig ({overdue} überfällig)."
|
||||
: $"Alle {Rows.Count} Prüfungen aktuell.";
|
||||
}
|
||||
|
||||
public LearningGroup? FindGroup(Guid id) => _groups.GetById(id);
|
||||
}
|
||||
Reference in New Issue
Block a user