import Link from 'next/link';
import { ExternalLink } from 'lucide-react';
import { fmtDate } from '@/lib/format';
export interface ProvenanceInfo {
sourceSlug: string;
sourceName?: string | null;
dataset?: string | null;
datasetVersion?: string | null;
retrievedAt?: Date | string | null;
sourceUrl?: string | null;
layer?: 'raw' | 'normalized' | 'canonical' | 'derived' | 'ranked';
license?: string | null;
evidenceType?: string | null;
pmid?: string | null;
ingestRunId?: string | null;
note?: string | null;
}
/** One-line provenance summary for `title` attributes on compact badges (dataset · version · retrieved). */
export function provenanceTitle(p: ProvenanceInfo): string {
const bits = [p.sourceName ?? p.sourceSlug];
if (p.dataset) bits.push(p.dataset);
if (p.datasetVersion) bits.push(`version ${p.datasetVersion}`);
if (p.retrievedAt) bits.push(`retrieved ${fmtDate(p.retrievedAt)}`);
if (p.layer === 'derived' || p.layer === 'ranked') bits.push('computed by CancerIndex');
return bits.join(' · ');
}
/**
* Small source badge; hover / focus reveals the provenance popover (source, dataset, version,
* retrieved date, raw vs normalized, link). CSS-only so it works inside server components.
*
* `compact`: link only, no popover — for dense tables. When every row shares one source/dataset the
* popover is shown once in the table caption; when provenance genuinely differs per row (e.g.
* epidemiology observations from different datasets/years) pass `title` (or let it default to a
* dataset · version · retrieved summary) so the detail stays one hover away without the markup.
*/
export function SourceBadge({ p, className = '', compact = false, title }: { p: ProvenanceInfo; className?: string; compact?: boolean; title?: string | null }) {
if (compact) {
// The visible slug is the link text; the "Source" column header gives the context and `title`
// (dataset · version · retrieved) is exposed as the accessible description. No aria-label
// duplicate: every attribute here is repeated hundreds of times per page (HTML + RSC payload).
const t = title === null ? undefined : (title ?? (p.dataset || p.datasetVersion ? provenanceTitle(p) : undefined));
const extra = t ? { title: t } : {};
return (
{p.sourceSlug}
);
}
return (
{p.sourceSlug}
Provenance
{p.note ? {p.note} : null}
{p.sourceUrl ? (
Open at source
: the popover contains a
on (React #418 in production).