using System.Collections.ObjectModel; using System.IO; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using EngineeringSync.Domain.Entities; using EngineeringSync.TrayApp.Services; namespace EngineeringSync.TrayApp.ViewModels; public partial class PendingChangesViewModel(ApiClient api) : ObservableObject { [ObservableProperty] private ObservableCollection _projects = []; [ObservableProperty] private ProjectConfig? _selectedProject; [ObservableProperty] private ObservableCollection _changes = []; [ObservableProperty] private bool _isLoading; [ObservableProperty] private string _statusMessage = string.Empty; partial void OnSelectedProjectChanged(ProjectConfig? value) { if (value is not null) _ = LoadChangesAsync(); } [RelayCommand] public async Task LoadProjectsAsync() { IsLoading = true; try { var projects = await api.GetProjectsAsync() ?? []; Projects = new ObservableCollection(projects); if (SelectedProject is null && projects.Count > 0) SelectedProject = projects[0]; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"[TrayApp] LoadProjects Fehler: {ex}"); StatusMessage = "Service nicht erreichbar."; } finally { IsLoading = false; } } [RelayCommand] public async Task LoadChangesAsync() { if (SelectedProject is null) return; IsLoading = true; try { var changes = await api.GetChangesAsync(SelectedProject.Id) ?? []; Changes = new ObservableCollection( changes.Select(c => new PendingChangeItem(c))); StatusMessage = $"{Changes.Count} ausstehende Änderung(en)"; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"[TrayApp] LoadChanges Fehler: {ex}"); StatusMessage = "Fehler beim Laden."; } finally { IsLoading = false; } } [RelayCommand] public async Task SyncSelectedAsync() { var ids = Changes.Where(c => c.IsSelected).Select(c => c.Change.Id).ToList(); if (ids.Count == 0) return; IsLoading = true; try { await api.SyncChangesAsync(ids); await LoadChangesAsync(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"[TrayApp] SyncSelected Fehler: {ex}"); StatusMessage = "Sync fehlgeschlagen."; } finally { IsLoading = false; } } [RelayCommand] public async Task IgnoreSelectedAsync() { var ids = Changes.Where(c => c.IsSelected).Select(c => c.Change.Id).ToList(); if (ids.Count == 0) return; IsLoading = true; try { await api.IgnoreChangesAsync(ids); await LoadChangesAsync(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"[TrayApp] IgnoreSelected Fehler: {ex}"); StatusMessage = "Ignore fehlgeschlagen."; } finally { IsLoading = false; } } [RelayCommand] public void SelectAll() { foreach (var c in Changes) c.IsSelected = true; } [RelayCommand] public void SelectNone() { foreach (var c in Changes) c.IsSelected = false; } } public partial class PendingChangeItem(PendingChange change) : ObservableObject { public PendingChange Change { get; } = change; [ObservableProperty] private bool _isSelected; public string FileName => Path.GetFileName(Change.RelativePath); public string RelativePath => Change.RelativePath; public string ChangeTypeDisplay => Change.ChangeType.ToString(); public string CreatedAtDisplay => Change.CreatedAt.ToLocalTime().ToString("dd.MM.yyyy HH:mm:ss"); }