Skip to content

Commit f3ca12e

Browse files
author
Markus Heimbach
committed
fix(web): keep the Working cue in collapsed project status
The collapsed project indicator now names Working like the thread pill does, and a blocked question outranks one the agent keeps working past regardless of thread order.
1 parent 40b9cca commit f3ca12e

4 files changed

Lines changed: 32 additions & 5 deletions

File tree

‎apps/web/src/components/LegacySidebar.tsx‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ import {
201201
isSidebarNestedLinkClick,
202202
isTrailingDoubleClick,
203203
resolveProjectStatusIndicator,
204+
threadStatusPillText,
204205
resolveThreadLastVisitedAt,
205206
resolveThreadStatusPill,
206207
orderItemsByPreferredIds,
@@ -2302,7 +2303,7 @@ const SidebarProjectItem = memo(function SidebarProjectItem(props: SidebarProjec
23022303
<TooltipTrigger
23032304
render={
23042305
<span
2305-
aria-label={projectStatus.label}
2306+
aria-label={threadStatusPillText(projectStatus)}
23062307
className={`-ml-0.5 relative inline-flex size-3.5 shrink-0 items-center justify-center ${projectStatus.colorClass}`}
23072308
/>
23082309
}
@@ -2316,7 +2317,7 @@ const SidebarProjectItem = memo(function SidebarProjectItem(props: SidebarProjec
23162317
</span>
23172318
<ChevronRightIcon className="absolute inset-0 m-auto size-3.5 text-icon-muted opacity-0 transition-opacity duration-150 group-hover/project-header:opacity-100" />
23182319
</TooltipTrigger>
2319-
<TooltipPopup side="top">{projectStatus.label}</TooltipPopup>
2320+
<TooltipPopup side="top">{threadStatusPillText(projectStatus)}</TooltipPopup>
23202321
</Tooltip>
23212322
) : (
23222323
<ChevronRightIcon

‎apps/web/src/components/Sidebar.logic.test.ts‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
type SidebarListMarker,
3434
type SidebarSection,
3535
resolveSidebarDropVerb,
36+
threadStatusPillText,
3637
} from "./Sidebar.logic";
3738
import { threadSearchMatchKey } from "@t3tools/client-runtime/state/thread-search";
3839
import {
@@ -620,6 +621,21 @@ describe("resolveThreadStatusPill", () => {
620621
});
621622

622623
describe("resolveProjectStatusIndicator", () => {
624+
it("lets a blocked question outrank one the agent keeps working past", () => {
625+
const input = {
626+
label: "Awaiting Input" as const,
627+
colorClass: "text-indigo-600",
628+
dotClass: "bg-indigo-500",
629+
};
630+
const blocked = { ...input, pulse: false, working: false };
631+
const working = { ...input, pulse: true, working: true };
632+
633+
expect(resolveProjectStatusIndicator([blocked, working])).toBe(blocked);
634+
expect(resolveProjectStatusIndicator([working, blocked])).toBe(blocked);
635+
expect(threadStatusPillText(working)).toBe("Awaiting Input · Working");
636+
expect(threadStatusPillText(blocked)).toBe("Awaiting Input");
637+
});
638+
623639
it("ranks waiting below active work and above plan-ready", () => {
624640
const waiting = {
625641
label: "Waiting" as const,

‎apps/web/src/components/Sidebar.logic.ts‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,10 @@ export interface ThreadStatusPill {
642642
working?: boolean;
643643
}
644644

645+
export function threadStatusPillText(status: ThreadStatusPill): string {
646+
return status.working ? `${status.label} · Working` : status.label;
647+
}
648+
645649
const THREAD_STATUS_PRIORITY: Record<ThreadStatusPill["label"], number> = {
646650
"Pending Approval": 5,
647651
"Awaiting Input": 4,
@@ -1168,9 +1172,14 @@ export function resolveProjectStatusIndicator(
11681172

11691173
for (const status of statuses) {
11701174
if (status === null) continue;
1175+
const priority = THREAD_STATUS_PRIORITY[status.label];
1176+
const highestPriority =
1177+
highestPriorityStatus === null ? null : THREAD_STATUS_PRIORITY[highestPriorityStatus.label];
11711178
if (
1172-
highestPriorityStatus === null ||
1173-
THREAD_STATUS_PRIORITY[status.label] > THREAD_STATUS_PRIORITY[highestPriorityStatus.label]
1179+
highestPriority === null ||
1180+
priority > highestPriority ||
1181+
// A blocked question outranks one the agent keeps working past.
1182+
(priority === highestPriority && highestPriorityStatus?.working === true && !status.working)
11741183
) {
11751184
highestPriorityStatus = status;
11761185
}

‎apps/web/src/components/ThreadStatusIndicators.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import {
4343
pullRequestMatchesSearchQuery,
4444
resolveThreadLastVisitedAt,
4545
resolveThreadStatusPill,
46+
threadStatusPillText,
4647
type ThreadStatusPill,
4748
useRetainedValue,
4849
useSidebarRowSubscriptionLease,
@@ -810,7 +811,7 @@ export function ThreadStatusLabel({
810811
status: ThreadStatusPill;
811812
compact?: boolean;
812813
}) {
813-
const text = status.working ? `${status.label} · Working` : status.label;
814+
const text = threadStatusPillText(status);
814815
if (compact) {
815816
return (
816817
<Tooltip>

0 commit comments

Comments
 (0)