I want to share the little dataviewjs code that I have made with the help of great forum members. (Special thanks to @holroy who I have learned a lot from.) I’ve searched the forum and couldn’t find the exact thing that I wanted. I hope somebody found it useful; that’s the reason I’m sharing this, and if you have a better solution, please let me know.
The wish:
Creating 3 Obsidian collapsible callouts in daily note template for overdue, to-do (today’s tasks), and done (done today), displaying the tasks’ count in each callout header so that one can see the tasks’ count without expanding the callout. That’s specifically useful when there is no task in the desired category.
The Logic:
The code tries to create task queries (with the tasks plugin) using dataviewjs. You may ask why I didn’t use just the tasks plugin. That’s because with just using the Tasks plugin, I could not find a way to extract the task count from the query and display it in the callout title. Therefore, I have used dataview to get tasks’ counts. Now, you may ask why I didn’t use just dataview query twice (once for getting tasks’ counts and once for getting the actual list). That’s because I wanted to display tasks in shortmode (just task description and icons for start, due, etc.), which is not possible in dataview queries. (as far as I know)
Appearance:
Lastly, I wanted to display daily notes in Obsidian’s side panel. Therefore, I have tried to obtain a minimal appearance with little distance between elements and fixed size scrollable callouts. The custom CSS that I have tried to make with the help of related posts is not complete yet, but it works enough for the basic needs. You can change and complete it, if you have even wanted to have such lists and appearance.
The Code (daily notes template)
---
date: "{{date:YYYY-MM-DD}}"
tags:
- notes/cat/daily
parent: "[[MOC Daily notes]]"
cssclass: "daily_note"
---
```dataviewjs
const {dailyUtils} = await cJS()
var prev_next_days = dailyUtils.create_prev_next_links(dv)
// --- OVERDUE ---
const dv_qry_overdue = `\
TASK
FROM #task
WHERE contains(tags, "#task") and ( \
(date(scheduled) and scheduled < date("{{date:YYYY-MM-DD}}") ) or \
(date(due) and due < date("{{date:YYYY-MM-DD}}") ) \
) \
and !completed`
const tasks_qry_overdue = `\
> (scheduled before {{date:YYYY-MM-DD}}) OR (due before {{date:YYYY-MM-DD}})
> not done
> short mode
> hide tags
> hide task count
> group by filename
> sort by priority`
// --- TO-DO ---
const dv_qry_todo = `\
TASK
FROM #task
WHERE contains(tags, "#task") and ( \
(date(scheduled) and scheduled = date("{{date:YYYY-MM-DD}}") ) or \
(date(due) and due = date("{{date:YYYY-MM-DD}}") ) \
) \
and !completed`
const tasks_qry_todo = `\
> (scheduled on {{date:YYYY-MM-DD}}) OR (due on {{date:YYYY-MM-DD}})
> not done
> short mode
> hide tags
> hide task count
> group by filename
> sort by priority`
// --- DONE ---
const dv_qry_done = `\
TASK
FROM #task
WHERE contains(tags, "#task") and
completed and
( date(completion) and completion = date("{{date:YYYY-MM-DD}}") )`
const tasks_qry_done = `\
> done on {{date:YYYY-MM-DD}}
> short mode
> hide tags
> hide task count
> group by filename
> sort by priority`
// --- OVERDUE ---
var taskQuery = await dv.query(dv_qry_overdue)
if ( !taskQuery.successful )
dv.paragraph("~~~~\n" + taskQuery.error + "\n~~~~")
else {
const callout_overdue = `> [!danger|daily]- Overdue (${ taskQuery.value.values.length }) \n> \`\`\`tasks\n` + tasks_qry_overdue + `\n> \`\`\`\n`
// --- TO-DO ---
taskQuery = await dv.query(dv_qry_todo)
if ( !taskQuery.successful )
dv.paragraph("~~~~\n" + taskQuery.error + "\n~~~~")
else {
const callout_todo = `> [!todo|daily]+ To-Do (${ taskQuery.value.values.length }) \n> \`\`\`tasks\n` + tasks_qry_todo + `\n> \`\`\`\n`
// --- DONE / CANCELLED ---
taskQuery = await dv.query(dv_qry_done)
if ( !taskQuery.successful )
dv.paragraph("~~~~\n" + taskQuery.error + "\n~~~~")
else {
const callout_done = `> [!done|daily]- Done (${ taskQuery.value.values.length }) \n> \`\`\`tasks\n` + tasks_qry_done + `\n> \`\`\`\n`
//Write the result
dv.el('prev_next', prev_next_days);
dv.el('callout_overdue', callout_overdue);
dv.el('separator_1', ` `);
dv.el('callout_todo', callout_todo);
dv.el('separator_2', ` `);
dv.el('callout_done', callout_done);
//dv.el('dvq_done', `\n\`\`\`dataview\n` + dv_qry_done + `\n\`\`\`\n`);
}
}
}
The CSS
.markdown-source-view.daily_note .cm-editor .cm-scroller {
font-family: 'Cascadia Code', Menlo, Monaco, 'Courier New', monospace !important;
font-size: 11px;
}
/* Tasks grouping options */
.daily_note h4.tasks-group-heading {
background-color: rgba(255, 255, 0, 0.15) !important;
font-size: 9px;
line-height: 9px;
}
.daily_note .tasks-list-text {
font-size: 10px;
}
.callout[data-callout-metadata="daily"]{
--p-spacing: .8rem;
--shown-line-count: 6;
padding: 0px;
}
.callout[data-callout-metadata="daily"] .callout-title {
padding: 5px;
}
.callout[data-callout-metadata="daily"] .callout-content {
max-height: calc(var(--line-height-normal) * 1rem * var(--shown-line-count));
padding-left: 30px;
}
Screenshot
That’s it! Have a good luck.