feat(ui): add Refine button, icon, and command to task card
This commit is contained in:
@@ -76,6 +76,9 @@
|
||||
<!-- Icon.PlanDay (stroke-rendered via Path.plan-icon — sun over horizon) -->
|
||||
<StreamGeometry x:Key="Icon.PlanDay">M3,20 L21,20 M8.4,11 a3.6,3.6 0 1,0 7.2,0 a3.6,3.6 0 1,0 -7.2,0 M12,4.5 L12,3 M6,11 L4.5,11 M18,11 L19.5,11 M7.5,6.5 L6.4,5.4 M16.5,6.5 L17.6,5.4</StreamGeometry>
|
||||
|
||||
<!-- Icon.Refine (stroke-rendered via Path.plan-icon — list lines + sparkle + edit tail) -->
|
||||
<StreamGeometry x:Key="Icon.Refine">M3,5 L11,5 M3,9 L9,9 M3,13 L7,13 M19,1.8 L19.7,3.9 L21.7,4.6 L19.7,5.3 L19,7.4 L18.3,5.3 L16.3,4.6 L18.3,3.9 Z M18,10.5 L12.2,16.3 M16.6,9.1 L19.4,11.9 M12.2,16.3 L11,18.5 L13.2,17.5 Z</StreamGeometry>
|
||||
|
||||
<!-- Icon.X -->
|
||||
<StreamGeometry x:Key="Icon.X">M6 6l12 12M18 6L6 18</StreamGeometry>
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@ public sealed partial class TaskRowViewModel : ViewModelBase
|
||||
[ObservableProperty] private bool _showListChip = true;
|
||||
[ObservableProperty] private bool _parentFinalized;
|
||||
[ObservableProperty] private int _roadblockCount;
|
||||
[ObservableProperty] private bool _isRefining;
|
||||
|
||||
public bool CanRefine => Status == TaskStatus.Idle && PlanningPhase == PlanningPhase.None && !IsRefining;
|
||||
|
||||
public DateTime CreatedAt { get; init; }
|
||||
public string CreatedAtFormatted => CreatedAt == default ? "—" : Loc.T("vm.taskRow.createdPrefix", CreatedAt.ToString("MMM d"));
|
||||
@@ -125,6 +128,7 @@ public sealed partial class TaskRowViewModel : ViewModelBase
|
||||
OnPropertyChanged(nameof(CanOpenPlanningSession));
|
||||
OnPropertyChanged(nameof(CanRemoveFromQueue));
|
||||
OnPropertyChanged(nameof(CanSendToQueue));
|
||||
OnPropertyChanged(nameof(CanRefine));
|
||||
}
|
||||
|
||||
partial void OnParentTaskIdChanged(string? value)
|
||||
@@ -155,8 +159,11 @@ public sealed partial class TaskRowViewModel : ViewModelBase
|
||||
OnPropertyChanged(nameof(CanOpenPlanningSession));
|
||||
OnPropertyChanged(nameof(CanResumeOrDiscardPlanning));
|
||||
OnPropertyChanged(nameof(CanQueuePlan));
|
||||
OnPropertyChanged(nameof(CanRefine));
|
||||
}
|
||||
|
||||
partial void OnIsRefiningChanged(bool value) => OnPropertyChanged(nameof(CanRefine));
|
||||
|
||||
partial void OnHasQueuedSubtasksChanged(bool value)
|
||||
{
|
||||
OnPropertyChanged(nameof(CanRemoveFromQueue));
|
||||
|
||||
@@ -82,6 +82,8 @@ public sealed partial class TasksIslandViewModel : ViewModelBase
|
||||
_worker.WorktreeUpdatedEvent += OnWorkerTaskUpdated;
|
||||
_worker.ListUpdatedEvent += OnWorkerListUpdated;
|
||||
_worker.ConnectionRestoredEvent += () => LoadForList(_currentList);
|
||||
_worker.RefineStartedEvent += OnRefineStarted;
|
||||
_worker.RefineFinishedEvent += OnRefineFinished;
|
||||
}
|
||||
Loc.LanguageChanged += (_, _) => RefreshLocalizedText();
|
||||
}
|
||||
@@ -830,6 +832,27 @@ public sealed partial class TasksIslandViewModel : ViewModelBase
|
||||
Regroup();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task RefineTask(TaskRowViewModel row)
|
||||
{
|
||||
if (row is null || !row.CanRefine) return;
|
||||
row.IsRefining = true;
|
||||
try { await _worker!.RefineTaskAsync(row.Id); }
|
||||
catch { row.IsRefining = false; }
|
||||
}
|
||||
|
||||
private void OnRefineStarted(string taskId)
|
||||
{
|
||||
var row = Items.FirstOrDefault(r => r.Id == taskId);
|
||||
if (row is not null) row.IsRefining = true;
|
||||
}
|
||||
|
||||
private void OnRefineFinished(string taskId, bool ok, string? error)
|
||||
{
|
||||
var row = Items.FirstOrDefault(r => r.Id == taskId);
|
||||
if (row is not null) row.IsRefining = false;
|
||||
}
|
||||
|
||||
partial void OnSelectedTaskChanged(TaskRowViewModel? value)
|
||||
{
|
||||
foreach (var i in Items) i.IsSelected = ReferenceEquals(i, value);
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
Click="OnClearScheduleClick"/>
|
||||
</ContextMenu>
|
||||
</Border.ContextMenu>
|
||||
<Grid ColumnDefinitions="0,18,32,*,Auto,32" Margin="6,8,10,8">
|
||||
<Grid ColumnDefinitions="0,18,32,*,Auto,Auto,32" Margin="6,8,10,8">
|
||||
|
||||
<!-- Chevron toggle (only for planning parent tasks) -->
|
||||
<Button Grid.Column="1"
|
||||
@@ -194,8 +194,19 @@
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Refine button -->
|
||||
<Button Grid.Column="5" Classes="icon-btn refine-btn"
|
||||
IsVisible="{Binding CanRefine}"
|
||||
Command="{Binding $parent[ItemsControl].((vm:TasksIslandViewModel)DataContext).RefineTaskCommand}"
|
||||
CommandParameter="{Binding}"
|
||||
ToolTip.Tip="{loc:Tr tasks.refineTip}">
|
||||
<Viewbox Width="16" Height="16">
|
||||
<Path Classes="plan-icon" Data="{StaticResource Icon.Refine}"/>
|
||||
</Viewbox>
|
||||
</Button>
|
||||
|
||||
<!-- Star toggle -->
|
||||
<Button Grid.Column="5" Classes="icon-btn star-btn"
|
||||
<Button Grid.Column="6" Classes="icon-btn star-btn"
|
||||
Classes.on="{Binding IsStarred}"
|
||||
VerticalAlignment="Top" Margin="0,2,0,0"
|
||||
Command="{Binding $parent[ItemsControl].((vm:TasksIslandViewModel)DataContext).ToggleStarCommand}"
|
||||
|
||||
Reference in New Issue
Block a user