using Avalonia.Controls; using Avalonia.Controls.Templates; using Avalonia.Data; using LehrerApp.Core.Interfaces; using LehrerApp.Core.Services; using LehrerApp.Desktop.ViewModels.Groups; using Microsoft.Extensions.DependencyInjection; namespace LehrerApp.Desktop.Views.Groups; public partial class ParticipationTabView : UserControl { private ParticipationTabViewModel? _vm; public ParticipationTabView() => InitializeComponent(); protected override void OnDataContextChanged(EventArgs e) { base.OnDataContextChanged(e); if (DataContext is ParticipationTabViewModel vm) { _vm = vm; vm.OnAddSession = ShowAddSessionDialog; vm.OnQuickInput = ShowQuickInputDialog; vm.OnComputeGrade = ShowComputeGradeDialog; vm.Aspects.CollectionChanged += (_, _) => BuildColumns(); vm.PropertyChanged += (_, pe) => { if (pe.PropertyName == nameof(ParticipationTabViewModel.RebuildColumnsSignal)) BuildColumns(); }; BuildColumns(); } } private void BuildColumns() { var grid = this.FindControl("RatingGrid"); if (grid is null || _vm is null) return; grid.Columns.Clear(); grid.Columns.Add(new DataGridTextColumn { Header = "Schüler", Binding = new Binding("Name"), Width = new DataGridLength(160, DataGridLengthUnitType.Pixel), }); // Aspekt-Spalten foreach (var (aspect, i) in _vm.Aspects.Select((a, i) => (a, i))) { var idx = i; grid.Columns.Add(new DataGridTemplateColumn { Header = $"{aspect.Label} [{AspectShortcut(i)}]", Width = new DataGridLength(1, DataGridLengthUnitType.Star), CellTemplate = BuildCellTemplate(idx, forCompetency: false), }); } // Kompetenz-Spalten (opt-in) if (_vm.StudentCompetencyRatingsVisible && _vm.ActiveCompetencyCodes.Count > 0) { foreach (var (code, i) in _vm.ActiveCompetencyCodes.Select((c, i) => (c, i))) { var idx = i; grid.Columns.Add(new DataGridTemplateColumn { Header = code, Width = new DataGridLength(80, DataGridLengthUnitType.Pixel), CellTemplate = BuildCellTemplate(idx, forCompetency: true), }); } } } private static IDataTemplate BuildCellTemplate(int cellIndex, bool forCompetency) { return new FuncDataTemplate((row, _) => { if (row is null) return new TextBlock(); var cell = forCompetency ? row.CompetencyCells.ElementAtOrDefault(cellIndex) : row.Cells.ElementAtOrDefault(cellIndex); if (cell is null) return new TextBlock(); var panel = new StackPanel { Orientation = Avalonia.Layout.Orientation.Horizontal, HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center, VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center, Spacing = 2, Margin = new Avalonia.Thickness(0, 2), }; foreach (var (label, val) in new[] { ("−−", -2), ("−", -1), ("∼", 0), ("+", 1), ("++", 2) }) { var btn = new Button { Content = label, Padding = new Avalonia.Thickness(5, 1), FontSize = 11, Opacity = cell.Value == val ? 1.0 : 0.3, }; var capturedVal = val; btn.Click += (_, _) => cell.SetValue(capturedVal); cell.PropertyChanged += (_, pe) => { if (pe.PropertyName == nameof(RatingCell.Value)) btn.Opacity = cell.Value == capturedVal ? 1.0 : 0.3; }; panel.Children.Add(btn); } return panel; }); } private static string AspectShortcut(int i) => i switch { 0 => "Q", 1 => "W", 2 => "E", 3 => "R", 4 => "T", _ => "" }; private async Task ShowAddSessionDialog() { var vm = new AddSessionDialogViewModel(); var dialog = new AddSessionDialog { DataContext = vm }; var owner = TopLevel.GetTopLevel(this) as Window; if (owner is null) return null; var ok = await dialog.ShowDialog(owner); return ok ? vm.Result : null; } private async Task ShowQuickInputDialog(ParticipationTabViewModel tabVm) { if (tabVm.StudentRows.Count == 0) return; var quickVm = new QuickInputViewModel( tabVm.StudentRows.ToList(), tabVm.Aspects.ToList()); var dialog = new ParticipationQuickInputDialog { DataContext = quickVm }; var owner = TopLevel.GetTopLevel(this) as Window; if (owner is not null) await dialog.ShowDialog(owner); } private async Task ShowComputeGradeDialog(ParticipationTabViewModel tabVm) { var dialogVm = new ParticipationGradeDialogViewModel( App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService(), tabVm.GroupId, tabVm.SchoolYear, tabVm.GradingSystem); var dialog = new ParticipationGradeDialog { DataContext = dialogVm }; var owner = TopLevel.GetTopLevel(this) as Window; if (owner is not null) await dialog.ShowDialog(owner); } }