import Link from 'next/link'; import { Section, Note } from '@/components/ui/section'; import { EmptyState } from '@/components/ui/empty-state'; import { FrequencyTables } from '@/components/data/frequency-table'; import { cohortsForCancer, frequenciesForCancer } from '@/lib/queries/genomics'; import { loadProvenance } from '@/lib/queries/provenance'; import { fmtInt } from '@/lib/format'; import type { CancerBundle } from '../load'; /** * Cohort selector renders ONE cohort by default — the one with the largest number of cases * profiled — plus an explicit "All cohorts" option (`?cohort=all`). Cohorts are never pooled. */ export async function GenomicsTab({ b, cohort }: { b: CancerBundle; cohort: string | null }) { const cohorts = await cohortsForCancer(b.descendants); if (cohorts.length === 0) { return (
No genomic cohort is mapped to this entity or its descendants. Frequencies come from open-access cohorts (GDC projects) and always carry their denominator (cases profiled); they are never pooled across cohorts.
); } const withRows = cohorts.filter((c) => c.frequency_rows > 0); const defaultCohort = (withRows[0] ?? cohorts[0])!; const showAll = cohort === 'all'; const selected = showAll ? null : cohorts.find((c) => c.cohort_id === cohort || c.study_id === cohort) ?? defaultCohort; const rows = await frequenciesForCancer(b.descendants, { cohortId: selected?.cohort_id ?? null }); const prov = await loadProvenance(rows.map((r) => r.provenance_id)); const base = `/cancer/${b.cancer.slug}/genomics`; const hrefFor = (c: (typeof cohorts)[number]) => (c.cohort_id === defaultCohort.cohort_id ? base : `${base}?cohort=${encodeURIComponent(c.study_id)}`); return (
{rows.length ? ( ) : ( The cohort is mapped to this entity but no gene frequency has been ingested for it yet. )}
Cohorts mapped to a descendant (e.g. a subtype) are included because their cases belong to this entity by definition; the mapping and its match type are shown per cohort.
); }