104 lines
2.7 KiB
TypeScript
104 lines
2.7 KiB
TypeScript
import { useMemo, useState } from 'react';
|
|
import { Button, message } from 'antd';
|
|
import { SettingOutlined } from '@ant-design/icons';
|
|
import type { ColumnsType, ColumnType } from 'antd/es/table';
|
|
import type { HqListColumnKey } from '@dukang/shared-types';
|
|
import { AdminListColumnsModal } from '../components/AdminListColumnsModal';
|
|
import { useListColumnPrefs } from './ListColumnPrefsContext';
|
|
import {
|
|
ACTIONS_COLUMN_KEY,
|
|
SERIAL_COLUMN_KEY,
|
|
applyColumnPrefs,
|
|
settingItems,
|
|
type ListColumnSettingItem,
|
|
} from './list-column-prefs';
|
|
|
|
type Options = {
|
|
page?: number;
|
|
pageSize?: number;
|
|
};
|
|
|
|
export function useAdminListColumns<T>(
|
|
listKey: HqListColumnKey,
|
|
allColumns: ColumnsType<T>,
|
|
options: Options = {},
|
|
) {
|
|
const { page = 1, pageSize = 20 } = options;
|
|
const { prefs, save } = useListColumnPrefs();
|
|
const [open, setOpen] = useState(false);
|
|
const [saving, setSaving] = useState(false);
|
|
const pref = prefs[listKey];
|
|
|
|
const configured = useMemo(
|
|
() => applyColumnPrefs(allColumns as ColumnType<T>[], pref),
|
|
[allColumns, pref],
|
|
);
|
|
|
|
const items = useMemo(
|
|
() => settingItems(allColumns as ColumnType<T>[], pref),
|
|
[allColumns, pref],
|
|
);
|
|
|
|
const serialCol: ColumnType<T> = useMemo(
|
|
() => ({
|
|
key: SERIAL_COLUMN_KEY,
|
|
title: '序号',
|
|
width: 64,
|
|
fixed: 'left' as const,
|
|
render: (_: unknown, __: T, index: number) => (page - 1) * pageSize + index + 1,
|
|
}),
|
|
[page, pageSize],
|
|
);
|
|
|
|
const columns = useMemo<ColumnsType<T>>(
|
|
() => [
|
|
serialCol,
|
|
...configured.map((col) =>
|
|
col.title === '操作' || col.key === ACTIONS_COLUMN_KEY || col.key === 'actions'
|
|
? { ...col, key: col.key ?? ACTIONS_COLUMN_KEY }
|
|
: col,
|
|
),
|
|
],
|
|
[configured, serialCol],
|
|
);
|
|
|
|
async function persist(next: ListColumnSettingItem[] | null) {
|
|
setSaving(true);
|
|
try {
|
|
if (!next) {
|
|
await save(listKey, null);
|
|
} else {
|
|
await save(listKey, {
|
|
order: next.map((i) => i.key),
|
|
hidden: next.filter((i) => !i.visible).map((i) => i.key),
|
|
});
|
|
}
|
|
setOpen(false);
|
|
message.success(next ? '列设置已保存' : '已恢复默认列');
|
|
} catch (e) {
|
|
message.error(e instanceof Error ? e.message : '保存失败');
|
|
} finally {
|
|
setSaving(false);
|
|
}
|
|
}
|
|
|
|
const settingsButton = (
|
|
<Button icon={<SettingOutlined />} onClick={() => setOpen(true)}>
|
|
列设置
|
|
</Button>
|
|
);
|
|
|
|
const settingsModal = (
|
|
<AdminListColumnsModal
|
|
open={open}
|
|
items={items}
|
|
saving={saving}
|
|
onCancel={() => setOpen(false)}
|
|
onReset={() => void persist(null)}
|
|
onSave={(draft) => void persist(draft)}
|
|
/>
|
|
);
|
|
|
|
return { columns, settingsButton, settingsModal };
|
|
}
|