Mitarbeits Wizzard und neue Statuslabels für Anwesenheit und Hausaufgaben
This commit is contained in:
@@ -47,6 +47,7 @@ public partial class ParticipationTabViewModel : ObservableObject
|
||||
|
||||
public Func<Task<ParticipationSession?>>? OnAddSession { get; set; }
|
||||
public Func<ParticipationTabViewModel, Task>? OnQuickInput { get; set; }
|
||||
public Func<ParticipationTabViewModel, Task>? OnStatusQuickInput { get; set; }
|
||||
public Func<ParticipationTabViewModel, Task>? OnComputeGrade { get; set; }
|
||||
public Func<ParticipationTabViewModel, Task>? OnOpenWizard { get; set; }
|
||||
|
||||
@@ -119,6 +120,7 @@ public partial class ParticipationTabViewModel : ObservableObject
|
||||
CompetencyTagGroups.Clear();
|
||||
ActiveCompetencyCodes = [];
|
||||
QuickInputCommand.NotifyCanExecuteChanged();
|
||||
StatusQuickInputCommand.NotifyCanExecuteChanged();
|
||||
RebuildColumnsSignal++;
|
||||
return;
|
||||
}
|
||||
@@ -151,6 +153,7 @@ public partial class ParticipationTabViewModel : ObservableObject
|
||||
StudentRows.Add(row);
|
||||
}
|
||||
QuickInputCommand.NotifyCanExecuteChanged();
|
||||
StatusQuickInputCommand.NotifyCanExecuteChanged();
|
||||
RebuildColumnsSignal++;
|
||||
}
|
||||
|
||||
@@ -190,11 +193,12 @@ public partial class ParticipationTabViewModel : ObservableObject
|
||||
if (SelectedSession is not null) LoadGrid(SelectedSession.Id);
|
||||
}
|
||||
|
||||
private void SaveHomework(Guid sessionId, Guid studentId, bool value)
|
||||
private void SaveHomework(Guid sessionId, Guid studentId, HomeworkStatus? value)
|
||||
{
|
||||
var entry = _entries.GetBySessionAndStudent(sessionId, studentId)
|
||||
?? new ParticipationEntry { SessionId = sessionId, StudentId = studentId };
|
||||
entry.HomeworkMissing = value;
|
||||
entry.Homework = value;
|
||||
entry.HomeworkMissing = HomeworkDisplay.CountsAsMissing(value);
|
||||
_entries.Save(entry);
|
||||
}
|
||||
|
||||
@@ -273,6 +277,14 @@ public partial class ParticipationTabViewModel : ObservableObject
|
||||
|
||||
private bool CanQuickInput() => SelectedSession is not null && StudentRows.Count > 0;
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanQuickInput))]
|
||||
private async Task StatusQuickInput()
|
||||
{
|
||||
if (OnStatusQuickInput is null) return;
|
||||
await OnStatusQuickInput(this);
|
||||
if (SelectedSession is not null) LoadGrid(SelectedSession.Id);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task ComputeGrade()
|
||||
{
|
||||
@@ -338,15 +350,17 @@ public partial class ParticipationStudentRow : ObservableObject
|
||||
public ObservableCollection<RatingCell> Cells { get; } = [];
|
||||
public ObservableCollection<RatingCell> CompetencyCells { get; } = [];
|
||||
|
||||
[ObservableProperty] private bool _homeworkMissing;
|
||||
[ObservableProperty] private HomeworkStatus? _homework;
|
||||
[ObservableProperty] private AttendanceStatus? _attendance;
|
||||
|
||||
public string AttendanceLabel => AttendanceDisplay.ShortLabel(Attendance);
|
||||
public string AttendanceTooltip => AttendanceDisplay.Label(Attendance);
|
||||
public string HomeworkSymbol => HomeworkDisplay.Symbol(Homework);
|
||||
public string HomeworkTooltip => HomeworkDisplay.Label(Homework);
|
||||
|
||||
public Action<Guid, string, int?>? OnRatingChanged { get; set; }
|
||||
public Action<Guid, string, int?>? OnCompetencyRatingChanged { get; set; }
|
||||
public Action<Guid, bool>? HomeworkChangedCallback { get; set; }
|
||||
public Action<Guid, HomeworkStatus?>? HomeworkChangedCallback { get; set; }
|
||||
public Action<Guid, AttendanceStatus?>? AttendanceChangedCallback { get; set; }
|
||||
|
||||
public ParticipationStudentRow(Guid id, string name, ParticipationEntry entry,
|
||||
@@ -356,7 +370,7 @@ public partial class ParticipationStudentRow : ObservableObject
|
||||
Name = name;
|
||||
_entry = entry;
|
||||
_aspectDefs = aspects;
|
||||
_homeworkMissing = entry.HomeworkMissing;
|
||||
_homework = HomeworkDisplay.Effective(entry);
|
||||
_attendance = entry.Attendance;
|
||||
|
||||
foreach (var a in aspects)
|
||||
@@ -389,8 +403,18 @@ public partial class ParticipationStudentRow : ObservableObject
|
||||
[RelayCommand]
|
||||
private void ToggleHomework()
|
||||
{
|
||||
HomeworkMissing = !HomeworkMissing;
|
||||
HomeworkChangedCallback?.Invoke(StudentId, HomeworkMissing);
|
||||
Homework = HomeworkDisplay.Next(Homework);
|
||||
OnPropertyChanged(nameof(HomeworkSymbol));
|
||||
OnPropertyChanged(nameof(HomeworkTooltip));
|
||||
HomeworkChangedCallback?.Invoke(StudentId, Homework);
|
||||
}
|
||||
|
||||
public void SetHomework(HomeworkStatus? value)
|
||||
{
|
||||
Homework = value;
|
||||
OnPropertyChanged(nameof(HomeworkSymbol));
|
||||
OnPropertyChanged(nameof(HomeworkTooltip));
|
||||
HomeworkChangedCallback?.Invoke(StudentId, value);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
@@ -398,11 +422,14 @@ public partial class ParticipationStudentRow : ObservableObject
|
||||
{
|
||||
Attendance = Attendance switch
|
||||
{
|
||||
null => AttendanceStatus.ExcusePending,
|
||||
AttendanceStatus.ExcusePending => AttendanceStatus.Excused,
|
||||
AttendanceStatus.Excused => AttendanceStatus.Unexcused,
|
||||
AttendanceStatus.Unexcused => null,
|
||||
_ => null,
|
||||
null => AttendanceStatus.Present,
|
||||
AttendanceStatus.Present => AttendanceStatus.ExcusePending,
|
||||
AttendanceStatus.ExcusePending => AttendanceStatus.Excused,
|
||||
AttendanceStatus.Excused => AttendanceStatus.Unexcused,
|
||||
AttendanceStatus.Unexcused => AttendanceStatus.Truant,
|
||||
AttendanceStatus.Truant => AttendanceStatus.OtherSchoolEvent,
|
||||
AttendanceStatus.OtherSchoolEvent => null,
|
||||
_ => null,
|
||||
};
|
||||
OnPropertyChanged(nameof(AttendanceLabel));
|
||||
OnPropertyChanged(nameof(AttendanceTooltip));
|
||||
@@ -419,27 +446,109 @@ public partial class ParticipationStudentRow : ObservableObject
|
||||
}
|
||||
}
|
||||
|
||||
// ── Hausaufgaben-Anzeige ─────────────────────────────────────────────────────
|
||||
|
||||
public static class HomeworkDisplay
|
||||
{
|
||||
public static HomeworkStatus? Effective(ParticipationEntry entry) =>
|
||||
entry.Homework ?? (entry.HomeworkMissing ? HomeworkStatus.MissingOpen : null);
|
||||
|
||||
public static HomeworkStatus? Next(HomeworkStatus? status) => status switch
|
||||
{
|
||||
null => HomeworkStatus.Completed,
|
||||
HomeworkStatus.Completed => HomeworkStatus.PartiallyCompleted,
|
||||
HomeworkStatus.PartiallyCompleted => HomeworkStatus.PartialSubmittedLate,
|
||||
HomeworkStatus.PartialSubmittedLate => HomeworkStatus.PartialMissingOverdue,
|
||||
HomeworkStatus.PartialMissingOverdue => HomeworkStatus.MissingOpen,
|
||||
HomeworkStatus.MissingOpen => HomeworkStatus.MissingOverdue,
|
||||
HomeworkStatus.MissingOverdue => HomeworkStatus.SubmittedLate,
|
||||
HomeworkStatus.SubmittedLate => null,
|
||||
_ => null,
|
||||
};
|
||||
|
||||
public static string Label(HomeworkStatus? status) => status switch
|
||||
{
|
||||
null => "Keine Hausaufgabe erfasst",
|
||||
HomeworkStatus.Completed => "Hausaufgabe gemacht",
|
||||
HomeworkStatus.PartiallyCompleted => "Teilweise angefertigt – Rest offen",
|
||||
HomeworkStatus.PartialSubmittedLate => "Teilweise angefertigt – Rest nachgereicht",
|
||||
HomeworkStatus.PartialMissingOverdue => "Teilweise angefertigt – Rest nicht nachgereicht",
|
||||
HomeworkStatus.MissingOpen => "Nicht gemacht – Nachreichen offen",
|
||||
HomeworkStatus.MissingOverdue => "Nicht gemacht – nicht mehr nachgereicht",
|
||||
HomeworkStatus.SubmittedLate => "Hausaufgabe nachgereicht",
|
||||
_ => "Keine Hausaufgabe erfasst",
|
||||
};
|
||||
|
||||
public static string Symbol(HomeworkStatus? status) => status switch
|
||||
{
|
||||
null => "·",
|
||||
HomeworkStatus.Completed => "✓",
|
||||
HomeworkStatus.PartiallyCompleted => "◐",
|
||||
HomeworkStatus.PartialSubmittedLate => "◕",
|
||||
HomeworkStatus.PartialMissingOverdue => "◒",
|
||||
HomeworkStatus.MissingOpen => "!",
|
||||
HomeworkStatus.MissingOverdue => "✕",
|
||||
HomeworkStatus.SubmittedLate => "↺",
|
||||
_ => "·",
|
||||
};
|
||||
|
||||
public static string Color(HomeworkStatus? status) => status switch
|
||||
{
|
||||
HomeworkStatus.Completed => "#2E9D57",
|
||||
HomeworkStatus.PartiallyCompleted => "#D98200",
|
||||
HomeworkStatus.PartialSubmittedLate => "#7F77DD",
|
||||
HomeworkStatus.PartialMissingOverdue => "#D64545",
|
||||
HomeworkStatus.MissingOpen => "#D98200",
|
||||
HomeworkStatus.MissingOverdue => "#D64545",
|
||||
HomeworkStatus.SubmittedLate => "#7F77DD",
|
||||
_ => "",
|
||||
};
|
||||
|
||||
public static bool CountsAsMissing(HomeworkStatus? status) => status is
|
||||
HomeworkStatus.MissingOpen or
|
||||
HomeworkStatus.MissingOverdue or
|
||||
HomeworkStatus.PartiallyCompleted or
|
||||
HomeworkStatus.PartialMissingOverdue;
|
||||
}
|
||||
|
||||
// ── Anwesenheits-Anzeige ──────────────────────────────────────────────────────
|
||||
|
||||
public static class AttendanceDisplay
|
||||
{
|
||||
public static string Label(AttendanceStatus? s) => s switch
|
||||
{
|
||||
null => "Anwesend",
|
||||
null => "Noch nicht kontrolliert",
|
||||
AttendanceStatus.Present => "Anwesend",
|
||||
AttendanceStatus.ExcusePending => "Krank (Entschuldigung offen)",
|
||||
AttendanceStatus.Excused => "Krank, entschuldigt",
|
||||
AttendanceStatus.Unexcused => "Krank, unentschuldigt",
|
||||
AttendanceStatus.Truant => "Geschwänzt",
|
||||
AttendanceStatus.OtherSchoolEvent => "Andere Schulveranstaltung",
|
||||
_ => "Anwesend",
|
||||
};
|
||||
|
||||
public static string ShortLabel(AttendanceStatus? s) => s switch
|
||||
{
|
||||
null => "",
|
||||
AttendanceStatus.ExcusePending => "K ?",
|
||||
AttendanceStatus.Excused => "K ✓",
|
||||
AttendanceStatus.Unexcused => "K ✗",
|
||||
AttendanceStatus.Present => "✓",
|
||||
AttendanceStatus.ExcusePending => "?",
|
||||
AttendanceStatus.Excused => "⊘",
|
||||
AttendanceStatus.Unexcused => "!",
|
||||
AttendanceStatus.Truant => "✕",
|
||||
AttendanceStatus.OtherSchoolEvent => "◇",
|
||||
_ => "",
|
||||
};
|
||||
|
||||
public static string Color(AttendanceStatus? s) => s switch
|
||||
{
|
||||
AttendanceStatus.Present => "#2E9D57",
|
||||
AttendanceStatus.ExcusePending => "#D98200",
|
||||
AttendanceStatus.Excused => "#4C86A8",
|
||||
AttendanceStatus.Unexcused => "#D96C00",
|
||||
AttendanceStatus.Truant => "#D64545",
|
||||
AttendanceStatus.OtherSchoolEvent => "#5277C3",
|
||||
_ => "",
|
||||
};
|
||||
}
|
||||
|
||||
// ── Eine Bewertungszelle ──────────────────────────────────────────────────────
|
||||
@@ -731,3 +840,48 @@ public partial class QuickAspectRow : ObservableObject
|
||||
2 => "++", 1 => "+", 0 => "~", -1 => "−", -2 => "−−", _ => "·",
|
||||
};
|
||||
}
|
||||
|
||||
// ── Schnelleingabe Anwesenheit / Hausaufgaben ────────────────────────────────
|
||||
|
||||
public partial class AttendanceHomeworkQuickInputViewModel : ObservableObject
|
||||
{
|
||||
public List<ParticipationStudentRow> Rows { get; }
|
||||
public string SessionLabel { get; }
|
||||
|
||||
[ObservableProperty] private ParticipationStudentRow? _selectedRow;
|
||||
[ObservableProperty] private bool _advanceAfterInput = true;
|
||||
|
||||
public AttendanceHomeworkQuickInputViewModel(
|
||||
IEnumerable<ParticipationStudentRow> rows, string sessionLabel)
|
||||
{
|
||||
Rows = rows.ToList();
|
||||
SessionLabel = sessionLabel;
|
||||
SelectedRow = Rows.FirstOrDefault();
|
||||
}
|
||||
|
||||
public void ApplyAttendance(ParticipationStudentRow row, AttendanceStatus? status)
|
||||
{
|
||||
SelectedRow = row;
|
||||
row.SetAttendance(status);
|
||||
AdvanceIfRequested();
|
||||
}
|
||||
|
||||
public void ApplyHomework(ParticipationStudentRow row, HomeworkStatus? status)
|
||||
{
|
||||
SelectedRow = row;
|
||||
row.SetHomework(status);
|
||||
AdvanceIfRequested();
|
||||
}
|
||||
|
||||
public void MoveSelection(int delta)
|
||||
{
|
||||
if (Rows.Count == 0) return;
|
||||
var current = SelectedRow is null ? 0 : Rows.IndexOf(SelectedRow);
|
||||
SelectedRow = Rows[Math.Clamp(current + delta, 0, Rows.Count - 1)];
|
||||
}
|
||||
|
||||
private void AdvanceIfRequested()
|
||||
{
|
||||
if (AdvanceAfterInput) MoveSelection(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,15 @@ public partial class ParticipationWizardDialogViewModel : ObservableObject
|
||||
[ObservableProperty] private string _sectionValidationMessage = "";
|
||||
[ObservableProperty] private ParticipationPeriodOption _rollupPeriod;
|
||||
[ObservableProperty] private string _rollupStatusMessage = "";
|
||||
[ObservableProperty] private double _timelineZoom = 1.0;
|
||||
[ObservableProperty] private bool _showQuality = true;
|
||||
[ObservableProperty] private bool _showQuantity = true;
|
||||
[ObservableProperty] private bool _showWorkphase = true;
|
||||
[ObservableProperty] private bool _showDataPoints = true;
|
||||
[ObservableProperty] private bool _showWeightedTrend = true;
|
||||
[ObservableProperty] private bool _showQualityTrend;
|
||||
[ObservableProperty] private bool _showQuantityTrend;
|
||||
[ObservableProperty] private bool _showWorkphaseTrend;
|
||||
|
||||
public List<ParticipationPeriodOption> RollupPeriodOptions { get; } =
|
||||
[
|
||||
@@ -68,8 +77,10 @@ public partial class ParticipationWizardDialogViewModel : ObservableObject
|
||||
_groupId = groupId; _schoolYear = schoolYear; _gradingSystem = gradingSystem;
|
||||
GroupLabel = groupLabel;
|
||||
|
||||
_aspectWeights = aspects.GetDefaults().Concat(aspects.GetByGroup(groupId))
|
||||
.ToDictionary(a => a.Key, a => a.Weight);
|
||||
_aspectWeights = aspects.GetDefaults()
|
||||
.Concat(aspects.GetByGroup(groupId))
|
||||
.GroupBy(a => a.Key)
|
||||
.ToDictionary(g => g.Key, g => g.Last().Weight);
|
||||
_students = students.GetByGroup(groupId).OrderBy(s => s.LastName).ThenBy(s => s.FirstName).ToList();
|
||||
_allSessions = sessions.GetByGroup(groupId).OrderBy(s => s.Date).ToList();
|
||||
_sectionList = sectionRepo.GetByGroup(groupId).OrderBy(s => s.StartDate).ToList();
|
||||
@@ -120,6 +131,11 @@ public partial class ParticipationWizardDialogViewModel : ObservableObject
|
||||
if (result is null) continue;
|
||||
points.Add((exam.Date, BuildExamPoint(exam, result)));
|
||||
}
|
||||
foreach (var grade in _grades.GetByStudentAndGroup(studentId, _groupId)
|
||||
.Where(g => g.Category != GradeCategory.Participation))
|
||||
{
|
||||
points.Add((grade.Date, BuildOtherGradePoint(grade)));
|
||||
}
|
||||
points = points.OrderBy(p => p.Date).ToList();
|
||||
|
||||
Timeline.Clear();
|
||||
@@ -140,7 +156,8 @@ public partial class ParticipationWizardDialogViewModel : ObservableObject
|
||||
|
||||
private WizardTimelinePoint BuildSessionPoint(ParticipationSession session, ParticipationEntry? entry, Guid studentId)
|
||||
{
|
||||
var ratingLabel = entry is not null ? WeightedRatingLabel(entry) : "";
|
||||
var weightedValue = entry is not null ? WeightedRating(entry) : null;
|
||||
var ratingLabel = weightedValue is not null ? RatingLabel((int)Math.Round(weightedValue.Value, MidpointRounding.AwayFromZero)) : "";
|
||||
var note = entry?.Note;
|
||||
var tooltip = $"{session.Date:dd.MM.yyyy}" +
|
||||
(ratingLabel.Length > 0 ? $" · {ratingLabel}" : "") +
|
||||
@@ -149,9 +166,14 @@ public partial class ParticipationWizardDialogViewModel : ObservableObject
|
||||
var point = new WizardTimelinePoint(session.Date, isExam: false, ratingLabel, examLabel: "",
|
||||
hasNote: !string.IsNullOrWhiteSpace(note), tooltip: tooltip)
|
||||
{
|
||||
HasHomework = entry?.HomeworkMissing ?? false,
|
||||
Homework = entry is null ? null : HomeworkDisplay.Effective(entry),
|
||||
AttendanceIcon = AttendanceDisplay.ShortLabel(entry?.Attendance),
|
||||
AttendanceTooltip = AttendanceDisplay.Label(entry?.Attendance),
|
||||
AttendanceColor = AttendanceDisplay.Color(entry?.Attendance),
|
||||
AspectValues = entry?.Ratings.ToDictionary(r => r.Key, r => r.Value)
|
||||
?? new Dictionary<string, int>(),
|
||||
WeightedValue = weightedValue,
|
||||
OverallGrade = weightedValue is null ? "" : _grading.ParticipationGrade(weightedValue.Value, _gradingSystem),
|
||||
};
|
||||
point.ToggleHomeworkCommand = new RelayCommand(() => ToggleHomeworkAt(session.Id, studentId, point));
|
||||
point.CycleAttendanceCommand = new RelayCommand(() => CycleAttendanceAt(session.Id, studentId, point));
|
||||
@@ -165,9 +187,24 @@ public partial class ParticipationWizardDialogViewModel : ObservableObject
|
||||
hasNote: false, tooltip: $"{exam.Date:dd.MM.yyyy} · Klausur {examLabel}");
|
||||
}
|
||||
|
||||
private string WeightedRatingLabel(ParticipationEntry entry)
|
||||
private static WizardTimelinePoint BuildOtherGradePoint(Grade grade)
|
||||
{
|
||||
if (entry.Ratings.Count == 0) return "";
|
||||
var category = grade.Category switch
|
||||
{
|
||||
GradeCategory.Oral => "Mündlich",
|
||||
GradeCategory.Homework => "Hausaufgabe",
|
||||
GradeCategory.Project => "Projekt",
|
||||
_ => "Sonstige Leistung",
|
||||
};
|
||||
var detail = string.IsNullOrWhiteSpace(grade.Note) ? category : grade.Note.Trim();
|
||||
var label = $"{detail}: {grade.Value}";
|
||||
return new WizardTimelinePoint(grade.Date, isExam: true, ratingLabel: "", examLabel: label,
|
||||
hasNote: false, tooltip: $"{grade.Date:dd.MM.yyyy} · {category} · {label}");
|
||||
}
|
||||
|
||||
private double? WeightedRating(ParticipationEntry entry)
|
||||
{
|
||||
if (entry.Ratings.Count == 0) return null;
|
||||
var weightSum = 0.0; var valueSum = 0.0;
|
||||
foreach (var r in entry.Ratings)
|
||||
{
|
||||
@@ -175,8 +212,7 @@ public partial class ParticipationWizardDialogViewModel : ObservableObject
|
||||
if (w <= 0) continue;
|
||||
valueSum += r.Value * w; weightSum += w;
|
||||
}
|
||||
if (weightSum <= 0) return "";
|
||||
return RatingLabel((int)Math.Round(valueSum / weightSum, MidpointRounding.AwayFromZero));
|
||||
return weightSum <= 0 ? null : valueSum / weightSum;
|
||||
}
|
||||
|
||||
private static string RatingLabel(int v) => v switch
|
||||
@@ -188,9 +224,10 @@ public partial class ParticipationWizardDialogViewModel : ObservableObject
|
||||
{
|
||||
var entry = _entries.GetBySessionAndStudent(sessionId, studentId)
|
||||
?? new ParticipationEntry { SessionId = sessionId, StudentId = studentId };
|
||||
entry.HomeworkMissing = !entry.HomeworkMissing;
|
||||
entry.Homework = HomeworkDisplay.Next(HomeworkDisplay.Effective(entry));
|
||||
entry.HomeworkMissing = HomeworkDisplay.CountsAsMissing(entry.Homework);
|
||||
_entries.Save(entry);
|
||||
point.HasHomework = entry.HomeworkMissing;
|
||||
point.Homework = entry.Homework;
|
||||
}
|
||||
|
||||
private void CycleAttendanceAt(Guid sessionId, Guid studentId, WizardTimelinePoint point)
|
||||
@@ -199,15 +236,21 @@ public partial class ParticipationWizardDialogViewModel : ObservableObject
|
||||
?? new ParticipationEntry { SessionId = sessionId, StudentId = studentId };
|
||||
entry.Attendance = entry.Attendance switch
|
||||
{
|
||||
null => AttendanceStatus.ExcusePending,
|
||||
AttendanceStatus.ExcusePending => AttendanceStatus.Excused,
|
||||
AttendanceStatus.Excused => AttendanceStatus.Unexcused,
|
||||
AttendanceStatus.Unexcused => null,
|
||||
_ => null,
|
||||
null => AttendanceStatus.Present,
|
||||
AttendanceStatus.Present => AttendanceStatus.ExcusePending,
|
||||
AttendanceStatus.ExcusePending => AttendanceStatus.Excused,
|
||||
AttendanceStatus.Excused => AttendanceStatus.Unexcused,
|
||||
AttendanceStatus.Unexcused => AttendanceStatus.Truant,
|
||||
AttendanceStatus.Truant => AttendanceStatus.OtherSchoolEvent,
|
||||
AttendanceStatus.OtherSchoolEvent => null,
|
||||
_ => null,
|
||||
};
|
||||
_entries.Save(entry);
|
||||
point.AttendanceIcon = AttendanceDisplay.ShortLabel(entry.Attendance);
|
||||
// Das Setzen jeder ObservableProperty kann unmittelbar ein Neuzeichnen auslösen.
|
||||
// Deshalb muss die zum aktiven Symbol gehörende Farbe zuerst bereitstehen.
|
||||
point.AttendanceColor = AttendanceDisplay.Color(entry.Attendance);
|
||||
point.AttendanceTooltip = AttendanceDisplay.Label(entry.Attendance);
|
||||
point.AttendanceIcon = AttendanceDisplay.ShortLabel(entry.Attendance);
|
||||
}
|
||||
|
||||
// ── Abschnitte ────────────────────────────────────────────────────────────
|
||||
@@ -364,19 +407,36 @@ public class WizardSectionGroup(string bandLabel, bool isOpen)
|
||||
|
||||
public partial class WizardTimelinePoint : ObservableObject
|
||||
{
|
||||
public DateOnly Date { get; }
|
||||
public string DateDisplay { get; }
|
||||
public bool IsExam { get; }
|
||||
public string RatingLabel { get; }
|
||||
public string ExamLabel { get; }
|
||||
public bool HasNote { get; }
|
||||
public string TooltipText { get; }
|
||||
public IReadOnlyDictionary<string, int> AspectValues { get; init; } = new Dictionary<string, int>();
|
||||
public double? WeightedValue { get; init; }
|
||||
public string OverallGrade { get; init; } = "";
|
||||
|
||||
[ObservableProperty] private bool _hasHomework;
|
||||
[ObservableProperty] private HomeworkStatus? _homework;
|
||||
[ObservableProperty] private string _attendanceIcon = "";
|
||||
[ObservableProperty] private string _attendanceTooltip = "Anwesend";
|
||||
[ObservableProperty] private string _attendanceColor = "";
|
||||
|
||||
public bool IsAbsent => AttendanceIcon.Length > 0;
|
||||
public string AttendanceButtonLabel => AttendanceIcon.Length > 0 ? AttendanceIcon : "Anw";
|
||||
public string AttendanceButtonLabel => AttendanceIcon.Length > 0 ? AttendanceIcon : "·";
|
||||
public bool HasHomeworkStatus => Homework is not null;
|
||||
public string HomeworkSymbol => HomeworkDisplay.Symbol(Homework);
|
||||
public string HomeworkTooltip => HomeworkDisplay.Label(Homework);
|
||||
public string HomeworkColor => HomeworkDisplay.Color(Homework);
|
||||
|
||||
partial void OnHomeworkChanged(HomeworkStatus? value)
|
||||
{
|
||||
OnPropertyChanged(nameof(HasHomeworkStatus));
|
||||
OnPropertyChanged(nameof(HomeworkSymbol));
|
||||
OnPropertyChanged(nameof(HomeworkTooltip));
|
||||
OnPropertyChanged(nameof(HomeworkColor));
|
||||
}
|
||||
|
||||
partial void OnAttendanceIconChanged(string value)
|
||||
{
|
||||
@@ -390,6 +450,7 @@ public partial class WizardTimelinePoint : ObservableObject
|
||||
public WizardTimelinePoint(DateOnly date, bool isExam, string ratingLabel, string examLabel,
|
||||
bool hasNote, string tooltip)
|
||||
{
|
||||
Date = date;
|
||||
DateDisplay = date.ToString("dd.MM.", CultureInfo.InvariantCulture);
|
||||
IsExam = isExam;
|
||||
RatingLabel = ratingLabel;
|
||||
|
||||
Reference in New Issue
Block a user