feat(tags): 编辑任务时可从已有标签里选,不必每次手打

TagInput 增加候选下拉:聚焦即展开(输入框为空列全部、有草稿按子串过滤),
上下键移动高亮、回车选中高亮项、点击也能选;候选项排除已选中的,选完自动
从列表移除。列表没展开或没有匹配时,回车仍把草稿建成新标签,原行为不变。
候选点击用 mousedown.prevent 保住输入框焦点,否则 blur 会先把草稿提交掉。

把「全部标签」从 BoardToolbar 的局部 computed 提到 store 的 allTags,
筛选下拉和标签候选共用同一份,避免两处各算一份导致结果不一致。

测试:TagInput 新增 13 条(候选过滤、键盘选择、失焦/Escape 收起、aria-selected),
store 新增 2 条 allTags,E2E 新增 1 条打通 store → 抽屉 → 组件这条接线。
This commit is contained in:
chenshoulin
2026-10-18 20:26:55 +08:00
parent 48f178e5bb
commit 88ea09e94d
7 changed files with 341 additions and 43 deletions
+13
View File
@@ -89,6 +89,18 @@ export const useTaskStore = defineStore('tasks', () => {
return result
})
/**
* 现有任务里出现过的全部标签,按中文排序。
* 筛选下拉和编辑任务时的标签候选都用它,避免两处各算一份、结果不一致。
*/
const allTags = computed(() => {
const collected = new Set<string>()
for (const task of tasks.value) {
for (const tag of task.tags) collected.add(tag)
}
return [...collected].sort((a, b) => a.localeCompare(b, 'zh-Hans-CN'))
})
function persist(): void {
if (!repository) return
try {
@@ -391,6 +403,7 @@ export const useTaskStore = defineStore('tasks', () => {
snapshots,
byColumn,
counts,
allTags,
init,
createTask,
updateTask,