W9-5: Tooltip sweep — HelpTip helper + per-view decode (#533)

* [W9-5a] Tooltip sweep foundation: HelpTip helper + shared cryptic badges

HelpTip: DRY wrapper over the verbose 3-element Radix Tooltip pattern so a
broad sweep stays a one-line wrap per site (falsy label short-circuits to the
bare child). Unit-tested (3 cases).

TaskStatusBadge + AgentStateBadge: the panel's most cryptic, most-frequent
elements (15 task lifecycle states, 11 agent states) had no explanation
anywhere. Add a per-state tooltip via HelpTip, with the canonical text in one
description map and exported as taskStatusDescription / agentStateDescription
so the per-view inline renderers (kanban, task header) reuse it instead of
re-declaring. This is part 1 of the W9-5 tooltip sweep; the per-view inline
surfaces follow in subsequent PRs.

* [W9-5b] Per-view tooltip sweep: decode cryptic badges, icon-only buttons, status dots

35 HelpTip additions across 22 panel components, reusing the W9-5a
helper plus taskStatusDescription/agentStateDescription. Tipped:
task-id/commit-hash/branch/PR badges, severity/origin/status badges,
priority (P0-P3), migration/shared flags, MegaTask umbrella badge,
Review Gate / For Resumption / Confidential note badges, icon-only
view/delete/edit/clear/show-hide buttons, semver bump + gate-state
badges, ahead-not-pushed badge. Skipped self-explanatory labeled
buttons and elements already carrying title=.

---------

Co-authored-by: Renn F <rennf93@users.noreply.github.com>
This commit is contained in:
Renzo F
2026-07-15 04:34:17 +02:00
committed by GitHub
co-authored by Renn F
parent f07e2420a8
commit b7f2d84c77
26 changed files with 438 additions and 207 deletions
@@ -34,6 +34,7 @@ import {
import Link from "next/link";
import { TaskStatus, Team, type Task } from "@/types";
import { toast } from "sonner";
import { HelpTip } from "@/components/ui/help-tip";
interface CeoApprovalQueueProps {
className?: string;
@@ -171,18 +172,24 @@ export function CeoApprovalQueue({ className }: CeoApprovalQueueProps) {
{
label: string;
variant: "default" | "secondary" | "destructive" | "outline";
desc: string;
}
> = {
0: { label: "P0", variant: "destructive" },
1: { label: "P1", variant: "destructive" },
2: { label: "P2", variant: "secondary" },
3: { label: "P3", variant: "outline" },
0: { label: "P0", variant: "destructive", desc: "Critical priority — blocks all other work" },
1: { label: "P1", variant: "destructive", desc: "High priority — should be done soon" },
2: { label: "P2", variant: "secondary", desc: "Medium priority — normal scheduling" },
3: { label: "P3", variant: "outline", desc: "Low priority — can wait" },
};
const { label, variant } = variants[priority] || {
const { label, variant, desc } = variants[priority] || {
label: `P${priority}`,
variant: "outline" as const,
desc: `Priority level ${priority}`,
};
return <Badge variant={variant}>{label}</Badge>;
return (
<HelpTip label={desc}>
<Badge variant={variant}>{label}</Badge>
</HelpTip>
);
};
if (isLoading) {
@@ -237,9 +244,11 @@ export function CeoApprovalQueue({ className }: CeoApprovalQueueProps) {
clipping against it (mirrors the dialog footer's flex-col sm:flex-row). */}
<div className="flex flex-wrap items-center gap-2 sm:ml-4 sm:shrink-0">
<Link href={`/tasks/${task.id}`} prefetch={false}>
<Button variant="ghost" size="sm">
<FileText className="h-4 w-4" />
</Button>
<HelpTip label="View task details">
<Button variant="ghost" size="sm">
<FileText className="h-4 w-4" />
</Button>
</HelpTip>
</Link>
<Button
variant="outline"