assistant-todo/src/ui/task/drag/DroppableTable.tsx

145 lines
6.5 KiB
TypeScript
Raw Normal View History

2025-03-19 06:59:45 -04:00
'use client'
2025-06-26 06:59:31 -04:00
import React, {CSSProperties} from "react";
2025-03-19 06:59:45 -04:00
import {Draggable, Droppable} from "react-beautiful-dnd";
2025-06-26 06:59:31 -04:00
import {ConfigProvider, Tooltip} from "antd";
2025-03-19 06:59:45 -04:00
import {DataType} from "@/lib/definitions";
import './index.modules.css'
2025-06-26 06:59:31 -04:00
import dayjs from "dayjs";
import {getTaskState, taskPriorityList} from "@/lib/task/project/data";
import {List as VirtualizedList, AutoSizer} from "react-virtualized";
import 'react-virtualized/styles.css';
import OperationButton from "@/ui/task/OperationButton";
2025-03-19 06:59:45 -04:00
2025-06-26 06:59:31 -04:00
interface DroppableTableProps {
tableCode: string,
taskList: DataType[]
2025-03-19 06:59:45 -04:00
}
2025-06-26 06:59:31 -04:00
export const DroppableTable = React.memo((props: DroppableTableProps) => {
const stateName = React.useMemo(() => {
switch (props.tableCode) {
case '0':
return '不紧急不重要';
case '1':
return '紧急不重要';
case '2':
return '不紧急重要';
case '3':
return '紧急重要';
default:
return '';
2025-03-19 06:59:45 -04:00
}
2025-06-26 06:59:31 -04:00
}, [props.tableCode]);
const getItemStyle = React.useCallback((isDragging: boolean, draggableStyle: any): CSSProperties => ({
2025-03-19 06:59:45 -04:00
userSelect: "none",
2025-06-26 06:59:31 -04:00
background: isDragging ? "lightgreen" : "white",
position: 'relative', // 确保 zIndex 生效
zIndex: isDragging ? 2147483647 : 'auto', // 使用 'auto' 代替 0 可能更好
2025-03-19 06:59:45 -04:00
...draggableStyle,
2025-06-26 06:59:31 -04:00
borderBottom: '1px solid #f0f0f0',
boxSizing: 'border-box',
// verticalAlign: 'middle',
// textAlign: 'center',
}), []);
2025-03-19 06:59:45 -04:00
2025-06-26 06:59:31 -04:00
const getListStyle = React.useCallback((isDraggingOver: boolean) => ({
background: isDraggingOver ? "lightblue" : "white",
height: 'calc((100vh - 42px)/2)',
width: '50vw'
}), []);
2025-03-19 06:59:45 -04:00
2025-06-26 06:59:31 -04:00
const rowRenderer = React.useCallback(({index, key, style}: {
index: number;
key: string;
style: React.CSSProperties
}) => {
const record = props.taskList[index];
if (!record) return null;
2025-03-19 06:59:45 -04:00
2025-06-26 06:59:31 -04:00
return (
<Draggable key={record.id} draggableId={record.id} index={index}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(snapshot.isDragging, {...provided.draggableProps.style, ...style})}
className="virtualized-row displayFlexRow"
>
<div style={{width: '15%'}} className='displayFlexRow'>
<Tooltip placement="topLeft" title={record.name} className='displayFlexRow'>
<div className='displayFlexRow'>{record.name}</div>
</Tooltip>
</div>
<div style={{width: '40%' , boxSizing: 'border-box', minWidth: 0}} className='displayFlexRow'>
<Tooltip placement="topLeft" title={record.description}>
<div className='displayFlexRow'>{record.description}</div>
</Tooltip>
</div>
<div style={{
width: '10%',
}} className='displayFlexRow'>{getTaskState(record.state) ? getTaskState(record.state).name : ""}</div>
<div style={{width: '25%'}} className='displayFlexColumn'>
<div>: {record.expectedStartTime ? dayjs(record.expectedStartTime).format("YYYY-MM-DD HH:mm") : ""}</div>
<div>: {record.expectedStartTime ? dayjs(record.expectedStartTime).format("YYYY-MM-DD HH:mm") : ""}</div>
</div>
<div style={{width: '10%'}} className='displayFlexRow'>
<OperationButton itemId={record.id} priority={record.priority} pid={record.pid}
pPid={record.pPid}/>
</div>
</div>
)}
</Draggable>
);
}, [props.taskList, getItemStyle]);
const headerStyle = React.useMemo(() => ({
backgroundColor: taskPriorityList.find((item) => item.code === props.tableCode)?.color,
height: '55px',
borderBottom: '1px solid #f0f0f0',
fontWeight: 'bold'
}), [props.tableCode]);
2025-03-19 06:59:45 -04:00
return (
2025-06-26 06:59:31 -04:00
<Droppable droppableId={props.tableCode} key={props.tableCode}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.droppableProps}
style={getListStyle(snapshot.isDraggingOver)}
className="droppable-table"
2025-03-19 06:59:45 -04:00
>
2025-06-26 06:59:31 -04:00
<ConfigProvider>
{/* 表头 */}
<div style={headerStyle} className='displayFlexRow'>
<div style={{width: '15%'}} className='displayFlexRow'>{stateName}</div>
<div style={{width: '40%'}} className='displayFlexRow'></div>
<div style={{width: '15%'}} className='displayFlexRow'></div>
<div style={{width: '20%'}} className='displayFlexRow'></div>
<div style={{width: '10%'}} className='displayFlexRow'></div>
</div>
{/* 虚拟列表主体 */}
<div style={{height: 'calc(50vh - 76px)'}}>
<AutoSizer>
{({height, width}) => (
<VirtualizedList
className={"scrollHidden"}
height={height}
width={width}
rowCount={props.taskList.length}
rowHeight={80} // 与你的行高匹配
rowRenderer={rowRenderer}
overscanRowCount={8} // 预渲染的行数
/>
)}
</AutoSizer>
</div>
2025-06-23 06:49:52 -04:00
</ConfigProvider>
2025-03-19 06:59:45 -04:00
{provided.placeholder}
</div>
)}
</Droppable>
)
2025-06-26 06:59:31 -04:00
});