feat(ui): WeeklyReportModalViewModel with default-range logic
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -52,6 +52,7 @@ public interface IWorkerClient : INotifyPropertyChanged
|
||||
Task QueuePlanningSubtasksAsync(string parentTaskId, CancellationToken ct = default);
|
||||
Task<string?> GetWeekReportAsync(DateOnly start, DateOnly end);
|
||||
Task<string> GenerateWeekReportAsync(DateOnly start, DateOnly end);
|
||||
Task<AppSettingsDto?> GetAppSettingsAsync();
|
||||
Task<List<DailyNoteDto>> GetDailyNotesAsync(DateOnly day);
|
||||
Task<DailyNoteDto?> AddDailyNoteAsync(DateOnly day, string text);
|
||||
Task UpdateDailyNoteAsync(string id, string text);
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
using ClaudeDo.Ui.Services;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace ClaudeDo.Ui.ViewModels.Modals;
|
||||
|
||||
public sealed partial class WeeklyReportModalViewModel : ViewModelBase
|
||||
{
|
||||
private readonly IWorkerClient _worker;
|
||||
|
||||
public WeeklyReportModalViewModel(IWorkerClient worker) => _worker = worker;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(HasReport))]
|
||||
[NotifyPropertyChangedFor(nameof(EmptyStateVisible))]
|
||||
private string? _reportMarkdown;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(EmptyStateVisible))]
|
||||
[NotifyCanExecuteChangedFor(nameof(GenerateCommand))]
|
||||
private bool _isBusy;
|
||||
|
||||
[ObservableProperty] private DateTime? _startDate;
|
||||
[ObservableProperty] private DateTime? _endDate;
|
||||
[ObservableProperty] private string _statusMessage = "";
|
||||
|
||||
public bool HasReport => !string.IsNullOrWhiteSpace(ReportMarkdown);
|
||||
public bool EmptyStateVisible => !HasReport && !IsBusy;
|
||||
|
||||
public Action? CloseAction { get; set; }
|
||||
[RelayCommand] private void Close() => CloseAction?.Invoke();
|
||||
|
||||
public static (DateOnly Start, DateOnly End) DefaultRange(DayOfWeek standup, DateOnly today)
|
||||
{
|
||||
int diff = ((int)today.DayOfWeek - (int)standup + 7) % 7;
|
||||
if (diff == 0) diff = 7;
|
||||
return (today.AddDays(-diff), today);
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
var standup = DayOfWeek.Wednesday;
|
||||
var settings = await _worker.GetAppSettingsAsync();
|
||||
if (settings is not null && settings.StandupWeekday is >= 0 and <= 6)
|
||||
standup = (DayOfWeek)settings.StandupWeekday;
|
||||
|
||||
var (start, end) = DefaultRange(standup, DateOnly.FromDateTime(DateTime.Today));
|
||||
StartDate = start.ToDateTime(TimeOnly.MinValue);
|
||||
EndDate = end.ToDateTime(TimeOnly.MinValue);
|
||||
await LoadStoredAsync();
|
||||
}
|
||||
|
||||
partial void OnStartDateChanged(DateTime? value) => _ = LoadStoredAsync();
|
||||
partial void OnEndDateChanged(DateTime? value) => _ = LoadStoredAsync();
|
||||
|
||||
private bool RangeValid => StartDate is not null && EndDate is not null && StartDate <= EndDate;
|
||||
|
||||
private async Task LoadStoredAsync()
|
||||
{
|
||||
if (!RangeValid) return;
|
||||
StatusMessage = "";
|
||||
try
|
||||
{
|
||||
ReportMarkdown = await _worker.GetWeekReportAsync(
|
||||
DateOnly.FromDateTime(StartDate!.Value), DateOnly.FromDateTime(EndDate!.Value));
|
||||
}
|
||||
catch (Exception ex) { StatusMessage = ex.Message; }
|
||||
}
|
||||
|
||||
private bool CanGenerate() => !IsBusy;
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanGenerate))]
|
||||
private async Task Generate()
|
||||
{
|
||||
if (!RangeValid) { StatusMessage = "Ungültiger Zeitraum."; return; }
|
||||
IsBusy = true;
|
||||
StatusMessage = "Bericht wird erstellt…";
|
||||
try
|
||||
{
|
||||
ReportMarkdown = await _worker.GenerateWeekReportAsync(
|
||||
DateOnly.FromDateTime(StartDate!.Value), DateOnly.FromDateTime(EndDate!.Value));
|
||||
StatusMessage = "";
|
||||
}
|
||||
catch (Exception ex) { StatusMessage = $"Fehler: {ex.Message}"; }
|
||||
finally { IsBusy = false; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user