在每日日记显示当天的完成的任务
代码
利用了 dv.view()
展示
在 2024-09-09
内
```dataviewjs
await dv.view("taskToday",{})
```
只要文件夹的名字是 taskToday
就行
视频讲解
\taskToday\view.js
// Obsidian view template for displaying today's tasks
let { pages, date, showParent = true } = input
// Error Handling
if (!date && !dv.date(date) && !dv.current().file.day) {
dv.span(
'> [!ERROR] Missing date \n \
> \n \
> Please set the pages name include the date in the format of `YYYY-MM-DD` in the file name. \n \
> \n \
> Or set the date in the `{date: YYYY-MM-DD}` \
',
)
return false
}
const dv_current_day = dv.current().file.day ?? dv.date(date)
const calDay = (d, f = 'YYYY-MM-DD') => {
return moment(dv_current_day.plus({ days: d }).toString()).format(f)
}
// default values
if (!pages) {
pages = '3-Tasks'
}
if (!date) {
date = calDay(0)
console.log(date)
}
// const
const taskIcon = {
todo: '📝',
done: '✅',
due: '📅',
scheduled: '⏳',
recurrence: '🔁',
overdue: '⚠️',
process: '⏺️',
cancelled: '🚫',
start: '🛫',
dailyNote: '📄',
}
const fieldNames = ['due', 'scheduled', 'created', 'start', 'completion']
// 添加判断条件,请使用互斥条件,即只能有一个条件为真,虽然后续代码一个为真后会跳出循环
const times = {
全天: (task, field) => task[field].c.hour == 0 && task[field].c.minute == 0,
上午: (task, field) =>
task[field].c.hour < 12 &&
!(task[field].c.hour == 0 && task[field].c.minute == 0),
下午: (task, field) => task[field].c.hour >= 12 && task[field].c.hour < 18,
晚上: (task, field) => task[field].c.hour >= 18,
}
const extendFields = ['priority', 'repeat']
const isOneDay = (a, b) => {
if (!a || !b) return false
if (typeof a == 'string') a = dv.date(a)
if (typeof b == 'string') b = dv.date(b)
if (!a || !b) return false
if (!('c' in a) || !('c' in b)) return false
// console.log(a, b)
if (a.c.year == b.c.year && a.c.month == b.c.month && a.c.day == b.c.day)
return true
else return false
}
const getData = (pages, date) => {
let todayTasks = {}
const taskAll = dv.pages('"' + pages + '"').file.tasks
taskAll.forEach((t) => {
// dateview 的 annotated 为 true 表示有元数据
if (t.annotated) {
// 每个字段都匹配一下
for (const field of fieldNames) {
if (field in t && isOneDay(t[field], dv.date(date))) {
// 分配到时间段
for (let time in times) {
// 判断是否符合时间段
if (times[time](t, field)) {
if (!(time in todayTasks)) {
todayTasks[time] = {}
}
if (!(field in todayTasks[time])) {
todayTasks[time][field] = []
}
todayTasks[time][field].push(t)
break
}
}
}
}
}
})
console.log(todayTasks)
return todayTasks
}
const priorityColorMap = {
low: 'rgb(55 166 155)',
medium: 'orange',
high: 'red',
}
// regex to remove the field priority in text
const regex = /\[priority[^\]]+\]/g
const taskVisual = (t, field) => {
let icon = ''
// 有icon的可以显示icon
field.forEach((f) => {
if (f in taskIcon) {
icon += taskIcon[f]
}
})
// 在前方显示一条颜色线区分优先级
t.visual =
icon +
' ' +
getColorCode(t?.priority) +
t.text.replace(/\[[^\]]*::[^\]]*\]/g, '').trim()
const meta = dv.page(t.path)
const project = meta.project ?? meta.file.name
if (showParent && t.parent) {
const parentTask = meta.file.tasks.find((k) => k.line == t.parent)
// 有可能parentTask不是任务,而是列表
if (parentTask) {
parentTask.subtasks.forEach((k) => {
k.visual = k.text.replace(/\[[^\]]*::[^\]]*\]/g, '').trim()
})
parentTask.subtasks[
parentTask.subtasks.findIndex((k) => k.line == t.line)
] = t
t = parentTask
}
}
const el = dv.el('div', '')
dv.api.taskList([t], false, el, dv.component)
return [field, el, project]
}
function listId(item) {
return item.path + ':' + item.line
}
function parentListId(item) {
return item.path + ':' + item.parent
}
const todayTaskTable = (taskLists) => {
if (Object.keys(taskLists).length == 0) return
// 保存显示的table的内容
const tdata = []
// todo 把每个时间段的任务合并
for (let time in taskLists) {
// 保存每个时间段内的任务 和 字段
const taskTime = new Map()
for (let field in taskLists[time]) {
for (let task of taskLists[time][field]) {
const listItem = listId(task)
if (taskTime.has(listItem)) {
taskTime.get(listItem).push(field)
} else {
taskTime.set(listItem, [field])
}
}
}
console.log('taskTime', taskTime)
// 读取每个时间段内的任务,合并成一个数组
const totalArr = []
Object.keys(taskLists[time]).forEach((item) => {
totalArr.push(...taskLists[time][item])
})
for (let [timeItem, times] of taskTime) {
const task = totalArr.find((item) => listId(item) == timeItem)
if (task) tdata.push([time, ...taskVisual(task, times)])
}
}
// 排序
tdata.sort(
(a, b) =>
Object.keys(times).indexOf(a[0]) - Object.keys(times).indexOf(b[0]),
)
if (tdata.length != 0) {
dv.header(3, '行云')
dv.table(['时间', '操作', '任务', '项目'], tdata)
} else {
dv.span('> [!] 暂无任务')
}
}
function getColorCode(priority) {
const color = priorityColorMap[priority] ?? 'grey'
return `<span style='border-left: 3px solid ${color};'> </span>`
}
function render() {
const taskList = getData(pages, date)
console.log(taskList)
todayTaskTable(taskList)
// dv.taskList(taskList, false)
}
render()