WIP (unstable): WebUntis-iCal-Abgleich für Vertretungen/Ausfälle
Erkennt Vertretungen, Ausfälle und Zusatzaufsichten aus dem persönlichen WebUntis-iCal-Feed und schreibt sie automatisch als SubstitutionEntry. Bekannter offener Bug: es tauchen weiterhin falsche Vertretungen für Stunden auf, die real unverändert sind — wird in einem Folge-Commit untersucht, deshalb vorerst auf diesem Branch statt main. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -36,8 +36,9 @@ public enum SettingsTab
|
||||
Privacy = 10,
|
||||
Sync = 11,
|
||||
Ai = 12,
|
||||
Appearance = 13,
|
||||
Trash = 14,
|
||||
WebUntis = 13,
|
||||
Appearance = 14,
|
||||
Trash = 15,
|
||||
}
|
||||
|
||||
// ── Haupt-ViewModel ───────────────────────────────────────────────────────────
|
||||
@@ -191,6 +192,16 @@ public partial class SettingsViewModel : ObservableObject
|
||||
[ObservableProperty] private bool _aiIsLoggedIn;
|
||||
[ObservableProperty] private string _aiBalanceDisplay = "";
|
||||
|
||||
// ── WebUntis-iCal-Abgleich (Nutzer-Feedback) ──────────────────────────────
|
||||
|
||||
[ObservableProperty] private bool _untisEnabled;
|
||||
[ObservableProperty] private bool _untisIsConfigured;
|
||||
[ObservableProperty] private string _untisIcalUrlInput = "";
|
||||
[ObservableProperty] private string _untisUrlError = "";
|
||||
[ObservableProperty] private string _untisStatusDisplay = "";
|
||||
[ObservableProperty] private bool _untisFetchBusy;
|
||||
public Func<Task>? OnReviewUntisMapping { get; set; }
|
||||
|
||||
// ── Synchronisation (Kapitel 10) ──────────────────────────────────────────
|
||||
|
||||
[ObservableProperty] private string _syncServerUrl = "";
|
||||
@@ -268,6 +279,8 @@ public partial class SettingsViewModel : ObservableObject
|
||||
private readonly ISupervisionDutyRepository _supervisionDuties;
|
||||
private readonly AiSettingsService _aiSettings;
|
||||
private readonly AiPlanningService _aiPlanning;
|
||||
private readonly WebUntisSettingsService _untisSettings;
|
||||
private readonly UntisSyncService? _untisSync;
|
||||
private readonly SyncSettingsService _syncSettings;
|
||||
private readonly SyncAuthService _syncAuth;
|
||||
private readonly EventQueue _eventQueue;
|
||||
@@ -289,10 +302,12 @@ public partial class SettingsViewModel : ObservableObject
|
||||
SchoolCalendarSettingsService calendarSettings, PeriodScheduleService periodSchedule,
|
||||
ISupervisionDutyRepository supervisionDuties, LetterTemplateService letterTemplates,
|
||||
AiSettingsService aiSettings, AiPlanningService aiPlanning,
|
||||
WebUntisSettingsService untisSettings,
|
||||
SyncSettingsService syncSettings, SyncAuthService syncAuth, EventQueue eventQueue,
|
||||
AppLogger logger, SyncKeyStatus syncKeyStatus, SyncKeyRecoveryService syncKeyRecovery,
|
||||
AppearanceSettingsService appearance, TrashViewModel trashTab,
|
||||
SnapshotService? snapshotService = null, SyncEngine? syncEngine = null)
|
||||
SnapshotService? snapshotService = null, SyncEngine? syncEngine = null,
|
||||
UntisSyncService? untisSync = null)
|
||||
{
|
||||
_logger = logger;
|
||||
_syncKeyRecovery = syncKeyRecovery;
|
||||
@@ -320,6 +335,8 @@ public partial class SettingsViewModel : ObservableObject
|
||||
_letterTemplates = letterTemplates;
|
||||
_aiSettings = aiSettings;
|
||||
_aiPlanning = aiPlanning;
|
||||
_untisSettings = untisSettings;
|
||||
_untisSync = untisSync;
|
||||
_syncSettings = syncSettings;
|
||||
_syncAuth = syncAuth;
|
||||
_eventQueue = eventQueue;
|
||||
@@ -342,6 +359,7 @@ public partial class SettingsViewModel : ObservableObject
|
||||
LoadSupervisionDuties();
|
||||
LoadLetterTemplates();
|
||||
LoadAiSettings();
|
||||
LoadUntisSettings();
|
||||
LoadSyncSettings();
|
||||
LoadSyncConflicts();
|
||||
}
|
||||
@@ -485,6 +503,60 @@ public partial class SettingsViewModel : ObservableObject
|
||||
AiBalanceDisplay = "";
|
||||
}
|
||||
|
||||
// ── WebUntis-iCal-Abgleich: Laden / Speichern / Entfernen / Jetzt abrufen ────
|
||||
//
|
||||
// Wie bei Sync deckt ein Neustart das Registrieren von UntisSyncService ab
|
||||
// (AppBootstrapper registriert es nur einmalig beim Start, wenn URL+Enabled vorliegen).
|
||||
|
||||
private void LoadUntisSettings()
|
||||
{
|
||||
UntisEnabled = _untisSettings.Enabled;
|
||||
UntisIsConfigured = _untisSettings.IsConfigured;
|
||||
UntisStatusDisplay = _untisSettings.LastSyncAt is { } at
|
||||
? $"Letzter Abgleich: {at.ToLocalTime():dd.MM.yyyy HH:mm} — {_untisSettings.LastSyncStatus}"
|
||||
: "Noch kein Abgleich durchgeführt.";
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void UntisSaveUrl()
|
||||
{
|
||||
UntisUrlError = "";
|
||||
if (string.IsNullOrWhiteSpace(UntisIcalUrlInput)) { UntisUrlError = "iCal-URL erforderlich."; return; }
|
||||
if (!Uri.TryCreate(UntisIcalUrlInput, UriKind.Absolute, out _)) { UntisUrlError = "Ungültige URL."; return; }
|
||||
|
||||
_untisSettings.SetIcalUrl(UntisIcalUrlInput.Trim());
|
||||
_untisSettings.SetEnabled(true);
|
||||
UntisIcalUrlInput = "";
|
||||
AppBootstrapper.RestartApplication();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void UntisRemove()
|
||||
{
|
||||
_untisSettings.ClearIcalUrl();
|
||||
LoadUntisSettings();
|
||||
AppBootstrapper.RestartApplication();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task UntisFetchNow()
|
||||
{
|
||||
if (_untisSync is null) { UntisStatusDisplay = "Abgleich nicht aktiv — App neu starten."; return; }
|
||||
UntisFetchBusy = true;
|
||||
try
|
||||
{
|
||||
await _untisSync.PollAsync();
|
||||
LoadUntisSettings();
|
||||
}
|
||||
finally { UntisFetchBusy = false; }
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task UntisReviewMapping()
|
||||
{
|
||||
if (OnReviewUntisMapping is not null) await OnReviewUntisMapping();
|
||||
}
|
||||
|
||||
// ── Synchronisation: Laden / Anmelden / Abmelden / Verbindungstest ───────
|
||||
//
|
||||
// Server-URL, Zugangsdaten und Token werden erst nach erfolgreichem Login zusammen
|
||||
|
||||
Reference in New Issue
Block a user