98 lines
3.4 KiB
TypeScript
98 lines
3.4 KiB
TypeScript
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<T>(col: ColumnType<T>, 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<T>(col: ColumnType<T>, 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<T>(
|
|
columns: ColumnType<T>[],
|
|
pref: HqListColumnPref | undefined,
|
|
): ColumnType<T>[] {
|
|
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<T> => !!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<T>(
|
|
columns: ColumnType<T>[],
|
|
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 };
|