This was driving me crazy, and I’m so pleased with the result.
The problem: every time I switched a top-level task status to DOING, all of its subtask todos would suddenly appear in my todo queries, so that dozens of really granular tasks like “sand off rust” or “research microphone cables” would be cluttering up a list of high level tasks like “buy a house” or “career change.”
Here’s the query that solves the problem. The trick was defining a recursive rule in the inputs that checks if a block is an ancestor, then using that rule to find all blocks with no ancestors with todo markers:
#+BEGIN_QUERY
{:query [:find (pull ?b [*])
:in $ %
:where
[?b :block/marker ?marker]
[(contains? #{"TODO"} ?marker)]
;; ancestor is true when ?ancestor is an ancestor of b
(not (ancestor ?b ?ancestor)
[?ancestor :block/marker ?amarker]
[(contains? #{"TODO" "NOW" "DOING"} ?amarker)])]
:inputs
[[[[ancestor ?b ?ancestor]
[?b :block/parent ?ancestor]]
[[ancestor ?b ?ancestor]
[?child :block/parent ?ancestor]
(ancestor ?b ?child)]]]
:result-transform (fn [result]
(sort-by (fn [b]
(get b :block/priority "Z")) result))
:breadcrumb-show? false
}
#+END_QUERY
And here’s a screenshot to demonstrate the result:
Your work is super brilliant! Interestingly, my trouble is kinda a reverse of yours: I’d like to have a parent TODO task and its sub TODO tasks ALL shown in one query listing all TODO tasks, for example. Sadly, the sub TODO tasks would show in the query only when their parent task changes to some other status like DOING.
Agreed. Awesome filtering skills. For me it is more logical to see the bottom most task. For me that is the one I can do, since the parent tasks are dependant on their children first. I could of course rearrange all my tasks the other way around. But I am afraid it would be a hard pill to swallow.
In a way this could be an excellent way to se my projects.
Awesome query! I wonder how I could adjust your query to get next actions only instead? aka bottom tasks only (with no descendants with todo markers). In my case, I’m essentially trying to purge the list from the parent tasks. Could someone help me out? :block/child doesn’t seem to be a thing as opposed to :block/parent…
I’m afraid I don’t have anything to add except to say thanks. I’ve been trying to work out some sort of an ‘ancestor’ search for a long time and I’m just not good enough with the language.
I’m intending to use it for finding subtasks in a brainstorming tree.