Klassenlehrer-Tab: restliche Quick-Wins (responsive Balken, Tagesüberblick-Chart, Tooltips, Status-Symbol)
Balkenbreiten hingen bisher an einer im ViewModel hart codierten Pixelkonstante; Grid.ColumnDefinitions ließ sich dafür nicht binden (AVLN3000, kein Setter bei kompilierten Bindings), deshalb neuer FractionWidthConverter (MultiBinding gegen die gerenderte Breite einer Track-Border statt Grid-Sternspalten). Tagesüberblick zeigt jetzt denselben gestapelten Balken statt vier Einzelzeilen. AbsenceTooltip und TodayUnexcusedPercent waren berechnet aber ungebunden, jetzt sichtbar. Status-Zeilen bekommen zusätzlich zur Farbe ein vorangestelltes Symbol (Barrierefreiheit). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -224,11 +224,44 @@ public sealed class ClassTeacherViewModelsTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TrendDay_BalkenbreitenSummierenSichZurGesamtbreite()
|
||||
public void TrendDay_AnteileSummierenSichZurGesamtquote()
|
||||
{
|
||||
var day = new ClassTeacherTrendDay("Mo", 5, 2, 1, 2, 40d, 20d, 40d);
|
||||
var day = new ClassTeacherTrendDay("Mo", 5, 2, 1, 2, 0.4d, 0.2d, 0.4d);
|
||||
|
||||
Assert.Equal(100d, day.TotalBarWidth);
|
||||
Assert.Equal(1.0d, day.TotalFraction, precision: 10);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RosterBuild_StelltGefahrUndWarnungMitSymbolVoran()
|
||||
{
|
||||
var students = new[] { Student(1001, "Ada Müller"), Student(1002, "Ben Schmidt") };
|
||||
var todayAbsences = new[]
|
||||
{
|
||||
new ClassAbsenceDaySummaryRow(new DateOnly(2026, 8, 26), "Müller Ada", 1001, 2, 90,
|
||||
["Che"], [1, 2], ["nicht entsch."], ["Absent"], null, null, false),
|
||||
new ClassAbsenceDaySummaryRow(new DateOnly(2026, 8, 26), "Schmidt Ben", 1002, 2, 90,
|
||||
["Che"], [1, 2], ["entsch."], ["Absent"], null, null, false),
|
||||
};
|
||||
|
||||
var roster = ClassTeacherRosterRow.Build(students, todayAbsences, [], new DateOnly(2026, 8, 26));
|
||||
|
||||
var ada = Assert.Single(roster, r => r.StudentName == "Ada Müller");
|
||||
Assert.Equal(ClassTeacherStatusKind.Danger, ada.StatusKind);
|
||||
Assert.StartsWith("✕ ", ada.StatusTextWithGlyph);
|
||||
|
||||
var ben = Assert.Single(roster, r => r.StudentName == "Ben Schmidt");
|
||||
Assert.Equal(ClassTeacherStatusKind.Warning, ben.StatusKind);
|
||||
Assert.StartsWith("△ ", ben.StatusTextWithGlyph);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RosterBuild_LaesstUnauffaelligenStatusOhneSymbol()
|
||||
{
|
||||
var students = new[] { Student(1001, "Zora Unauffällig") };
|
||||
|
||||
var row = Assert.Single(ClassTeacherRosterRow.Build(students, [], [], new DateOnly(2026, 8, 26)));
|
||||
|
||||
Assert.Equal(row.StatusText, row.StatusTextWithGlyph);
|
||||
}
|
||||
|
||||
private static UntisStudentRosterCacheEntry Student(int? externKey, string displayName) =>
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Globalization;
|
||||
using LehrerApp.Desktop.Converters;
|
||||
using Xunit;
|
||||
|
||||
namespace LehrerApp.Desktop.Tests;
|
||||
|
||||
public sealed class FractionWidthConverterTests
|
||||
{
|
||||
[Fact]
|
||||
public void Convert_MultipliziertTrackbreiteMitAnteil()
|
||||
{
|
||||
var result = FractionWidthConverter.Instance.Convert(
|
||||
[200d, 0.25d], typeof(double), null, CultureInfo.InvariantCulture);
|
||||
|
||||
Assert.Equal(50d, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Convert_LiefertNullBreiteBeiUngueltigenWerten()
|
||||
{
|
||||
// Bounds.Width kann vor dem ersten Layout-Pass NaN sein (Element noch nicht gemessen) —
|
||||
// darf nicht zu einer negativen oder undefinierten Breite führen.
|
||||
Assert.Equal(0d, FractionWidthConverter.Instance.Convert(
|
||||
[double.NaN, 0.5d], typeof(double), null, CultureInfo.InvariantCulture));
|
||||
Assert.Equal(0d, FractionWidthConverter.Instance.Convert(
|
||||
["not a double", 0.5d], typeof(double), null, CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Convert_ClamptNegativeErgebnisseAufNull()
|
||||
{
|
||||
var result = FractionWidthConverter.Instance.Convert(
|
||||
[100d, -0.2d], typeof(double), null, CultureInfo.InvariantCulture);
|
||||
|
||||
Assert.Equal(0d, result);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user