Merge claudedo/1891227787ae4085a52c112bd1dcd75a
This commit is contained in:
@@ -45,6 +45,10 @@ public sealed partial class TaskRowViewModel : ViewModelBase
|
||||
// Set by the custom drag while this row is being dragged — drives the "grabbed" row style.
|
||||
[ObservableProperty] private bool _isDragging;
|
||||
|
||||
// True while a drag is hovering this row (i.e. it would show a drop-hint gap). Used to
|
||||
// suppress the ordinary hover highlight/transitions so they don't fight the hint.
|
||||
public bool IsDropTarget => DropHintAbove || DropHintBelow;
|
||||
|
||||
public bool CanRefine => Status == TaskStatus.Idle && PlanningPhase == PlanningPhase.None
|
||||
&& !IsRefining && !IsManual;
|
||||
|
||||
@@ -289,6 +293,8 @@ public sealed partial class TaskRowViewModel : ViewModelBase
|
||||
partial void OnDiffAdditionsChanged(int value) { OnPropertyChanged(nameof(HasDiff)); OnPropertyChanged(nameof(DiffAdditionsText)); }
|
||||
partial void OnDiffDeletionsChanged(int value) { OnPropertyChanged(nameof(HasDiff)); OnPropertyChanged(nameof(DiffDeletionsText)); }
|
||||
partial void OnRoadblockCountChanged(int value) { OnPropertyChanged(nameof(HasRoadblock)); OnPropertyChanged(nameof(RoadblockTooltip)); }
|
||||
partial void OnDropHintAboveChanged(bool value) => OnPropertyChanged(nameof(IsDropTarget));
|
||||
partial void OnDropHintBelowChanged(bool value) => OnPropertyChanged(nameof(IsDropTarget));
|
||||
|
||||
public void RefreshLocalized()
|
||||
{
|
||||
|
||||
@@ -336,26 +336,53 @@ public sealed partial class TasksIslandViewModel : ViewModelBase, IDisposable
|
||||
try
|
||||
{
|
||||
await using var db = await _dbFactory.CreateDbContextAsync(ct);
|
||||
var all = await db.Tasks
|
||||
.Include(t => t.List)
|
||||
.Include(t => t.Worktree)
|
||||
.OrderBy(t => t.SortOrder).ThenBy(t => t.CreatedAt)
|
||||
.ToListAsync(ct);
|
||||
var filter = _filters.Resolve(list.Id);
|
||||
var baseQuery = db.Tasks.Include(t => t.List).Include(t => t.Worktree);
|
||||
|
||||
var filteredList = filter is null
|
||||
? new List<TaskEntity>()
|
||||
: await baseQuery.Where(filter.MatchExpression).ToListAsync(ct);
|
||||
|
||||
ct.ThrowIfCancellationRequested();
|
||||
|
||||
var filter = _filters.Resolve(list.Id);
|
||||
var filteredList = filter is null
|
||||
? new List<TaskEntity>()
|
||||
: all.Where(t => filter.Matches(t) || filter.MatchesAsContext(t, all)).ToList();
|
||||
var topIds = filteredList.Where(t => t.ParentTaskId == null).Select(t => t.Id).ToHashSet();
|
||||
var existingIds = filteredList.Select(t => t.Id).ToHashSet();
|
||||
foreach (var c in all.Where(t => t.ParentTaskId != null && topIds.Contains(t.ParentTaskId!)))
|
||||
if (filter is not null)
|
||||
{
|
||||
if (existingIds.Add(c.Id))
|
||||
filteredList.Add(c);
|
||||
// Contextual parent rows (e.g. a planning parent hosting an already-matched queued/running
|
||||
// child): only fetch candidates that could plausibly qualify — parents of tasks we already
|
||||
// matched — instead of scanning the whole table.
|
||||
var candidateParentIds = filteredList
|
||||
.Where(t => t.ParentTaskId != null)
|
||||
.Select(t => t.ParentTaskId!)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
if (candidateParentIds.Count > 0)
|
||||
{
|
||||
var existingParentIds = filteredList.Select(t => t.Id).ToHashSet();
|
||||
var parentCandidates = await baseQuery
|
||||
.Where(t => candidateParentIds.Contains(t.Id) && !existingParentIds.Contains(t.Id))
|
||||
.ToListAsync(ct);
|
||||
foreach (var p in parentCandidates)
|
||||
if (filter.MatchesAsContext(p, filteredList))
|
||||
filteredList.Add(p);
|
||||
}
|
||||
}
|
||||
|
||||
ct.ThrowIfCancellationRequested();
|
||||
|
||||
// Pull in every child of an already-matched top-level row, regardless of whether the child
|
||||
// itself matches the filter, so subtasks render nested under their parent.
|
||||
var topIds = filteredList.Where(t => t.ParentTaskId == null).Select(t => t.Id).ToHashSet();
|
||||
if (topIds.Count > 0)
|
||||
{
|
||||
var existingIds = filteredList.Select(t => t.Id).ToHashSet();
|
||||
var extraChildren = await baseQuery
|
||||
.Where(t => t.ParentTaskId != null && topIds.Contains(t.ParentTaskId!) && !existingIds.Contains(t.Id))
|
||||
.ToListAsync(ct);
|
||||
filteredList.AddRange(extraChildren);
|
||||
}
|
||||
|
||||
filteredList = filteredList.OrderBy(t => t.SortOrder).ThenBy(t => t.CreatedAt).ToList();
|
||||
|
||||
var showListChip = list.Kind == ListKind.Virtual;
|
||||
foreach (var t in filteredList)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user