Files
iboard/src/pages/task/ListView.jsx
T
jif2.zhang 1673cbdb7d
Docker Build and Push / build-image (push) Successful in 1m3s
refactor(V0.2): 拖动交互收紧 —— 仅把手触发 / 缩小把手 / 去多余元素 / 打卡跨组
- 打卡与列表: 去掉卡片整体长按拖动路径, 只有 ⠿ 把手可拖; 把手缩小
- 列表行去掉跟动的蓝色目标列徽标 (drag-pill), 占位/克隆浮层承担全部反馈
- 打卡支持跨组拖动: 落到其他周期组的目标卡 = 改周期 + 落位一次完成
  (updateHabit period + reorder), 组内排序不变
- 看板: 去掉 ⠿ 把手, 恢复长按拖动
2026-10-25 02:19:03 +08:00

80 lines
3.0 KiB
React

import { useState } from 'react'
import TaskRow from '../../components/task/TaskRow.jsx'
import useRowDrag from '../../components/task/useRowDrag.js'
// 列表视图 (T-VW-01, T-ST-04/05)
// 按看板列分组展示; 子任务缩进 + 折叠展开
// 换列: 行/把手拖动, 跟手浮层, 手指划到哪个分组松手就落到哪 (与看板一致)
// (列表只展示有任务的列, 空列需到看板视图拖入)
export default function ListView({
tasks, columns, onToggle, onOpen, onMore, onMoveColumn, onReorder,
}) {
const [collapsed, setCollapsed] = useState({})
const drag = useRowDrag({ columns, onDrop: onMoveColumn, onReorder })
if (!tasks || tasks.length === 0) {
return (
<div className="empty" style={{ paddingTop: 90 }}>
<div className="ico">✓</div>
<p>这个项目还没有任务</p>
</div>
)
}
// 分组: 按列顺序, 未匹配列的任务归到一起
const groups = []
const orderedCols = [...(columns || [])].sort((a, b) => a.sortOrder - b.sortOrder)
for (const c of orderedCols) {
const list = tasks.filter((t) => t.columnId === c.id)
if (list.length) groups.push({ key: c.id, name: c.name, list })
}
const known = new Set(orderedCols.map((c) => c.id))
const orphans = tasks.filter((t) => !known.has(t.columnId))
if (orphans.length) groups.push({ key: 'other', name: '其他', list: orphans })
return (
<div className="list-body">
{groups.map((g) => (
<div key={g.key} data-column-id={g.key === 'other' ? undefined : g.key}>
<div className="group-title">
{g.name}
<span className="cnt">{g.list.length}</span>
</div>
{g.list.map((t) => {
const kids = t.children || []
const isCollapsed = !!collapsed[t.id]
const dragging = drag.drag?.task?.id === t.id ? drag.drag : null
return (
<div key={t.id}>
<TaskRow
task={t}
onToggle={onToggle}
onClick={() => { if (!drag.justEnded()) onOpen(t) }}
onMore={onMore}
bindDragHandle={drag.bindHandle}
dragging={!!dragging}
dragOver={drag.over?.id === t.id ? drag.over : null}
/>
{kids.length > 0 && (
<>
{!isCollapsed && kids.map((c) => (
<TaskRow key={c.id} task={c} indent onToggle={onToggle} onClick={() => onOpen(c)} onMore={onMore} />
))}
<div
className="collapse"
onClick={() => setCollapsed((p) => ({ ...p, [t.id]: !p[t.id] }))}
>
{isCollapsed ? `展开 ${kids.length} 个子任务 ⌄` : `收起 ${kids.length} 个子任务 ⌃`}
</div>
</>
)}
</div>
)
})}
</div>
))}
</div>
)
}