Gesamtbild: konfigurierbare Gewichtung, Dämpfung nach Vorgang, Rückfall-Warnung
CI / build-and-test (push) Canceled after 0s

Feste Score-Gewichte durch einen Einstellungsdialog ersetzt. Ein
geschlossener Vorgang dämpft ab seinem Schließ-Datum den zu seinen
Schlagwörtern passenden Score-Bereich (Anwesenheit/Verspätung/
Klassenbuch), ohne Schlagwort-Treffer vorsichtshalber alle drei — die
faktische Fehlquote bleibt davon unberührt. Verschlechtert sich die Lage
danach wieder spürbar, erscheint eine "erneut auffällig"-Warnung im
bestehenden "Muster erkannt"-Panel.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-01 23:52:38 +02:00
co-authored by Claude Sonnet 5
parent 0d5fb6d146
commit 216708e879
10 changed files with 543 additions and 36 deletions
@@ -227,7 +227,7 @@
<Border Grid.Row="0" Background="{DynamicResource AppCardBackgroundBrush}"
BorderBrush="{DynamicResource AppCardBorderBrush}" BorderThickness="1"
CornerRadius="8" Padding="8" Margin="0,0,0,4">
<Grid ColumnDefinitions="Auto,Auto,Auto,Auto,*,250" ColumnSpacing="8">
<Grid ColumnDefinitions="Auto,Auto,Auto,Auto,Auto,*,250" ColumnSpacing="8">
<Button Grid.Column="0" Classes="filter" Classes.active="{Binding AlertsFilterSelected}"
Content="Auffällig" Command="{Binding ShowAlertsCommand}"/>
<Button Grid.Column="1" Classes="filter" Classes.active="{Binding ClassRegisterFilterSelected}"
@@ -243,7 +243,10 @@
<Button Grid.Column="3" Classes="filter" Classes.active="{Binding PatternScoreFilterSelected}"
Content="Gesamtbild" Command="{Binding ShowPatternScoreCommand}"
ToolTip.Tip="Sortiert nach Auffälligkeits-Score seit Schuljahresbeginn (unentschuldigt zählt am stärksten, Verspätung am wenigsten) statt nur nach dem heutigen Status."/>
<TextBox Grid.Column="5" Text="{Binding SearchText, Mode=TwoWay}" PlaceholderText="Schüler*in suchen…"
<Button Grid.Column="4" Content="⚙ Gewichtung" FontSize="12" Padding="10,4"
Background="Transparent" Click="OnEditPatternScoreWeights"
ToolTip.Tip="Legt fest, wie stark einzelne Ereignisse in den Auffälligkeits-Score der 'Gesamtbild'-Sortierung einfließen."/>
<TextBox Grid.Column="6" Text="{Binding SearchText, Mode=TwoWay}" PlaceholderText="Schüler*in suchen…"
FontSize="12" MinHeight="32"/>
</Grid>
</Border>
@@ -1,8 +1,26 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
using LehrerApp.Core.Services;
using LehrerApp.Desktop.ViewModels.ClassTeacher;
using Microsoft.Extensions.DependencyInjection;
namespace LehrerApp.Desktop.Views.ClassTeacher;
public partial class ClassTeacherOverviewView : UserControl
{
public ClassTeacherOverviewView() => InitializeComponent();
private async void OnEditPatternScoreWeights(object? sender, RoutedEventArgs e)
{
var owner = TopLevel.GetTopLevel(this) as Window;
if (owner is null) return;
var vm = new PatternScoreWeightsDialogViewModel(App.Services.GetRequiredService<PatternScoreSettingsService>());
var dialog = new PatternScoreWeightsDialog { DataContext = vm };
await dialog.ShowDialog(owner);
// Neue Gewichtung soll sofort in der "Gesamtbild"-Sortierung wirken, nicht erst beim
// nächsten manuellen Aktualisieren.
if (DataContext is ClassTeacherOverviewViewModel overviewVm) overviewVm.LoadCommand.Execute(null);
}
}
@@ -0,0 +1,48 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels.ClassTeacher"
x:Class="LehrerApp.Desktop.Views.ClassTeacher.PatternScoreWeightsDialog"
x:DataType="vm:PatternScoreWeightsDialogViewModel"
Title="Gewichtung „Gesamtbild&#8220;"
Width="440" SizeToContent="Height" MinHeight="300"
CanResize="True" WindowStartupLocation="CenterOwner">
<Grid RowDefinitions="*,Auto" Margin="24">
<StackPanel Grid.Row="0" Spacing="12">
<TextBlock Text="Gewichtung „Gesamtbild&#8220;" Classes="dialogtitle"/>
<TextBlock TextWrapping="Wrap" FontSize="12" Opacity="0.6"
Text="Bestimmt, wie stark einzelne Ereignisse in den Auffälligkeits-Score einfließen, nach dem der „Gesamtbild&#8220;-Reiter sortiert. Wirkt erst nach erneutem Laden der Übersicht."/>
<Grid ColumnDefinitions="*,110" RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto" RowSpacing="10">
<TextBlock Grid.Row="0" Grid.Column="0" Text="Unentschuldigt (pro Tag)" VerticalAlignment="Center"/>
<NumericUpDown Grid.Row="0" Grid.Column="1" Value="{Binding UnexcusedDayWeight}"
Minimum="0" Maximum="50" FormatString="0.0" Increment="0.1" ShowButtonSpinner="False"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Entschuldigt abwesend (pro Tag)" VerticalAlignment="Center"/>
<NumericUpDown Grid.Row="1" Grid.Column="1" Value="{Binding ExcusedDayWeight}"
Minimum="0" Maximum="50" FormatString="0.0" Increment="0.1" ShowButtonSpinner="False"/>
<TextBlock Grid.Row="2" Grid.Column="0" Text="Nur verspätet (pro Tag)" VerticalAlignment="Center"/>
<NumericUpDown Grid.Row="2" Grid.Column="1" Value="{Binding LateDayWeight}"
Minimum="0" Maximum="50" FormatString="0.0" Increment="0.1" ShowButtonSpinner="False"/>
<TextBlock Grid.Row="3" Grid.Column="0" Text="Negativer Klassenbucheintrag" VerticalAlignment="Center"
TextWrapping="Wrap"/>
<NumericUpDown Grid.Row="3" Grid.Column="1" Value="{Binding NegativeClassRegisterEntryWeight}"
Minimum="0" Maximum="50" FormatString="0.0" Increment="0.1" ShowButtonSpinner="False"/>
<TextBlock Grid.Row="4" Grid.Column="0" Text="+ Hausaufgaben-/Mitarbeit-Schlüsselwort" VerticalAlignment="Center"
TextWrapping="Wrap"/>
<NumericUpDown Grid.Row="4" Grid.Column="1" Value="{Binding ConcerningKeywordBonus}"
Minimum="0" Maximum="50" FormatString="0.0" Increment="0.1" ShowButtonSpinner="False"/>
<TextBlock Grid.Row="5" Grid.Column="0" Text="+ „Suspendiert&#8220;-Schlüsselwort" VerticalAlignment="Center"
TextWrapping="Wrap"/>
<NumericUpDown Grid.Row="5" Grid.Column="1" Value="{Binding SuspensionKeywordWeight}"
Minimum="0" Maximum="100" FormatString="0.0" Increment="0.5" ShowButtonSpinner="False"/>
</Grid>
</StackPanel>
<Button Grid.Row="1" Content="Fertig" HorizontalAlignment="Right" Margin="0,20,0,0" Click="OnClose"/>
</Grid>
</Window>
@@ -0,0 +1,16 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
using LehrerApp.Desktop.ViewModels.ClassTeacher;
namespace LehrerApp.Desktop.Views.ClassTeacher;
public partial class PatternScoreWeightsDialog : Window
{
public PatternScoreWeightsDialog() => InitializeComponent();
private void OnClose(object? sender, RoutedEventArgs e)
{
if (DataContext is PatternScoreWeightsDialogViewModel vm) vm.SaveCommand.Execute(null);
Close();
}
}