mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
feat(panel): tooltip sweep — tasks, kanban, task assistant, git, work sessions (58 tips, 22 files)
Full import-graph walk per page: filter-chip and plan-section icon buttons gain their first accessible names, per-state description maps for git/docs/finding/priority badges, truncation-gated full-value tips, disabled buttons explain their gate. Stateful Radix triggers use the task-tabs data-state re-assertion pattern.
This commit is contained in:
@@ -10,6 +10,7 @@ import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { FileCode, FileDiff, WrapText } from "lucide-react";
|
||||
import { HelpTip } from "@/components/ui/help-tip";
|
||||
|
||||
interface GitDiffViewerProps {
|
||||
stagedDiff: GitDiffResponse | undefined;
|
||||
@@ -124,21 +125,39 @@ export function GitDiffViewer({
|
||||
<Tabs defaultValue="unstaged">
|
||||
<div className="px-4 border-b">
|
||||
<TabsList className="h-9">
|
||||
{/* HelpTip wraps an inner span, never the TabsTrigger itself —
|
||||
TooltipTrigger's asChild would clobber the trigger's own
|
||||
data-state and break the active-tab highlight (see
|
||||
task-tabs.tsx for the fuller writeup of this bug class). */}
|
||||
<TabsTrigger value="unstaged" className="text-xs gap-1">
|
||||
Working Directory
|
||||
{unstagedCount > 0 && (
|
||||
<Badge variant="secondary" className="h-4 px-1 text-[10px]">
|
||||
{unstagedCount}
|
||||
</Badge>
|
||||
)}
|
||||
<HelpTip label="Files changed on disk that haven't been staged for the next commit yet">
|
||||
<span className="inline-flex items-center gap-1">
|
||||
Working Directory
|
||||
{unstagedCount > 0 && (
|
||||
<Badge
|
||||
variant="secondary"
|
||||
className="h-4 px-1 text-[10px]"
|
||||
>
|
||||
{unstagedCount}
|
||||
</Badge>
|
||||
)}
|
||||
</span>
|
||||
</HelpTip>
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="staged" className="text-xs gap-1">
|
||||
Staged
|
||||
{stagedCount > 0 && (
|
||||
<Badge variant="secondary" className="h-4 px-1 text-[10px]">
|
||||
{stagedCount}
|
||||
</Badge>
|
||||
)}
|
||||
<HelpTip label="Files staged and ready to be included in the next commit">
|
||||
<span className="inline-flex items-center gap-1">
|
||||
Staged
|
||||
{stagedCount > 0 && (
|
||||
<Badge
|
||||
variant="secondary"
|
||||
className="h-4 px-1 text-[10px]"
|
||||
>
|
||||
{stagedCount}
|
||||
</Badge>
|
||||
)}
|
||||
</span>
|
||||
</HelpTip>
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</div>
|
||||
|
||||
@@ -14,12 +14,22 @@ import {
|
||||
ArrowDown,
|
||||
CheckCircle,
|
||||
} from "lucide-react";
|
||||
import { HelpTip } from "@/components/ui/help-tip";
|
||||
|
||||
interface GitStatusPanelProps {
|
||||
status: GitStatusResponse | undefined;
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
// Plain-language explanation per file bucket, mirroring the task-status-badge
|
||||
// per-state description map so non-git-fluent readers (CEO, PM) know what
|
||||
// each section means without having to already know git jargon.
|
||||
const FILE_SECTION_DESCRIPTIONS = {
|
||||
staged: "Changes staged and ready to be included in the next commit.",
|
||||
unstaged: "Tracked files with changes not yet staged for commit.",
|
||||
untracked: "New files git isn't tracking yet.",
|
||||
} as const;
|
||||
|
||||
export function GitStatusPanel({ status, isLoading }: GitStatusPanelProps) {
|
||||
if (isLoading) {
|
||||
return (
|
||||
@@ -77,16 +87,20 @@ export function GitStatusPanel({ status, isLoading }: GitStatusPanelProps) {
|
||||
{(status.ahead > 0 || status.behind > 0) && (
|
||||
<div className="flex items-center gap-2">
|
||||
{status.ahead > 0 && (
|
||||
<Badge variant="secondary" className="text-xs">
|
||||
<ArrowUp className="h-3 w-3 mr-1" />
|
||||
{status.ahead} ahead
|
||||
</Badge>
|
||||
<HelpTip label="Local commits not yet pushed to the remote.">
|
||||
<Badge variant="secondary" className="text-xs">
|
||||
<ArrowUp className="h-3 w-3 mr-1" />
|
||||
{status.ahead} ahead
|
||||
</Badge>
|
||||
</HelpTip>
|
||||
)}
|
||||
{status.behind > 0 && (
|
||||
<Badge variant="secondary" className="text-xs">
|
||||
<ArrowDown className="h-3 w-3 mr-1" />
|
||||
{status.behind} behind
|
||||
</Badge>
|
||||
<HelpTip label="Remote commits not yet merged into your local branch.">
|
||||
<Badge variant="secondary" className="text-xs">
|
||||
<ArrowDown className="h-3 w-3 mr-1" />
|
||||
{status.behind} behind
|
||||
</Badge>
|
||||
</HelpTip>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
@@ -99,9 +113,11 @@ export function GitStatusPanel({ status, isLoading }: GitStatusPanelProps) {
|
||||
{/* Staged Files */}
|
||||
{status.staged_files.length > 0 && (
|
||||
<div>
|
||||
<h4 className="text-xs font-semibold text-green-600 uppercase tracking-wider mb-1">
|
||||
Staged ({status.staged_files.length})
|
||||
</h4>
|
||||
<HelpTip label={FILE_SECTION_DESCRIPTIONS.staged}>
|
||||
<h4 className="text-xs font-semibold text-green-600 uppercase tracking-wider mb-1 w-fit">
|
||||
Staged ({status.staged_files.length})
|
||||
</h4>
|
||||
</HelpTip>
|
||||
<div className="space-y-0.5">
|
||||
{status.staged_files.map((file) => (
|
||||
<div
|
||||
@@ -121,9 +137,11 @@ export function GitStatusPanel({ status, isLoading }: GitStatusPanelProps) {
|
||||
{/* Unstaged Files */}
|
||||
{status.unstaged_files.length > 0 && (
|
||||
<div>
|
||||
<h4 className="text-xs font-semibold text-orange-600 uppercase tracking-wider mb-1">
|
||||
Modified ({status.unstaged_files.length})
|
||||
</h4>
|
||||
<HelpTip label={FILE_SECTION_DESCRIPTIONS.unstaged}>
|
||||
<h4 className="text-xs font-semibold text-orange-600 uppercase tracking-wider mb-1 w-fit">
|
||||
Modified ({status.unstaged_files.length})
|
||||
</h4>
|
||||
</HelpTip>
|
||||
<div className="space-y-0.5">
|
||||
{status.unstaged_files.map((file) => (
|
||||
<div
|
||||
@@ -143,9 +161,11 @@ export function GitStatusPanel({ status, isLoading }: GitStatusPanelProps) {
|
||||
{/* Untracked Files */}
|
||||
{status.untracked_files.length > 0 && (
|
||||
<div>
|
||||
<h4 className="text-xs font-semibold text-blue-600 uppercase tracking-wider mb-1">
|
||||
Untracked ({status.untracked_files.length})
|
||||
</h4>
|
||||
<HelpTip label={FILE_SECTION_DESCRIPTIONS.untracked}>
|
||||
<h4 className="text-xs font-semibold text-blue-600 uppercase tracking-wider mb-1 w-fit">
|
||||
Untracked ({status.untracked_files.length})
|
||||
</h4>
|
||||
</HelpTip>
|
||||
<div className="space-y-0.5">
|
||||
{status.untracked_files.map((file) => (
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user