color Changes
This commit is contained in:
parent
b617d39c8f
commit
549ab3e53b
@ -1,5 +0,0 @@
|
||||
namespace ChronoFlow.Controller;
|
||||
|
||||
public class Class1
|
||||
{
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
namespace ChronoFlow.Model;
|
||||
|
||||
public class Class1
|
||||
{
|
||||
}
|
||||
@ -23,5 +23,6 @@ namespace ChronoFlow.Model
|
||||
OriginalUsername = "";
|
||||
}
|
||||
public DateTime LetzterLogin { get; set; } = DateTime.MinValue;
|
||||
public DateTime VorletzterLogin { get; set; }
|
||||
}
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
namespace ChronoFlow.Persistence;
|
||||
|
||||
public class Class1
|
||||
{
|
||||
}
|
||||
@ -23,6 +23,8 @@ namespace ChronoFlow.Persistence
|
||||
|
||||
// IMMER prüfen, auch nach neuem Erstellen
|
||||
PrüfeUndErweitereDatenbank();
|
||||
|
||||
_ = StelleDatenbankstrukturSicherAsync(); // Async-Aufruf ignorieren
|
||||
}
|
||||
|
||||
private void ErstelleDatenbank()
|
||||
@ -92,6 +94,8 @@ namespace ChronoFlow.Persistence
|
||||
AddColumnIfMissing(connection, "Benutzer", "Mitarbeitennummer", "TEXT");
|
||||
AddColumnIfMissing(connection, "Benutzer", "Abteilung", "TEXT");
|
||||
AddColumnIfMissing(connection, "Benutzer", "MussPasswortAendern", "INTEGER DEFAULT 1");
|
||||
AddColumnIfMissing(connection, "Benutzer", "LetzterLogin", "TEXT");
|
||||
AddColumnIfMissing(connection, "Benutzer", "VorletzterLogin", "TEXT");
|
||||
AddColumnIfMissing(connection, "Zeiteintraege", "LetzteBearbeitung", "TEXT");
|
||||
}
|
||||
|
||||
@ -158,11 +162,24 @@ namespace ChronoFlow.Persistence
|
||||
connection.Open();
|
||||
|
||||
var cmd = connection.CreateCommand();
|
||||
cmd.CommandText = "SELECT Id, Username, Password, Role, Mitarbeitennummer, Abteilung, MussPasswortAendern FROM Benutzer;";
|
||||
cmd.CommandText = @"
|
||||
SELECT Id, Username, Password, Role, Mitarbeitennummer, Abteilung, MussPasswortAendern, LetzterLogin, VorletzterLogin
|
||||
FROM Benutzer;
|
||||
";
|
||||
|
||||
using var reader = cmd.ExecuteReader();
|
||||
while (reader.Read())
|
||||
{
|
||||
// Absicherungen für mögliche NULL- oder ungültige Werte:
|
||||
var letzterLogin = DateTime.MinValue;
|
||||
var vorletzterLogin = DateTime.MinValue;
|
||||
|
||||
if (!reader.IsDBNull(7))
|
||||
DateTime.TryParse(reader.GetString(7), out letzterLogin);
|
||||
|
||||
if (!reader.IsDBNull(8))
|
||||
DateTime.TryParse(reader.GetString(8), out vorletzterLogin);
|
||||
|
||||
benutzerListe.Add(new User
|
||||
{
|
||||
Id = reader.GetInt32(0),
|
||||
@ -172,6 +189,8 @@ namespace ChronoFlow.Persistence
|
||||
Mitarbeiternummer = reader.IsDBNull(4) ? "" : reader.GetString(4),
|
||||
Abteilung = reader.IsDBNull(5) ? "" : reader.GetString(5),
|
||||
MussPasswortAendern = reader.GetInt32(6) == 1,
|
||||
LetzterLogin = letzterLogin,
|
||||
VorletzterLogin = vorletzterLogin,
|
||||
OriginalUsername = reader.GetString(1)
|
||||
});
|
||||
}
|
||||
@ -179,6 +198,7 @@ namespace ChronoFlow.Persistence
|
||||
return benutzerListe;
|
||||
}
|
||||
|
||||
|
||||
public void UpdateBenutzer(User benutzer)
|
||||
{
|
||||
using var connection = new SqliteConnection($"Data Source={_dbPath}");
|
||||
@ -468,6 +488,26 @@ VALUES
|
||||
Console.WriteLine($"🔒 Passwort für Benutzer '{username}' zurückgesetzt (Rows affected: {rowsAffected})");
|
||||
}
|
||||
|
||||
public void UpdateLoginZeiten(User user)
|
||||
{
|
||||
using var connection = new SqliteConnection($"Data Source={_dbPath}");
|
||||
connection.Open();
|
||||
|
||||
var cmd = connection.CreateCommand();
|
||||
cmd.CommandText = @"
|
||||
UPDATE Benutzer
|
||||
SET LetzterLogin = $LetzterLogin,
|
||||
VorletzterLogin = $VorletzterLogin
|
||||
WHERE Username = $Username;
|
||||
";
|
||||
|
||||
cmd.Parameters.AddWithValue("$LetzterLogin", user.LetzterLogin.ToString("o"));
|
||||
cmd.Parameters.AddWithValue("$VorletzterLogin", user.VorletzterLogin.ToString("o"));
|
||||
cmd.Parameters.AddWithValue("$Username", user.Username);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
public async Task<List<Zeiteintrag>> GetEintraegeFuerMitarbeiterAsync(string name)
|
||||
{
|
||||
var eintraege = new List<Zeiteintrag>();
|
||||
@ -504,6 +544,43 @@ VALUES
|
||||
return eintraege;
|
||||
}
|
||||
|
||||
public async Task StelleDatenbankstrukturSicherAsync()
|
||||
{
|
||||
using var connection = new SqliteConnection($"Data Source={_dbPath}");
|
||||
await connection.OpenAsync();
|
||||
|
||||
//Überprüfung ob die Spalte "Voletzter Login" bereits besteht
|
||||
var checkCmd = connection.CreateCommand();
|
||||
checkCmd.CommandText = "PRAGMA table_info(Benutzer);";
|
||||
|
||||
var reader = await checkCmd.ExecuteReaderAsync();
|
||||
bool spalteExistiert = false;
|
||||
|
||||
while (await reader.ReadAsync())
|
||||
{
|
||||
if (reader.GetString(1).Equals("Vorletzer Login", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
spalteExistiert = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
await reader.DisposeAsync();
|
||||
|
||||
if (!spalteExistiert)
|
||||
{
|
||||
var alterCmd = connection.CreateCommand();
|
||||
alterCmd.CommandText = "ALTER TABLE Benutzer ADD COLUMN VorletzterLogin TEXT;";
|
||||
await alterCmd.ExecuteNonQueryAsync();
|
||||
|
||||
Console.WriteLine("🛠 Spalte 'VorletzterLogin' wurde zur Tabelle 'Benutzer' hinzugefügt.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("✅ Spalte 'VorletzterLogin' ist bereits vorhanden.");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task UpdateStatusUndKommentarAsync(int id, bool erledigt, string mitarbeiterKommentar)
|
||||
{
|
||||
using var connection = new SqliteConnection($"Data Source={_dbPath}");
|
||||
|
||||
@ -3,29 +3,60 @@
|
||||
xmlns:model1="clr-namespace:ChronoFlow.Model;assembly=ChronoFlow.Model"
|
||||
x:Class="ChronoFlow.View.Admin.AlleProjekteView">
|
||||
<Grid RowDefinitions="Auto,Auto,*,Auto" Margin="20">
|
||||
<TextBlock Grid.Row="0" Text="Alle Projekte" FontSize="20" FontWeight="Bold" HorizontalAlignment="Center" Margin="0,0,0,10"/>
|
||||
|
||||
<TextBox Grid.Row="1" x:Name="Suchfeld" Watermark="🔍 Nach Projekt oder Mitarbeiter suchen..." KeyUp="Suchfeld_KeyUp" Margin="0,0,0,10"/>
|
||||
<!-- Überschrift -->
|
||||
<TextBlock Grid.Row="0" Text="Alle Projekte" FontSize="20" FontWeight="Bold"
|
||||
HorizontalAlignment="Center" Margin="0,0,0,10"/>
|
||||
|
||||
<!-- Suchfeld -->
|
||||
<TextBox Grid.Row="1" x:Name="Suchfeld" Watermark="🔍 Nach Projekt oder Mitarbeiter suchen..."
|
||||
KeyUp="Suchfeld_KeyUp" Margin="0,0,0,10"/>
|
||||
|
||||
<!-- Projektliste -->
|
||||
<ScrollViewer Grid.Row="2">
|
||||
<ListBox x:Name="ProjekteListe">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type model1:Zeiteintrag}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="10" Margin="5">
|
||||
<TextBlock Text="{Binding Projekt}" Width="150"/>
|
||||
<TextBlock Text="{Binding Mitarbeiter}" Width="150"/>
|
||||
<TextBlock Text="{Binding Startzeit}" Width="150"/>
|
||||
<TextBlock Text="{Binding Endzeit}" Width="150"/>
|
||||
<TextBlock Text="{Binding Kommentar}" Width="200"/>
|
||||
<Button Content="🖋 Bearbeiten" Tag="{Binding}" Click="Bearbeiten_Click"/>
|
||||
<Button Content="🗑 Löschen" Tag="{Binding}" Click="Loeschen_Click"/>
|
||||
<Button Content="✅ Abschließen" Tag="{Binding}" Click="Abschliessen_Click"/>
|
||||
</StackPanel>
|
||||
<Border BorderBrush="Gray" BorderThickness="1" CornerRadius="5" Padding="10" Margin="0,5">
|
||||
<StackPanel Spacing="5">
|
||||
|
||||
<!-- Projektübersicht -->
|
||||
<StackPanel Orientation="Horizontal" Spacing="10">
|
||||
<TextBlock Text="{Binding Projekt}" Width="150"/>
|
||||
<TextBlock Text="{Binding Mitarbeiter}" Width="150"/>
|
||||
<TextBlock Text="{Binding Startzeit}" Width="150"/>
|
||||
<TextBlock Text="{Binding Endzeit}" Width="150"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Kommentar vom Admin -->
|
||||
<TextBlock Text="📝 Kommentar (Admin):" FontSize="12" Foreground="LightGray"/>
|
||||
<TextBlock Text="{Binding Kommentar}" FontWeight="SemiBold"/>
|
||||
|
||||
<!-- Kommentar vom Mitarbeiter -->
|
||||
<TextBlock Text="💬 Kommentar (Mitarbeiter):" FontSize="12" Foreground="LightGray"/>
|
||||
<TextBlock Text="{Binding MitarbeiterKommentar}"
|
||||
FontStyle="Italic"
|
||||
Foreground="Gray"
|
||||
FontSize="12"
|
||||
TextWrapping="Wrap"
|
||||
Margin="0,2,0,0"/>
|
||||
|
||||
<!-- Aktionsbuttons -->
|
||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||
<Button Content="🖋 Bearbeiten" Tag="{Binding}" Click="Bearbeiten_Click"/>
|
||||
<Button Content="🗑 Löschen" Tag="{Binding}" Click="Loeschen_Click"/>
|
||||
<Button Content="✅ Abschließen" Tag="{Binding}" Click="Abschliessen_Click"/>
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</ScrollViewer>
|
||||
|
||||
<Button Grid.Row="3" Content="⬅ Zurück zum Dashboard" Click="ZurueckButton_Click" HorizontalAlignment="Center" Margin="0,10,0,0"/>
|
||||
<!-- Zurück-Button -->
|
||||
<Button Grid.Row="3" Content="⬅ Zurück zum Dashboard"
|
||||
Click="ZurueckButton_Click" HorizontalAlignment="Center" Margin="0,10,0,0"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@ -26,13 +26,10 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="MitarbeiterHinzufuegenView.axaml.cs">
|
||||
<DependentUpon>MitarbeiterHinzufuegenView.axaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Mitarbeiter\EmployeeTasksViewModel.axaml.cs">
|
||||
<DependentUpon>EmployeeTasksViewModel.axaml.axaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="MitarbeiterHinzufuegenView.axaml.cs">
|
||||
<DependentUpon>MitarbeiterHinzufuegenView.axaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@ -10,15 +10,17 @@ namespace ChronoFlow.View.Converter
|
||||
public IBrush TrueBrush { get; set; } = Brushes.Blue;
|
||||
public IBrush FalseBrush { get; set; } = Brushes.Gray;
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is bool b)
|
||||
return b ? TrueBrush : FalseBrush;
|
||||
if (value is bool boolValue && boolValue)
|
||||
return Brushes.Blue;
|
||||
|
||||
return FalseBrush;
|
||||
return Brushes.Gray;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
|
||||
throw new NotSupportedException();
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException(); // wird i.d.R. nicht benötigt
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -106,13 +106,20 @@ namespace ChronoFlow.View
|
||||
try
|
||||
{
|
||||
Console.WriteLine("🚀 Öffne MainWindow...");
|
||||
|
||||
// ⏱️ bisherigen Login sichern und VorletzterLogin setzen
|
||||
var bisherigerLogin = user.LetzterLogin;
|
||||
user.LetzterLogin = DateTime.Now;
|
||||
user.VorletzterLogin = bisherigerLogin;
|
||||
|
||||
// 💾 Neue Login-Zeitpunkte speichern
|
||||
service.UpdateLoginZeiten(user);
|
||||
|
||||
// Fenster öffnen
|
||||
var main = new MainWindow(user);
|
||||
main.Show();
|
||||
Console.WriteLine("✅ MainWindow wurde geöffnet.");
|
||||
|
||||
this.Close();
|
||||
Console.WriteLine("✅ LoginWindow wurde geschlossen.");
|
||||
main.Activate(); // ✨ explizit in den Vordergrund bringen
|
||||
Close(); // LoginWindow erst danach schließen
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@ -1,16 +1,12 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:ChronoFlow.ViewModels.Mitarbeiter"
|
||||
xmlns:converter="clr-namespace:ChronoFlow.View.Converter"
|
||||
x:Class="ChronoFlow.View.Mitarbeiter.EmployeeTasksView">
|
||||
<UserControl.Resources>
|
||||
<converter:BoolToBrushConverter x:Key="BoolToBrushConverter"/>
|
||||
</UserControl.Resources>
|
||||
|
||||
<ScrollViewer>
|
||||
<StackPanel Margin="20" Spacing="10">
|
||||
<TextBlock Text="Meine Aufgaben" FontSize="24" FontWeight="Bold"/>
|
||||
|
||||
<!-- 🟢 Der Hinweis kommt vor dem ItemsControl -->
|
||||
<!-- Hinweis bei leerer Liste -->
|
||||
<TextBlock Text="🎉 Du hast aktuell keine Aufgaben!"
|
||||
FontSize="16"
|
||||
FontStyle="Italic"
|
||||
@ -18,16 +14,29 @@
|
||||
HorizontalAlignment="Center"
|
||||
IsVisible="{Binding HatKeineEintraege}"/>
|
||||
|
||||
<!-- 📝 Die eigentliche Aufgabenliste -->
|
||||
<!-- Aufgabenliste -->
|
||||
<ItemsControl ItemsSource="{Binding Eintraege}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border BorderBrush="{Binding WurdeSeitLoginBearbeitet, Converter={StaticResource BoolToBrushConverter}}"
|
||||
BorderThickness="1" CornerRadius="4" Padding="10" Margin="5">
|
||||
<StackPanel Spacing="5">
|
||||
|
||||
<!-- Projekttitel -->
|
||||
<TextBlock Text="{Binding Projekt}" FontWeight="Bold"/>
|
||||
<CheckBox Content="Erledigt" IsChecked="{Binding Erledigt}"/>
|
||||
|
||||
<!-- Admin-Kommentar -->
|
||||
<TextBlock Text="📝 Kommentar (Admin):" FontSize="12" Foreground="LightGray"/>
|
||||
<TextBlock Text="{Binding Kommentar}" FontWeight="SemiBold"/>
|
||||
|
||||
<!-- Mitarbeiter-Kommentar -->
|
||||
<TextBlock Text="💬 Dein Kommentar:" FontSize="12" Foreground="LightGray"/>
|
||||
<TextBox Text="{Binding MitarbeiterKommentar}" Watermark="Kommentar hinzufügen..."/>
|
||||
|
||||
<!-- Erledigt-Checkbox -->
|
||||
<CheckBox Content="Erledigt" IsChecked="{Binding Erledigt}"/>
|
||||
|
||||
<!-- Deadline -->
|
||||
<TextBlock Text="{Binding Endzeit, StringFormat='Deadline: {0:dd.MM.yyyy}'}"
|
||||
Foreground="{Binding PrioritaetsFarbe}"
|
||||
FontWeight="Bold" FontSize="14"/>
|
||||
@ -37,9 +46,9 @@
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
<!-- Speichern -->
|
||||
<Button Content="Änderungen speichern" Command="{Binding SpeichereEintraegeCommand}"/>
|
||||
<TextBlock Text="{Binding StatusText}" Foreground="Green" FontStyle="Italic"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
</UserControl>
|
||||
@ -1,5 +1,5 @@
|
||||
using Avalonia.Controls;
|
||||
using ChronoFlow.ViewModels.Mitarbeiter;
|
||||
using ChronoFlow.View.Mitarbeiter;
|
||||
using ChronoFlow.Persistence;
|
||||
using ChronoFlow.Model;
|
||||
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:viewmodels="clr-namespace:ChronoFlow.ViewModels"
|
||||
mc:Ignorable="d">
|
||||
<StackPanel Margin="20" Spacing="10">
|
||||
<TextBlock Text="Meine Aufgaben" FontSize="24" FontWeight="Bold"/>
|
||||
|
||||
<ItemsControl ItemsSource="{Binding Eintraege}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border BorderThickness="1" BorderBrush="Gray" Padding="10" Margin="5">
|
||||
<StackPanel Spacing="5">
|
||||
<TextBlock Text="{Binding TaskDescription}" FontWeight="Bold"/>
|
||||
<TextBlock Text="{Binding Date}" FontStyle="Italic"/>
|
||||
<TextBlock Text="Priorität: {Binding Priority}" Foreground="DarkRed"/>
|
||||
<CheckBox Content="Erledigt" IsChecked="{Binding IsCompleted}"/>
|
||||
<TextBox Text="{Binding Comment}" Watermark="Kommentar eingeben..."/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
<Button Content="Änderungen speichern" Command="{Binding SaveChangesCommand}" HorizontalAlignment="Right"/>
|
||||
<TextBlock Text="{Binding StatusText}"
|
||||
Foreground="Green"
|
||||
FontStyle="Italic"
|
||||
FontWeight="SemiBold"
|
||||
Margin="5"/>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@ -1,3 +1,4 @@
|
||||
// TestKommentar
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
@ -6,28 +7,49 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using ChronoFlow.Model;
|
||||
using ChronoFlow.Persistence;
|
||||
using ChronoFlow.View.Mitarbeiter;
|
||||
|
||||
namespace ChronoFlow.ViewModels.Mitarbeiter
|
||||
namespace ChronoFlow.View.Mitarbeiter
|
||||
{
|
||||
/// <summary>
|
||||
/// ViewModel für die Mitarbeiter-Aufgabenansicht.
|
||||
/// Enthält alle Aufgaben für den eingeloggten Benutzer und erlaubt das Speichern von Änderungen.
|
||||
/// </summary>
|
||||
public partial class EmployeeTasksViewModel : ObservableObject
|
||||
{
|
||||
// 🧑💼 Der aktuell eingeloggte Benutzer (Mitarbeiter)
|
||||
private readonly User _benutzer;
|
||||
|
||||
// 💾 Zugriff auf die Datenbank-Funktionen (SQL-Repository)
|
||||
private readonly IZeiterfassungsRepository _repository;
|
||||
|
||||
// 📛 Einfacher Zugriff auf den Benutzernamen (spart Schreibarbeit)
|
||||
private readonly string aktuellerBenutzername;
|
||||
|
||||
// 📋 Alle Zeiteinträge, die dem Benutzer angezeigt werden
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<Zeiteintrag> eintraege = new();
|
||||
|
||||
// 💬 Statusmeldung unten im Fenster (z. B. bei Erfolg)
|
||||
[ObservableProperty]
|
||||
private string? statusText;
|
||||
|
||||
// ✅ Hilfs-Property, die sagt: "Gibt es keine Einträge?"
|
||||
public bool HatKeineEintraege => Eintraege.Count == 0;
|
||||
|
||||
/// <summary>
|
||||
/// Diese Methode wird automatisch aufgerufen, wenn sich die Einträge ändern.
|
||||
/// Damit wird die UI über die Änderung von 'HatKeineEintraege' informiert.
|
||||
/// </summary>
|
||||
partial void OnEintraegeChanged(ObservableCollection<Zeiteintrag>? oldValue, ObservableCollection<Zeiteintrag> newValue)
|
||||
{
|
||||
OnPropertyChanged(nameof(HatKeineEintraege));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Konstruktor: Bekommt den eingeloggten Benutzer und das Repository.
|
||||
/// Lädt automatisch alle offenen Einträge für diesen Benutzer.
|
||||
/// </summary>
|
||||
public EmployeeTasksViewModel(User benutzer, IZeiterfassungsRepository repository)
|
||||
{
|
||||
_benutzer = benutzer;
|
||||
@ -36,9 +58,15 @@ namespace ChronoFlow.ViewModels.Mitarbeiter
|
||||
|
||||
Console.WriteLine($"[DEBUG] ViewModel erstellt für Benutzer: {aktuellerBenutzername}");
|
||||
|
||||
_ = LadeEintraegeAsync(); // Lade Daten automatisch beim Öffnen
|
||||
// Daten automatisch beim Öffnen laden
|
||||
_ = LadeEintraegeAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lädt alle offenen Einträge für den aktuell eingeloggten Mitarbeiter.
|
||||
/// Sortiert nach Fälligkeitsdatum (Endzeit).
|
||||
/// Erkennt auch, ob seit dem letzten Login Änderungen gemacht wurden.
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
public async Task LadeEintraegeAsync()
|
||||
{
|
||||
@ -49,23 +77,25 @@ namespace ChronoFlow.ViewModels.Mitarbeiter
|
||||
.OrderBy(e => e.Endzeit)
|
||||
.ToList();
|
||||
|
||||
// 🔔 Setze Markierung für geänderte Aufgaben
|
||||
// 🔔 Markiere geänderte Einträge seit dem letzten Login
|
||||
foreach (var eintrag in offene)
|
||||
{
|
||||
eintrag.WurdeSeitLoginBearbeitet = eintrag.LetzteBearbeitung > _benutzer.LetzterLogin;
|
||||
|
||||
// 🔍 Debug-Ausgabe zur Prüfung
|
||||
Console.WriteLine($"[DEBUG] Eintrag {eintrag.Id}: Endzeit={eintrag.Endzeit}, LetzteBearbeitung={eintrag.LetzteBearbeitung}, LetzterLogin={_benutzer.LetzterLogin}, Markiert={eintrag.WurdeSeitLoginBearbeitet}");
|
||||
eintrag.WurdeSeitLoginBearbeitet = eintrag.LetzteBearbeitung > _benutzer.VorletzterLogin;
|
||||
}
|
||||
|
||||
|
||||
// 🔔 Zeige Hinweis, wenn neue Änderungen vorhanden sind
|
||||
if (offene.Any(e => e.WurdeSeitLoginBearbeitet))
|
||||
StatusText = "📢 Es wurden Aufgaben seit Ihrem letzten Login geändert.";
|
||||
|
||||
// 🔄 Aktualisiere ObservableCollection für UI
|
||||
Eintraege = new ObservableCollection<Zeiteintrag>(offene);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Speichert alle Änderungen an den sichtbaren Einträgen
|
||||
/// (Status 'erledigt' + Mitarbeiter-Kommentar).
|
||||
/// Danach wird die Liste automatisch neu geladen.
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
public async Task SpeichereEintraegeAsync()
|
||||
{
|
||||
@ -79,7 +109,9 @@ namespace ChronoFlow.ViewModels.Mitarbeiter
|
||||
}
|
||||
|
||||
StatusText = "✅ Änderungen gespeichert.";
|
||||
await LadeEintraegeAsync(); // automatisch neu laden
|
||||
|
||||
// 🔄 Nach dem Speichern direkt neu laden
|
||||
await LadeEintraegeAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user