feat: adding tasks statuses support

This commit is contained in:
Kacper Kula 2026-03-29 20:28:02 +01:00
parent b92963abc1
commit 3abb46722b
5 changed files with 40 additions and 5 deletions

View file

@ -0,0 +1,5 @@
---
"sqlseal": minor
---
Adding tasks statuses support

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

View file

@ -44,6 +44,7 @@ Tasks table consists of the following columns:
| --------------- |--------------------------------------------------------------------------------------------------------------------------| ------------- |
| `task` | Content of the task (text) | |
| `completed` | 0 if not completed, 1 if completed | |
| `status` | The raw checkbox character (` ` for unchecked, `x` for completed, `/` for in-progress, `-` for cancelled, etc.) | 0.40.0 |
| `path` | Full path of the file the tag belongs to | 0.24.1 |
| `filePath` | (deprecated) same like `path`. Name changed for compatibility with other tables. Will get removed in the future versions | |
| `checkbox` | Interactive checkbox for the task that can be clicked to toggle completion state | 0.29.0 |
@ -88,3 +89,9 @@ WHERE target = @path
AND json_extract(position, '$.frontmatterKey') = 'type'
```
## Task Status Field
The `status` column in the `tasks` table contains the raw checkbox character from your markdown tasks. This enables querying tasks by their specific states beyond just completed/uncompleted. This is functionality used commonly in plugins like Tasks and Obsidian natively supports them too. Many themes also render these fields correctly by default. You can read more about it in [the Tasks documentation](https://publish.obsidian.md/tasks/Getting+Started/Statuses#Credit%20Sytone%20and%20the%20'Tasks%20SQL%20Powered'%20plugin).
### Example
![Tasks Statuses](tasks-statuses.png)

View file

@ -47,6 +47,7 @@ export class TasksFileSyncTable extends AFileSyncTable {
checked: status,
path: file.path,
task: taskContent,
status: listItem.task,
position: {
line: listItem.position.start.line,
lineContent: lineContent

View file

@ -11,7 +11,8 @@ interface CheckboxProps {
line: number,
lineContent: string
},
task: string
task: string,
status?: string
}
const isCheckboxProp = (arg: any): arg is CheckboxProps => {
@ -45,7 +46,8 @@ export class CheckboxParser implements CellFunction<Args> {
const el = createEl('input', {
type: 'checkbox',
attr: {
checked: !!(values && values.checked) ? true : null
checked: !!(values && values.checked) ? true : null,
'data-task': values.status || ' '
}
})
@ -73,11 +75,26 @@ export class CheckboxParser implements CellFunction<Args> {
// Get the line containing the task
const lineIndex = values.position?.line
if (lineIndex >= 0 && lineIndex < lines.length) {
// Get current status
const currentStatus = values.status || (values.checked ? 'x' : ' ')
// Escape special regex characters
const escapedStatus = currentStatus.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
// Update the task status
if (el.checked) {
lines[lineIndex] = lines[lineIndex].replace('- [ ]', '- [x]')
// Mark as completed
lines[lineIndex] = lines[lineIndex].replace(
new RegExp(`- \\[${escapedStatus}\\]`),
'- [x]'
)
} else {
lines[lineIndex] = lines[lineIndex].replace('- [x]', '- [ ]')
// Restore original status
const originalStatus = currentStatus === 'x' ? ' ' : currentStatus
lines[lineIndex] = lines[lineIndex].replace(
'- [x]',
`- [${originalStatus}]`
)
}
// Write back to the file
@ -98,10 +115,15 @@ export class CheckboxParser implements CellFunction<Args> {
}
return '[ ]'
} else {
// Use status if available
if (values.status) {
return `[${values.status}]`
}
// Fall back to checked boolean
if (values.checked) {
return '[x]'
} else {
return '[ ] '
return '[ ]'
}
}
}