Stunde/Einheit-Dialog: Gruppe + Fach anzeigen, nicht nur Fach
Bei einer Klasse, die in mehreren Fächern unterrichtet wird (mehrere
LearningGroup-Datensätze mit gleichem Namen, z.B. zwei "10c"), zeigte
UnitDialog bisher nur das Fach ("Fach: Chemie"), LessonDialog gar keinen
Gruppen-/Fach-Hinweis. Beide zeigen jetzt "Gruppe · Fach" (z.B. "10c ·
Chemie") direkt unter dem Dialogtitel, nicht editierbar, nur zur Einordnung.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -19,7 +19,17 @@ public sealed class LessonDialogViewModelTests
|
|||||||
FakeTimetableSlots? slots = null, PeriodScheduleService? periodSchedule = null) =>
|
FakeTimetableSlots? slots = null, PeriodScheduleService? periodSchedule = null) =>
|
||||||
new(new FakeLessons(), new FakeShorthandCodes([]), new FakeAlternativeLessonPaths([]),
|
new(new FakeLessons(), new FakeShorthandCodes([]), new FakeAlternativeLessonPaths([]),
|
||||||
slots ?? new FakeTimetableSlots(), periodSchedule ?? NewPeriodSchedule(),
|
slots ?? new FakeTimetableSlots(), periodSchedule ?? NewPeriodSchedule(),
|
||||||
unitId, groupId, [], [], editing);
|
unitId, groupId, "10c", "Chemie", [], [], editing);
|
||||||
|
|
||||||
|
/// Nutzer-Feedback: bei einer Klasse, die in mehreren Fächern unterrichtet wird (mehrere
|
||||||
|
/// LearningGroup-Datensätze mit gleichem Namen), war im Stunden-Dialog nicht erkennbar,
|
||||||
|
/// welche der beiden Stunden man gerade bearbeitet.
|
||||||
|
[Fact]
|
||||||
|
public void GroupSubjectDisplay_ZeigtGruppeUndFachZusammen()
|
||||||
|
{
|
||||||
|
var vm = BuildVm(Guid.NewGuid(), Guid.NewGuid());
|
||||||
|
Assert.Equal("10c · Chemie", vm.GroupSubjectDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void AddPhase_FuegtZeileMitStandardwertenHinzu()
|
public void AddPhase_FuegtZeileMitStandardwertenHinzu()
|
||||||
@@ -83,7 +93,7 @@ public sealed class LessonDialogViewModelTests
|
|||||||
var codes = new FakeShorthandCodes([new ShorthandCode { Code = "Tb" }, new ShorthandCode { Code = "SH" }]);
|
var codes = new FakeShorthandCodes([new ShorthandCode { Code = "Tb" }, new ShorthandCode { Code = "SH" }]);
|
||||||
var vm = new LessonDialogViewModel(new FakeLessons(), codes, new FakeAlternativeLessonPaths([]),
|
var vm = new LessonDialogViewModel(new FakeLessons(), codes, new FakeAlternativeLessonPaths([]),
|
||||||
new FakeTimetableSlots(), NewPeriodSchedule(),
|
new FakeTimetableSlots(), NewPeriodSchedule(),
|
||||||
Guid.NewGuid(), Guid.NewGuid(), [], ["Plenum", "LDE", "Tb"], null); // "Tb" doppelt (Katalog + Historie), soll nur einmal erscheinen
|
Guid.NewGuid(), Guid.NewGuid(), "10c", "Chemie", [], ["Plenum", "LDE", "Tb"], null); // "Tb" doppelt (Katalog + Historie), soll nur einmal erscheinen
|
||||||
|
|
||||||
Assert.Equal(["LDE", "Plenum", "SH", "Tb"], vm.ShorthandSuggestions);
|
Assert.Equal(["LDE", "Plenum", "SH", "Tb"], vm.ShorthandSuggestions);
|
||||||
}
|
}
|
||||||
@@ -145,7 +155,7 @@ public sealed class LessonDialogViewModelTests
|
|||||||
var groupId = Guid.NewGuid();
|
var groupId = Guid.NewGuid();
|
||||||
var lessons = new FakeLessons();
|
var lessons = new FakeLessons();
|
||||||
var vm = new LessonDialogViewModel(lessons, new FakeShorthandCodes([]), new FakeAlternativeLessonPaths([]),
|
var vm = new LessonDialogViewModel(lessons, new FakeShorthandCodes([]), new FakeAlternativeLessonPaths([]),
|
||||||
new FakeTimetableSlots(), NewPeriodSchedule(), unitId, groupId, [], [], null)
|
new FakeTimetableSlots(), NewPeriodSchedule(), unitId, groupId, "10c", "Chemie", [], [], null)
|
||||||
{
|
{
|
||||||
Topic = "Brechung", DateText = "01.09.2025", StartTimeText = "11:45",
|
Topic = "Brechung", DateText = "01.09.2025", StartTimeText = "11:45",
|
||||||
};
|
};
|
||||||
@@ -242,7 +252,7 @@ public sealed class LessonDialogViewModelTests
|
|||||||
};
|
};
|
||||||
|
|
||||||
var vm = new LessonDialogViewModel(new FakeLessons(), new FakeShorthandCodes([]), alternativePaths,
|
var vm = new LessonDialogViewModel(new FakeLessons(), new FakeShorthandCodes([]), alternativePaths,
|
||||||
new FakeTimetableSlots(), NewPeriodSchedule(), Guid.NewGuid(), Guid.NewGuid(), [], [], editing);
|
new FakeTimetableSlots(), NewPeriodSchedule(), Guid.NewGuid(), Guid.NewGuid(), "10c", "Chemie", [], [], editing);
|
||||||
|
|
||||||
Assert.True(vm.Phases[0].HasAlternativePath);
|
Assert.True(vm.Phases[0].HasAlternativePath);
|
||||||
Assert.Equal("Kurzversion", vm.Phases[0].AlternativePathName);
|
Assert.Equal("Kurzversion", vm.Phases[0].AlternativePathName);
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using LehrerApp.Desktop.ViewModels.Groups;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace LehrerApp.Desktop.Tests;
|
||||||
|
|
||||||
|
/// Nutzer-Feedback: bei einer Klasse, die in mehreren Fächern unterrichtet wird (mehrere
|
||||||
|
/// LearningGroup-Datensätze mit gleichem Namen), war im Einheiten-Dialog nur das Fach sichtbar,
|
||||||
|
/// nicht welche Klasse gemeint ist — beides zusammen macht es eindeutig.
|
||||||
|
public sealed class UnitDialogViewModelTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void GroupSubjectDisplay_ZeigtGruppeUndFachZusammen()
|
||||||
|
{
|
||||||
|
var vm = new UnitDialogViewModel(new FakeUnits(), new FakeCompetencyDomains(),
|
||||||
|
Guid.NewGuid(), Guid.NewGuid(), 10, "10c", "Chemie", editingUnit: null);
|
||||||
|
|
||||||
|
Assert.Equal("10c · Chemie", vm.GroupSubjectDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GroupSubjectDisplay_OhneFach_WeistDaraufHin()
|
||||||
|
{
|
||||||
|
var vm = new UnitDialogViewModel(new FakeUnits(), new FakeCompetencyDomains(),
|
||||||
|
Guid.NewGuid(), null, 10, "10c", "", editingUnit: null);
|
||||||
|
|
||||||
|
Assert.Equal("10c · kein Fach hinterlegt (siehe Lerngruppe)", vm.GroupSubjectDisplay);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,6 +39,7 @@ public partial class PlanningTabViewModel : ObservableObject
|
|||||||
public Guid? SubjectId { get; private set; }
|
public Guid? SubjectId { get; private set; }
|
||||||
public int GradeLevel { get; private set; }
|
public int GradeLevel { get; private set; }
|
||||||
public string SubjectName { get; private set; } = "";
|
public string SubjectName { get; private set; } = "";
|
||||||
|
public string GroupLabel { get; private set; } = "";
|
||||||
|
|
||||||
[ObservableProperty] private UnitSummary? _selectedUnit;
|
[ObservableProperty] private UnitSummary? _selectedUnit;
|
||||||
[ObservableProperty] private LessonSummary? _selectedLesson;
|
[ObservableProperty] private LessonSummary? _selectedLesson;
|
||||||
@@ -88,6 +89,7 @@ public partial class PlanningTabViewModel : ObservableObject
|
|||||||
SubjectId = group?.SubjectId;
|
SubjectId = group?.SubjectId;
|
||||||
GradeLevel = group?.GradeLevel ?? 0;
|
GradeLevel = group?.GradeLevel ?? 0;
|
||||||
SubjectName = SubjectId is Guid sid ? _subjects.GetById(sid)?.Name ?? "" : "";
|
SubjectName = SubjectId is Guid sid ? _subjects.GetById(sid)?.Name ?? "" : "";
|
||||||
|
GroupLabel = group?.Name ?? "";
|
||||||
LoadUnits();
|
LoadUnits();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -494,21 +496,23 @@ public partial class UnitDialogViewModel : ObservableObject
|
|||||||
public string CompetencySummary => _competencyCodes.Count == 0
|
public string CompetencySummary => _competencyCodes.Count == 0
|
||||||
? "Keine Kompetenzen" : $"{_competencyCodes.Count} Kompetenz(en)";
|
? "Keine Kompetenzen" : $"{_competencyCodes.Count} Kompetenz(en)";
|
||||||
|
|
||||||
/// Fach kommt von der Lerngruppe, nicht editierbar (jede Gruppe unterrichtet ein Fach).
|
/// Gruppe + Fach kommen von der Lerngruppe, nicht editierbar (jede Gruppe unterrichtet ein
|
||||||
public string SubjectDisplay { get; }
|
/// Fach) — beide zusammen zeigen, da dieselbe Klasse in mehreren Fächern (mehrere
|
||||||
|
/// Lerngruppen mit gleichem Namen) sonst nicht unterscheidbar wäre (Nutzer-Feedback).
|
||||||
|
public string GroupSubjectDisplay { get; }
|
||||||
|
|
||||||
public Unit? Result { get; private set; }
|
public Unit? Result { get; private set; }
|
||||||
public string DialogTitle => _editingUnit is null ? "Neue Einheit anlegen" : "Einheit bearbeiten";
|
public string DialogTitle => _editingUnit is null ? "Neue Einheit anlegen" : "Einheit bearbeiten";
|
||||||
public string SaveButtonText => _editingUnit is null ? "Anlegen" : "Speichern";
|
public string SaveButtonText => _editingUnit is null ? "Anlegen" : "Speichern";
|
||||||
|
|
||||||
public UnitDialogViewModel(IUnitRepository units, ICompetencyDomainRepository competencyDomains,
|
public UnitDialogViewModel(IUnitRepository units, ICompetencyDomainRepository competencyDomains,
|
||||||
Guid groupId, Guid? subjectId, int gradeLevel, string subjectName, Unit? editingUnit)
|
Guid groupId, Guid? subjectId, int gradeLevel, string groupName, string subjectName, Unit? editingUnit)
|
||||||
{
|
{
|
||||||
_units = units; _competencyDomains = competencyDomains;
|
_units = units; _competencyDomains = competencyDomains;
|
||||||
_groupId = groupId; _subjectId = subjectId; _gradeLevel = gradeLevel;
|
_groupId = groupId; _subjectId = subjectId; _gradeLevel = gradeLevel;
|
||||||
_editingUnit = editingUnit;
|
_editingUnit = editingUnit;
|
||||||
SubjectDisplay = string.IsNullOrWhiteSpace(subjectName)
|
GroupSubjectDisplay = string.IsNullOrWhiteSpace(subjectName)
|
||||||
? "Kein Fach hinterlegt (siehe Lerngruppe)" : $"Fach: {subjectName}";
|
? $"{groupName} · kein Fach hinterlegt (siehe Lerngruppe)" : $"{groupName} · {subjectName}";
|
||||||
|
|
||||||
_competencyCodes = editingUnit is not null ? [.. editingUnit.Competencies] : [];
|
_competencyCodes = editingUnit is not null ? [.. editingUnit.Competencies] : [];
|
||||||
BuildCompetencyTagGroups();
|
BuildCompetencyTagGroups();
|
||||||
@@ -631,6 +635,12 @@ public partial class LessonDialogViewModel : ObservableObject
|
|||||||
public string DialogTitle => _editingLesson is null ? "Neue Stunde anlegen" : "Stunde bearbeiten";
|
public string DialogTitle => _editingLesson is null ? "Neue Stunde anlegen" : "Stunde bearbeiten";
|
||||||
public string SaveButtonText => _editingLesson is null ? "Anlegen" : "Speichern";
|
public string SaveButtonText => _editingLesson is null ? "Anlegen" : "Speichern";
|
||||||
|
|
||||||
|
/// Gruppe + Fach der Einheit, zu der diese Stunde gehört — nicht editierbar, nur zur
|
||||||
|
/// Einordnung. Ohne das war bei gleichnamigen Klassen in mehreren Fächern (mehrere
|
||||||
|
/// Lerngruppen mit gleichem Namen) nicht erkennbar, welche Stunde man gerade bearbeitet
|
||||||
|
/// (Nutzer-Feedback).
|
||||||
|
public string GroupSubjectDisplay { get; }
|
||||||
|
|
||||||
// Für die KI-Unterstützung mit Fokus auf genau diese Stunde (4.5.22) — nur für bereits
|
// Für die KI-Unterstützung mit Fokus auf genau diese Stunde (4.5.22) — nur für bereits
|
||||||
// gespeicherte Stunden sinnvoll, eine gerade erst angelegte, noch ungespeicherte Stunde hat
|
// gespeicherte Stunden sinnvoll, eine gerade erst angelegte, noch ungespeicherte Stunde hat
|
||||||
// keine echte Id, auf die sich die KI beziehen könnte.
|
// keine echte Id, auf die sich die KI beziehen könnte.
|
||||||
@@ -645,12 +655,14 @@ public partial class LessonDialogViewModel : ObservableObject
|
|||||||
|
|
||||||
public LessonDialogViewModel(ILessonRepository lessons, IShorthandCodeRepository shorthandCodes,
|
public LessonDialogViewModel(ILessonRepository lessons, IShorthandCodeRepository shorthandCodes,
|
||||||
IAlternativeLessonPathRepository alternativePaths, ITimetableSlotRepository timetableSlots,
|
IAlternativeLessonPathRepository alternativePaths, ITimetableSlotRepository timetableSlots,
|
||||||
PeriodScheduleService periodSchedule, Guid unitId, Guid groupId,
|
PeriodScheduleService periodSchedule, Guid unitId, Guid groupId, string groupName, string subjectName,
|
||||||
List<string> materialSuggestions, List<string> shorthandHistorySuggestions, Lesson? editingLesson)
|
List<string> materialSuggestions, List<string> shorthandHistorySuggestions, Lesson? editingLesson)
|
||||||
{
|
{
|
||||||
_lessons = lessons; _alternativePaths = alternativePaths;
|
_lessons = lessons; _alternativePaths = alternativePaths;
|
||||||
_timetableSlots = timetableSlots; _periodSchedule = periodSchedule;
|
_timetableSlots = timetableSlots; _periodSchedule = periodSchedule;
|
||||||
_unitId = unitId; _groupId = groupId; _editingLesson = editingLesson;
|
_unitId = unitId; _groupId = groupId; _editingLesson = editingLesson;
|
||||||
|
GroupSubjectDisplay = string.IsNullOrWhiteSpace(subjectName)
|
||||||
|
? $"{groupName} · kein Fach hinterlegt (siehe Lerngruppe)" : $"{groupName} · {subjectName}";
|
||||||
MaterialSuggestions = [.. materialSuggestions];
|
MaterialSuggestions = [.. materialSuggestions];
|
||||||
|
|
||||||
// Vorschläge kommen sowohl aus dem gepflegten Kürzel-Katalog (Einstellungen) als auch aus
|
// Vorschläge kommen sowohl aus dem gepflegten Kürzel-Katalog (Einstellungen) als auch aus
|
||||||
|
|||||||
@@ -10,7 +10,10 @@
|
|||||||
<Grid RowDefinitions="*,Auto" Margin="24">
|
<Grid RowDefinitions="*,Auto" Margin="24">
|
||||||
<ScrollViewer Grid.Row="0">
|
<ScrollViewer Grid.Row="0">
|
||||||
<StackPanel Spacing="14" Margin="0,0,12,0">
|
<StackPanel Spacing="14" Margin="0,0,12,0">
|
||||||
<TextBlock Text="{Binding DialogTitle}" Classes="dialogtitle"/>
|
<StackPanel Spacing="2">
|
||||||
|
<TextBlock Text="{Binding DialogTitle}" Classes="dialogtitle"/>
|
||||||
|
<TextBlock Text="{Binding GroupSubjectDisplay}" FontSize="12" Opacity="0.6"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
<Grid ColumnDefinitions="*,12,*,12,*,12,*">
|
<Grid ColumnDefinitions="*,12,*,12,*,12,*">
|
||||||
<StackPanel Grid.Column="0" Spacing="4">
|
<StackPanel Grid.Column="0" Spacing="4">
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public partial class PlanningTabView : UserControl
|
|||||||
var dialogVm = new UnitDialogViewModel(
|
var dialogVm = new UnitDialogViewModel(
|
||||||
App.Services.GetRequiredService<IUnitRepository>(),
|
App.Services.GetRequiredService<IUnitRepository>(),
|
||||||
App.Services.GetRequiredService<ICompetencyDomainRepository>(),
|
App.Services.GetRequiredService<ICompetencyDomainRepository>(),
|
||||||
groupId, vm.SubjectId, vm.GradeLevel, vm.SubjectName, editingUnit);
|
groupId, vm.SubjectId, vm.GradeLevel, vm.GroupLabel, vm.SubjectName, editingUnit);
|
||||||
|
|
||||||
var dialog = new UnitDialog { DataContext = dialogVm };
|
var dialog = new UnitDialog { DataContext = dialogVm };
|
||||||
var owner = TopLevel.GetTopLevel(this) as Window;
|
var owner = TopLevel.GetTopLevel(this) as Window;
|
||||||
@@ -80,13 +80,16 @@ public partial class PlanningTabView : UserControl
|
|||||||
private async Task<bool> ShowLessonDialog(Guid unitId, Guid groupId,
|
private async Task<bool> ShowLessonDialog(Guid unitId, Guid groupId,
|
||||||
List<string> materialSuggestions, List<string> shorthandHistorySuggestions, Lesson? editingLesson)
|
List<string> materialSuggestions, List<string> shorthandHistorySuggestions, Lesson? editingLesson)
|
||||||
{
|
{
|
||||||
|
if (DataContext is not PlanningTabViewModel vm) return false;
|
||||||
|
|
||||||
var dialogVm = new LessonDialogViewModel(
|
var dialogVm = new LessonDialogViewModel(
|
||||||
App.Services.GetRequiredService<ILessonRepository>(),
|
App.Services.GetRequiredService<ILessonRepository>(),
|
||||||
App.Services.GetRequiredService<IShorthandCodeRepository>(),
|
App.Services.GetRequiredService<IShorthandCodeRepository>(),
|
||||||
App.Services.GetRequiredService<IAlternativeLessonPathRepository>(),
|
App.Services.GetRequiredService<IAlternativeLessonPathRepository>(),
|
||||||
App.Services.GetRequiredService<ITimetableSlotRepository>(),
|
App.Services.GetRequiredService<ITimetableSlotRepository>(),
|
||||||
App.Services.GetRequiredService<PeriodScheduleService>(),
|
App.Services.GetRequiredService<PeriodScheduleService>(),
|
||||||
unitId, groupId, materialSuggestions, shorthandHistorySuggestions, editingLesson);
|
unitId, groupId, vm.GroupLabel, vm.SubjectName,
|
||||||
|
materialSuggestions, shorthandHistorySuggestions, editingLesson);
|
||||||
|
|
||||||
var dialog = new LessonDialog { DataContext = dialogVm };
|
var dialog = new LessonDialog { DataContext = dialogVm };
|
||||||
var owner = TopLevel.GetTopLevel(this) as Window;
|
var owner = TopLevel.GetTopLevel(this) as Window;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<StackPanel Spacing="14" Margin="0,0,12,0">
|
<StackPanel Spacing="14" Margin="0,0,12,0">
|
||||||
<StackPanel Spacing="2">
|
<StackPanel Spacing="2">
|
||||||
<TextBlock Text="{Binding DialogTitle}" Classes="dialogtitle"/>
|
<TextBlock Text="{Binding DialogTitle}" Classes="dialogtitle"/>
|
||||||
<TextBlock Text="{Binding SubjectDisplay}" FontSize="12" Opacity="0.6"/>
|
<TextBlock Text="{Binding GroupSubjectDisplay}" FontSize="12" Opacity="0.6"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel Spacing="4">
|
<StackPanel Spacing="4">
|
||||||
|
|||||||
@@ -286,6 +286,13 @@ gruppenspezifischen Tab "Planung" (`GroupDetailView`), siehe unten.
|
|||||||
- [x] **4.1.1** Listenansicht der Einheiten je Gruppe mit Status und Zeitraum
|
- [x] **4.1.1** Listenansicht der Einheiten je Gruppe mit Status und Zeitraum
|
||||||
(ersetzt den Platzhalter im Tab "Planung").
|
(ersetzt den Platzhalter im Tab "Planung").
|
||||||
- [x] **4.1.2** Dialog Einheit anlegen/bearbeiten: Titel, Fach, Zeitraum, Status, Notizen.
|
- [x] **4.1.2** Dialog Einheit anlegen/bearbeiten: Titel, Fach, Zeitraum, Status, Notizen.
|
||||||
|
|
||||||
|
**Nachtrag (Nutzer-Feedback, im Zuge des 4.3.3-Bugfixes):** Bei einer Klasse, die in
|
||||||
|
mehreren Fächern unterrichtet wird (mehrere `LearningGroup`-Datensätze mit gleichem Namen,
|
||||||
|
z.B. zwei "10c"), zeigte der Dialog bisher nur das Fach ("Fach: Chemie"), nicht welche
|
||||||
|
Klasse gemeint ist — beides zusammen war nirgends auf einen Blick zu sehen. Jetzt zeigen
|
||||||
|
sowohl `UnitDialog` (Einheit) als auch `LessonDialog` (Stunde) direkt unter dem Dialogtitel
|
||||||
|
"Gruppe · Fach" (z.B. "10c · Chemie"), nicht editierbar, nur zur Einordnung.
|
||||||
- [x] **4.1.3** Kompetenzen aus dem Katalog (siehe 8) einer Einheit zuordnen — Mehrfachauswahl.
|
- [x] **4.1.3** Kompetenzen aus dem Katalog (siehe 8) einer Einheit zuordnen — Mehrfachauswahl.
|
||||||
- [x] **4.1.4** Einheit als Vorlage speichern und in eine andere Gruppe kopieren
|
- [x] **4.1.4** Einheit als Vorlage speichern und in eine andere Gruppe kopieren
|
||||||
(inkl. Stunden, ohne Datumsbezug).
|
(inkl. Stunden, ohne Datumsbezug).
|
||||||
|
|||||||
Reference in New Issue
Block a user