feat(notes): notes get their own list, a day log and an Enter chain
The editor was reachable from one button that only appeared in My Day, which is how it got forgotten. It is now a permanent sidebar entry next to My Day and Planned, and it fills the tasks island rather than the details pane, because a note list is content. Inside, the date picker is gone: today sits at the top with the capture box, older days follow as dated groups. Enter in a note saves it and opens the next one, Shift+Enter breaks the line so notes can be several, Backspace on an empty note deletes it and steps back up. Deleting also has a visible hover button instead of only "clear the text and hope". Agent-written notes carry a marker. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
ae0c7d3771
commit
0f04b796f4
@@ -20,7 +20,6 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable
|
||||
private readonly IDbContextFactory<ClaudeDoDbContext> _dbFactory;
|
||||
private readonly IWorkerClient _worker;
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly INotesApi _notesApi;
|
||||
private readonly MergeCoordinator _merge;
|
||||
|
||||
// ── Section view models ───────────────────────────────────────────────────
|
||||
@@ -39,29 +38,20 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable
|
||||
private readonly Action<string, string?> _workerPlanningMergeAbortedHandler;
|
||||
private readonly Action<string> _workerPlanningCompletedHandler;
|
||||
|
||||
[ObservableProperty] private bool _isNotesMode;
|
||||
[ObservableProperty] private bool _isPrepMode;
|
||||
|
||||
public bool IsTaskDetailVisible => !IsNotesMode && !IsPrepMode;
|
||||
public bool IsTaskDetailVisible => !IsPrepMode;
|
||||
|
||||
/// <summary>Centered placeholder shown when no task is selected — hidden in Notes/Prep mode,
|
||||
/// <summary>Centered placeholder shown when no task is selected — hidden in Prep mode,
|
||||
/// where <see cref="IsTaskDetailVisible"/> is already false.</summary>
|
||||
public bool IsEmptyStateVisible => Task is null && IsTaskDetailVisible;
|
||||
|
||||
partial void OnIsNotesModeChanged(bool value)
|
||||
{
|
||||
OnPropertyChanged(nameof(IsTaskDetailVisible));
|
||||
OnPropertyChanged(nameof(IsEmptyStateVisible));
|
||||
}
|
||||
|
||||
partial void OnIsPrepModeChanged(bool value)
|
||||
{
|
||||
OnPropertyChanged(nameof(IsTaskDetailVisible));
|
||||
OnPropertyChanged(nameof(IsEmptyStateVisible));
|
||||
}
|
||||
|
||||
public NotesEditorViewModel Notes { get; private set; } = null!;
|
||||
|
||||
// Current task row (set by IslandsShellViewModel via Bind)
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(EnqueueCommand))]
|
||||
@@ -324,13 +314,11 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable
|
||||
IDbContextFactory<ClaudeDoDbContext> dbFactory,
|
||||
IWorkerClient worker,
|
||||
IServiceProvider services,
|
||||
INotesApi notesApi,
|
||||
MergeCoordinator merge)
|
||||
{
|
||||
_dbFactory = dbFactory;
|
||||
_worker = worker;
|
||||
_services = services;
|
||||
_notesApi = notesApi;
|
||||
_merge = merge;
|
||||
|
||||
Monitor = new TaskMonitorViewModel(dbFactory, worker);
|
||||
@@ -374,8 +362,6 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable
|
||||
if (e.PropertyName == nameof(OperationStatus.IsRunning)) ParkReviewCommand.NotifyCanExecuteChanged();
|
||||
};
|
||||
|
||||
Notes = new NotesEditorViewModel(_notesApi);
|
||||
Notes.ErrorReported += msg => { if (ShowErrorAsync is not null) _ = ShowErrorAsync(msg); };
|
||||
Subtasks.CollectionChanged += (_, _) => NotifyStepsChanged();
|
||||
Subtasks.CollectionChanged += (_, _) => Merge.SyncChildOutcomes(HasChildOutcomes, Subtasks.Count);
|
||||
Attachments.CollectionChanged += (_, _) => OnPropertyChanged(nameof(FilesBadge));
|
||||
@@ -592,18 +578,9 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable
|
||||
catch { }
|
||||
}
|
||||
|
||||
public void ShowNotes()
|
||||
{
|
||||
Bind(null, "notes");
|
||||
IsPrepMode = false;
|
||||
IsNotesMode = true;
|
||||
_ = Notes.LoadDayAsync(DateOnly.FromDateTime(DateTime.Today));
|
||||
}
|
||||
|
||||
public void ShowPrep()
|
||||
{
|
||||
Bind(null, "prep");
|
||||
IsNotesMode = false;
|
||||
IsPrepMode = true;
|
||||
_ = Prep.LoadLastPrepLogIfEmptyAsync();
|
||||
}
|
||||
@@ -612,7 +589,6 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable
|
||||
/// logged with the bind timing so rebind churn can be attributed to a trigger.</param>
|
||||
public void Bind(TaskRowViewModel? row, string source = "?")
|
||||
{
|
||||
IsNotesMode = false;
|
||||
IsPrepMode = false;
|
||||
_loadCts?.Cancel();
|
||||
_loadCts?.Dispose();
|
||||
|
||||
Reference in New Issue
Block a user