Procházet zdrojové kódy

enhance: support tags in query dsl

Tienson Qin před 1 rokem
rodič
revize
bb08621fea

+ 7 - 1
deps/db/src/logseq/db/frontend/rules.cljc

@@ -153,7 +153,13 @@
   "Rules used by frontend.query.dsl for db graphs"
   (merge
    (dissoc query-dsl-rules :namespace)
-   {:page-tags
+   {:tags
+    '[(tags ?b ?tags)
+      [?b :block/tags ?t]
+      [?t :block/name ?tag]
+      [(missing? $ ?b :block/link)]
+      [(contains? ?tags ?tag)]]
+    :page-tags
     '[(page-tags ?p ?tags)
       [?p :block/tags ?t]
       [?t :block/name ?tag]

+ 99 - 17
src/main/frontend/components/query/builder.cljs

@@ -202,10 +202,11 @@
 
 (rum/defc tags
   [repo *tree opts loc]
-  (let [[values set-values!] (rum/use-state nil)]
+  (let [[values set-values!] (rum/use-state nil)
+        db-based? (config/db-based-graph? repo)]
     (rum/use-effect!
      (fn []
-       (p/let [result (db-async/<get-tags repo)]
+       (let [result (db-model/get-all-classes repo {:except-root-class? true})]
          (set-values! result)))
      [])
     (let [items (->> values
@@ -213,9 +214,86 @@
                      sort)]
       (select items
               (fn [{:keys [value]}]
-                (append-tree! *tree opts loc [:page-tags value]))))))
+                (append-tree! *tree opts loc [(if db-based? :tags :page-tags) value]))))))
 
-(defn- query-filter-picker
+(defn- db-based-query-filter-picker
+  [state *find *tree loc clause opts]
+  (let [*mode (::mode state)
+        *property (::property state)
+        repo (state/get-current-repo)]
+    [:div
+     (case @*mode
+       "property"
+       (property-select *mode *property)
+
+       "property-value"
+       (property-value-select repo *property *find *tree opts loc)
+
+       "sample"
+       (select (range 1 101)
+               (fn [{:keys [value]}]
+                 (append-tree! *tree opts loc [:sample (util/safe-parse-int value)])))
+
+       "tags"
+       (tags repo *tree opts loc)
+
+       "task"
+       (let [items (let [values (:property/closed-values (db/entity :logseq.task/status))]
+                     (mapv db-property/property-value-content values))]
+         (select items
+                 (constantly nil)
+                 {:multiple-choices? true
+                ;; Need the existing choices later to improve the UX
+                  :selected-choices #{}
+                  :extract-chosen-fn :value
+                  :prompt-key :select/default-select-multiple
+                  :close-modal? false
+                  :on-apply (fn [choices]
+                              (when (seq choices)
+                                (append-tree! *tree opts loc (vec (cons :task choices)))))}))
+
+       "priority"
+       (select (if (config/db-based-graph? repo)
+                 (let [values (:property/closed-values (db/entity :logseq.task/priority))]
+                   (mapv db-property/property-value-content values))
+                 gp-db/built-in-priorities)
+               (constantly nil)
+               {:multiple-choices? true
+                :selected-choices #{}
+                :extract-chosen-fn :value
+                :prompt-key :select/default-select-multiple
+                :close-modal? false
+                :on-apply (fn [choices]
+                            (when (seq choices)
+                              (append-tree! *tree opts loc (vec (cons :priority choices)))))})
+
+       "page"
+       (let [pages (sort (db-model/get-all-page-titles repo))]
+         (select pages
+                 (fn [{:keys [value]}]
+                   (append-tree! *tree opts loc [:page value]))))
+
+       ;; TODO: replace with node reference
+       "page reference"
+       (let [pages (sort (db-model/get-all-page-titles repo))]
+         (select pages
+                 (fn [{:keys [value]}]
+                   (append-tree! *tree opts loc [:page-ref value]))
+                 {}))
+
+       "full text search"
+       (search (fn [v] (append-tree! *tree opts loc v))
+               (:toggle-fn opts))
+
+       "between"
+       (between (merge opts
+                       {:tree *tree
+                        :loc loc
+                        :clause clause}))
+
+       nil)]))
+
+(defn- file-based-query-filter-picker
   [state *find *tree loc clause opts]
   (let [*mode (::mode state)
         *property (::property state)
@@ -307,24 +385,28 @@
   [state *find *tree loc clause opts]
   (let [*mode (::mode state)
         db-based? (config/db-based-graph? (state/get-current-repo))
-        filters (if (= :page @*find)
-                  (if db-based?
-                    (remove #{"namespace"} query-builder/page-filters)
-                    query-builder/page-filters)
-                  query-builder/block-filters)
+        filters (if db-based?
+                  query-builder/db-based-block-filters
+                  (if (= :page @*find)
+                    query-builder/page-filters
+                    query-builder/block-filters))
         filters-and-ops (concat filters query-builder/operators)
         operator? #(contains? query-builder/operators-set (keyword %))]
     [:div.query-builder-picker
      (if @*mode
        (when-not (operator? @*mode)
-         (query-filter-picker state *find *tree loc clause opts))
+         (if db-based?
+           (db-based-query-filter-picker state *find *tree loc clause opts)
+           (file-based-query-filter-picker state *find *tree loc clause opts)))
        [:div
-        (when-not @*find
-          [:div.flex.flex-row.items-center.p-2.justify-between
-           [:div.ml-2 "Find: "]
-           (page-block-selector *find)])
-        (when-not @*find
-          [:hr.m-0])
+        (when-not db-based?
+          [:<>
+           (when-not @*find
+             [:div.flex.flex-row.items-center.p-2.justify-between
+              [:div.ml-2 "Find: "]
+              (page-block-selector *find)])
+           (when-not @*find
+             [:hr.m-0])])
         (select
          (map name filters-and-ops)
          (fn [{:keys [value]}]
@@ -366,7 +448,7 @@
       (= (keyword f) :page-ref)
       (page-ref/->page-ref (second clause))
 
-      (= (keyword f) :page-tags)
+      (contains? #{:tags :page-tags} (keyword f))
       (cond
         (string? (second clause))
         (str "#" (second clause))

+ 6 - 6
src/main/frontend/db/async.cljs

@@ -169,11 +169,11 @@
   (when-let [page (some-> page-name (db-model/get-page))]
     (when-let [^Object worker @db-browser/*worker]
       (p/let [result (.get-block-and-children worker
-                       (state/get-current-repo)
-                       (str (:block/uuid page))
-                       (ldb/write-transit-str
-                         {:children? true
-                          :nested-children? false}))]
+                                              (state/get-current-repo)
+                                              (str (:block/uuid page))
+                                              (ldb/write-transit-str
+                                               {:children? true
+                                                :nested-children? false}))]
         (some-> result (ldb/read-transit-str) (:children))))))
 
 (defn <get-block-refs
@@ -286,7 +286,7 @@
 (defn <get-tags
   [graph]
   (<q graph {:transact-db? false}
-      '[:find [(pull ?tag [:db/id :block/title])]
+      '[:find [(pull ?tag [:db/id :block/title]) ...]
         :where
         [?tag :block/type "class"]]))
 

+ 14 - 0
src/main/frontend/db/query_dsl.cljs

@@ -351,6 +351,17 @@
       {:query (list 'has-page-property '?p k')
        :rules [:has-page-property]})))
 
+(defn- build-tags
+  [e]
+  (let [tags (if (coll? (first (rest e)))
+               (first (rest e))
+               (rest e))
+        tags (map (comp string/lower-case name) tags)]
+    (when (seq tags)
+      (let [tags (set (map (comp page-ref/get-page-name! string/lower-case name) tags))]
+        {:query (list 'tags '?p tags)
+         :rules [:tags]}))))
+
 (defn- build-page-tags
   [e]
   (let [tags (if (coll? (first (rest e)))
@@ -480,6 +491,9 @@ Some bindings in this fn:
        (= 'page-property fe)
        (build-page-property e env)
 
+       (= 'tags fe)
+       (build-tags e)
+
        (= 'page-tags fe)
        (build-page-tags e)
 

+ 13 - 0
src/main/frontend/handler/query/builder.cljs

@@ -23,6 +23,16 @@
                     "full text search"
                     "between"
                     "sample"])
+(def db-based-block-filters
+  ["tags"
+   "page reference"
+   "property"
+   "task"
+   "priority"
+   "page"
+   "full text search"
+   "between"
+   "sample"])
 
 (defn- vec-dissoc-item
   [vec idx]
@@ -143,6 +153,9 @@
     (and (vector? f) (= :page-ref (keyword (first f))))
     (->page-ref (second f))
 
+    (and (vector? f) (= :tags (keyword (first f))))
+    [(symbol :tags) (->page-ref (second f))]
+
     (and (vector? f) (= :page-tags (keyword (first f))))
     [(symbol :page-tags) (->page-ref (second f))]