Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add custom grouping, with 'group by function' option #2028

Merged
merged 129 commits into from Jun 11, 2023

Conversation

claremacrae
Copy link
Collaborator

@claremacrae claremacrae commented Jun 10, 2023

Description

A powerful, flexible mechanism to give users a lot of control over custom grouping rules.

Credit: This work was only made possible by @hauntedhost, who kindly taught me how to evaluate user-supplied functions in TypeScript.

Examples (taken from the docs)

group by function task.due?.format("YYYY-MM-DD dddd") || ""  
  • Like "group by task.due", except it does not write "No due date" if there is no due date. The question mark (?) and || "" are needed because the due date value may be null.
group by function task.due?.format("dddd") || ""  
  • Group by day of the week (Monday, Tuesday, etc).
group by function task.due?.format("YYYY MM MMM") || "no due date"  
  • Group by month, for example "2023 05 May". The month number is also displayed, to control the sort order of headings.
group by function task.description.replace('short', '==short==')  
  • Highlight the word "short" in any group descriptions.
group by function task.tags.filter( (t) => t.includes("#context/"))  
  • Only create headings for tags that contain "#context/".
group by function task.tags.filter( (t) => ! t.includes("#tag"))  
  • Create headings for all tags that do not contain "#tag".

New Features

  • Add major new group by function feature, for custom grouping by many of the properties of tasks
  • This adds the ability to group by some fields that it was not previously possible to group by:
    • task.description
    • task.status.symbol
    • task.status.nextStatusSymbol
  • It enables custom-formatting of date headings, when grouping by date fields
    • So for example, grouping by week or month.
    • See the group by due docs for examples

New Documentation

  • New top-level section Scripting
  • Note the documentation will be finalised in later commits - I need a break from this now and just want to merge it, so I can pick up later improvements in smaller chunks of work.

Enabling changes

  • Add some getters to Task whose names match the corresponding query instructions:
    • created
    • done
    • due
    • scheduled
    • start
    • happens (and also happensDates)
    • recurring (for future use)

TODO

Not all fields are exposed yet, as some will require refactoring to avoid them in a way that is consistent with the current filter instructions.

Notable omissions:

  • task.priority
  • task.file.path
  • task.file.fileName
  • task.file.root
  • task.file.folder
  • task.heading

Motivation and Context

There have been quite a few requests for variations on existing grouping options. This enables many of those to be done in one single step.

How has this been tested?

  • Lots of manual testing in Obsidian.
  • Lots of tests added.
  • All the documentation examples are machined-generated, so if the sample group by function instructions ever break, we will know.

Screenshots (if appropriate)

Types of changes

Changes visible to users:

  • New feature (prefix: feat - non-breaking change which adds functionality)
  • Documentation (prefix: docs - improvements to any documentation content for users)
  • Sample vault (prefix: vault - improvements to the Tasks-Demo sample vault)

Internal changes:

  • Refactor (prefix: refactor - non-breaking change which only improves the design or structure of existing code, and making no changes to its external behaviour)
  • Tests (prefix: test - additions and improvements to unit tests and the smoke tests)

Checklist

Terms

claremacrae and others added 30 commits June 7, 2023 15:37
Total credit for this goes to Jules Omlor.

I just updated it to work with the current Tasks code,
and added initial tests.

Co-Authored-By: Jules Omlor <jules@haunted.host>
This will mean there is a lot less to document.
And I will gradually expose Task facilities, and document them
as they become stable.
In preparation for machine-generating documentation.
It's easier to not do that, and allow users to do it optionally,
than to do it on all fields and find that things like tags with underscores
in are broken.
… is not releasable

... as it cannot return a string value, due to name-clash with existing recurrence field in Task.
I think it will be more useful for task.priority to refer to the name.
Currently, it gives the number. Needs more thought.
For recent changes in test file names.
@claremacrae claremacrae changed the title feat: Add custom grouping, with 'group by function' code feat: Add custom grouping, with 'group by function' option Jun 10, 2023
@claremacrae claremacrae added the scope: grouping Changes to the grouping capabilities label Jun 11, 2023
@claremacrae claremacrae merged commit 34ea414 into obsidian-tasks-group:main Jun 11, 2023
1 check passed
@claremacrae claremacrae deleted the add-group-by-function branch June 15, 2023 21:08
@claremacrae claremacrae added the scope: scripting Issues to do with custom filters, custom sorting and similar label Jul 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
scope: grouping Changes to the grouping capabilities scope: scripting Issues to do with custom filters, custom sorting and similar
Projects
Status: 🎉 Released
Development

Successfully merging this pull request may close these issues.

None yet

1 participant