feat(V0.2): 克隆卡片跟手浮层 + 列表组内排序 + 把手统一移到最左
Docker Build and Push / build-image (push) Successful in 1m1s
Docker Build and Push / build-image (push) Successful in 1m1s
- 浮层改为激活时克隆原卡片 (DOM clone, 淡化+投影) 挂 body 顶层, 移动直接改 transform —— 替代蓝色信息条, 所见即所拖 - 任务列表支持组内排序: 拖到本组某行上/下半显示插入指示, 松手提交 POST /projects/:id/tasks/reorder (顶层任务按展平顺序重写 sortOrder); 拖到其他分组仍为换列 - ⠿ 把手统一移到卡片最左: 打卡 / 列表任务行 / 看板卡片 (看板新增把手 即按即拖路径, 与列表同款 touchstart preventDefault 双保险) - useColumnDrag onDrop 经 ref 桥接防陈旧闭包
This commit is contained in:
@@ -40,6 +40,7 @@ export default function BoardView({
|
||||
task={t}
|
||||
dragging={drag.dragTask?.id === t.id}
|
||||
bindDrag={drag.bind}
|
||||
bindDragHandle={drag.bindHandle}
|
||||
onClick={() => { if (!drag.dragTask && !drag.justEnded()) onOpen?.(t) }}
|
||||
onToggleSub={onToggleSub}
|
||||
onToggle={onToggle}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useState } from 'react'
|
||||
import { createPortal } from 'react-dom'
|
||||
import TaskRow from '../../components/task/TaskRow.jsx'
|
||||
import useRowDrag from '../../components/task/useRowDrag.js'
|
||||
|
||||
@@ -8,10 +7,10 @@ import useRowDrag from '../../components/task/useRowDrag.js'
|
||||
// 换列: 行/把手拖动, 跟手浮层, 手指划到哪个分组松手就落到哪 (与看板一致)
|
||||
// (列表只展示有任务的列, 空列需到看板视图拖入)
|
||||
export default function ListView({
|
||||
tasks, columns, onToggle, onOpen, onMore, onMoveColumn,
|
||||
tasks, columns, onToggle, onOpen, onMore, onMoveColumn, onReorder,
|
||||
}) {
|
||||
const [collapsed, setCollapsed] = useState({})
|
||||
const drag = useRowDrag({ columns, onDrop: onMoveColumn })
|
||||
const drag = useRowDrag({ columns, onDrop: onMoveColumn, onReorder })
|
||||
|
||||
if (!tasks || tasks.length === 0) {
|
||||
return (
|
||||
@@ -56,6 +55,7 @@ export default function ListView({
|
||||
bindDrag={drag.bind}
|
||||
bindDragHandle={drag.bindHandle}
|
||||
dragTarget={dragging ? orderedCols[dragging.toIdx] : null}
|
||||
dragOver={drag.over?.id === t.id ? drag.over : null}
|
||||
/>
|
||||
{kids.length > 0 && (
|
||||
<>
|
||||
@@ -75,17 +75,6 @@ export default function ListView({
|
||||
})}
|
||||
</div>
|
||||
))}
|
||||
|
||||
{/* 跟手浮层: Portal 挂 body, 任务名 + 手指所在分组 */}
|
||||
{drag.drag && createPortal(
|
||||
<div ref={drag.ghostRef} className="drag-ghost">
|
||||
{drag.drag.task.title}
|
||||
{orderedCols[drag.drag.toIdx] && (
|
||||
<b>→ {orderedCols[drag.drag.toIdx].name}</b>
|
||||
)}
|
||||
</div>,
|
||||
document.body,
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -102,6 +102,28 @@ export default function ProjectView({ projectId, onProjectChanged, onProjectExit
|
||||
} catch { /* 已回滚并提示 */ }
|
||||
}
|
||||
|
||||
/** 组内拖动排序: 按分组顺序展平重写 sortOrder (只动顶层任务) */
|
||||
const reorderTask = async (task, targetId, after) => {
|
||||
const snapshot = tasks
|
||||
const orderedCols = [...(columns || [])].sort((a, b) => a.sortOrder - b.sortOrder)
|
||||
const groups = orderedCols.map((c) => (tasks || []).filter((t) => t.columnId === c.id)).filter((l) => l.length)
|
||||
const g = groups.find((l) => l.some((t) => t.id === task.id))
|
||||
if (!g) return
|
||||
const rest = g.filter((t) => t.id !== task.id)
|
||||
const ti = rest.findIndex((t) => t.id === targetId)
|
||||
if (ti < 0) return
|
||||
rest.splice(after ? ti + 1 : ti, 0, task)
|
||||
const flat = groups.map((l) => (l === g ? rest : l)).flat()
|
||||
const orderOf = new Map(flat.map((t, i) => [t.id, i]))
|
||||
setTasks((prev) => (prev || []).map((t) => (orderOf.has(t.id) ? { ...t, sortOrder: orderOf.get(t.id) } : t)))
|
||||
try {
|
||||
await taskApi.reorder(projectId, flat.map((t) => t.id))
|
||||
} catch (e) {
|
||||
setTasks(snapshot)
|
||||
Toast.show({ content: e.message || '排序保存失败' })
|
||||
}
|
||||
}
|
||||
|
||||
/** 改状态 (T-BD-14~16) */
|
||||
const changeStatus = async (task, status) => {
|
||||
try {
|
||||
@@ -222,6 +244,7 @@ export default function ProjectView({ projectId, onProjectChanged, onProjectExit
|
||||
onOpen={(t) => setOpenTask(t)}
|
||||
onMore={openTaskMenu}
|
||||
onMoveColumn={moveToColumn}
|
||||
onReorder={reorderTask}
|
||||
/>
|
||||
) : (
|
||||
<BoardView
|
||||
|
||||
Reference in New Issue
Block a user