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 = "";
|
OriginalUsername = "";
|
||||||
}
|
}
|
||||||
public DateTime LetzterLogin { get; set; } = DateTime.MinValue;
|
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
|
// IMMER prüfen, auch nach neuem Erstellen
|
||||||
PrüfeUndErweitereDatenbank();
|
PrüfeUndErweitereDatenbank();
|
||||||
|
|
||||||
|
_ = StelleDatenbankstrukturSicherAsync(); // Async-Aufruf ignorieren
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ErstelleDatenbank()
|
private void ErstelleDatenbank()
|
||||||
@ -92,6 +94,8 @@ namespace ChronoFlow.Persistence
|
|||||||
AddColumnIfMissing(connection, "Benutzer", "Mitarbeitennummer", "TEXT");
|
AddColumnIfMissing(connection, "Benutzer", "Mitarbeitennummer", "TEXT");
|
||||||
AddColumnIfMissing(connection, "Benutzer", "Abteilung", "TEXT");
|
AddColumnIfMissing(connection, "Benutzer", "Abteilung", "TEXT");
|
||||||
AddColumnIfMissing(connection, "Benutzer", "MussPasswortAendern", "INTEGER DEFAULT 1");
|
AddColumnIfMissing(connection, "Benutzer", "MussPasswortAendern", "INTEGER DEFAULT 1");
|
||||||
|
AddColumnIfMissing(connection, "Benutzer", "LetzterLogin", "TEXT");
|
||||||
|
AddColumnIfMissing(connection, "Benutzer", "VorletzterLogin", "TEXT");
|
||||||
AddColumnIfMissing(connection, "Zeiteintraege", "LetzteBearbeitung", "TEXT");
|
AddColumnIfMissing(connection, "Zeiteintraege", "LetzteBearbeitung", "TEXT");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,11 +162,24 @@ namespace ChronoFlow.Persistence
|
|||||||
connection.Open();
|
connection.Open();
|
||||||
|
|
||||||
var cmd = connection.CreateCommand();
|
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();
|
using var reader = cmd.ExecuteReader();
|
||||||
while (reader.Read())
|
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
|
benutzerListe.Add(new User
|
||||||
{
|
{
|
||||||
Id = reader.GetInt32(0),
|
Id = reader.GetInt32(0),
|
||||||
@ -172,6 +189,8 @@ namespace ChronoFlow.Persistence
|
|||||||
Mitarbeiternummer = reader.IsDBNull(4) ? "" : reader.GetString(4),
|
Mitarbeiternummer = reader.IsDBNull(4) ? "" : reader.GetString(4),
|
||||||
Abteilung = reader.IsDBNull(5) ? "" : reader.GetString(5),
|
Abteilung = reader.IsDBNull(5) ? "" : reader.GetString(5),
|
||||||
MussPasswortAendern = reader.GetInt32(6) == 1,
|
MussPasswortAendern = reader.GetInt32(6) == 1,
|
||||||
|
LetzterLogin = letzterLogin,
|
||||||
|
VorletzterLogin = vorletzterLogin,
|
||||||
OriginalUsername = reader.GetString(1)
|
OriginalUsername = reader.GetString(1)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -179,6 +198,7 @@ namespace ChronoFlow.Persistence
|
|||||||
return benutzerListe;
|
return benutzerListe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void UpdateBenutzer(User benutzer)
|
public void UpdateBenutzer(User benutzer)
|
||||||
{
|
{
|
||||||
using var connection = new SqliteConnection($"Data Source={_dbPath}");
|
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})");
|
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)
|
public async Task<List<Zeiteintrag>> GetEintraegeFuerMitarbeiterAsync(string name)
|
||||||
{
|
{
|
||||||
var eintraege = new List<Zeiteintrag>();
|
var eintraege = new List<Zeiteintrag>();
|
||||||
@ -504,6 +544,43 @@ VALUES
|
|||||||
return eintraege;
|
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)
|
public async Task UpdateStatusUndKommentarAsync(int id, bool erledigt, string mitarbeiterKommentar)
|
||||||
{
|
{
|
||||||
using var connection = new SqliteConnection($"Data Source={_dbPath}");
|
using var connection = new SqliteConnection($"Data Source={_dbPath}");
|
||||||
|
|||||||
@ -3,29 +3,60 @@
|
|||||||
xmlns:model1="clr-namespace:ChronoFlow.Model;assembly=ChronoFlow.Model"
|
xmlns:model1="clr-namespace:ChronoFlow.Model;assembly=ChronoFlow.Model"
|
||||||
x:Class="ChronoFlow.View.Admin.AlleProjekteView">
|
x:Class="ChronoFlow.View.Admin.AlleProjekteView">
|
||||||
<Grid RowDefinitions="Auto,Auto,*,Auto" Margin="20">
|
<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">
|
<ScrollViewer Grid.Row="2">
|
||||||
<ListBox x:Name="ProjekteListe">
|
<ListBox x:Name="ProjekteListe">
|
||||||
<ListBox.ItemTemplate>
|
<ListBox.ItemTemplate>
|
||||||
<DataTemplate DataType="{x:Type model1:Zeiteintrag}">
|
<DataTemplate DataType="{x:Type model1:Zeiteintrag}">
|
||||||
<StackPanel Orientation="Horizontal" Spacing="10" Margin="5">
|
<Border BorderBrush="Gray" BorderThickness="1" CornerRadius="5" Padding="10" Margin="0,5">
|
||||||
<TextBlock Text="{Binding Projekt}" Width="150"/>
|
<StackPanel Spacing="5">
|
||||||
<TextBlock Text="{Binding Mitarbeiter}" Width="150"/>
|
|
||||||
<TextBlock Text="{Binding Startzeit}" Width="150"/>
|
<!-- Projektübersicht -->
|
||||||
<TextBlock Text="{Binding Endzeit}" Width="150"/>
|
<StackPanel Orientation="Horizontal" Spacing="10">
|
||||||
<TextBlock Text="{Binding Kommentar}" Width="200"/>
|
<TextBlock Text="{Binding Projekt}" Width="150"/>
|
||||||
<Button Content="🖋 Bearbeiten" Tag="{Binding}" Click="Bearbeiten_Click"/>
|
<TextBlock Text="{Binding Mitarbeiter}" Width="150"/>
|
||||||
<Button Content="🗑 Löschen" Tag="{Binding}" Click="Loeschen_Click"/>
|
<TextBlock Text="{Binding Startzeit}" Width="150"/>
|
||||||
<Button Content="✅ Abschließen" Tag="{Binding}" Click="Abschliessen_Click"/>
|
<TextBlock Text="{Binding Endzeit}" Width="150"/>
|
||||||
</StackPanel>
|
</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>
|
</DataTemplate>
|
||||||
</ListBox.ItemTemplate>
|
</ListBox.ItemTemplate>
|
||||||
</ListBox>
|
</ListBox>
|
||||||
</ScrollViewer>
|
</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>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@ -26,13 +26,10 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Update="MitarbeiterHinzufuegenView.axaml.cs">
|
<Compile Update="MitarbeiterHinzufuegenView.axaml.cs">
|
||||||
<DependentUpon>MitarbeiterHinzufuegenView.axaml</DependentUpon>
|
<DependentUpon>MitarbeiterHinzufuegenView.axaml</DependentUpon>
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Update="Mitarbeiter\EmployeeTasksViewModel.axaml.cs">
|
|
||||||
<DependentUpon>EmployeeTasksViewModel.axaml.axaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -10,15 +10,17 @@ namespace ChronoFlow.View.Converter
|
|||||||
public IBrush TrueBrush { get; set; } = Brushes.Blue;
|
public IBrush TrueBrush { get; set; } = Brushes.Blue;
|
||||||
public IBrush FalseBrush { get; set; } = Brushes.Gray;
|
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)
|
if (value is bool boolValue && boolValue)
|
||||||
return b ? TrueBrush : FalseBrush;
|
return Brushes.Blue;
|
||||||
|
|
||||||
return FalseBrush;
|
return Brushes.Gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
throw new NotSupportedException();
|
{
|
||||||
|
throw new NotImplementedException(); // wird i.d.R. nicht benötigt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,13 +106,20 @@ namespace ChronoFlow.View
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Console.WriteLine("🚀 Öffne MainWindow...");
|
Console.WriteLine("🚀 Öffne MainWindow...");
|
||||||
|
|
||||||
|
// ⏱️ bisherigen Login sichern und VorletzterLogin setzen
|
||||||
|
var bisherigerLogin = user.LetzterLogin;
|
||||||
user.LetzterLogin = DateTime.Now;
|
user.LetzterLogin = DateTime.Now;
|
||||||
|
user.VorletzterLogin = bisherigerLogin;
|
||||||
|
|
||||||
|
// 💾 Neue Login-Zeitpunkte speichern
|
||||||
|
service.UpdateLoginZeiten(user);
|
||||||
|
|
||||||
|
// Fenster öffnen
|
||||||
var main = new MainWindow(user);
|
var main = new MainWindow(user);
|
||||||
main.Show();
|
main.Show();
|
||||||
Console.WriteLine("✅ MainWindow wurde geöffnet.");
|
main.Activate(); // ✨ explizit in den Vordergrund bringen
|
||||||
|
Close(); // LoginWindow erst danach schließen
|
||||||
this.Close();
|
|
||||||
Console.WriteLine("✅ LoginWindow wurde geschlossen.");
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,16 +1,12 @@
|
|||||||
<UserControl xmlns="https://github.com/avaloniaui"
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
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">
|
x:Class="ChronoFlow.View.Mitarbeiter.EmployeeTasksView">
|
||||||
<UserControl.Resources>
|
|
||||||
<converter:BoolToBrushConverter x:Key="BoolToBrushConverter"/>
|
|
||||||
</UserControl.Resources>
|
|
||||||
<ScrollViewer>
|
<ScrollViewer>
|
||||||
<StackPanel Margin="20" Spacing="10">
|
<StackPanel Margin="20" Spacing="10">
|
||||||
<TextBlock Text="Meine Aufgaben" FontSize="24" FontWeight="Bold"/>
|
<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!"
|
<TextBlock Text="🎉 Du hast aktuell keine Aufgaben!"
|
||||||
FontSize="16"
|
FontSize="16"
|
||||||
FontStyle="Italic"
|
FontStyle="Italic"
|
||||||
@ -18,16 +14,29 @@
|
|||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
IsVisible="{Binding HatKeineEintraege}"/>
|
IsVisible="{Binding HatKeineEintraege}"/>
|
||||||
|
|
||||||
<!-- 📝 Die eigentliche Aufgabenliste -->
|
<!-- Aufgabenliste -->
|
||||||
<ItemsControl ItemsSource="{Binding Eintraege}">
|
<ItemsControl ItemsSource="{Binding Eintraege}">
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Border BorderBrush="{Binding WurdeSeitLoginBearbeitet, Converter={StaticResource BoolToBrushConverter}}"
|
<Border BorderBrush="{Binding WurdeSeitLoginBearbeitet, Converter={StaticResource BoolToBrushConverter}}"
|
||||||
BorderThickness="1" CornerRadius="4" Padding="10" Margin="5">
|
BorderThickness="1" CornerRadius="4" Padding="10" Margin="5">
|
||||||
<StackPanel Spacing="5">
|
<StackPanel Spacing="5">
|
||||||
|
|
||||||
|
<!-- Projekttitel -->
|
||||||
<TextBlock Text="{Binding Projekt}" FontWeight="Bold"/>
|
<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..."/>
|
<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}'}"
|
<TextBlock Text="{Binding Endzeit, StringFormat='Deadline: {0:dd.MM.yyyy}'}"
|
||||||
Foreground="{Binding PrioritaetsFarbe}"
|
Foreground="{Binding PrioritaetsFarbe}"
|
||||||
FontWeight="Bold" FontSize="14"/>
|
FontWeight="Bold" FontSize="14"/>
|
||||||
@ -37,9 +46,9 @@
|
|||||||
</ItemsControl.ItemTemplate>
|
</ItemsControl.ItemTemplate>
|
||||||
</ItemsControl>
|
</ItemsControl>
|
||||||
|
|
||||||
|
<!-- Speichern -->
|
||||||
<Button Content="Änderungen speichern" Command="{Binding SpeichereEintraegeCommand}"/>
|
<Button Content="Änderungen speichern" Command="{Binding SpeichereEintraegeCommand}"/>
|
||||||
<TextBlock Text="{Binding StatusText}" Foreground="Green" FontStyle="Italic"/>
|
<TextBlock Text="{Binding StatusText}" Foreground="Green" FontStyle="Italic"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@ -1,5 +1,5 @@
|
|||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using ChronoFlow.ViewModels.Mitarbeiter;
|
using ChronoFlow.View.Mitarbeiter;
|
||||||
using ChronoFlow.Persistence;
|
using ChronoFlow.Persistence;
|
||||||
using ChronoFlow.Model;
|
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;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -6,28 +7,49 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
|||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using ChronoFlow.Model;
|
using ChronoFlow.Model;
|
||||||
using ChronoFlow.Persistence;
|
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
|
public partial class EmployeeTasksViewModel : ObservableObject
|
||||||
{
|
{
|
||||||
|
// 🧑💼 Der aktuell eingeloggte Benutzer (Mitarbeiter)
|
||||||
private readonly User _benutzer;
|
private readonly User _benutzer;
|
||||||
|
|
||||||
|
// 💾 Zugriff auf die Datenbank-Funktionen (SQL-Repository)
|
||||||
private readonly IZeiterfassungsRepository _repository;
|
private readonly IZeiterfassungsRepository _repository;
|
||||||
|
|
||||||
|
// 📛 Einfacher Zugriff auf den Benutzernamen (spart Schreibarbeit)
|
||||||
private readonly string aktuellerBenutzername;
|
private readonly string aktuellerBenutzername;
|
||||||
|
|
||||||
|
// 📋 Alle Zeiteinträge, die dem Benutzer angezeigt werden
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private ObservableCollection<Zeiteintrag> eintraege = new();
|
private ObservableCollection<Zeiteintrag> eintraege = new();
|
||||||
|
|
||||||
|
// 💬 Statusmeldung unten im Fenster (z. B. bei Erfolg)
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? statusText;
|
private string? statusText;
|
||||||
|
|
||||||
|
// ✅ Hilfs-Property, die sagt: "Gibt es keine Einträge?"
|
||||||
public bool HatKeineEintraege => Eintraege.Count == 0;
|
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)
|
partial void OnEintraegeChanged(ObservableCollection<Zeiteintrag>? oldValue, ObservableCollection<Zeiteintrag> newValue)
|
||||||
{
|
{
|
||||||
OnPropertyChanged(nameof(HatKeineEintraege));
|
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)
|
public EmployeeTasksViewModel(User benutzer, IZeiterfassungsRepository repository)
|
||||||
{
|
{
|
||||||
_benutzer = benutzer;
|
_benutzer = benutzer;
|
||||||
@ -36,9 +58,15 @@ namespace ChronoFlow.ViewModels.Mitarbeiter
|
|||||||
|
|
||||||
Console.WriteLine($"[DEBUG] ViewModel erstellt für Benutzer: {aktuellerBenutzername}");
|
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]
|
[RelayCommand]
|
||||||
public async Task LadeEintraegeAsync()
|
public async Task LadeEintraegeAsync()
|
||||||
{
|
{
|
||||||
@ -49,23 +77,25 @@ namespace ChronoFlow.ViewModels.Mitarbeiter
|
|||||||
.OrderBy(e => e.Endzeit)
|
.OrderBy(e => e.Endzeit)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// 🔔 Setze Markierung für geänderte Aufgaben
|
// 🔔 Markiere geänderte Einträge seit dem letzten Login
|
||||||
foreach (var eintrag in offene)
|
foreach (var eintrag in offene)
|
||||||
{
|
{
|
||||||
eintrag.WurdeSeitLoginBearbeitet = eintrag.LetzteBearbeitung > _benutzer.LetzterLogin;
|
eintrag.WurdeSeitLoginBearbeitet = eintrag.LetzteBearbeitung > _benutzer.VorletzterLogin;
|
||||||
|
|
||||||
// 🔍 Debug-Ausgabe zur Prüfung
|
|
||||||
Console.WriteLine($"[DEBUG] Eintrag {eintrag.Id}: Endzeit={eintrag.Endzeit}, LetzteBearbeitung={eintrag.LetzteBearbeitung}, LetzterLogin={_benutzer.LetzterLogin}, Markiert={eintrag.WurdeSeitLoginBearbeitet}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🔔 Zeige Hinweis, wenn neue Änderungen vorhanden sind
|
||||||
if (offene.Any(e => e.WurdeSeitLoginBearbeitet))
|
if (offene.Any(e => e.WurdeSeitLoginBearbeitet))
|
||||||
StatusText = "📢 Es wurden Aufgaben seit Ihrem letzten Login geändert.";
|
StatusText = "📢 Es wurden Aufgaben seit Ihrem letzten Login geändert.";
|
||||||
|
|
||||||
|
// 🔄 Aktualisiere ObservableCollection für UI
|
||||||
Eintraege = new ObservableCollection<Zeiteintrag>(offene);
|
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]
|
[RelayCommand]
|
||||||
public async Task SpeichereEintraegeAsync()
|
public async Task SpeichereEintraegeAsync()
|
||||||
{
|
{
|
||||||
@ -79,7 +109,9 @@ namespace ChronoFlow.ViewModels.Mitarbeiter
|
|||||||
}
|
}
|
||||||
|
|
||||||
StatusText = "✅ Änderungen gespeichert.";
|
StatusText = "✅ Änderungen gespeichert.";
|
||||||
await LadeEintraegeAsync(); // automatisch neu laden
|
|
||||||
|
// 🔄 Nach dem Speichern direkt neu laden
|
||||||
|
await LadeEintraegeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user