Improve desktop UX and accessibility
This commit is contained in:
@@ -7,6 +7,17 @@
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceInclude Source="avares://LehrerApp.Desktop/Styles/SemanticBrushes.axaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<!-- Plattformunabhängige Vektoricons für die Hauptnavigation (14.10). -->
|
||||
<StreamGeometry x:Key="IconSearch">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</StreamGeometry>
|
||||
<StreamGeometry x:Key="IconDashboard">M3,3 H10 V10 H3 Z M14,3 H21 V7 H14 Z M14,11 H21 V21 H14 Z M3,14 H10 V21 H3 Z</StreamGeometry>
|
||||
<StreamGeometry x:Key="IconGroups">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</StreamGeometry>
|
||||
<StreamGeometry x:Key="IconStudents">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</StreamGeometry>
|
||||
<StreamGeometry x:Key="IconExams">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</StreamGeometry>
|
||||
<StreamGeometry x:Key="IconCalendar">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</StreamGeometry>
|
||||
<StreamGeometry x:Key="IconClock">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</StreamGeometry>
|
||||
<StreamGeometry x:Key="IconClassTeacher">M2,8 L12,3 L22,8 L12,13 Z M6,11 V16 C9,19 15,19 18,16 V11 M22,8 V15</StreamGeometry>
|
||||
<StreamGeometry x:Key="IconSettings">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</StreamGeometry>
|
||||
<StreamGeometry x:Key="IconRefresh">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</StreamGeometry>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
|
||||
@@ -24,5 +35,17 @@
|
||||
<Setter Property="Opacity" Value="0.4"/>
|
||||
<Setter Property="FontSize" Value="13"/>
|
||||
</Style>
|
||||
<Style Selector="Button.touchTarget">
|
||||
<Setter Property="MinWidth" Value="40"/>
|
||||
<Setter Property="MinHeight" Value="40"/>
|
||||
</Style>
|
||||
<Style Selector="Button:focus-visible">
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource SystemAccentColor}"/>
|
||||
<Setter Property="BorderThickness" Value="2"/>
|
||||
</Style>
|
||||
<Style Selector="TextBox:focus-visible, ComboBox:focus-visible">
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource SystemAccentColor}"/>
|
||||
<Setter Property="BorderThickness" Value="2"/>
|
||||
</Style>
|
||||
</Application.Styles>
|
||||
</Application>
|
||||
|
||||
@@ -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<ViewModels.Exams.ExamsOverviewViewModel>();
|
||||
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<GlobalSearchViewModel>();
|
||||
|
||||
@@ -43,6 +43,8 @@ public partial class ExamsOverviewViewModel : ObservableObject
|
||||
public Func<Exam, Task>? OnGradeExam { get; set; }
|
||||
public Func<Exam, Task>? OnEvaluateExam { get; set; }
|
||||
public Action<Guid>? 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);
|
||||
|
||||
@@ -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<StudentListItem> 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<Task>? OnAddStudent { get; set; }
|
||||
|
||||
@@ -20,17 +20,17 @@
|
||||
<StackPanel Spacing="20">
|
||||
|
||||
<!-- Begrüßung -->
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<Grid RowDefinitions="Auto,Auto">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Greeting}" FontSize="14" Opacity="0.6"/>
|
||||
<TextBlock Text="{Binding CurrentDate}" FontSize="24" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="8">
|
||||
<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="Bereiche anpassen" Command="{Binding ToggleDashboardSettingsCommand}"
|
||||
VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</WrapPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- Der Tagesfokus beantwortet zuerst die vier Fragen, die beim Öffnen der App zählen:
|
||||
@@ -72,9 +72,13 @@
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<CheckBox Content="{Binding Title}" IsChecked="{Binding IsVisible}" VerticalAlignment="Center"/>
|
||||
<Button Content="↑" Padding="6,2"
|
||||
ToolTip.Tip="Bereich nach oben verschieben"
|
||||
AutomationProperties.Name="Dashboard-Bereich nach oben verschieben"
|
||||
Command="{Binding $parent[ItemsControl].((vm:DashboardViewModel)DataContext).MoveCardUpCommand}"
|
||||
CommandParameter="{Binding}"/>
|
||||
<Button Content="↓" Padding="6,2"
|
||||
ToolTip.Tip="Bereich nach unten verschieben"
|
||||
AutomationProperties.Name="Dashboard-Bereich nach unten verschieben"
|
||||
Command="{Binding $parent[ItemsControl].((vm:DashboardViewModel)DataContext).MoveCardDownCommand}"
|
||||
CommandParameter="{Binding}"/>
|
||||
</StackPanel>
|
||||
@@ -250,8 +254,10 @@
|
||||
Width="130" Margin="12,0"/>
|
||||
<Button Grid.Column="2" Content="Heute" FontSize="11" Padding="8,2"
|
||||
Command="{Binding CalendarTodayCommand}" Margin="0,0,4,0"/>
|
||||
<Button Grid.Column="3" Content="‹" Padding="8,2" Command="{Binding PrevMonthCommand}"/>
|
||||
<Button Grid.Column="4" Content="›" Padding="8,2" Command="{Binding NextMonthCommand}" Margin="4,0,0,0"/>
|
||||
<Button Grid.Column="3" Content="‹" Padding="8,2" Command="{Binding PrevMonthCommand}"
|
||||
ToolTip.Tip="Vorheriger Monat" AutomationProperties.Name="Vorheriger Monat"/>
|
||||
<Button Grid.Column="4" Content="›" Padding="8,2" Command="{Binding NextMonthCommand}" Margin="4,0,0,0"
|
||||
ToolTip.Tip="Nächster Monat" AutomationProperties.Name="Nächster Monat"/>
|
||||
</Grid>
|
||||
|
||||
<ItemsControl ItemsSource="{Binding CalendarWeekdayHeaders}">
|
||||
|
||||
@@ -182,8 +182,14 @@
|
||||
<!-- Liste aller Klausuren, nach Priorität sortiert (nicht nach Datum) ─────────── -->
|
||||
<ScrollViewer Grid.Row="2" Margin="20,0,20,16">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding EmptyHint}" Classes="emptyhint" Margin="0,20,0,0"
|
||||
IsVisible="{Binding EmptyHint, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
||||
<StackPanel Margin="0,28,0,0" Spacing="10" HorizontalAlignment="Center"
|
||||
IsVisible="{Binding HasNoExams}">
|
||||
<TextBlock Text="Noch keine Klausuren im aktuellen Schuljahr." Classes="emptyhint"
|
||||
FontSize="15" TextAlignment="Center"/>
|
||||
<TextBlock Text="Klausuren werden im jeweiligen Kurs angelegt." FontSize="12" Opacity="0.55"/>
|
||||
<Button Content="Zu den Lerngruppen" Command="{Binding GoToGroupsCommand}"
|
||||
HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<ItemsControl ItemsSource="{Binding Rows}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:ExamListRowViewModel">
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
<Border Grid.Row="0" Padding="20,16"
|
||||
BorderBrush="{DynamicResource SystemControlForegroundBaseLowBrush}"
|
||||
BorderThickness="0,0,0,1">
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<shared:PageHeader Grid.Column="0" Title="{Binding GroupTitle}" Subtitle="{Binding GroupSubtitle}"/>
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="8">
|
||||
<Grid RowDefinitions="Auto,Auto">
|
||||
<shared:PageHeader Title="{Binding GroupTitle}" Subtitle="{Binding GroupSubtitle}"/>
|
||||
<WrapPanel Grid.Row="1" Orientation="Horizontal" ItemSpacing="8" LineSpacing="8" Margin="0,10,0,0">
|
||||
<TextBlock VerticalAlignment="Center" Opacity="0.6" FontSize="13">
|
||||
<Run Text="{Binding StudentCount}"/>
|
||||
<Run Text=" Schüler"/>
|
||||
@@ -34,7 +34,7 @@
|
||||
<Button Content="Austragung zurücknehmen" Command="{Binding ReinstateStudentCommand}"
|
||||
IsVisible="{Binding SelectedStudent.HasExitDate}"/>
|
||||
<Button Content="+ Klausur" Command="{Binding AddExamCommand}" IsEnabled="{Binding IsEditable}"/>
|
||||
</StackPanel>
|
||||
</WrapPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
|
||||
@@ -11,13 +11,14 @@
|
||||
<Border Grid.Row="0" Padding="20,16"
|
||||
BorderBrush="{DynamicResource SystemControlForegroundBaseLowBrush}"
|
||||
BorderThickness="0,0,0,1">
|
||||
<Grid ColumnDefinitions="*,Auto,Auto">
|
||||
<shared:PageHeader Grid.Column="0" Title="Lerngruppen" Subtitle="{Binding ListSummary}"/>
|
||||
<ComboBox Grid.Column="1" ItemsSource="{Binding SchoolYears}"
|
||||
<Grid RowDefinitions="Auto,Auto" ColumnDefinitions="*,Auto,Auto">
|
||||
<shared:PageHeader Grid.ColumnSpan="3" Title="Lerngruppen" Subtitle="{Binding ListSummary}"/>
|
||||
<ComboBox Grid.Row="1" Grid.Column="1" ItemsSource="{Binding SchoolYears}"
|
||||
SelectedItem="{Binding SelectedSchoolYear}"
|
||||
Width="100" Margin="0,0,8,0" VerticalAlignment="Center"/>
|
||||
<Button Grid.Column="2" Content="+ Neue Gruppe"
|
||||
Command="{Binding AddGroupCommand}" VerticalAlignment="Center"/>
|
||||
Width="110" Margin="0,10,8,0" VerticalAlignment="Center"
|
||||
AutomationProperties.Name="Schuljahr auswählen"/>
|
||||
<Button Grid.Row="1" Grid.Column="2" Content="+ Neue Gruppe"
|
||||
Command="{Binding AddGroupCommand}" VerticalAlignment="Center" Margin="0,10,0,0"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
@@ -76,7 +77,7 @@
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Grid.Column="2" Content="⋯" Width="36" Height="32" Margin="0,10,10,0"
|
||||
<Button Grid.Column="2" Content="⋯" Width="40" Height="40" Margin="0,10,10,0"
|
||||
Padding="0" VerticalAlignment="Top"
|
||||
ToolTip.Tip="Lerngruppe verwalten"
|
||||
AutomationProperties.Name="{Binding ManageAutomationName}">
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
x:DataType="vm:MainWindowViewModel"
|
||||
Title="LehrerApp"
|
||||
Width="1280" Height="800"
|
||||
MinWidth="900" MinHeight="600">
|
||||
MinWidth="640" MinHeight="480">
|
||||
|
||||
<Panel>
|
||||
<!--
|
||||
@@ -81,14 +81,14 @@
|
||||
FontFamily explizit auf die farbige Emoji-Schrift gepinnt: Windows kann für
|
||||
Emoji-Codepoints je nach Fallback-Auflösung sonst auf "Segoe UI Symbol"
|
||||
(einfarbig/schwarz) statt "Segoe UI Emoji" (farbig) ausweichen. -->
|
||||
<Style Selector="TextBlock.navicon">
|
||||
<Setter Property="FontSize" Value="15"/>
|
||||
<Style Selector="PathIcon.navicon">
|
||||
<Setter Property="Width" Value="24"/>
|
||||
<Setter Property="FontFamily" Value="Segoe UI Emoji,Segoe UI Symbol,Segoe UI"/>
|
||||
<Setter Property="Height" Value="24"/>
|
||||
</Style>
|
||||
<Style Selector="Button.navitem">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Padding" Value="10,8"/>
|
||||
<Setter Property="MinHeight" Value="40"/>
|
||||
</Style>
|
||||
<Style Selector="Button.navitem.active">
|
||||
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundAccentBrush}"/>
|
||||
@@ -98,9 +98,9 @@
|
||||
<Style Selector="DockPanel.compact TextBlock.navlabel">
|
||||
<Setter Property="IsVisible" Value="False"/>
|
||||
</Style>
|
||||
<Style Selector="DockPanel.compact TextBlock.navicon">
|
||||
<Setter Property="FontSize" Value="20"/>
|
||||
<Style Selector="DockPanel.compact PathIcon.navicon">
|
||||
<Setter Property="Width" Value="28"/>
|
||||
<Setter Property="Height" Value="28"/>
|
||||
</Style>
|
||||
<Style Selector="DockPanel.compact Button.navitem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
||||
@@ -157,7 +157,7 @@
|
||||
ToolTip.Tip="Suchen und schnell erfassen (Strg/⌘+K)"
|
||||
AutomationProperties.Name="Suchen und schnell erfassen">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||||
<TextBlock Classes="navicon" Text="⌕" TextAlignment="Center"/>
|
||||
<PathIcon Classes="navicon" Data="{StaticResource IconSearch}"/>
|
||||
<TextBlock Grid.Column="1" Classes="navlabel" Text="Suchen / Erfassen"/>
|
||||
<TextBlock Grid.Column="2" Classes="navlabel" Text="⌘K" FontSize="10" Opacity="0.45"
|
||||
VerticalAlignment="Center"/>
|
||||
@@ -169,9 +169,10 @@
|
||||
HorizontalContentAlignment="Left"
|
||||
CornerRadius="6"
|
||||
Command="{Binding NavigateToCommand}"
|
||||
CommandParameter="{x:Static vm:NavItem.Dashboard}">
|
||||
CommandParameter="{x:Static vm:NavItem.Dashboard}"
|
||||
ToolTip.Tip="Dashboard (Strg/⌘+1)" AutomationProperties.Name="Dashboard">
|
||||
<StackPanel Classes="navcontent" Orientation="Horizontal" Spacing="10">
|
||||
<TextBlock Classes="navicon" Text="📊" TextAlignment="Center"/>
|
||||
<PathIcon Classes="navicon" Data="{StaticResource IconDashboard}"/>
|
||||
<TextBlock Classes="navlabel" Text="Dashboard"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
@@ -183,9 +184,10 @@
|
||||
HorizontalContentAlignment="Left"
|
||||
CornerRadius="6"
|
||||
Command="{Binding NavigateToCommand}"
|
||||
CommandParameter="{x:Static vm:NavItem.Groups}">
|
||||
CommandParameter="{x:Static vm:NavItem.Groups}"
|
||||
ToolTip.Tip="Lerngruppen (Strg/⌘+2)" AutomationProperties.Name="Lerngruppen">
|
||||
<StackPanel Classes="navcontent" Orientation="Horizontal" Spacing="10">
|
||||
<TextBlock Classes="navicon" Text="🏫" TextAlignment="Center"/>
|
||||
<PathIcon Classes="navicon" Data="{StaticResource IconGroups}"/>
|
||||
<TextBlock Classes="navlabel" Text="Lerngruppen"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
@@ -193,9 +195,10 @@
|
||||
HorizontalContentAlignment="Left"
|
||||
CornerRadius="6"
|
||||
Command="{Binding NavigateToCommand}"
|
||||
CommandParameter="{x:Static vm:NavItem.Students}">
|
||||
CommandParameter="{x:Static vm:NavItem.Students}"
|
||||
ToolTip.Tip="Schüler (Strg/⌘+3)" AutomationProperties.Name="Schüler">
|
||||
<StackPanel Classes="navcontent" Orientation="Horizontal" Spacing="10">
|
||||
<TextBlock Classes="navicon" Text="👤" TextAlignment="Center"/>
|
||||
<PathIcon Classes="navicon" Data="{StaticResource IconStudents}"/>
|
||||
<TextBlock Classes="navlabel" Text="Schüler"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
@@ -203,9 +206,10 @@
|
||||
HorizontalContentAlignment="Left"
|
||||
CornerRadius="6"
|
||||
Command="{Binding NavigateToCommand}"
|
||||
CommandParameter="{x:Static vm:NavItem.Exams}">
|
||||
CommandParameter="{x:Static vm:NavItem.Exams}"
|
||||
ToolTip.Tip="Klausuren (Strg/⌘+4)" AutomationProperties.Name="Klausuren">
|
||||
<StackPanel Classes="navcontent" Orientation="Horizontal" Spacing="10">
|
||||
<TextBlock Classes="navicon" Text="📝" TextAlignment="Center"/>
|
||||
<PathIcon Classes="navicon" Data="{StaticResource IconExams}"/>
|
||||
<TextBlock Classes="navlabel" Text="Klausuren"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
@@ -213,9 +217,10 @@
|
||||
HorizontalContentAlignment="Left"
|
||||
CornerRadius="6"
|
||||
Command="{Binding NavigateToCommand}"
|
||||
CommandParameter="{x:Static vm:NavItem.Planner}">
|
||||
CommandParameter="{x:Static vm:NavItem.Planner}"
|
||||
ToolTip.Tip="Planung (Strg/⌘+5)" AutomationProperties.Name="Planung">
|
||||
<StackPanel Classes="navcontent" Orientation="Horizontal" Spacing="10">
|
||||
<TextBlock Classes="navicon" Text="📅" TextAlignment="Center"/>
|
||||
<PathIcon Classes="navicon" Data="{StaticResource IconCalendar}"/>
|
||||
<TextBlock Classes="navlabel" Text="Planung"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
@@ -227,9 +232,10 @@
|
||||
HorizontalContentAlignment="Left"
|
||||
CornerRadius="6"
|
||||
Command="{Binding NavigateToCommand}"
|
||||
CommandParameter="{x:Static vm:NavItem.Workload}">
|
||||
CommandParameter="{x:Static vm:NavItem.Workload}"
|
||||
ToolTip.Tip="Arbeitszeit (Strg/⌘+6)" AutomationProperties.Name="Arbeitszeit">
|
||||
<StackPanel Classes="navcontent" Orientation="Horizontal" Spacing="10">
|
||||
<TextBlock Classes="navicon" Text="⏱" TextAlignment="Center"/>
|
||||
<PathIcon Classes="navicon" Data="{StaticResource IconClock}"/>
|
||||
<TextBlock Classes="navlabel" Text="Arbeitszeit"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
@@ -237,9 +243,10 @@
|
||||
HorizontalContentAlignment="Left"
|
||||
CornerRadius="6"
|
||||
Command="{Binding NavigateToCommand}"
|
||||
CommandParameter="{x:Static vm:NavItem.ClassTeacher}">
|
||||
CommandParameter="{x:Static vm:NavItem.ClassTeacher}"
|
||||
ToolTip.Tip="Klassenlehrer (Strg/⌘+7)" AutomationProperties.Name="Klassenlehrer">
|
||||
<StackPanel Classes="navcontent" Orientation="Horizontal" Spacing="10">
|
||||
<TextBlock Classes="navicon" Text="🎓" TextAlignment="Center"/>
|
||||
<PathIcon Classes="navicon" Data="{StaticResource IconClassTeacher}"/>
|
||||
<TextBlock Classes="navlabel" Text="Klassenlehrer"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
@@ -247,9 +254,10 @@
|
||||
HorizontalContentAlignment="Left"
|
||||
CornerRadius="6"
|
||||
Command="{Binding NavigateToCommand}"
|
||||
CommandParameter="{x:Static vm:NavItem.Settings}">
|
||||
CommandParameter="{x:Static vm:NavItem.Settings}"
|
||||
ToolTip.Tip="Einstellungen (Strg/⌘+8)" AutomationProperties.Name="Einstellungen">
|
||||
<StackPanel Classes="navcontent" Orientation="Horizontal" Spacing="10">
|
||||
<TextBlock Classes="navicon" Text="⚙️" TextAlignment="Center"/>
|
||||
<PathIcon Classes="navicon" Data="{StaticResource IconSettings}"/>
|
||||
<TextBlock Classes="navlabel" Text="Einstellungen"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
@@ -36,6 +36,13 @@ public partial class MainWindow : Window
|
||||
return;
|
||||
}
|
||||
|
||||
if (commandModifier && TryGetNavigationShortcut(e.Key, out var destination))
|
||||
{
|
||||
vm.NavigateToCommand.Execute(destination);
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!vm.IsCommandPaletteOpen) return;
|
||||
if (e.Key == Key.Escape)
|
||||
{
|
||||
@@ -54,6 +61,23 @@ public partial class MainWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryGetNavigationShortcut(Key key, out NavItem destination)
|
||||
{
|
||||
destination = key switch
|
||||
{
|
||||
Key.D1 or Key.NumPad1 => NavItem.Dashboard,
|
||||
Key.D2 or Key.NumPad2 => NavItem.Groups,
|
||||
Key.D3 or Key.NumPad3 => NavItem.Students,
|
||||
Key.D4 or Key.NumPad4 => NavItem.Exams,
|
||||
Key.D5 or Key.NumPad5 => NavItem.Planner,
|
||||
Key.D6 or Key.NumPad6 => NavItem.Workload,
|
||||
Key.D7 or Key.NumPad7 => NavItem.ClassTeacher,
|
||||
Key.D8 or Key.NumPad8 => NavItem.Settings,
|
||||
_ => default,
|
||||
};
|
||||
return key is >= Key.D1 and <= Key.D8 or >= Key.NumPad1 and <= Key.NumPad8;
|
||||
}
|
||||
|
||||
private void OnOpenCommandPaletteClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is MainWindowViewModel vm)
|
||||
|
||||
@@ -154,9 +154,11 @@
|
||||
|
||||
<Grid ColumnDefinitions="Auto,Auto,*,Auto,Auto,Auto">
|
||||
<Button Grid.Column="0" Content="‹" FontWeight="Bold" Padding="10,4"
|
||||
Command="{Binding PreviousWeekCommand}" ToolTip.Tip="Vorherige Woche"/>
|
||||
Command="{Binding PreviousWeekCommand}" ToolTip.Tip="Vorherige Woche"
|
||||
AutomationProperties.Name="Vorherige Woche"/>
|
||||
<Button Grid.Column="1" Content="›" FontWeight="Bold" Padding="10,4" Margin="4,0,0,0"
|
||||
Command="{Binding NextWeekCommand}" ToolTip.Tip="Nächste Woche"/>
|
||||
Command="{Binding NextWeekCommand}" ToolTip.Tip="Nächste Woche"
|
||||
AutomationProperties.Name="Nächste Woche"/>
|
||||
<TextBlock Grid.Column="2" FontSize="16" FontWeight="SemiBold"
|
||||
VerticalAlignment="Center" Margin="12,0,0,0">
|
||||
<Run Text="Woche "/><Run Text="{Binding WeekRangeLabel}"/>
|
||||
@@ -166,7 +168,8 @@
|
||||
<Button Grid.Column="4" Content="Ausnahme eintragen" Margin="0,0,8,0"
|
||||
Command="{Binding AddSubstitutionCommand}"/>
|
||||
<Button Grid.Column="5" Content="⚙️" Command="{Binding OpenSettingsCommand}"
|
||||
ToolTip.Tip="Einstellungen (Ferien, Aufsichten, Stundenraster)"/>
|
||||
ToolTip.Tip="Einstellungen (Ferien, Aufsichten, Stundenraster)"
|
||||
AutomationProperties.Name="Stundenplan-Einstellungen"/>
|
||||
</Grid>
|
||||
|
||||
<Border Background="#33F59E0B" BorderBrush="#F59E0B" BorderThickness="1"
|
||||
@@ -281,7 +284,7 @@
|
||||
<Button Classes="weekCellMenuTrigger" Content="⋮"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Top"
|
||||
IsVisible="{Binding HasGroupId}"
|
||||
ToolTip.Tip="Weitere Ziele…">
|
||||
ToolTip.Tip="Weitere Ziele…" AutomationProperties.Name="Weitere Ziele">
|
||||
<Button.Flyout>
|
||||
<MenuFlyout Placement="BottomEdgeAlignedRight">
|
||||
<MenuItem Header="▶ Unterrichtsansicht" IsVisible="{Binding HasLesson}"
|
||||
@@ -404,7 +407,8 @@
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Center" Background="Transparent"
|
||||
Command="{Binding $parent[ItemsControl;1].((vm:TimetableViewModel)DataContext).EditCellCommand}"
|
||||
CommandParameter="{Binding}"/>
|
||||
CommandParameter="{Binding}"
|
||||
AutomationProperties.Name="Stundenplan-Eintrag hinzufügen"/>
|
||||
<Border Background="#D85A30" CornerRadius="8" Padding="5,1"
|
||||
IsVisible="{Binding HasBadge}"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Top" Margin="2">
|
||||
|
||||
@@ -8,18 +8,21 @@
|
||||
<Border Grid.Row="0" Padding="20,16"
|
||||
BorderBrush="{DynamicResource SystemControlForegroundBaseLowBrush}"
|
||||
BorderThickness="0,0,0,1">
|
||||
<Grid ColumnDefinitions="*,Auto,Auto,Auto">
|
||||
<shared:PageHeader Grid.Column="0" Title="Schüler" Subtitle="{Binding CountSummary}"/>
|
||||
<CheckBox Grid.Column="1" Content="Inaktive anzeigen"
|
||||
<Grid RowDefinitions="Auto,Auto" ColumnDefinitions="*,Auto,Auto,Auto">
|
||||
<shared:PageHeader Grid.ColumnSpan="4" Title="Schüler" Subtitle="{Binding CountSummary}"/>
|
||||
<CheckBox Grid.Row="1" Grid.Column="1" Content="Inaktive anzeigen"
|
||||
IsChecked="{Binding ShowInactive}"
|
||||
VerticalAlignment="Center" Margin="0,0,12,0"/>
|
||||
<Button Grid.Column="2" Content="⇩ Importieren…" Click="OnImportClick"
|
||||
VerticalAlignment="Center" Margin="0,0,8,0"/>
|
||||
<Button Grid.Column="3" Content="+ Neuer Schüler"
|
||||
Command="{Binding AddStudentCommand}" VerticalAlignment="Center"/>
|
||||
VerticalAlignment="Center" Margin="0,10,12,0"/>
|
||||
<Button Grid.Row="1" Grid.Column="2" Content="⇩ Importieren…" Click="OnImportClick"
|
||||
IsEnabled="{Binding !IsImporting}"
|
||||
VerticalAlignment="Center" Margin="0,10,8,0"
|
||||
AutomationProperties.Name="Schüler importieren"/>
|
||||
<Button Grid.Row="1" Grid.Column="3" Content="+ Neuer Schüler"
|
||||
Command="{Binding AddStudentCommand}" VerticalAlignment="Center" Margin="0,10,0,0"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
<DockPanel Grid.Row="1">
|
||||
<Grid Grid.Row="1">
|
||||
<DockPanel IsVisible="{Binding HasStudents}">
|
||||
<TextBox DockPanel.Dock="Top" Text="{Binding SearchText}"
|
||||
PlaceholderText="Name oder Lerngruppe suchen…" Margin="16,10,16,4"/>
|
||||
<DataGrid ItemsSource="{Binding Students}"
|
||||
@@ -45,5 +48,22 @@
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</DockPanel>
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="10"
|
||||
IsVisible="{Binding HasNoStudents}">
|
||||
<TextBlock Text="{Binding EmptyListMessage}" Classes="emptyhint" FontSize="15"
|
||||
TextAlignment="Center"/>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="8"
|
||||
IsVisible="{Binding SearchText, Converter={x:Static StringConverters.IsNullOrEmpty}}">
|
||||
<Button Content="+ Ersten Schüler anlegen" Command="{Binding AddStudentCommand}"/>
|
||||
<Button Content="⇩ Schülerliste importieren" Click="OnImportClick"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
<Border Background="#70000000" IsVisible="{Binding IsImporting}">
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="10">
|
||||
<ProgressBar IsIndeterminate="True" Width="220" Height="5"/>
|
||||
<TextBlock Text="Schülerliste wird analysiert …" Foreground="White"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -36,6 +36,7 @@ public partial class StudentListView : UserControl
|
||||
});
|
||||
if (files.Count == 0) return;
|
||||
|
||||
list.IsImporting = true;
|
||||
try
|
||||
{
|
||||
await using var source = await files[0].OpenReadAsync();
|
||||
@@ -67,5 +68,9 @@ public partial class StudentListView : UserControl
|
||||
{
|
||||
App.Services.GetRequiredService<NotificationService>().ShowError(ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
list.IsImporting = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,17 @@
|
||||
Foreground="#D32F2F"/>
|
||||
<TextBlock Text="Sync angehalten" FontSize="10" Foreground="#D32F2F" Opacity="0.8"/>
|
||||
</StackPanel>
|
||||
<Button Grid.Column="1" Content="↻" FontSize="14"
|
||||
<Button Grid.Column="1" Classes="touchTarget"
|
||||
Command="{Binding SyncNowCommand}"
|
||||
IsVisible="{Binding CanAttemptSync}"
|
||||
Background="Transparent" Padding="6,4"
|
||||
ToolTip.Tip="Jetzt synchronisieren"/>
|
||||
Background="Transparent" Padding="8"
|
||||
ToolTip.Tip="Jetzt synchronisieren" AutomationProperties.Name="Jetzt synchronisieren">
|
||||
<Grid>
|
||||
<PathIcon Data="{StaticResource IconRefresh}" Width="18" Height="18"
|
||||
IsVisible="{Binding !IsSyncing}"/>
|
||||
<ProgressBar Width="22" Height="4" IsIndeterminate="True"
|
||||
IsVisible="{Binding IsSyncing}"/>
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
Reference in New Issue
Block a user