feat(ui): surface depends_on blocking in status chip, chain label, and detail pane

Usability-Audit 2026-09-10 found three gaps versus the dependency-chain-display
spec: a Queued task blocked on an unmet task_dependencies edge rendered the same
chip as one about to run, a cross-list predecessor silently dropped the
"after #N" chip, and the detail pane showed nothing about a wait at all.

- TaskRowViewModel gains IsBlockedByDependency/DependencyWaitLabel (extrinsic,
  assigned by TasksIslandViewModel like the existing chain fields); IsQueued/
  IsWaiting/StatusChipClass/StatusLabel/StatusChipTooltip now account for it
  alongside the existing BlockedByTaskId planning-chain link.
- TasksIslandViewModel.ApplyDependencyWaitState computes the blocked flag and
  wait label per row; a new RefreshExternalDependencyCacheAsync backfills
  Number/Title/Status for predecessors not loaded into the current list's
  Items (reusing the already-open DbContext, no new hub method), so
  BuildAfterLabel/blocking both resolve a listenfremder Vorgänger correctly.
- New "waiting" chip style (IslandStyles.axaml) and locale keys (en+de);
  TaskHeaderBar shows a "Waiting on #N" line bound straight to the same row.

Tests: TasksIslandChainTests (blocked/unblocked chip, cross-list predecessor),
DetailsIslandDependencyWaitTests (new), TaskRowViewModelNotificationsTests
updated for the new notification set.
This commit is contained in:
mika kuns
2026-09-10 13:32:36 +02:00
parent c1b133ff90
commit 4cf601e423
10 changed files with 363 additions and 22 deletions
+12
View File
@@ -297,6 +297,18 @@
<Setter Property="Foreground" Value="{StaticResource StatusQueuedBrush}" />
</Style>
<!-- waiting → muted amber: a Queued task blocked on an unmet predecessor (a task_dependencies
edge, or the planning chain's BlockedByTaskId) — distinct from queued (unblocked, next up
to run) and from children (a parent waiting on its own subtasks). Mutually exclusive with
.queued on the same chip (IsQueued/IsWaiting), so no declaration-order fight between them. -->
<Style Selector="Border.chip.waiting">
<Setter Property="Background" Value="#332F1A" />
<Setter Property="BorderBrush" Value="#4D451A" />
</Style>
<Style Selector="Border.chip.waiting > TextBlock">
<Setter Property="Foreground" Value="#C9A227" />
</Style>
<!-- done → green (#6FA86B) -->
<Style Selector="Border.chip.done">
<Setter Property="Background" Value="{StaticResource DoneTintBrush}" />