Ver Fonte

feat(query-dsl): add more filters

There're some graph improvements too:
1. the fly dots are smaller now
2. page tags have a different color
Tienson Qin há 4 anos atrás
pai
commit
a16d360611

+ 1 - 1
src/main/frontend/commands.cljs

@@ -100,7 +100,7 @@
                   [:editor/show-date-picker]]]
      ["Scheduled" [[:editor/clear-current-slash]
                    [:editor/show-date-picker]]]
-     ["Query" [[:editor/input "{{query }}" {:backward-pos 3}]]]
+     ["Query" [[:editor/input "{{query }}" {:backward-pos 2}]]]
      ["Draw" [[:editor/input "/draw "]
               [:editor/show-input [{:command :draw
                                     :id :title

+ 3 - 3
src/main/frontend/components/block.cljs

@@ -660,7 +660,7 @@
         (= name "query")
         [:div.dsl-query
          (custom-query (assoc config :dsl-query? true)
-                       {:title [:code (str "Query: " (first arguments))]
+                       {:title [:code.p-1 (str "Query: " (first arguments))]
                         :query (first arguments)})]
 
         (= name "youtube")
@@ -1628,9 +1628,9 @@
             ;; page list
             (and (seq result)
                  (:page/name (first result)))
-            [:ol
+            [:ul#query-pages.mt-1
              (for [{:page/keys [name original-name] :as page-entity} result]
-               [:li
+               [:li.mt-1
                 [:a {:href (rfe/href :page {:name name})
                      :on-click (fn [e]
                                  (util/stop e)

+ 62 - 27
src/main/frontend/db/query_dsl.cljs

@@ -20,8 +20,9 @@
 ;; property (block)
 ;; todo (block)
 ;; priority (block)
-;; page_tag (page, TBD)
-;; page_property (page, TBD)
+;; page-property (page)
+;; page-tags (page)
+;; all-page-tags
 ;; project (block, TBD)
 
 ;; Sort by (field, asc/desc):
@@ -34,9 +35,12 @@
 (defonce remove-nil? (partial remove nil?))
 
 (defn query-wrapper
-  [where]
-  (let [q '[:find (pull ?b [*])
-            :where]
+  [where blocks?]
+  (let [q (if blocks?                   ; FIXME: it doesn't need to be either blocks or pages
+            '[:find (pull ?b [*])
+              :where]
+            '[:find (pull ?p [*])
+              :where])
         result (if (coll? (first where))
                  (apply conj q where)
                  (conj q where))]
@@ -67,17 +71,32 @@
         (db-utils/date->int (t/plus (t/today) (tf duration)))))))
 
 (defn build-query
-  ([e sort-by]
-   (build-query e sort-by 0))
-  ([e sort-by level]
+  ([e env]
+   (build-query e env 0))
+  ([e {:keys [sort-by blocks?] :as env} level]
    ;; TODO: replace with multi-methods for extensibility.
-   (let [fe (first e)]
+   (let [fe (first e)
+         page-ref? (and
+                    (string? e)
+                    (string/starts-with? e "[[")
+                    (string/ends-with? e "]]"))]
+     (when (or page-ref?
+               (contains? #{'between 'property 'todo 'priority 'sort-by} fe))
+       (reset! blocks? true))
      (cond
        (nil? e)
        nil
 
+       page-ref?
+       (let [page-name (->>
+                        (subs e 2 (- (count e) 2))
+                        (string/lower-case))]
+         (when (and (not (string/blank? page-name))
+                    (some? (db-utils/entity [:page/name page-name])))
+           [['?b :block/ref-pages [:page/name page-name]]]))
+
        (contains? #{'and 'or} fe)
-       (let [clauses (->> (map #(build-query % sort-by (inc level)) (rest e))
+       (let [clauses (->> (map #(build-query % env (inc level)) (rest e))
                           remove-nil?
                           (apply concat))]
          (when (seq clauses)
@@ -87,7 +106,7 @@
                [result]))))
 
        (= 'not fe)
-       (let [clauses (->> (map #(build-query % sort-by) (rest e))
+       (let [clauses (->> (map #(build-query % env) (rest e))
                           remove-nil?
                           (apply concat))]
          (when (seq clauses)
@@ -128,17 +147,6 @@
              [['?b :block/priority '?priority]
               [(list 'contains? priorities '?priority)]])))
 
-       (and
-        (string? e)
-        (string/starts-with? e "[[")
-        (string/ends-with? e "]]")) ; page reference
-       (let [page-name (->>
-                        (subs e 2 (- (count e) 2))
-                        (string/lower-case))]
-         (when (and (not (string/blank? page-name))
-                    (some? (db-utils/entity [:page/name page-name])))
-           [['?b :block/ref-pages [:page/name page-name]]]))
-
        (= 'sort-by fe)
        (let [[k order] (rest e)
              order (if (and order (contains? #{:asc :desc}
@@ -157,6 +165,26 @@
                                                   (if :desc >= <=)))))
              nil)))
 
+       (= 'page-property fe)
+       (let [[k v] (rest e)]
+         [['?p :page/properties '?prop]
+          [(list 'get '?prop (keyword (nth e 1))) '?v]
+          [(list '= '?v (name (nth e 2)))]])
+
+       (= 'page-tags fe)
+       (let [tags (if (coll? (first (rest e)))
+                    (first (rest e))
+                    (rest e))]
+         (when (seq tags)
+           (let [tags (set (map (comp string/lower-case name) tags))]
+             [['?p :page/tags '?t]
+              ['?t :tag/name '?tag]
+              [(list 'contains? tags '?tag)]])))
+
+       (= 'all-page-tags fe)
+       [['?t :tag/name '?tag]
+        ['?p :page/name '?tag]]
+
        :else
        nil))))
 
@@ -171,7 +199,9 @@
                          (reader/read-string))
 
             sort-by (atom nil)
-            result (when form (build-query form sort-by))
+            blocks? (atom nil)
+            result (when form (build-query form {:sort-by sort-by
+                                                 :blocks? blocks?}))
             result (when (seq result)
                      (let [key (if (coll? (first result))
                                  (keyword (ffirst result))
@@ -188,21 +218,24 @@
 
                          result)))]
         {:query result
-         :sort-by @sort-by})
+         :sort-by @sort-by
+         :blocks? (boolean @blocks?)})
       (catch js/Error e
         (log/error :query-dsl/parse-error e)))))
 
 (defn query
   [query-string]
   (when query-string
-    (let [{:keys [query sort-by]} (parse query-string)]
+    (let [{:keys [query sort-by blocks?]} (parse query-string)]
       (when query
-        (let [query (query-wrapper query)]
+        (let [query (query-wrapper query blocks?)]
           (query-custom/react-query {:query query}
                                     (if sort-by
                                       {:transform-fn sort-by})))))))
 
 (comment
+  ;; {{query (and (page-property foo bar) [[hello]])}}
+
   (query "(and [[foo]] [[bar]])")
 
   (query "(or [[foo]] [[bar]])")
@@ -222,4 +255,6 @@
   ;; nested query
   (query "(and [[baz]] (or [[foo]] [[bar]]))")
 
-  (query "(and [[some page]] (sort-by created-at))"))
+  (query "(and [[some page]] (sort-by created-at))")
+
+  (query "(and (page-property foo bar) [[hello]])"))

+ 9 - 7
src/main/frontend/format/mldoc.cljs

@@ -93,6 +93,12 @@
         (recur (rest ast)))
       nil)))
 
+(defn- split-page-refs-without-brackets
+  [s]
+  (->> s
+       (sep-by-quote-or-space-or-comma)
+       (map remove-page-ref-brackets)))
+
 (defn collect-page-properties
   [ast]
   (if (seq ast)
@@ -126,15 +132,11 @@
                          (:roam_key properties)
                          (assoc :key (:roam_key properties))
                          (:alias properties)
-                         (update :alias
-                                 (fn [s]
-                                   (->> s
-                                        (sep-by-quote-or-space-or-comma)
-                                        (map remove-page-ref-brackets))))
+                         (update :alias split-page-refs-without-brackets)
                          (:tags properties)
-                         (update :tags sep-by-quote-or-space-or-comma)
+                         (update :tags split-page-refs-without-brackets)
                          (:roam_tags properties)
-                         (update :roam_tags sep-by-quote-or-space-or-comma))
+                         (update :roam_tags split-page-refs-without-brackets))
                        properties)
           definition-tags (get-tags-from-definition ast)
           properties (if definition-tags

+ 8 - 23
src/main/frontend/graph.cljs

@@ -54,20 +54,6 @@
                (.toString 16)
                (.padStart 6 "0"))))
 
-(defn- text-mode
-  [node ctx global-scale dark?]
-  (let [label (gobj/get node "id")
-        x (gobj/get node "x")
-        y (gobj/get node "y")
-        color (gobj/get node "color")
-        font-size (/ 14 global-scale)
-        text-width (gobj/get (.measureText ctx label) "width")]
-    (set! (.-font ctx) (str font-size "px Inter"))
-    (set! (.-filltextAlign ctx) "center")
-    (set! (.-textBaseLine ctx) "middle")
-    (set! (.-fillStyle ctx) color)
-    (.fillText ctx label (- x (/ text-width 2)) y)))
-
 (defn- dot-mode
   [node ctx global-scale dark?]
   (let [label (gobj/get node "id")
@@ -148,12 +134,13 @@
                    (let [link {:source (gobj/get link "source")
                                :target (gobj/get link "target")}]
                      (if (contains? @highlight-links link) 5 1)))
-      :linkDirectionalParticles 4
-      :linkDirectionalParticleWidth (fn [link] (let [link {:source (-> (gobj/get link "source")
-                                                                       (gobj/get "id"))
-                                                           :target (-> (gobj/get link "target")
-                                                                       (gobj/get "id"))}]
-                                                 (if (contains? @highlight-links link) 4 0)))
+      :linkDirectionalParticles 2
+      :linkDirectionalParticleWidth (fn [link]
+                                      (let [link {:source (-> (gobj/get link "source")
+                                                              (gobj/get "id"))
+                                                  :target (-> (gobj/get link "target")
+                                                              (gobj/get "id"))}]
+                                        (if (contains? @highlight-links link) 2 0)))
       :onNodeHover on-node-hover
       :onLinkHover on-link-hover
       :nodeLabel "id"
@@ -188,7 +175,5 @@
         (case @graph-mode
           :dot-text
           (dot-text-mode node ctx global-scale dark?)
-          :dot
-          (dot-mode node ctx global-scale dark?)
-          (text-mode node ctx global-scale dark?)))}
+          (dot-mode node ctx global-scale dark?)))}
      option)))

+ 25 - 18
src/main/frontend/handler/graph.cljs

@@ -21,21 +21,26 @@
                  edges)))
 
 (defn- build-nodes
-  [dark? current-page edges nodes]
-  (mapv (fn [p]
-          (let [current-page? (= p current-page)
-                color (case [dark? current-page?]
-                        [false false] "#222222"
-                        [false true]  "#045591"
-                        [true false]  "#8abbbb"
-                        [true true]   "#ffffff")] ; FIXME: Put it into CSS
-            {:id p
-             :name p
-             :val (get-connections p edges)
-             :autoColorBy "group"
-             :group (js/Math.ceil (* (js/Math.random) 12))
-             :color color}))
-        (set (flatten nodes))))
+  [dark? current-page edges tags nodes]
+  (let [pages (->> (set (flatten nodes))
+                   (remove nil?))]
+    (mapv (fn [p]
+            (let [current-page? (= p current-page)
+                  color (case [dark? current-page?] ; FIXME: Put it into CSS
+                          [false false] "#222222"
+                          [false true]  "#045591"
+                          [true false]  "#8abbbb"
+                          [true true]   "#ffffff")
+                  color (if (contains? tags (string/lower-case p))
+                          (if dark? "orange" "green")
+                          color)]
+              {:id p
+               :name p
+               :val (get-connections p edges)
+               :autoColorBy "group"
+               :group (js/Math.ceil (* (js/Math.random) 12))
+               :color color}))
+          pages)))
 
 (defn- normalize-page-name
   [{:keys [nodes links] :as g}]
@@ -62,6 +67,7 @@
     (when-let [repo (state/get-current-repo)]
       (let [relation (db/get-pages-relation repo show-journal?)
             tagged-pages (db/get-all-tagged-pages repo)
+            tags (set (map second tagged-pages))
             linked-pages (-> (concat
                               relation
                               tagged-pages)
@@ -86,7 +92,7 @@
                                 (fn [[_ to]]
                                   (nil? to))
                                 nodes))
-            nodes (build-nodes dark? current-page edges nodes)]
+            nodes (build-nodes dark? current-page edges tags nodes)]
         (normalize-page-name
          {:nodes nodes
           :links edges})))))
@@ -138,7 +144,7 @@
                         tags)
                        (remove nil?)
                        (distinct)
-                       (build-nodes dark? page edges))]
+                       (build-nodes dark? page edges (set tags)))]
         (normalize-page-name
          {:nodes nodes
           :links edges})))))
@@ -172,6 +178,7 @@
                         (map first ref-blocks))
                        (remove nil?)
                        (distinct)
-                       (build-nodes dark? block edges))]
+                       ;; FIXME: get block tags
+                       (build-nodes dark? block edges #{}))]
         {:nodes nodes
          :links edges}))))