/** * Shared prop and payload types for the Smart Group — Full View components * (`SmartGroupModal` shell + `SmartGroupFieldRecipe` auto mode + * `SmartGroupManual` manual mode). */ import type { FieldRecipeGroup, QcRoute, SmartGroupField, SmartGroupSampleRecord, } from './SmartGroupFieldRecipe.groups' import type { 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 // ── Controlled mode (driven by AutoGroupModal over the useAutoGroup engine). // When these are provided the component renders the supplied data and emits // events instead of running its own fixture grouping logic. /** 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[] }