Advanced query with custom block rendering/refs (list view)

I’m currently pulling my hair out over how to render block refs in an advanced query.

Basically, what I want is:

  1. retrieve all tasks

  2. group them by their project property

  3. display a view list (like you get when you don’t customize the :view function), for each project with its respective tasks

  4. and 2. where easy enough to solve, but I am really struggling with 3.

Here’s the query I have so far:

#+BEGIN_QUERY
{
 :title [ :h1 "Tasks by Project" ]
 :query [
         :find (pull ?b [*] )
         :where
         [?b :block/marker ?marker]
         [(contains? #{"TODO" "DOING"} ?marker)]
        ]
 :result-transform (fn [r]
      (group-by (fn [task]
                  (get (get task :block/properties-text-values) :project "NONE")
      ) r)
	)
:view (fn [r] 
       (for [proj r]
            [:div (key proj) (for [task (val proj)] [:pre (pr-str task)]) ]
        )
)

 :breadcrumb-show? true
}
#+END_QUERY

Now, in place of [:pre (pr-str task)] I would like to render a list of block references - but I have no idea how and didn’t find any documentation on how to do it.
Any help is very appreciated!

The issue with trying to transform data but still show it as a list is a tough one.
Here’s the closest I could get:

  • couldn’t find an official way to include? / transclude? block ref
  • attempted to use ((uuid))
  • attempted to use macro
  • i can get something to work with sort-by, but it wont show sections
  • i can fake the look of a todo item, but they aren’t transcluded and so cannot be ticked off
  • can sort them and have fully interactive items, but no longer have group labels

group-by Method

#+BEGIN_QUERY
{
:title [ :h1 "Tasks by Project" ]
:query [
  :find (pull ?b [*] )
  :where
    [?b :block/marker ?marker]
    [(contains? #{"TODO" "DOING"} ?marker)]    
]
:result-transform (fn [r]
  (sort-by first < 
    (group-by (fn [task]
      (str/trim (get (get task :block/properties-text-values) :project ""))
      ) ;grp fn
      r
    ) ;group
  ) ;sort
)
:view (fn [r]
  (for [proj r]
    [:div [:h4 (str "project: " (if (str/blank? (key proj)) "N/A" (key proj) ))]
    [:table   
    (for [task (val proj)] 
      [:tr [:td [:span.inline.todo 
        ;[:input {:type "checkbox" :class "form-checkbox h-4 w-4 transition duration-150 ease-in-out mr-1 cursor"}]
        [:a {:class (str "block-marker " (first (str/split (first (str/split (get task :block/content) "\n" )) " " )) )}
          (first (str/split (first (str/split (get task :block/content) "\n" )) " " )) ] 
        (str/join " " (rest (str/split (first (str/split (get task :block/content) "\n" )) " " )) )
      ]]]
    )
    ]] ;table ;div
) 
)
}
#+END_QUERY

sort-by Method

image

#+BEGIN_QUERY
{
:title [ :h1 "Tasks by Project" ]
:query [
  :find (pull ?b [*] )
  :keys block
  :where
    [?b :block/marker ?marker]
    [(contains? #{"TODO" "DOING"} ?marker)]    
]
:result-transform (fn [result] 
(sort-by (comp :proj :block/properties) <
(for [row result] 
(let [
    block-map (get row :block)
    current-properties (:block/properties block-map)
    proj (get current-properties :project "")
    updated-properties (assoc current-properties :proj proj)
    ]
    (assoc block-map :block/properties updated-properties)
) ) ) ) ;end let ;end for ;end sort ;end transform
}
#+END_QUERY