mirror of
https://github.com/callumalpass/tasknotes.git
synced 2026-07-22 12:50:26 +00:00
docs: add formula expressions to Base templates documentation
Include the actual Bases formula expressions in the formula reference tables so users can see and copy the exact syntax used.
This commit is contained in:
parent
c517957349
commit
d0d0974ec2
1 changed files with 53 additions and 53 deletions
|
|
@ -26,81 +26,81 @@ All templates include the following calculated formula properties that you can u
|
|||
|
||||
### Date calculations
|
||||
|
||||
| Formula | Description |
|
||||
|---------|-------------|
|
||||
| `daysUntilDue` | Days until due date (negative = overdue, positive = days remaining, null if no due date) |
|
||||
| `daysUntilScheduled` | Days until scheduled date (negative = past, positive = days remaining, null if no scheduled date) |
|
||||
| `daysSinceCreated` | Number of days since the task file was created |
|
||||
| `daysSinceModified` | Number of days since the task file was last modified |
|
||||
| Formula | Description | Expression |
|
||||
|---------|-------------|------------|
|
||||
| `daysUntilDue` | Days until due date (negative = overdue, positive = days remaining, null if no due date) | `if(due, ((number(date(due)) - number(today())) / 86400000).floor(), null)` |
|
||||
| `daysUntilScheduled` | Days until scheduled date (negative = past, positive = days remaining, null if no scheduled date) | `if(scheduled, ((number(date(scheduled)) - number(today())) / 86400000).floor(), null)` |
|
||||
| `daysSinceCreated` | Number of days since the task file was created | `((number(now()) - number(file.ctime)) / 86400000).floor()` |
|
||||
| `daysSinceModified` | Number of days since the task file was last modified | `((number(now()) - number(file.mtime)) / 86400000).floor()` |
|
||||
|
||||
### Boolean formulas
|
||||
|
||||
| Formula | Description |
|
||||
|---------|-------------|
|
||||
| `isOverdue` | True if task has a past due date and is not completed |
|
||||
| `isDueToday` | True if task is due today |
|
||||
| `isDueThisWeek` | True if task is due within the next 7 days |
|
||||
| `isScheduledToday` | True if task is scheduled for today |
|
||||
| `isRecurring` | True if task has a recurrence rule |
|
||||
| `hasTimeEstimate` | True if task has a time estimate > 0 |
|
||||
| Formula | Description | Expression |
|
||||
|---------|-------------|------------|
|
||||
| `isOverdue` | True if task has a past due date and is not completed | `due && date(due) < today() && status != "done"` |
|
||||
| `isDueToday` | True if task is due today | `due && date(due).date() == today()` |
|
||||
| `isDueThisWeek` | True if task is due within the next 7 days | `due && date(due) >= today() && date(due) <= today() + "7d"` |
|
||||
| `isScheduledToday` | True if task is scheduled for today | `scheduled && date(scheduled).date() == today()` |
|
||||
| `isRecurring` | True if task has a recurrence rule | `recurrence && !recurrence.isEmpty()` |
|
||||
| `hasTimeEstimate` | True if task has a time estimate > 0 | `timeEstimate && timeEstimate > 0` |
|
||||
|
||||
### Time tracking
|
||||
|
||||
| Formula | Description |
|
||||
|---------|-------------|
|
||||
| `timeRemaining` | Time estimate minus time tracked (in minutes), null if no estimate |
|
||||
| `efficiencyRatio` | Percentage of estimated time used (>100% = took longer, <100% = faster, null if no estimate) |
|
||||
| `timeTrackedThisWeek` | Total minutes tracked in the last 7 days |
|
||||
| `timeTrackedToday` | Total minutes tracked today |
|
||||
| Formula | Description | Expression |
|
||||
|---------|-------------|------------|
|
||||
| `timeRemaining` | Time estimate minus time tracked (in minutes), null if no estimate | `if(timeEstimate && timeEstimate > 0, timeEstimate - if(timeEntries, list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0), 0), null)` |
|
||||
| `efficiencyRatio` | Percentage of estimated time used (>100% = took longer, <100% = faster, null if no estimate) | `if(timeEstimate && timeEstimate > 0 && timeEntries, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / timeEstimate * 100).round(), null)` |
|
||||
| `timeTrackedThisWeek` | Total minutes tracked in the last 7 days | `if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime) >= today() - "7d").map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)` |
|
||||
| `timeTrackedToday` | Total minutes tracked today | `if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime).date() == today()).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)` |
|
||||
|
||||
### Grouping formulas
|
||||
|
||||
These formulas return string values useful for grouping tasks in views:
|
||||
|
||||
| Formula | Description | Example values |
|
||||
|---------|-------------|----------------|
|
||||
| `dueMonth` | Due date as year-month | "2025-01", "No due date" |
|
||||
| `dueWeek` | Due date as year-week | "2025-W01", "No due date" |
|
||||
| `scheduledMonth` | Scheduled date as year-month | "2025-01", "Not scheduled" |
|
||||
| `scheduledWeek` | Scheduled date as year-week | "2025-W01", "Not scheduled" |
|
||||
| `dueDateCategory` | Human-readable due date bucket | "Overdue", "Today", "Tomorrow", "This week", "Later", "No due date" |
|
||||
| `timeEstimateCategory` | Task size by time estimate | "No estimate", "Quick (<30m)", "Medium (30m-2h)", "Long (>2h)" |
|
||||
| `ageCategory` | Task age bucket | "Today", "This week", "This month", "Older" |
|
||||
| `createdMonth` | Creation date as year-month | "2025-01" |
|
||||
| `modifiedMonth` | Last modified date as year-month | "2025-01" |
|
||||
| `priorityCategory` | Priority as readable label | "High", "Normal", "Low", "No priority" |
|
||||
| `projectCount` | Number of assigned projects | "No projects", "Single project", "Multiple projects" |
|
||||
| `contextCount` | Number of assigned contexts | "No contexts", "Single context", "Multiple contexts" |
|
||||
| `trackingStatus` | Time tracking vs estimate | "No estimate", "Not started", "Under estimate", "Over estimate" |
|
||||
| Formula | Description | Example values | Expression |
|
||||
|---------|-------------|----------------|------------|
|
||||
| `dueMonth` | Due date as year-month | "2025-01", "No due date" | `if(due, date(due).format("YYYY-MM"), "No due date")` |
|
||||
| `dueWeek` | Due date as year-week | "2025-W01", "No due date" | `if(due, date(due).format("YYYY-[W]WW"), "No due date")` |
|
||||
| `scheduledMonth` | Scheduled date as year-month | "2025-01", "Not scheduled" | `if(scheduled, date(scheduled).format("YYYY-MM"), "Not scheduled")` |
|
||||
| `scheduledWeek` | Scheduled date as year-week | "2025-W01", "Not scheduled" | `if(scheduled, date(scheduled).format("YYYY-[W]WW"), "Not scheduled")` |
|
||||
| `dueDateCategory` | Human-readable due date bucket | "Overdue", "Today", "Tomorrow", "This week", "Later", "No due date" | `if(!due, "No due date", if(date(due) < today(), "Overdue", if(date(due).date() == today(), "Today", if(date(due).date() == today() + "1d", "Tomorrow", if(date(due) <= today() + "7d", "This week", "Later")))))` |
|
||||
| `timeEstimateCategory` | Task size by time estimate | "No estimate", "Quick (<30m)", "Medium (30m-2h)", "Long (>2h)" | `if(!timeEstimate \|\| timeEstimate == 0, "No estimate", if(timeEstimate < 30, "Quick (<30m)", if(timeEstimate <= 120, "Medium (30m-2h)", "Long (>2h)")))` |
|
||||
| `ageCategory` | Task age bucket | "Today", "This week", "This month", "Older" | `if(((number(now()) - number(file.ctime)) / 86400000) < 1, "Today", if(((number(now()) - number(file.ctime)) / 86400000) < 7, "This week", if(((number(now()) - number(file.ctime)) / 86400000) < 30, "This month", "Older")))` |
|
||||
| `createdMonth` | Creation date as year-month | "2025-01" | `file.ctime.format("YYYY-MM")` |
|
||||
| `modifiedMonth` | Last modified date as year-month | "2025-01" | `file.mtime.format("YYYY-MM")` |
|
||||
| `priorityCategory` | Priority as readable label | "High", "Normal", "Low", "No priority" | `if(priority=="high","High",if(priority=="normal","Normal",if(priority=="low","Low","No priority")))` |
|
||||
| `projectCount` | Number of assigned projects | "No projects", "Single project", "Multiple projects" | `if(!projects \|\| list(projects).length == 0, "No projects", if(list(projects).length == 1, "Single project", "Multiple projects"))` |
|
||||
| `contextCount` | Number of assigned contexts | "No contexts", "Single context", "Multiple contexts" | `if(!contexts \|\| list(contexts).length == 0, "No contexts", if(list(contexts).length == 1, "Single context", "Multiple contexts"))` |
|
||||
| `trackingStatus` | Time tracking vs estimate | "No estimate", "Not started", "Under estimate", "Over estimate" | `if(!timeEstimate \|\| timeEstimate == 0, "No estimate", if(!timeEntries \|\| list(timeEntries).length == 0, "Not started", if(formula.efficiencyRatio < 100, "Under estimate", "Over estimate")))` |
|
||||
|
||||
### Combined due/scheduled formulas
|
||||
|
||||
These formulas work with either due date or scheduled date, useful for finding the "next action date":
|
||||
|
||||
| Formula | Description | Example values |
|
||||
|---------|-------------|----------------|
|
||||
| `nextDate` | The earlier of due or scheduled date | Date value or null |
|
||||
| `daysUntilNext` | Days until next date (due or scheduled, whichever is sooner) | -2, 0, 5, null |
|
||||
| `hasDate` | True if task has either a due or scheduled date | true, false |
|
||||
| `isToday` | True if due OR scheduled today | true, false |
|
||||
| `isThisWeek` | True if due OR scheduled within 7 days | true, false |
|
||||
| `nextDateCategory` | Human-readable bucket for next date | "Overdue/Past", "Today", "Tomorrow", "This week", "Later", "No date" |
|
||||
| `nextDateMonth` | Next date as year-month | "2025-01", "No date" |
|
||||
| `nextDateWeek` | Next date as year-week | "2025-W01", "No date" |
|
||||
| Formula | Description | Example values | Expression |
|
||||
|---------|-------------|----------------|------------|
|
||||
| `nextDate` | The earlier of due or scheduled date | Date value or null | `if(due && scheduled, if(date(due) < date(scheduled), due, scheduled), if(due, due, scheduled))` |
|
||||
| `daysUntilNext` | Days until next date (due or scheduled, whichever is sooner) | -2, 0, 5, null | `if(due && scheduled, min(formula.daysUntilDue, formula.daysUntilScheduled), if(due, formula.daysUntilDue, formula.daysUntilScheduled))` |
|
||||
| `hasDate` | True if task has either a due or scheduled date | true, false | `due \|\| scheduled` |
|
||||
| `isToday` | True if due OR scheduled today | true, false | `(due && date(due).date() == today()) \|\| (scheduled && date(scheduled).date() == today())` |
|
||||
| `isThisWeek` | True if due OR scheduled within 7 days | true, false | `(due && date(due) >= today() && date(due) <= today() + "7d") \|\| (scheduled && date(scheduled) >= today() && date(scheduled) <= today() + "7d")` |
|
||||
| `nextDateCategory` | Human-readable bucket for next date | "Overdue/Past", "Today", "Tomorrow", "This week", "Later", "No date" | `if(!due && !scheduled, "No date", if((due && date(due) < today()) \|\| (scheduled && date(scheduled) < today()), "Overdue/Past", if((due && date(due).date() == today()) \|\| (scheduled && date(scheduled).date() == today()), "Today", if((due && date(due).date() == today() + "1d") \|\| (scheduled && date(scheduled).date() == today() + "1d"), "Tomorrow", if((due && date(due) <= today() + "7d") \|\| (scheduled && date(scheduled) <= today() + "7d"), "This week", "Later")))))` |
|
||||
| `nextDateMonth` | Next date as year-month | "2025-01", "No date" | `if(due && scheduled, if(date(due) < date(scheduled), date(due).format("YYYY-MM"), date(scheduled).format("YYYY-MM")), if(due, date(due).format("YYYY-MM"), if(scheduled, date(scheduled).format("YYYY-MM"), "No date")))` |
|
||||
| `nextDateWeek` | Next date as year-week | "2025-W01", "No date" | `if(due && scheduled, if(date(due) < date(scheduled), date(due).format("YYYY-[W]WW"), date(scheduled).format("YYYY-[W]WW")), if(due, date(due).format("YYYY-[W]WW"), if(scheduled, date(scheduled).format("YYYY-[W]WW"), "No date")))` |
|
||||
|
||||
### Sorting
|
||||
|
||||
| Formula | Description |
|
||||
|---------|-------------|
|
||||
| `priorityWeight` | Numeric weight for priority sorting (lower = higher priority) |
|
||||
| `urgencyScore` | Combines priority and next date proximity (due or scheduled, higher = more urgent) |
|
||||
| Formula | Description | Expression |
|
||||
|---------|-------------|------------|
|
||||
| `priorityWeight` | Numeric weight for priority sorting (lower = higher priority) | `if(priority=="none",0,if(priority=="low",1,if(priority=="normal",2,if(priority=="high",3,999))))` |
|
||||
| `urgencyScore` | Combines priority and next date proximity (due or scheduled, higher = more urgent) | `if(!due && !scheduled, formula.priorityWeight, formula.priorityWeight + max(0, 10 - formula.daysUntilNext))` |
|
||||
|
||||
### Display formulas
|
||||
|
||||
| Formula | Description | Example values |
|
||||
|---------|-------------|----------------|
|
||||
| `timeTrackedFormatted` | Total time tracked as readable text | "2h 30m", "45m", "0m" |
|
||||
| `dueDateDisplay` | Due date as relative text | "Today", "Tomorrow", "Yesterday", "3d ago", "Mon", "Dec 15" |
|
||||
| Formula | Description | Example values | Expression |
|
||||
|---------|-------------|----------------|------------|
|
||||
| `timeTrackedFormatted` | Total time tracked as readable text | "2h 30m", "45m", "0m" | `if(timeEntries, if(list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) >= 60, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / 60).floor() + "h " + (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) % 60).round() + "m", list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round() + "m"), "0m")` |
|
||||
| `dueDateDisplay` | Due date as relative text | "Today", "Tomorrow", "Yesterday", "3d ago", "Mon", "Dec 15" | `if(!due, "", if(date(due).date() == today(), "Today", if(date(due).date() == today() + "1d", "Tomorrow", if(date(due).date() == today() - "1d", "Yesterday", if(date(due) < today(), formula.daysUntilDue * -1 + "d ago", if(date(due) <= today() + "7d", date(due).format("ddd"), date(due).format("MMM D")))))))` |
|
||||
|
||||
## Mini Calendar
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue