Files
ulapp/FieldLogger/ViewModels/JobsViewModel.cs
2026-07-10 20:29:01 -05:00

125 lines
3.6 KiB
C#

using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using FieldLogger.Models;
using FieldLogger.Services;
using FieldLogger.Services.Data;
namespace FieldLogger.ViewModels;
public sealed partial class JobListItem : ObservableObject
{
public required Job Job { get; init; }
[ObservableProperty]
private int _pointCount;
[ObservableProperty]
private bool _isActive;
public string Name => Job.Name;
public string CreatedLabel => Job.CreatedUtc.ToLocalTime().ToString("g");
}
public sealed partial class JobsViewModel : ObservableObject
{
private readonly AppDatabase _database;
private readonly SettingsService _settings;
public ObservableCollection<JobListItem> Jobs { get; } = new();
[ObservableProperty]
private bool _isBusy;
public JobsViewModel(AppDatabase database, SettingsService settings)
{
_database = database;
_settings = settings;
}
public async Task RefreshAsync()
{
IsBusy = true;
try
{
var jobs = await _database.GetJobsAsync();
var activeId = _settings.ActiveJobId;
Jobs.Clear();
foreach (var job in jobs)
{
Jobs.Add(new JobListItem
{
Job = job,
PointCount = await _database.GetPointCountAsync(job.Id),
IsActive = job.Id == activeId,
});
}
}
finally
{
IsBusy = false;
}
}
[RelayCommand]
private async Task NewJobAsync()
{
try
{
Console.WriteLine("NewJobAsync: Starting...");
var name = await Shell.Current.DisplayPromptAsync("New Job", "Job name:",
placeholder: $"Job {DateTime.Now:yyyy-MM-dd}");
Console.WriteLine($"NewJobAsync: User entered: '{name}'");
if (string.IsNullOrWhiteSpace(name))
{
Console.WriteLine("NewJobAsync: Name was empty, cancelling");
return;
}
Console.WriteLine($"NewJobAsync: Creating job '{name.Trim()}'");
var job = await _database.CreateJobAsync(name.Trim());
Console.WriteLine($"NewJobAsync: Job created with ID {job.Id}");
_settings.ActiveJobId = job.Id;
Console.WriteLine($"NewJobAsync: Set active job to {job.Id}");
await RefreshAsync();
Console.WriteLine("NewJobAsync: Refresh complete");
}
catch (Exception ex)
{
Console.WriteLine($"NewJobAsync: ERROR - {ex.Message}");
Console.WriteLine($"NewJobAsync: Stack trace - {ex.StackTrace}");
}
}
[RelayCommand]
private async Task SetActiveAsync(JobListItem item)
{
_settings.ActiveJobId = item.Job.Id;
foreach (var j in Jobs)
j.IsActive = j.Job.Id == item.Job.Id;
await Task.CompletedTask;
}
[RelayCommand]
private Task OpenAsync(JobListItem item)
=> Shell.Current.GoToAsync($"jobdetail?jobId={item.Job.Id}");
[RelayCommand]
private async Task DeleteAsync(JobListItem item)
{
var confirmed = await Shell.Current.DisplayAlert("Delete Job",
$"Delete \"{item.Job.Name}\" and its {item.PointCount} logged points?", "Delete", "Cancel");
if (!confirmed)
return;
await _database.DeleteJobAsync(item.Job.Id);
if (_settings.ActiveJobId == item.Job.Id)
_settings.ActiveJobId = null;
await RefreshAsync();
}
}