import type { ColumnDef } from "../components/data-table/types" export type ColumnPinPolicy = { defaults: Record lockedLeft: string[] lockedRight: string[] } /** Derive default / locked pin policy from hub `ColumnDef[]`. */ export function columnPinPolicyFromDefs>( columns: ColumnDef[], ): ColumnPinPolicy { const defaults: Record = {} const lockedLeft: string[] = [] const lockedRight: string[] = [] for (const col of columns) { if (col.defaultPin) defaults[col.key] = col.defaultPin if (col.lockPin && col.defaultPin === "left") lockedLeft.push(col.key) if (col.lockPin && col.defaultPin === "right") lockedRight.push(col.key) } return { defaults, lockedLeft, lockedRight } } /** * Merge persisted pins with column defaults. Saved user pins win for * non-locked columns; locked columns always match `ColumnDef.lockPin`. * Default pins apply only when a column has no saved pin entry yet. */ export function reconcileColumnPins( saved: Record, policy: ColumnPinPolicy, ): Record { const next = { ...saved } for (const [key, pin] of Object.entries(policy.defaults)) { if (!(key in next)) next[key] = pin } for (const key of policy.lockedLeft) next[key] = "left" for (const key of policy.lockedRight) next[key] = "right" return next } /** Keep locked edge columns anchored; preserve middle order from saved state. */ export function mergeColOrderWithPinPolicy( saved: string[], columnKeys: Set, policy?: ColumnPinPolicy, ): string[] { const lockedLeft = policy?.lockedLeft.filter(k => columnKeys.has(k)) ?? [] const lockedRight = policy?.lockedRight.filter(k => columnKeys.has(k)) ?? [] const locked = new Set([...lockedLeft, ...lockedRight]) const middle = saved.filter(k => columnKeys.has(k) && !locked.has(k)) const inMiddle = new Set(middle) for (const key of columnKeys) { if (locked.has(key) || inMiddle.has(key)) continue middle.push(key) inMiddle.add(key) } return [...lockedLeft, ...middle, ...lockedRight] }