import type { ColumnType } from 'antd/es/table'; import type { HqListColumnKey, HqListColumnPref } from '@dukang/shared-types'; export const SERIAL_COLUMN_KEY = '__serial'; export const ACTIONS_COLUMN_KEY = '__actions'; export function columnKey(col: ColumnType, index: number): string { if (col.key != null && String(col.key).length) return String(col.key); const dataIndex = col.dataIndex; if (typeof dataIndex === 'string' && dataIndex) return dataIndex; if (Array.isArray(dataIndex) && dataIndex.length) return dataIndex.map(String).join('.'); if (typeof col.title === 'string' && col.title) return col.title; return `col-${index}`; } export function isActionsColumn(col: ColumnType, key: string): boolean { if (key === ACTIONS_COLUMN_KEY || key === 'actions' || key === 'action') return true; return col.title === '操作'; } export function mergeColumnOrder(defaultKeys: string[], pref?: HqListColumnPref): string[] { const known = new Set(defaultKeys); const ordered = (pref?.order ?? []).filter((k) => known.has(k)); for (const key of defaultKeys) { if (ordered.includes(key)) continue; const defaultIdx = defaultKeys.indexOf(key); let insertAt = ordered.length; for (let i = 0; i < ordered.length; i += 1) { if (defaultKeys.indexOf(ordered[i]) > defaultIdx) { insertAt = i; break; } } ordered.splice(insertAt, 0, key); } return ordered; } export function visibleColumnKeys(defaultKeys: string[], pref?: HqListColumnPref): string[] { const hidden = new Set(pref?.hidden ?? []); return mergeColumnOrder(defaultKeys, pref).filter((k) => !hidden.has(k)); } export function applyColumnPrefs( columns: ColumnType[], pref: HqListColumnPref | undefined, ): ColumnType[] { const keyed = columns.map((col, i) => { const key = columnKey(col, i); return { col: { ...col, key }, key, actions: isActionsColumn(col, key) }; }); const configurable = keyed.filter((c) => !c.actions); const actions = keyed.filter((c) => c.actions); const defaultKeys = configurable.map((c) => c.key); const visible = new Set(visibleColumnKeys(defaultKeys, pref)); const orderedKeys = mergeColumnOrder(defaultKeys, pref).filter((k) => visible.has(k)); const byKey = new Map(configurable.map((c) => [c.key, c.col])); return [ ...orderedKeys .map((k) => { const col = byKey.get(k); if (!col) return null; const w = pref?.widths?.[k]; return w != null ? { ...col, width: w } : col; }) .filter((c): c is ColumnType => !!c), ...actions.map((c) => { const w = pref?.widths?.[c.key]; return w != null ? { ...c.col, width: w } : c.col; }), ]; } export type ListColumnSettingItem = { key: string; title: string; visible: boolean; }; export function settingItems( columns: ColumnType[], pref?: HqListColumnPref, ): ListColumnSettingItem[] { const keyed = columns .map((col, i) => ({ col, key: columnKey(col, i) })) .filter(({ col, key }) => !isActionsColumn(col, key)); const hidden = new Set(pref?.hidden ?? []); const order = mergeColumnOrder(keyed.map((c) => c.key), pref); const byKey = new Map(keyed.map((c) => [c.key, c.col])); return order.map((key) => { const col = byKey.get(key); const title = typeof col?.title === 'string' ? col.title : key; return { key, title, visible: !hidden.has(key) }; }); } export type { HqListColumnKey };