mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
feat(panel): tooltip sweep — overview, agents, A2A, journals, auditor, metrics
Derivation tips on every key-metric, scorecard, and quality-metrics figure; the cryptic member-scorecard headers get full decodes; avatar initials, truncated ids, and toggle buttons gain accessible names; title-only hints upgrade to the HelpTip idiom throughout.
This commit is contained in:
@@ -5,6 +5,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import { HelpTip } from "@/components/ui/help-tip";
|
||||
import { ListChecks } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
|
||||
@@ -83,12 +84,16 @@ export function FindingsQueuePanel({
|
||||
>
|
||||
{finding.severity}
|
||||
</Badge>
|
||||
<Badge variant="outline" className="text-xs">
|
||||
{finding.origin}
|
||||
</Badge>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
round {finding.round}
|
||||
</span>
|
||||
<HelpTip label="Where this finding was raised — QA review, PR gate, PM review, or CEO approval">
|
||||
<Badge variant="outline" className="text-xs">
|
||||
{finding.origin}
|
||||
</Badge>
|
||||
</HelpTip>
|
||||
<HelpTip label="Revision round this finding was raised in — round 1 is the first pass">
|
||||
<span className="text-xs text-muted-foreground">
|
||||
round {finding.round}
|
||||
</span>
|
||||
</HelpTip>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground mb-2">
|
||||
{finding.actual ?? finding.expected ?? finding.criterion ?? "—"}
|
||||
@@ -104,9 +109,11 @@ export function FindingsQueuePanel({
|
||||
href={"/tasks/" + finding.task_id}
|
||||
prefetch={false}
|
||||
>
|
||||
<span className="text-primary hover:underline">
|
||||
Task #{finding.task_id.slice(0, 8)}
|
||||
</span>
|
||||
<HelpTip label="Short task ID — first 8 characters of the full task identifier">
|
||||
<span className="text-primary hover:underline">
|
||||
Task #{finding.task_id.slice(0, 8)}
|
||||
</span>
|
||||
</HelpTip>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -78,9 +78,11 @@ export function FlaggedItem({
|
||||
</span>
|
||||
{flag.related_task_id && (
|
||||
<Link href={"/tasks/" + flag.related_task_id} prefetch={false}>
|
||||
<span className="text-primary hover:underline">
|
||||
Task #{flag.related_task_id.slice(0, 8)}
|
||||
</span>
|
||||
<HelpTip label="Short task ID — first 8 characters of the full task identifier">
|
||||
<span className="text-primary hover:underline">
|
||||
Task #{flag.related_task_id.slice(0, 8)}
|
||||
</span>
|
||||
</HelpTip>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Progress } from "@/components/ui/progress";
|
||||
import { HelpTip } from "@/components/ui/help-tip";
|
||||
import {
|
||||
BarChart3,
|
||||
CheckCircle,
|
||||
@@ -22,6 +23,7 @@ interface MetricDisplay {
|
||||
icon: React.ReactNode;
|
||||
format: (value: number) => string;
|
||||
isPercent?: boolean;
|
||||
tip: string;
|
||||
}
|
||||
|
||||
const METRICS: MetricDisplay[] = [
|
||||
@@ -30,6 +32,7 @@ const METRICS: MetricDisplay[] = [
|
||||
label: "Tasks Completed (24h)",
|
||||
icon: <CheckCircle className="h-4 w-4 text-green-500" />,
|
||||
format: (v) => String(v),
|
||||
tip: "Tasks that reached completed in the last 24 hours",
|
||||
},
|
||||
{
|
||||
key: "qa_pass_rate",
|
||||
@@ -37,6 +40,7 @@ const METRICS: MetricDisplay[] = [
|
||||
icon: <BarChart3 className="h-4 w-4 text-blue-500" />,
|
||||
format: (v) => `${Math.round(v * 100)}%`,
|
||||
isPercent: true,
|
||||
tip: "Share of QA reviews that passed on the first attempt, no fail bounce",
|
||||
},
|
||||
{
|
||||
key: "avg_completion_time",
|
||||
@@ -44,6 +48,7 @@ const METRICS: MetricDisplay[] = [
|
||||
icon: <Clock className="h-4 w-4 text-purple-500" />,
|
||||
format: (v) =>
|
||||
`${(typeof v === "number" ? v : parseFloat(v) || 0).toFixed(1)}h`,
|
||||
tip: "Average wall-clock time from claim to completion across recent tasks",
|
||||
},
|
||||
{
|
||||
key: "documentation_rate",
|
||||
@@ -51,18 +56,21 @@ const METRICS: MetricDisplay[] = [
|
||||
icon: <FileText className="h-4 w-4 text-indigo-500" />,
|
||||
format: (v) => `${Math.round(v * 100)}%`,
|
||||
isPercent: true,
|
||||
tip: "Share of completed tasks that passed through a documentation step",
|
||||
},
|
||||
{
|
||||
key: "active_blockers",
|
||||
label: "Active Blockers",
|
||||
icon: <AlertTriangle className="h-4 w-4 text-red-500" />,
|
||||
format: (v) => String(v),
|
||||
tip: "Tasks currently in the blocked status right now",
|
||||
},
|
||||
{
|
||||
key: "longest_block_hours",
|
||||
label: "Longest Block",
|
||||
icon: <Clock className="h-4 w-4 text-orange-500" />,
|
||||
format: (v) => `${v}h`,
|
||||
tip: "How long the longest-running currently-blocked task has been stuck",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -91,15 +99,17 @@ export function QualityMetricsPanel({
|
||||
const value = metrics?.[m.key];
|
||||
return (
|
||||
<div key={m.key}>
|
||||
<div className="flex items-center justify-between text-sm mb-1">
|
||||
<div className="flex items-center gap-2 text-muted-foreground">
|
||||
{m.icon}
|
||||
{m.label}
|
||||
<HelpTip label={m.tip}>
|
||||
<div className="flex items-center justify-between text-sm mb-1">
|
||||
<div className="flex items-center gap-2 text-muted-foreground">
|
||||
{m.icon}
|
||||
{m.label}
|
||||
</div>
|
||||
<span className="font-medium">
|
||||
{value != null ? m.format(value) : "-"}
|
||||
</span>
|
||||
</div>
|
||||
<span className="font-medium">
|
||||
{value != null ? m.format(value) : "-"}
|
||||
</span>
|
||||
</div>
|
||||
</HelpTip>
|
||||
{m.isPercent && value != null && (
|
||||
<Progress value={value * 100} className="h-1.5" />
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user