SPB Git forge

spb/cancerindex

Public
37commits 1branches 0releases
2.9 MBsize
maindefault branch
10 days agolast push
TypeScript 97.2% SQL 1.5% CSS 0.6% JavaScript 0.5%

Web: single provenance popover per evidence table, compact row badges

Simon-Pierre Boucher committed 16 days ago (Sep 8, 2026) parent 36d464d

2 changed files +18 −3

modified apps/web/src/components/data/evidence-table.tsx +8 −2
@@ -26,8 +26,15 @@ function DirectionBadge({ e }: { e: EvidenceItem }) {
26 26 */
27 27 export function EvidenceTable({ items, prov, showCancer = false, showVariant = true }: { items: EvidenceItem[]; prov: Map<number, ProvRow>; showCancer?: boolean; showVariant?: boolean }) {
28 28 const groups = groupEvidence(items);
29 + // One provenance popover for the whole table (all rows come from one CIViC release); rows carry a compact badge.
30 + const first = items[0] ? toInfo(prov.get(items[0].provenance_id)) : null;
29 31 return (
30 32 <div className="space-y-6">
33 + <p className="flex flex-wrap items-center gap-2 text-[12px] text-ink-3">
34 + <SourceBadge p={first ?? { sourceSlug: 'civic', sourceName: 'CIViC' }} />
35 + <ClaimBadge kind="curated" />
36 + {items.length} evidence item{items.length === 1 ? '' : 's'} · levels, directions and significance as curated at the source; each row links to its CIViC record.
37 + </p>
31 38 {groups.map((g) => (
32 39 <section key={g.key} aria-label={g.label}>
33 40 {showVariant ? (
@@ -131,8 +138,7 @@ export function EvidenceTable({ items, prov, showCancer = false, showVariant = t
131 138 </td>
132 139 <td>
133 140 <span className="inline-flex flex-wrap gap-1">
134 {toInfo(prov.get(e.provenance_id)) ? <SourceBadge p={toInfo(prov.get(e.provenance_id))!} /> : <SourceBadge p={{ sourceSlug: 'civic', sourceName: 'CIViC' }} />}
135 <ClaimBadge kind="curated" />
141 + <SourceBadge compact p={toInfo(prov.get(e.provenance_id)) ?? { sourceSlug: 'civic', sourceName: 'CIViC' }} />
136 142 </span>
137 143 </td>
138 144 </tr>
modified apps/web/src/components/ui/source-badge.tsx +10 −1
@@ -21,7 +21,16 @@ export interface ProvenanceInfo {
21 21 * Small source badge; hover / focus reveals the provenance popover (source, dataset, version,
22 22 * retrieved date, raw vs normalized, link). CSS-only so it works inside server components.
23 23 */
24 export function SourceBadge({ p, className = '' }: { p: ProvenanceInfo; className?: string }) {
24 +export function SourceBadge({ p, className = '', compact = false }: { p: ProvenanceInfo; className?: string; compact?: boolean }) {
25 + // compact: link only, no popover — for dense tables where every row shares one source/dataset (the
26 + // popover is then shown once in the table caption).
27 + if (compact) {
28 + return (
29 + <Link href={`/source/${p.sourceSlug}`} className={`ci-mono inline-flex items-center rounded-sm border border-rule-strong bg-paper px-1 py-[0px] text-[10.5px] leading-4 text-ink-2 no-underline hover:border-accent hover:text-accent focus:border-accent ${className}`} aria-label={`Source: ${p.sourceName ?? p.sourceSlug}`}>
30 + {p.sourceSlug}
31 + </Link>
32 + );
33 + }
25 34 return (
26 35 <span className={`ci-pop ${className}`}>
27 36 <Link
28 37