From 4cf601e42317b1c7956cc288fd25ddeb52bc7cb1 Mon Sep 17 00:00:00 2001 From: mika kuns Date: Thu, 10 Sep 2026 13:20:30 +0200 Subject: [PATCH] feat(ui): surface depends_on blocking in status chip, chain label, and detail pane MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- src/ClaudeDo.Localization/locales/de.json | 4 +- src/ClaudeDo.Localization/locales/en.json | 4 +- src/ClaudeDo.Ui/Design/IslandStyles.axaml | 12 ++ .../ViewModels/Islands/TaskRowViewModel.cs | 36 ++++- .../Islands/TasksIslandViewModel.cs | 126 ++++++++++++++++-- .../Views/Islands/Detail/TaskHeaderBar.axaml | 8 ++ .../Views/Islands/TaskRowView.axaml | 3 +- .../DetailsIslandDependencyWaitTests.cs | 72 ++++++++++ .../ViewModels/TasksIslandChainTests.cs | 89 +++++++++++++ .../TaskRowViewModelNotificationsTests.cs | 31 +++++ 10 files changed, 363 insertions(+), 22 deletions(-) create mode 100644 tests/ClaudeDo.Ui.Tests/ViewModels/DetailsIslandDependencyWaitTests.cs diff --git a/src/ClaudeDo.Localization/locales/de.json b/src/ClaudeDo.Localization/locales/de.json index 2bb0b81e..d169e9a1 100644 --- a/src/ClaudeDo.Localization/locales/de.json +++ b/src/ClaudeDo.Localization/locales/de.json @@ -239,6 +239,7 @@ "toggleSubtasksTip": "Unteraufgaben ein-/ausklappen", "agentSuggestedTip": "Vom Agenten vorgeschlagen", "interactiveChipTip": "Interaktive Sitzung offen — klicken, um im Mission Control dorthin zu springen", + "waitingOnTip": "Wartet auf {0}", "scheduleTitle": "Aufgabe planen", "scheduleWhen": "WANN", "scheduleConfirm": "Planen", @@ -277,6 +278,7 @@ "starTip": "Favorit", "agentSettingsTip": "Agent-Einstellungen", "agentSettingsHeading": "Agent-Einstellungen (Überschreibungen)", + "waitingOnPrefix": "Wartet auf", "copyFormattedTip": "Titel, Beschreibung und offene Schritte kopieren", "toggleEditPreviewTip": "Bearbeiten/Vorschau umschalten", "planDay": "Tag planen", @@ -775,7 +777,7 @@ "shell": { "restartingWorker": "Worker wird neu gestartet…", "unexpectedError": "Unerwarteter Fehler: {0}" }, "mainWindow": { "closeConfirm": { "message": "{0} Mission-Control-Sitzung(en) laufen noch. Beim Beenden werden sie abgebrochen. Trotzdem schließen?" } }, "agentStatus": { "idle": "Leerlauf", "queued": "In Warteschlange", "running": "Läuft", "review": "Prüfung", "children": "Wartet auf Teilaufgaben", "done": "Fertig", "failed": "Fehlgeschlagen", "cancelled": "Abgebrochen" }, - "taskStatus": { "idle": "Leerlauf", "queued": "In Warteschlange", "running": "Läuft", "waitingForReview": "Wartet auf Prüfung", "waitingForChildren": "Wartet auf Teilaufgaben", "done": "Fertig", "failed": "Fehlgeschlagen", "cancelled": "Abgebrochen", "parked": "Geparkt", "interactive": "Interaktiv" }, + "taskStatus": { "idle": "Leerlauf", "queued": "In Warteschlange", "running": "Läuft", "waitingForReview": "Wartet auf Prüfung", "waitingForChildren": "Wartet auf Teilaufgaben", "done": "Fertig", "failed": "Fehlgeschlagen", "cancelled": "Abgebrochen", "parked": "Geparkt", "interactive": "Interaktiv", "waiting": "Wartet" }, "failureReason": { "maxTurns": "Turn-Limit erreicht", "timeout": "Zeitüberschreitung", "usageLimit": "Nutzungslimit erreicht", "error": "Fehler", "cancelled": "Abgebrochen", "unknown": "Grund unbekannt" }, "failureReasonTooltip": { "maxTurns": "Turn-Limit erreicht ({0}/{1} Turns) — der Worktree ist meist brauchbar; Task fortsetzen statt zurücksetzen." }, "planningBadge": { "active": "PLANUNG", "finalized": "GEPLANT" }, diff --git a/src/ClaudeDo.Localization/locales/en.json b/src/ClaudeDo.Localization/locales/en.json index c013ac84..2184215e 100644 --- a/src/ClaudeDo.Localization/locales/en.json +++ b/src/ClaudeDo.Localization/locales/en.json @@ -239,6 +239,7 @@ "toggleSubtasksTip": "Expand / collapse subtasks", "agentSuggestedTip": "Suggested by the agent", "interactiveChipTip": "Interactive session open — click to jump to it in Mission Control", + "waitingOnTip": "Waiting on {0}", "scheduleTitle": "Schedule task", "scheduleWhen": "WHEN", "scheduleConfirm": "Schedule", @@ -277,6 +278,7 @@ "starTip": "Star", "agentSettingsTip": "Agent settings", "agentSettingsHeading": "Agent settings (overrides)", + "waitingOnPrefix": "Waiting on", "copyFormattedTip": "Copy title, description and open steps", "toggleEditPreviewTip": "Toggle edit/preview", "planDay": "Plan day", @@ -775,7 +777,7 @@ "shell": { "restartingWorker": "Restarting worker…", "unexpectedError": "Unexpected error: {0}" }, "mainWindow": { "closeConfirm": { "message": "{0} Mission Control session(s) are still running. Closing the app will end them. Close anyway?" } }, "agentStatus": { "idle": "Idle", "queued": "Queued", "running": "Running", "review": "Review", "children": "Waiting for Subtasks", "done": "Done", "failed": "Failed", "cancelled": "Cancelled" }, - "taskStatus": { "idle": "Idle", "queued": "Queued", "running": "Running", "waitingForReview": "Waiting for Review", "waitingForChildren": "Waiting for Subtasks", "done": "Done", "failed": "Failed", "cancelled": "Cancelled", "parked": "Parked", "interactive": "Interactive" }, + "taskStatus": { "idle": "Idle", "queued": "Queued", "running": "Running", "waitingForReview": "Waiting for Review", "waitingForChildren": "Waiting for Subtasks", "done": "Done", "failed": "Failed", "cancelled": "Cancelled", "parked": "Parked", "interactive": "Interactive", "waiting": "Waiting" }, "failureReason": { "maxTurns": "Turn limit reached", "timeout": "Timed out", "usageLimit": "Usage limit reached", "error": "Error", "cancelled": "Cancelled", "unknown": "Unknown reason" }, "failureReasonTooltip": { "maxTurns": "Turn limit reached ({0}/{1} turns) — the worktree is usually fine; continue the task instead of resetting it." }, "planningBadge": { "active": "PLANNING", "finalized": "PLANNED" }, diff --git a/src/ClaudeDo.Ui/Design/IslandStyles.axaml b/src/ClaudeDo.Ui/Design/IslandStyles.axaml index b055dbaa..f5a375ee 100644 --- a/src/ClaudeDo.Ui/Design/IslandStyles.axaml +++ b/src/ClaudeDo.Ui/Design/IslandStyles.axaml @@ -297,6 +297,18 @@ + + + +