前言※
任务管理(待办清单)能够很好的规划自己近期的一些任务,我之前使用的是微软 todo,简洁却十分强大,但是现在的工作学习总结一般都在 trilium 上进行,微软 todo 作为一个外部软件与我的实际工作流有一些割裂。
trilium 的官方 demo 中有一个任务管理的功能,试用一番后意外的发现功能还挺有意思。于是结合自己的使用习惯将其调教为自己习惯的样式,下文就此做一下分享。
调教后效果※
改进步骤※
思路※
trilium 中的任务管理 demo 可以做到如下几点:
一键创建待办
可添加 location 和 tag 标签,并且自动进行分类
可以添加任务开始日期和任务完成日期,并且根据日期添加到日记的子节点下
根据任务完成情况自动改变任务状态
其实这些功能已经可以满足大部分的需求了,但是有些地方还可以优化以下,根据我的实际需求,要进行如下改进:
删除 location 标签 -- location 与 tag 有些重合,只保留 tag 作为分类标准就可以了
增加自动删除空标签的功能 -- 已完成的任务,没有必要保留空标签
增加中止任务功能 -- 某些任务可能因为一些原因必须暂时中止
删除 location 标签※
trilium 中的任务管理其实是通过 js 实现的,通过task template
中的~runOnAttributeChange=attribute changed
实现当标签发生变动时调用attribute changed
这一脚本。
所以在attribute changed
中将 location 相关的代码注释掉即可。
/**
const location = note.getLabelValue('location');
const locationRootNote = api.getNoteWithLabel('taskLocationRoot');
reconcileAssignments(note, locationRootNote, location ? [location] : [], 'taskLocationNote', isTaskDone);
**/
并且删除task template
中的location
标签。
自动删除空标签※
在 demo 中,会自动根据待办中的标签内容自动创建标签,并且将待办清单克隆到该标签下,方便根据标签查找待办清单。
但是当任务完成后,已经创建的标签并不会删除,有些冗杂。我认为当任务完成后没有内容的标签也自动删除才比较合理。
在reconcileAssignments
方法中的第一个 for 循环中加入以下代码即可:
//如果某个标签的无子节点,则删除该标签
if (categoryNote.getChildNotes() == "") {
categoryNote.deleteNote(categoryNote.noteId)
}
中止任务※
观察 js 脚本可发现,js 是通过获取笔记中的唯一标签定位目标笔记,然后调用后端 api 实现功能。
所以首先需要建立一个根笔记,用于存放已中止的任务。
在任务管理的下方建立一个名为」暂缓「的笔记,并且为此笔记打上标签#taskStopRoot
,目前为止任务管理的目录结构应该是这样:
任务管理
待办 #taskTodoRoot
标签 #taskTagRoot
已完成 #taskDoneRoot
暂缓 #taskStopRoot
接下来在attribute changed
脚本中定位到该笔记:
const stopRootNote = api.getNoteWithLabel('taskStopRoot');
在task template
中定义一个 boolean 类型的标签,提升该标签:
#label:stop=promoted,single,boolean
接着在attribute changed
脚本中获取该标签的变化:
const isTaskStop = note.getLabelValue("stop") == "true"
我需要实现的是在stop
上选中,该待办自动移动到【暂缓】笔记的下方,取消选中时自动移回【待办】下方,所以在脚本中增加以下代码:
note.toggleLabel(isTaskStop, "cssClass", "stop");
if (stopRootNote.getChildNotes().includes(note)) {
api.toggleNoteInParent(!isTaskStop, note.noteId, todoRootNote.noteId);
api.toggleNoteInParent(isTaskStop, note.noteId, stopRootNote.noteId);
}else{
api.toggleNoteInParent(isTaskStop, note.noteId, stopRootNote.noteId);
api.toggleNoteInParent(!isTaskStop, note.noteId, todoRootNote.noteId);
}
除此之外,我还希望当任务中止时该任务不要出现在标签和日记中,只在任务重新恢复待办状态时才出现。
这个很简单,只要在获取 tag 列表时判断一下任务是否中止,如果中止就赋值空数组:
const tags = isTaskStop ? [] : attributes.filter(attr => attr.type === 'label' && attr.name === 'tag').map(attr => attr.value);
日记中的 todo 和 done 状态也是如此,判断任务是否中止即可:
const doneTargetNoteId = (isTaskDone && !isTaskStop) ? api.getDateNote(doneDate).noteId : null;
const todoTargetNoteId = (!isTaskDone && todoDate && !isTaskStop) ? api.getDateNote(todoDate).noteId : null;
经过以上调教后即可呈现文章开头的效果。