feat(board): 支持批量添加与批量删除任务

- 批量添加面板:一行一条,整批共用目标列、优先级、标签与截止日期
- 快速新增支持粘贴多行文本,直接拆成多条任务
- 多选模式支持全选可见任务、整批删除,撤销时连原顺序一起还原
- 批量创建与删除走 store 的批量方法,一次落盘、一次广播
- 补充单元测试与 E2E 用例
This commit is contained in:
chenshoulin
2026-10-19 17:21:42 +08:00
parent 4aba003a9e
commit 2d6e24dc91
21 changed files with 1518 additions and 37 deletions
+24 -2
View File
@@ -10,9 +10,9 @@ import { isDueToday, isOverdue } from '@/utils/date'
import TagFilter from './TagFilter.vue'
defineProps<{ hiddenNote?: string }>()
defineProps<{ hiddenNote?: string; selecting?: boolean }>()
const emit = defineEmits<{ archive: [] }>()
const emit = defineEmits<{ archive: []; 'batch-add': []; 'toggle-select': [] }>()
const store = useTaskStore()
const filters = useFilterStore()
@@ -133,6 +133,28 @@ defineExpose({ focusSearch })
<span v-if="hiddenNote" class="text-slate-400 dark:text-zinc-500">{{ hiddenNote }}</span>
<div class="ml-auto flex items-center gap-1.5">
<button
type="button"
class="flex h-8 items-center rounded-md border border-slate-200 bg-white px-2.5 text-xs text-slate-600 transition hover:border-slate-300 hover:bg-slate-50 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-300 dark:hover:border-zinc-600 dark:hover:bg-zinc-800"
@click="emit('batch-add')"
>
批量添加
</button>
<button
type="button"
class="flex h-8 items-center rounded-md border px-2.5 text-xs transition"
:class="
selecting
? 'border-sky-300 bg-sky-50 text-sky-700 dark:border-sky-700 dark:bg-sky-950 dark:text-sky-300'
: 'border-slate-200 bg-white text-slate-600 hover:border-slate-300 hover:bg-slate-50 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-300 dark:hover:border-zinc-600 dark:hover:bg-zinc-800'
"
:aria-pressed="selecting === true"
@click="emit('toggle-select')"
>
{{ selecting ? '退出多选' : '多选' }}
</button>
<button
v-if="archivableCount > 0"
type="button"