@@ -0,0 +1,102 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Button, Checkbox, Modal, Space, Typography } from 'antd';
|
||||
import { HolderOutlined } from '@ant-design/icons';
|
||||
import type { ListColumnSettingItem } from '../lib/list-column-prefs';
|
||||
|
||||
type Props = {
|
||||
open: boolean;
|
||||
items: ListColumnSettingItem[];
|
||||
saving?: boolean;
|
||||
onCancel: () => void;
|
||||
onReset: () => void;
|
||||
onSave: (items: ListColumnSettingItem[]) => void;
|
||||
};
|
||||
|
||||
export function AdminListColumnsModal({ open, items, saving, onCancel, onReset, onSave }: Props) {
|
||||
const [draft, setDraft] = useState<ListColumnSettingItem[]>(items);
|
||||
const [dragKey, setDragKey] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (open) setDraft(items);
|
||||
}, [open, items]);
|
||||
|
||||
function move(from: number, to: number) {
|
||||
if (to < 0 || to >= draft.length) return;
|
||||
const next = [...draft];
|
||||
const [row] = next.splice(from, 1);
|
||||
next.splice(to, 0, row);
|
||||
setDraft(next);
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="列设置"
|
||||
open={open}
|
||||
onCancel={onCancel}
|
||||
footer={
|
||||
<Space style={{ width: '100%', justifyContent: 'space-between' }}>
|
||||
<Button onClick={onReset}>重置默认</Button>
|
||||
<Space>
|
||||
<Button onClick={onCancel}>取消</Button>
|
||||
<Button type="primary" loading={saving} onClick={() => onSave(draft)}>
|
||||
保存
|
||||
</Button>
|
||||
</Space>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<Typography.Paragraph type="secondary" style={{ marginTop: 0 }}>
|
||||
勾选显示列,拖拽或上下箭头调整顺序。序号与操作列固定,不在此列表中。
|
||||
</Typography.Paragraph>
|
||||
<div>
|
||||
{draft.map((item, index) => (
|
||||
<div
|
||||
key={item.key}
|
||||
draggable
|
||||
onDragStart={() => setDragKey(item.key)}
|
||||
onDragOver={(e) => e.preventDefault()}
|
||||
onDrop={() => {
|
||||
if (!dragKey || dragKey === item.key) return;
|
||||
const from = draft.findIndex((r) => r.key === dragKey);
|
||||
if (from >= 0) move(from, index);
|
||||
setDragKey(null);
|
||||
}}
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 8,
|
||||
padding: '6px 0',
|
||||
borderBottom: '1px solid #f0f0f0',
|
||||
cursor: 'move',
|
||||
}}
|
||||
>
|
||||
<HolderOutlined style={{ color: '#999' }} />
|
||||
<Checkbox
|
||||
checked={item.visible}
|
||||
onChange={(e) => {
|
||||
const next = [...draft];
|
||||
next[index] = { ...item, visible: e.target.checked };
|
||||
setDraft(next);
|
||||
}}
|
||||
>
|
||||
{item.title}
|
||||
</Checkbox>
|
||||
<span style={{ marginLeft: 'auto' }}>
|
||||
<Button type="link" size="small" disabled={index === 0} onClick={() => move(index, index - 1)}>
|
||||
上移
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
disabled={index === draft.length - 1}
|
||||
onClick={() => move(index, index + 1)}
|
||||
>
|
||||
下移
|
||||
</Button>
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user