import { FieldRecipeGroup, QcRoute, SmartGroupField, SmartGroupSampleRecord } from './SmartGroupFieldRecipe.groups'; import { ManualSample } from './SmartGroupManual.cohorts'; export type SmartGroupMode = 'auto' | 'manual'; /** A colour swatch in the manual assignment bar. */ export interface ManualPaletteEntry { /** CSS colour value (e.g. `var(--mint-sample-1)`). */ c: string; /** Human-readable swatch key for the `aria-label`. */ k: string; } /** Initial cohort assignment for a sample, keyed by sample name. */ export interface SmartGroupSeed { group?: string; sub?: string; sub2?: string; color?: string; } /** The QC summary chip shown in the rail when QC is not mixed into groups. */ export interface FieldRecipeQcChip { name: string; count: number; } /** One token of the example sample name, with the role it was read as. */ export interface FieldRecipeAnatomyToken { /** The token as written in the sample name. */ text: string; /** The layer number for a grouped field; the field name or role for any other token. */ caption: string; /** `on`: a grouped field. `off`: a field that is switched off. `fixed`: not a grouping field. */ state: 'on' | 'off' | 'fixed'; } export interface SmartGroupFieldRecipeProps { /** Sample records behind the experiment (one row per real sample). */ samples?: SmartGroupSampleRecord[]; /** Candidate grouping fields with role + value preview. */ fields?: SmartGroupField[]; /** Experiment code shown in the header; omitted from the subtitle when empty. */ experimentLabel?: string; /** Sample count shown in the header (real + QC). */ headerCount?: number; /** Which fields start switched on; defaults to every non-replicate field. */ initialOn?: boolean[]; /** Initial QC routing. */ initialRoute?: QcRoute; /** Group colours, cycled in group order. */ palette?: string[]; /** Colour of the QC pool's count bar. The QC dot is always the neutral QC marker (3a). */ qcColor?: string; /** Controls the field toggles; when set, clicking a toggle emits `toggle`. */ enabled?: boolean[]; /** * Per-card 1-based hierarchy layer (1 = the sample selector's major group), * `null` for cards not grouped by. When set, reorder clicks emit `move`. */ layers?: (number | null)[]; /** Pre-computed resulting groups; when set, the rail renders these directly. */ groups?: FieldRecipeGroup[]; /** QC summary chip to show in the rail; `null` hides it (e.g. when mixed). */ qcChip?: FieldRecipeQcChip | null; /** Controlled QC routing; when set, changing the select emits `update:route`. */ route?: QcRoute; /** QC sample count for the footer hint; defaults to `headerCount - samples`. */ qcCount?: number; /** Whether the template-download menu items are enabled (default `true`). */ canDownloadTemplate?: boolean; /** Show a loading state in the main body (e.g. while experiment data loads). */ loading?: boolean; /** Tokens of one example sample name; shown above the fields when not empty. */ anatomy?: FieldRecipeAnatomyToken[]; /** * Per-card hint for a field that is on, for example the groups that remain * when the user switches it off. `null` shows no hint for that card. */ hints?: (string | null)[]; /** One chip for each QC class; when set it replaces the single `qcChip`. */ qcChips?: FieldRecipeQcChip[]; /** Show the rename control on each field; a new name emits `rename`. */ renamable?: boolean; /** Names that a rename must refuse, in addition to the names of the other fields. */ reservedNames?: string[]; } export interface FieldRecipeApplyPayload { groups: FieldRecipeGroup[]; route: QcRoute; sampleTotal: number; activeFactors: string[]; } export interface SmartGroupManualProps { /** Flat list of sample names to group. */ sampleNames?: string[]; /** Initial assignments keyed by sample name. */ seed?: Record; /** Colour swatches offered in the assignment bar. */ palette?: ManualPaletteEntry[]; } export interface ManualDonePayload { samples: ManualSample[]; }