135 lines
4.4 KiB
React
135 lines
4.4 KiB
React
|
|
import { Button, Input, Space, Popover } from 'antd'
|
|||
|
|
import { ReloadOutlined, FilterOutlined } from '@ant-design/icons'
|
|||
|
|
import './ListActionBar.css'
|
|||
|
|
|
|||
|
|
const { Search } = Input
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 列表操作栏组件
|
|||
|
|
* @param {Object} props
|
|||
|
|
* @param {Array} props.actions - 左侧操作按钮配置数组
|
|||
|
|
* @param {Array} props.batchActions - 批量操作按钮配置数组(仅在有选中项时显示)
|
|||
|
|
* @param {Object} props.selectionInfo - 选中信息 { count: 选中数量, total: 总数量, isAllPagesSelected: 是否跨页全选 }
|
|||
|
|
* @param {Function} props.onSelectAllPages - 选择所有页回调
|
|||
|
|
* @param {Function} props.onClearSelection - 清除选择回调
|
|||
|
|
* @param {Object} props.search - 搜索配置
|
|||
|
|
* @param {Object} props.filter - 高级筛选配置(可选)
|
|||
|
|
* @param {boolean} props.showRefresh - 是否显示刷新按钮
|
|||
|
|
* @param {Function} props.onRefresh - 刷新回调
|
|||
|
|
*/
|
|||
|
|
function ListActionBar({
|
|||
|
|
actions = [],
|
|||
|
|
batchActions = [],
|
|||
|
|
selectionInfo,
|
|||
|
|
onSelectAllPages,
|
|||
|
|
onClearSelection,
|
|||
|
|
search,
|
|||
|
|
filter,
|
|||
|
|
showRefresh = false,
|
|||
|
|
onRefresh,
|
|||
|
|
}) {
|
|||
|
|
// 是否有选中项
|
|||
|
|
const hasSelection = selectionInfo && selectionInfo.count > 0
|
|||
|
|
return (
|
|||
|
|
<div className="list-action-bar">
|
|||
|
|
{/* 左侧操作按钮区 */}
|
|||
|
|
<div className="list-action-bar-left">
|
|||
|
|
{/* 常规操作按钮(无选中时显示) */}
|
|||
|
|
{!hasSelection && actions.map((action) => (
|
|||
|
|
<Button
|
|||
|
|
key={action.key}
|
|||
|
|
type={action.type || 'default'}
|
|||
|
|
icon={action.icon}
|
|||
|
|
disabled={action.disabled}
|
|||
|
|
danger={action.danger}
|
|||
|
|
onClick={action.onClick}
|
|||
|
|
>
|
|||
|
|
{action.label}
|
|||
|
|
</Button>
|
|||
|
|
))}
|
|||
|
|
|
|||
|
|
{/* 批量操作区域(有选中时显示) */}
|
|||
|
|
{hasSelection && (
|
|||
|
|
<Space>
|
|||
|
|
{/* 选中信息 */}
|
|||
|
|
<div className="selection-info">
|
|||
|
|
<span className="selection-count">
|
|||
|
|
已选择 <strong>{selectionInfo.count}</strong> 项
|
|||
|
|
{selectionInfo.isAllPagesSelected && (
|
|||
|
|
<span className="all-pages-tag">(全部页)</span>
|
|||
|
|
)}
|
|||
|
|
</span>
|
|||
|
|
{!selectionInfo.isAllPagesSelected && selectionInfo.total > selectionInfo.count && (
|
|||
|
|
<a onClick={onSelectAllPages} className="select-all-link">
|
|||
|
|
选择全部 {selectionInfo.total} 项
|
|||
|
|
</a>
|
|||
|
|
)}
|
|||
|
|
<a onClick={onClearSelection} className="clear-selection-link">
|
|||
|
|
清除
|
|||
|
|
</a>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{/* 批量操作按钮 */}
|
|||
|
|
{batchActions.map((action) => (
|
|||
|
|
<Button
|
|||
|
|
key={action.key}
|
|||
|
|
type={action.type || 'default'}
|
|||
|
|
icon={action.icon}
|
|||
|
|
disabled={action.disabled}
|
|||
|
|
danger={action.danger}
|
|||
|
|
onClick={action.onClick}
|
|||
|
|
>
|
|||
|
|
{action.label}
|
|||
|
|
</Button>
|
|||
|
|
))}
|
|||
|
|
</Space>
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{/* 右侧搜索筛选区 */}
|
|||
|
|
<div className="list-action-bar-right">
|
|||
|
|
<Space.Compact>
|
|||
|
|
<Search
|
|||
|
|
placeholder={search?.placeholder || '请输入搜索关键词'}
|
|||
|
|
allowClear
|
|||
|
|
style={{ width: search?.width || 280 }}
|
|||
|
|
onSearch={search?.onSearch}
|
|||
|
|
onChange={(e) => search?.onChange?.(e.target.value)}
|
|||
|
|
value={search?.value}
|
|||
|
|
/>
|
|||
|
|
{filter && (
|
|||
|
|
<Popover
|
|||
|
|
content={filter.content}
|
|||
|
|
title={
|
|||
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
|||
|
|
<FilterOutlined />
|
|||
|
|
<span>{filter.title || '高级筛选'}</span>
|
|||
|
|
</div>
|
|||
|
|
}
|
|||
|
|
trigger="click"
|
|||
|
|
open={filter.visible}
|
|||
|
|
onOpenChange={filter.onVisibleChange}
|
|||
|
|
placement="bottomRight"
|
|||
|
|
overlayClassName="filter-popover"
|
|||
|
|
>
|
|||
|
|
<Button
|
|||
|
|
icon={<FilterOutlined />}
|
|||
|
|
type={filter.isActive ? 'primary' : 'default'}
|
|||
|
|
>
|
|||
|
|
{filter.selectedLabel || '筛选'}
|
|||
|
|
</Button>
|
|||
|
|
</Popover>
|
|||
|
|
)}
|
|||
|
|
</Space.Compact>
|
|||
|
|
{showRefresh && (
|
|||
|
|
<Button icon={<ReloadOutlined />} onClick={onRefresh}>
|
|||
|
|
刷新
|
|||
|
|
</Button>
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export default ListActionBar
|