diff --git a/LehrerApp.Desktop.Tests/ExamsOverviewViewModelTests.cs b/LehrerApp.Desktop.Tests/ExamsOverviewViewModelTests.cs
index 4238eba..88c40b8 100644
--- a/LehrerApp.Desktop.Tests/ExamsOverviewViewModelTests.cs
+++ b/LehrerApp.Desktop.Tests/ExamsOverviewViewModelTests.cs
@@ -29,6 +29,20 @@ public sealed class ExamsOverviewViewModelTests
Assert.Equal("Neue Klausur", vm.Rows[1].Title);
}
+ [Fact]
+ public void LeereListe_BietetAbsprungZuLerngruppen()
+ {
+ var vm = BuildVm([], []);
+ var navigated = false;
+ vm.OnNavigateToGroups = () => navigated = true;
+
+ vm.LoadCommand.Execute(null);
+ vm.GoToGroupsCommand.Execute(null);
+
+ Assert.True(vm.HasNoExams);
+ Assert.True(navigated);
+ }
+
[Fact]
public void Load_ParallelkurseWerdenAlsGeschwisterErkannt()
{
diff --git a/LehrerApp.Desktop.Tests/StudentListViewModelTests.cs b/LehrerApp.Desktop.Tests/StudentListViewModelTests.cs
index ca757eb..67a8edf 100644
--- a/LehrerApp.Desktop.Tests/StudentListViewModelTests.cs
+++ b/LehrerApp.Desktop.Tests/StudentListViewModelTests.cs
@@ -51,6 +51,18 @@ public class StudentListViewModelTests
Assert.Equal("M", vm.Students.Single(s => s.Id == _ben.Id).AvatarLabel);
}
+ [Fact]
+ public void SucheOhneTreffer_LiefertHilfreichenLeerzustand()
+ {
+ var vm = BuildViewModel();
+
+ vm.SearchText = "nicht vorhanden";
+
+ Assert.True(vm.HasNoStudents);
+ Assert.False(vm.HasStudents);
+ Assert.Contains("Suche", vm.EmptyListMessage);
+ }
+
private StudentListViewModel BuildViewModel() => new(
new FakeStudents([_anna, _ben]),
new FakeGroups([_group]),
diff --git a/LehrerApp.Desktop/App.axaml b/LehrerApp.Desktop/App.axaml
index 42534fa..f539bc8 100644
--- a/LehrerApp.Desktop/App.axaml
+++ b/LehrerApp.Desktop/App.axaml
@@ -7,6 +7,17 @@
+
+ M10,2 A8,8 0 1 0 10,18 A8,8 0 1 0 10,2 M10,5 A5,5 0 1 1 10,15 A5,5 0 1 1 10,5 M15,14 L22,21 L20,23 L13,16 Z
+ M3,3 H10 V10 H3 Z M14,3 H21 V7 H14 Z M14,11 H21 V21 H14 Z M3,14 H10 V21 H3 Z
+ M3,8 L12,3 L21,8 V10 H3 Z M5,11 H8 V18 H5 Z M10,11 H14 V18 H10 Z M16,11 H19 V18 H16 Z M3,20 H21 V22 H3 Z
+ M12,3 A4,4 0 1 0 12,11 A4,4 0 1 0 12,3 M4,21 C4,16 7,13 12,13 C17,13 20,16 20,21 Z
+ M5,2 H15 L20,7 V22 H5 Z M7,5 V19 H18 V9 H13 V4 H7 Z M9,11 H16 V13 H9 Z M9,15 H16 V17 H9 Z
+ M3,4 H21 V22 H3 Z M5,10 V20 H19 V10 Z M7,2 H9 V7 H7 Z M15,2 H17 V7 H15 Z M7,12 H10 V15 H7 Z M12,12 H15 V15 H12 Z M7,17 H10 V19 H7 Z M12,17 H15 V19 H12 Z
+ M12,2 A10,10 0 1 0 12,22 A10,10 0 1 0 12,2 M12,5 A7,7 0 1 1 12,19 A7,7 0 1 1 12,5 M11,7 H13 V12 L17,14 L16,16 L11,13 Z
+ M2,8 L12,3 L22,8 L12,13 Z M6,11 V16 C9,19 15,19 18,16 V11 M22,8 V15
+ M3,5 H21 V7 H3 Z M8,3 A3,3 0 1 0 8,9 A3,3 0 1 0 8,3 M3,11 H21 V13 H3 Z M16,9 A3,3 0 1 0 16,15 A3,3 0 1 0 16,9 M3,17 H21 V19 H3 Z M10,15 A3,3 0 1 0 10,21 A3,3 0 1 0 10,15
+ M12,3 A9,9 0 0 1 21,12 H18 A6,6 0 0 0 8,7 L11,10 H3 V2 L6,5 A9,9 0 0 1 12,3 M12,21 A9,9 0 0 1 3,12 H6 A6,6 0 0 0 16,17 L13,14 H21 V22 L18,19 A9,9 0 0 1 12,21
@@ -24,5 +35,17 @@
+
+
+
diff --git a/LehrerApp.Desktop/App.axaml.cs b/LehrerApp.Desktop/App.axaml.cs
index 2e4a200..fdf5c91 100644
--- a/LehrerApp.Desktop/App.axaml.cs
+++ b/LehrerApp.Desktop/App.axaml.cs
@@ -154,6 +154,9 @@ public class App : Application
dash.OnNavigateToExam = id => main.NavigateToGroupDetail(id, 4); // Tab "Klausuren"
dash.OnNavigateToUnplannedLesson = id => main.NavigateToGroupDetail(id, 6); // Tab "Planung"
+ var examsOverview = Services.GetRequiredService();
+ examsOverview.OnNavigateToGroups = () => main.NavigateToCommand.Execute(NavItem.Groups);
+
// Globale Suche/Schnellerfassung (14.2): Navigation bleibt im MainWindow-VM, die
// vorhandenen Dialog-Helfer übernehmen Eingabe und Validierung.
var search = Services.GetRequiredService();
diff --git a/LehrerApp.Desktop/ViewModels/Exams/ExamsOverviewViewModel.cs b/LehrerApp.Desktop/ViewModels/Exams/ExamsOverviewViewModel.cs
index 3b20bba..beeccba 100644
--- a/LehrerApp.Desktop/ViewModels/Exams/ExamsOverviewViewModel.cs
+++ b/LehrerApp.Desktop/ViewModels/Exams/ExamsOverviewViewModel.cs
@@ -43,6 +43,8 @@ public partial class ExamsOverviewViewModel : ObservableObject
public Func? OnGradeExam { get; set; }
public Func? OnEvaluateExam { get; set; }
public Action? OnNavigateToGroup { get; set; }
+ public Action? OnNavigateToGroups { get; set; }
+ public bool HasNoExams => Rows.Count == 0;
public ExamsOverviewViewModel(IExamRepository exams, IExamResultRepository examResults,
IGroupRepository groups, IGroupMembershipRepository memberships, GradingService grading,
@@ -85,6 +87,7 @@ public partial class ExamsOverviewViewModel : ObservableObject
Rows.Add(row);
EmptyHint = Rows.Count == 0 ? "Keine Klausuren angelegt." : "";
+ OnPropertyChanged(nameof(HasNoExams));
SelectedRow = selectedId is { } id
? Rows.FirstOrDefault(r => r.Exam.Id == id) ?? Rows.FirstOrDefault()
: Rows.FirstOrDefault();
@@ -173,6 +176,9 @@ public partial class ExamsOverviewViewModel : ObservableObject
OnNavigateToGroup?.Invoke(SelectedRow.GroupId);
}
+ [RelayCommand]
+ private void GoToGroups() => OnNavigateToGroups?.Invoke();
+
[RelayCommand]
private void ToggleApproval() => ToggleDate(SelectedRow?.Exam, e => e.ApprovalGrantedAt,
(e, v) => e.ApprovalGrantedAt = v);
diff --git a/LehrerApp.Desktop/ViewModels/Students/StudentViewModels.cs b/LehrerApp.Desktop/ViewModels/Students/StudentViewModels.cs
index 7b6df1d..b7dd4fb 100644
--- a/LehrerApp.Desktop/ViewModels/Students/StudentViewModels.cs
+++ b/LehrerApp.Desktop/ViewModels/Students/StudentViewModels.cs
@@ -64,9 +64,15 @@ public partial class StudentListViewModel : ObservableObject
[ObservableProperty] private string _searchText = "";
[ObservableProperty] private bool _showInactive;
[ObservableProperty] private StudentListItem? _selectedStudent;
+ [ObservableProperty] private bool _isImporting;
public ObservableCollection Students { get; } = [];
public string CountSummary => $"{Students.Count} Schüler gesamt";
+ public bool HasNoStudents => Students.Count == 0;
+ public bool HasStudents => !HasNoStudents;
+ public string EmptyListMessage => string.IsNullOrWhiteSpace(SearchText)
+ ? ShowInactive ? "Noch keine Schüler vorhanden." : "Noch keine aktiven Schüler vorhanden."
+ : "Keine Schüler passen zur aktuellen Suche.";
public StudentListViewModel(IStudentRepository students, IGroupRepository groups,
IGroupMembershipRepository memberships)
@@ -105,6 +111,9 @@ public partial class StudentListViewModel : ObservableObject
}
foreach (var s in f) Students.Add(new StudentListItem(s));
OnPropertyChanged(nameof(CountSummary));
+ OnPropertyChanged(nameof(HasNoStudents));
+ OnPropertyChanged(nameof(HasStudents));
+ OnPropertyChanged(nameof(EmptyListMessage));
}
public Func? OnAddStudent { get; set; }
diff --git a/LehrerApp.Desktop/Views/Dashboard/DashboardView.axaml b/LehrerApp.Desktop/Views/Dashboard/DashboardView.axaml
index 3db8572..2271975 100644
--- a/LehrerApp.Desktop/Views/Dashboard/DashboardView.axaml
+++ b/LehrerApp.Desktop/Views/Dashboard/DashboardView.axaml
@@ -20,17 +20,17 @@
-
+
-
+
-
+
-
+
+
+
+
+
diff --git a/LehrerApp.Desktop/Views/Groups/GroupDetailView.axaml b/LehrerApp.Desktop/Views/Groups/GroupDetailView.axaml
index 085241a..d3867b0 100644
--- a/LehrerApp.Desktop/Views/Groups/GroupDetailView.axaml
+++ b/LehrerApp.Desktop/Views/Groups/GroupDetailView.axaml
@@ -13,9 +13,9 @@
-
-
-
+
+
+
@@ -34,7 +34,7 @@
-
+
diff --git a/LehrerApp.Desktop/Views/Groups/GroupListView.axaml b/LehrerApp.Desktop/Views/Groups/GroupListView.axaml
index e81ed4a..b86ccfb 100644
--- a/LehrerApp.Desktop/Views/Groups/GroupListView.axaml
+++ b/LehrerApp.Desktop/Views/Groups/GroupListView.axaml
@@ -11,13 +11,14 @@
-
-
-
+
+
-
+ Width="110" Margin="0,10,8,0" VerticalAlignment="Center"
+ AutomationProperties.Name="Schuljahr auswählen"/>
+
@@ -76,7 +77,7 @@
-