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:
@@ -9,6 +9,12 @@
|
||||
<Setter Property="Foreground" Value="Red"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
</Style>
|
||||
<Style Selector="Button.webuntishealth">
|
||||
<Setter Property="Foreground" Value="{DynamicResource AppStatusOkBrush}"/>
|
||||
</Style>
|
||||
<Style Selector="Button.webuntishealth.warning">
|
||||
<Setter Property="Foreground" Value="{DynamicResource AppStatusWarningBrush}"/>
|
||||
</Style>
|
||||
<Style Selector="Border.daycell.selected">
|
||||
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundAccentBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="2"/>
|
||||
@@ -26,9 +32,11 @@
|
||||
<TextBlock Text="{Binding CurrentDate}" FontSize="24" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
<WrapPanel Grid.Row="1" Orientation="Horizontal" ItemSpacing="8" LineSpacing="8" Margin="0,10,0,0">
|
||||
<Button Content="Klassenbuch abgleichen…" Click="OnCompareWebUntisDocumentationClick"
|
||||
VerticalAlignment="Center"/>
|
||||
<Button Content="Fehlende Hausaufgaben abgleichen…" Click="OnCompareWebUntisHomeworkClick"
|
||||
<!-- Fasst die vier WebUntis-Abgleiche zusammen, die jetzt nur noch im Menü "WebUntis"
|
||||
erreichbar sind (siehe TODO.md, Untis-Hub) - Klick öffnet den Hub. -->
|
||||
<Button Content="{Binding WebUntisHealthLabel}" Click="OnOpenUntisHubClick"
|
||||
IsVisible="{Binding IsWebUntisHealthVisible}"
|
||||
Classes="webuntishealth" Classes.warning="{Binding IsWebUntisHealthWarning}"
|
||||
VerticalAlignment="Center"/>
|
||||
<Button Content="Bereiche anpassen" Command="{Binding ToggleDashboardSettingsCommand}"
|
||||
VerticalAlignment="Center"/>
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using LehrerApp.Core.Interfaces;
|
||||
using LehrerApp.Core.Models;
|
||||
using LehrerApp.Core.Services;
|
||||
using LehrerApp.Desktop.Services;
|
||||
using LehrerApp.Desktop.ViewModels;
|
||||
using LehrerApp.Desktop.ViewModels.Groups;
|
||||
using LehrerApp.Desktop.ViewModels.Students;
|
||||
using LehrerApp.Desktop.Views.Groups;
|
||||
using LehrerApp.Desktop.Views.Students;
|
||||
using LehrerApp.Desktop.Views.UntisHub;
|
||||
using LehrerApp.Desktop.Views.Workload;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
@@ -32,32 +27,11 @@ public partial class DashboardView : UserControl
|
||||
return await WorkTaskDialogHelper.ShowDialog(owner, startAsReminder: startAsReminder);
|
||||
}
|
||||
|
||||
private async void OnCompareWebUntisDocumentationClick(object? sender, RoutedEventArgs e)
|
||||
private async void OnOpenUntisHubClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
var owner = TopLevel.GetTopLevel(this) as Window;
|
||||
if (owner is null) return;
|
||||
var dialogVm = new WebUntisDocumentationComparisonViewModel(
|
||||
App.Services.GetRequiredService<WebUntisIntegrationService>(),
|
||||
App.Services.GetRequiredService<IStudentRepository>(),
|
||||
App.Services.GetRequiredService<IGroupRepository>(),
|
||||
App.Services.GetRequiredService<IDocumentationRepository>(),
|
||||
App.Services.GetRequiredService<SchoolYearService>());
|
||||
await new WebUntisDocumentationComparisonDialog { DataContext = dialogVm }.ShowDialog(owner);
|
||||
}
|
||||
|
||||
private async void OnCompareWebUntisHomeworkClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
var owner = TopLevel.GetTopLevel(this) as Window;
|
||||
if (owner is null) return;
|
||||
var dialogVm = new WebUntisHomeworkComparisonViewModel(
|
||||
App.Services.GetRequiredService<WebUntisIntegrationService>(),
|
||||
App.Services.GetRequiredService<IStudentRepository>(),
|
||||
App.Services.GetRequiredService<IGroupRepository>(),
|
||||
App.Services.GetRequiredService<ISubjectRepository>(),
|
||||
App.Services.GetRequiredService<IGroupMembershipRepository>(),
|
||||
App.Services.GetRequiredService<IParticipationSessionRepository>(),
|
||||
App.Services.GetRequiredService<IParticipationRepository>(),
|
||||
App.Services.GetRequiredService<SchoolYearService>());
|
||||
await new WebUntisHomeworkComparisonDialog { DataContext = dialogVm }.ShowDialog(owner);
|
||||
await new UntisHubDialog().ShowDialog(owner);
|
||||
if (DataContext is DashboardViewModel vm) vm.RefreshWebUntisHealth();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,16 @@
|
||||
darunter als Overlay-Drawer mit Hamburger-Button (automatisch).
|
||||
Kein eigener Code nötig.
|
||||
-->
|
||||
<DockPanel>
|
||||
<Menu DockPanel.Dock="Top">
|
||||
<MenuItem Header="WebUntis">
|
||||
<MenuItem Header="Untis-Hub…" Click="OnOpenUntisHub"/>
|
||||
<Separator/>
|
||||
<MenuItem Header="Offene Stunden…" Click="OnOpenUntisPeriods"/>
|
||||
<MenuItem Header="Klassenbuchabgleich…" Click="OnCompareUntisKlassenbuch"/>
|
||||
<MenuItem Header="Hausaufgabenabgleich…" Click="OnCompareUntisHausaufgaben"/>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
<DrawerPage x:Name="RootDrawer"
|
||||
DrawerLength="220"
|
||||
DrawerBehavior="Auto"
|
||||
@@ -250,15 +260,6 @@
|
||||
<TextBlock Classes="navlabel" Text="Klassenlehrer"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Classes="navitem" HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Left" CornerRadius="6"
|
||||
Click="OnOpenUntisPeriods"
|
||||
ToolTip.Tip="Offene Untis-Stunden" AutomationProperties.Name="Offene Untis-Stunden">
|
||||
<StackPanel Classes="navcontent" Orientation="Horizontal" Spacing="10">
|
||||
<PathIcon Classes="navicon" Data="{StaticResource IconOpenPeriods}"/>
|
||||
<TextBlock Classes="navlabel" Text="Offene Untis-Stunden"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Classes="navitem" Classes.active="{Binding IsSettingsActive}" HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Left"
|
||||
CornerRadius="6"
|
||||
@@ -276,6 +277,7 @@
|
||||
</DrawerPage.Drawer>
|
||||
|
||||
</DrawerPage>
|
||||
</DockPanel>
|
||||
|
||||
<!-- Globale Suche und Schnellerfassung (14.2). Bewusst als Overlay auf der aktuellen Seite:
|
||||
Der Nutzer behält den Kontext und kann mit Escape ohne Navigation zurückkehren. -->
|
||||
|
||||
@@ -3,7 +3,9 @@ using Avalonia.Input;
|
||||
using Avalonia.Threading;
|
||||
using LehrerApp.Desktop.Services;
|
||||
using LehrerApp.Desktop.ViewModels;
|
||||
using LehrerApp.Desktop.Views.UntisHub;
|
||||
using LehrerApp.Sync;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace LehrerApp.Desktop.Views;
|
||||
|
||||
@@ -23,9 +25,24 @@ public partial class MainWindow : Window
|
||||
KeyDown += OnWindowKeyDown;
|
||||
}
|
||||
|
||||
private async void OnOpenUntisHub(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
{
|
||||
await new UntisHubDialog().ShowDialog(this);
|
||||
}
|
||||
|
||||
private async void OnOpenUntisPeriods(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
{
|
||||
await new OpenUntisPeriodsDialog().ShowDialog(this);
|
||||
await UntisHubActions.RunOffenePeriodsAsync(this, App.Services.GetRequiredService<UntisHubService>());
|
||||
}
|
||||
|
||||
private async void OnCompareUntisKlassenbuch(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
{
|
||||
await UntisHubActions.RunKlassenbuchAsync(this, App.Services.GetRequiredService<UntisHubService>());
|
||||
}
|
||||
|
||||
private async void OnCompareUntisHausaufgaben(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
{
|
||||
await UntisHubActions.RunHausaufgabenAsync(this, App.Services.GetRequiredService<UntisHubService>());
|
||||
}
|
||||
|
||||
private void OnWindowKeyDown(object? sender, KeyEventArgs e)
|
||||
|
||||
@@ -23,6 +23,10 @@ public sealed class OpenUntisPeriodsDialog : Window
|
||||
private UntisOpenPeriodsMeta? _meta;
|
||||
private int _yearId;
|
||||
|
||||
/// <summary>Für den Untis-Hub (<see cref="UntisHubActions.RunOffenePeriodsAsync"/>): letzter
|
||||
/// Status-Text nach dem automatischen Laden beim Öffnen.</summary>
|
||||
public string? LastStatus => _status.Text;
|
||||
|
||||
public OpenUntisPeriodsDialog()
|
||||
{
|
||||
Title = "Offene WebUntis-Stunden";
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels.UntisHub"
|
||||
x:Class="LehrerApp.Desktop.Views.UntisHub.UntisHubDialog"
|
||||
x:DataType="vm:UntisHubViewModel"
|
||||
Title="Untis-Hub"
|
||||
Width="900" Height="600" MinWidth="640" MinHeight="400"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
|
||||
<Window.Styles>
|
||||
<Style Selector="TextBlock.duestatus">
|
||||
<Setter Property="Foreground" Value="{DynamicResource AppStatusOkBrush}"/>
|
||||
</Style>
|
||||
<Style Selector="TextBlock.duestatus.warning">
|
||||
<Setter Property="Foreground" Value="{DynamicResource AppStatusWarningBrush}"/>
|
||||
</Style>
|
||||
<Style Selector="TextBlock.duestatus.danger">
|
||||
<Setter Property="Foreground" Value="{DynamicResource AppStatusDangerBrush}"/>
|
||||
</Style>
|
||||
</Window.Styles>
|
||||
|
||||
<DockPanel Margin="20">
|
||||
<StackPanel DockPanel.Dock="Top" Spacing="10" Margin="0,0,0,14">
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<TextBlock Text="Untis-Hub" FontSize="22" FontWeight="SemiBold"/>
|
||||
<Button Grid.Column="1" Content="Aktualisieren" Click="OnRefreshClick"/>
|
||||
</Grid>
|
||||
<TextBlock Text="{Binding Status}" FontSize="12" Opacity="0.7" TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
|
||||
<DataGrid ItemsSource="{Binding Rows}" AutoGenerateColumns="False" IsReadOnly="True"
|
||||
GridLinesVisibility="Horizontal" BorderBrush="{DynamicResource AppCardBorderBrush}"
|
||||
BorderThickness="1" CanUserResizeColumns="True" CanUserSortColumns="True" RowHeight="46"
|
||||
IsVisible="{Binding IsAvailable}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Bereich" Binding="{Binding GroupName}" Width="1.3*"/>
|
||||
<DataGridTextColumn Header="Prüfung" Binding="{Binding JobLabel}" Width="1.3*"/>
|
||||
<DataGridTemplateColumn Header="Status" Width="1.1*">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="vm:UntisHubRowViewModel">
|
||||
<TextBlock Text="{Binding DueLabel}" Classes="duestatus"
|
||||
Classes.warning="{Binding IsWarning}" Classes.danger="{Binding IsDanger}"
|
||||
VerticalAlignment="Center"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<DataGridTextColumn Header="Letztes Ergebnis" Binding="{Binding LastResultSummary}" Width="2*"/>
|
||||
<DataGridTemplateColumn Header="" Width="130">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="vm:UntisHubRowViewModel">
|
||||
<Button Content="Jetzt prüfen" Click="OnCheckClick" DataContext="{Binding}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<TextBlock IsVisible="{Binding !IsAvailable}" Text="WebUntis ist nicht konfiguriert. Bitte zuerst in den Einstellungen hinterlegen."
|
||||
FontSize="14" Opacity="0.7" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</DockPanel>
|
||||
</Window>
|
||||
@@ -0,0 +1,58 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using LehrerApp.Core.Interfaces;
|
||||
using LehrerApp.Core.Models;
|
||||
using LehrerApp.Core.Services;
|
||||
using LehrerApp.Desktop.Services;
|
||||
using LehrerApp.Desktop.ViewModels.UntisHub;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace LehrerApp.Desktop.Views.UntisHub;
|
||||
|
||||
public partial class UntisHubDialog : Window
|
||||
{
|
||||
public UntisHubDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = new UntisHubViewModel(
|
||||
App.Services.GetRequiredService<UntisHubService>(),
|
||||
App.Services.GetRequiredService<IGroupRepository>(),
|
||||
App.Services.GetRequiredService<WebUntisIntegrationService>());
|
||||
}
|
||||
|
||||
private void OnRefreshClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is UntisHubViewModel vm) vm.Load();
|
||||
}
|
||||
|
||||
private async void OnCheckClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is not UntisHubViewModel vm || sender is not Button { DataContext: UntisHubRowViewModel row })
|
||||
return;
|
||||
var hub = App.Services.GetRequiredService<UntisHubService>();
|
||||
var today = DateOnly.FromDateTime(DateTime.Today);
|
||||
|
||||
switch (row.Kind)
|
||||
{
|
||||
case UntisHubJobKind.FehlzeitenKurz or UntisHubJobKind.FehlzeitenLang:
|
||||
var group = row.GroupId is { } id ? vm.FindGroup(id) : null;
|
||||
if (group is null) return;
|
||||
var schoolYears = App.Services.GetRequiredService<SchoolYearService>();
|
||||
var start = row.Kind == UntisHubJobKind.FehlzeitenKurz
|
||||
? today.AddDays(-30)
|
||||
: schoolYears.SchoolYearStart(schoolYears.CurrentSchoolYear());
|
||||
await UntisHubActions.RunFehlzeitenAsync(this, group, row.Kind, start, today, hub);
|
||||
break;
|
||||
case UntisHubJobKind.OffenePeriods:
|
||||
await UntisHubActions.RunOffenePeriodsAsync(this, hub);
|
||||
break;
|
||||
case UntisHubJobKind.Klassenbuchabgleich:
|
||||
await UntisHubActions.RunKlassenbuchAsync(this, hub);
|
||||
break;
|
||||
case UntisHubJobKind.Hausaufgabenabgleich:
|
||||
await UntisHubActions.RunHausaufgabenAsync(this, hub);
|
||||
break;
|
||||
}
|
||||
vm.Load();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user