RowStatusChip.tsx2.0 KBView on GitHub 'use client';
/**
* The reserved `_status` column, rendered as a per-row state chip.
*
* Progress needs no bespoke channel: a fan-out orchestrator writing `_status` is an ordinary
* cell write that rides the same Y.js delta and SSE path as anything else
* (apps/mail/docs/table-documents.md §3.2 step 7), so a 40-row run lights up row by row here
* with nothing else in the client involved. `_error` is the failure text, surfaced on hover
* rather than inline — a row that failed still has to fit on one line.
*/
import { Check, CircleDashed, Loader2, TriangleAlert } from 'lucide-react';
import { cn } from '@/lib/utils';
import { ROW_STATUS_LABELS } from './constants';
const ICON_BY_STATUS = {
pending: CircleDashed,
running: Loader2,
done: Check,
failed: TriangleAlert,
} as const;
const TONE_BY_STATUS = {
pending: 'text-muted-foreground',
running: 'text-primary',
done: 'text-emerald-600 dark:text-emerald-400',
failed: 'text-destructive',
} as const;
export interface RowStatusChipProps {
/** Raw `_status` cell value. Anything outside the four known states renders verbatim. */
status: string;
/** Raw `_error` cell value, shown as the chip's title when present. */
error?: string;
className?: string;
}
export function RowStatusChip({ status, error, className }: RowStatusChipProps) {
const key=[redacted];
const known = key in ICON_BY_STATUS ? (key as keyof typeof ICON_BY_STATUS) : null;
const Icon = known ? ICON_BY_STATUS[known] : null;
const label = known ? ROW_STATUS_LABELS[known] : status.trim();
if (!label) return null;
return (
<span
title={error?.trim() || label}
className={cn(
'inline-flex max-w-full items-center gap-1 text-xs',
known ? TONE_BY_STATUS[known] : 'text-muted-foreground',
className,
)}
>
{Icon && <Icon className={cn('size-3 shrink-0', known === 'running' && 'animate-spin')} />}
<span className="truncate">{label}</span>
</span>
);
}