完整管理指南:添加、排序、移动与层级同步原理)
Super Productivity 子任务Subtasks完整管理指南添加、排序、移动与层级同步原理【免费下载链接】super-productivitySuper Productivity is an advanced todo list app with integrated Timeboxing and time tracking capabilities. It also comes with integrations for Jira, GitLab, GitHub and Open Project.项目地址: https://gitcode.com/GitHub_Trending/su/super-productivity导读子任务是 Super Productivity 中把大任务拆解为可独立执行步骤的核心机制每个子任务都是一个拥有独立标题、计时与完成状态的真实任务同时通过双向链接归属到父任务之下。本文围绕 子任务管理文档 与 子任务建模文档 的完整脉络讲解添加、排序、移动、转换、显隐切换等全部 UI 操作并结合task.reducer.ts、task-internal.effects.ts等源码揭示父子关系如何在底层建模与同步。读完你可以熟练地在项目视图、标签视图与 Today 视图中驾驭多层级任务结构并理解父任务自动完成项目继承级联删除背后的实现机制。子任务的底层建模双向链接的父子关系在深入了解操作之前先理解子任务在数据模型中的存在方式。从 task.model.ts 的源码可以看到任务实体通过两个字段建立父子关联子任务child侧parentId?: stringtask.model.ts——子任务保存指向父任务的引用这正是它为什么是子任务的依据。父任务parent侧subTaskIds默认值为[]——父任务保存一份有序的子任务 ID 列表列表中的顺序即展开父任务时看到的顺序。由于双向都持久化应用可以快速渲染父任务的子任务列表、在子任务完成或移动时同步更新父任务并在重组时保持层级一致。任何对层级的修改添加、移动父级、删除父级都会同时更新子任务的parentId与父任务的subTaskIds保证两者始终匹配。值得强调的是子任务是独立的任务实体不是父任务内部的行文本。每个子任务拥有自己的 ID、项目、已用时间、备注与完成状态。子任务还可以继续拥有子任务嵌套同一任务可以既是父任务又是子任务不过在实践与部分工作流如基于 Markdown 的同步中建议保持一到两层嵌套。添加子任务三种入口方式原文档提供了三条添加子任务的路径它们在 UI 与代码层面对应同一核心动作addSubTask从右键菜单右键点击父任务 → 选择Add subtask。该选项只对未完成的父任务出现。从任务详情面板点击任务打开右侧详情面板在Subtasks区域底部点击Add subtask按钮加号图标 文字标签。用键盘聚焦父任务点击或方向键选中后按A键——A是Add subtask的默认快捷键。可在 键盘快捷键文档 中查看或修改该绑定。从源码看三条入口最终都汇聚到 task.service.ts 的addSubTaskTo(parentId, additional)方法它创建带默认值的新任务并 dispatchaddSubTaskaction。空标题的新子任务会自动进入标题编辑状态focusTaskById会在双帧 RAF 后聚焦并进入编辑模式。此外在子任务输入框中Enter提交、ModEnter则停留并追加新的空兄弟行方便连续录入。新子任务在 reducer 中的初始化逻辑task.reducer.ts 中的on(addSubTask)处理器揭示了新建子任务时自动完成的字段处理这是理解层级一致性的关键projectId强制继承父任务——新子任务的项目永远是父任务的项目注释写明 should always be the one of the parenttagIds强制清空——子任务不自动继承父任务标签若这是父任务的第一个子任务且新任务未自带timeEstimate与timeSpentOnDay则从父任务复制时间估算与已用时间避免出现父任务 2 小时、唯一子任务 0 分钟的割裂将新任务 ID追加进父任务的subTaskIds若父任务此前正在计时则currentTaskId切换到该子任务最后通过reCalcTimesForParentIfParent重新汇总父任务的剩余时间。另外在 task-internal.effects.ts 中还有一个setDefaultEstimateIfNonGiveneffect如果新子任务没有时间估算会根据设置中的timeTracking.defaultEstimateSubTasks自动套用默认估算值与顶层任务使用的defaultEstimate是独立配置项。在父任务内重新排序子任务原文档给出三种排序手段快捷键均在 3.03-Keyboard-Shortcuts 中登记且可配置操作快捷键上移一位CtrlShiftArrowUp下移一位CtrlShiftArrowDown移到子任务列表顶部CtrlAltArrowUp移到子任务列表底部CtrlAltArrowDown拖拽按住任务行左侧的拖动手柄grip 图标在同一个父任务的子任务列表内上下拖动在目标位置松开即可。右键菜单右键点击未完成任务 →Move to top或Move to bottom将其移动到当前列表的顶部或底部。对顶层任务而言该列表是常规/backlog 列表对子任务而言则是父任务的子任务列表。在标签视图或 Today 视图等扁平展示场景下子任务不在父任务下方展示此时应改用键盘快捷键。从源码看这四个操作对应 task.actions.ts 中四个持久化 actionmoveSubTaskUp、moveSubTaskDown、moveSubTaskToTop、moveSubTaskToBottom均携带{ id, parentId }并以OpType.Move写入操作日志。reducer 侧通过统一的moveFn帮助函数task.reducer.ts对父任务的subTaskIds数组执行重排。同父级内的排序只改变父任务subTaskIds列表的顺序不触碰子任务的parentId引用与项目归属。将子任务移动到另一个父任务拖拽子任务的拖动手柄将其直接放到目标父任务行上或放入目标父任务的子任务列表中即可完成跨父级迁移。此时发生一组同步更新保证层级一致旧父任务的subTaskIds移除该子任务新父任务的subTaskIds在指定位置插入该子任务子任务的parentId更新为新父任务子任务的项目继承新父任务的项目。对应的底层动作是 task.actions.ts 中的moveSubTask参数含taskId、srcTaskId、targetTaskId、afterTaskIdreducer 会同时更新新旧两侧的列表与子任务引用见 task.reducer.ts 附近对旧父列表过滤、新父列表moveItemAfterAnchor的逻辑。项目继承是刻意设计的行为移动后子任务自动归属新父任务的项目无需手动修改若再移回另一项目的父任务则再次继承新的项目。将子任务转换为主任务右键点击子任务 →Convert to parent task该子任务会在同一项目中变成顶层任务移除parentId。转换同样受以下限制约束详见下文限制一节重复任务与 issue 关联任务不能被转换为子任务。值得注意的细节是 task-internal.effects.ts 中的reassertOwnTagsAfterConverteffect从 v18.20.1 开始本客户端在convertToSubTask/convertToMainTask时保留任务自身的标签而旧版本客户端在重放这些操作时会抹掉转成子任务时或覆盖转回主任务时tagIds。该 effect 在转换真正生效时通过追加一条updateTask操作重新声明保留的标签使新旧客户端最终收敛到一致状态——这体现了操作日志op-log重放场景下的兼容性处理。显示 / 隐藏已完成子任务在父任务行的子任务列表旁有一个小切换按钮加/减号图标tooltip 为 Toggle subtask visibility.。每次点击在三种状态间循环Show all—— 显示全部子任务Hide done—— 隐藏已完成的子任务Hide all—— 收起整个子任务列表。当子任务被隐藏时会出现一行提示文字例如 3 done sub tasks或 5 sub tasks点击即可重新展开。父任务聚焦时也可以使用Expand subtasks/Collapse subtasks快捷键注意这两个快捷键默认无绑定需在设置中自行配置。这一状态并非纯 UI 记忆源码注释task.actions.ts明确指出虽然 action 名为updateTaskUi但它携带的_hideSubTasksMode属于必须跨重启保留的任务数据因此像updateTask一样以持久化 actionOpType.Update写入 op-log折叠状态在重新加载后不会丢失对应 issue #8781。同步路径上还通过clearedFieldsProps显式处理被清空的字段避免JSON.stringify丢失键导致展开状态无法同步issue #9776。完成行为单独完成、自动标记与级联删除子任务可以独立完成子任务可以单独标记完成完成顺序不受父任务约束你可以先完成全部子任务再勾掉父任务也可以先完成父任务、留几个子任务稍后处理。父任务的完成状态是独立的。剩余时间聚合是按子任务逐项计算的——父任务剩余工作量等于其未完成子任务剩余估算估算减已用时间的总和并用于 日程视图 与 时间估算 的计算。父任务自动完成可配置当所有子任务都被标记为完成时父任务会被自动标记为完成。这由 task-internal.effects.ts 的onAllSubTasksDoneeffect 实现其触发条件包括任务配置isAutoMarkParentAsDone已开启默认行为可在设置中调整被更新为完成的任务确实带有parentId该父任务的subTaskIds中不存在未完成的子任务。满足上述条件后effect 会派发一条updateTask将父任务置为完成。如果你想先勾选父任务、留部分子任务未完成直接操作即可应用不会强制顺序。级联删除删除父任务时其所有子任务会一并删除不会逐个询问——这是为了避免遗留孤儿子任务保证列表一致性对应 reducer 中对subTaskIds的级联过滤。如果你只想移除父任务但保留子任务请先将其移动到其他父任务或按需转换为主任务再删除父任务。子任务的限制哪些任务不能成为子任务为了保持模型一致性两类任务不能被转换为子任务重复任务Repeating tasks——按计划循环如每日、每周的任务不能作为另一任务的子任务因为重复规则作用于单个任务嵌套会与之冲突。详见 重复任务文档issue 关联任务——与外部 issue如 Jira、GitHub一对一关联的任务不能成为子任务应用不支持 issue 子任务这种形式。详见 任务集成文档。如果你尝试转换例如在基于 Markdown 的工作流中通过缩进转成子任务应用会给出警告并将该任务保持为顶层任务。你仍然可以在父任务下创建普通子任务并让重复任务/issue 关联任务作为独立任务与其并列。在基于 Markdown 的工作流如 sync-md 插件中缩进层级会转换为父子结构过深的缩进可能被解释为笔记内容或另一层嵌套而非额外的子任务层级。因此依赖 Markdown 导入/导出的场景下建议将嵌套保持在一到两层。复制整个层级CtrlD默认绑定可复制当前聚焦的未完成的父任务及其全部子任务。从源码行为看复制会生成全新 ID 并保留相同的父子链接所有子任务仍挂在新父任务之下得到完整结构副本——不会出现父任务复制了、子任务丢失的情况。标签视图中的父子关系约定标签视图4.07-Tag-View展示带有指定标签的任务。为了避免同一工作重复出现并保持列表整洁当你将子任务加入某标签时应用会把父任务从该标签中移除。因此在标签视图中同一标签下要么显示父任务、要么显示其子任务不会同时出现强制保持一级任务的一致性父与子同在一个标签的模式不被支持。常见操作速查需求操作添加子任务右键菜单 / 详情面板底部按钮 / 聚焦父任务后按A子任务上移 / 下移CtrlShift↑/CtrlShift↓子任务置顶 / 置底CtrlAlt↑/CtrlAlt↓跨父级移动拖拽手柄到目标父任务或其子任务列表转为顶层任务右键 →Convert to parent task切换子任务显隐父任务行旁的 /- 切换按钮Show all → Hide done → Hide all展开 / 收起子任务默认无绑定的 Expand / Collapse Subtasks 快捷键需自行配置复制父任务及全部子任务CtrlD相关主题可继续阅读 4.11-Subtasks建模与限制、4.09-Task-Attributes、4.06-Project-View 与 3.03-Keyboard-Shortcuts。【免费下载链接】super-productivitySuper Productivity is an advanced todo list app with integrated Timeboxing and time tracking capabilities. It also comes with integrations for Jira, GitLab, GitHub and Open Project.项目地址: https://gitcode.com/GitHub_Trending/su/super-productivity创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考