Browse Source

fix: custom query not updated (#11551)

 fix: custom query trigger
Tienson Qin 1 year ago
parent
commit
22d2c83a91

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

@@ -2171,7 +2171,7 @@
        (query-builder-component/builder (:block/title block)
                                         {:block block
                                          :query-object? true})
-       (when @*hover?
+       (when (and @*hover? (not (string/blank? (:block/title block))))
          (shui/button
           {:variant "outline"
            :size :sm

+ 2 - 2
src/main/frontend/components/file_based/query.cljs

@@ -31,7 +31,7 @@
 (rum/defc custom-query-header
   [{:keys [dsl-query?] :as config}
    {:keys [title query] :as q}
-   {:keys [collapsed? result table? current-block view-f page-list? query-error-atom fulltext-query-result-atom]}]
+   {:keys [collapsed? result table? current-block view-f page-list? query-error-atom]}]
   (let [dsl-page-query? (and dsl-query?
                              (false? (:blocks? (query-dsl/parse-query query))))
         full-text-search? (and dsl-query?
@@ -82,4 +82,4 @@
            (query-refresh-button query-time {:full-text-search? full-text-search?
                                              :on-pointer-down (fn [e]
                                                                 (util/stop e)
-                                                                (query-result/trigger-custom-query! config q query-error-atom fulltext-query-result-atom))}))]])]))
+                                                                (query-result/trigger-custom-query! config q query-error-atom (fn [])))}))]])]))

+ 51 - 46
src/main/frontend/components/query.cljs

@@ -124,46 +124,16 @@
                           (:block/collapsed? current-block)))]
     collapsed?'))
 
-(rum/defcs custom-query* < rum/reactive rum/static db-mixins/query
-  (rum/local nil ::query-result-atom)
-  (rum/local nil ::prev-q)
-  {:init (fn [state]
-           (let [[{:keys [dsl-query? db-graph? built-in-query?] :as config}
-                  {:keys [collapsed?]}] (:rum/args state)]
-             ;; collapsed? not needed for db graphs
-             (when (not db-graph?)
-               (when-not (or built-in-query? dsl-query?)
-                 (when collapsed?
-                   (editor-handler/collapse-block! (or (:block/uuid (:block config))
-                                                       (:block/uuid config)))))))
-           (assoc state :query-error (atom nil)
-                  :fulltext-query-result (atom nil)))}
-  [state {:keys [db-graph? dsl-query? built-in-query?] :as config} {:keys [builder query view collapsed?] :as q}]
-  (let [*prev-q (::prev-q state)
-        *query-result-atom (::query-result-atom state)
-        *query-error (:query-error state)
-        *fulltext-query-result (:fulltext-query-result state)
-        current-block-uuid (or (:block/uuid (:block config))
-                               (:block/uuid config))
-        current-block (db/entity [:block/uuid current-block-uuid])
-        ;; Get query result
-        collapsed?' (calculate-collapsed? current-block current-block-uuid {:collapsed? (if-not db-graph? collapsed? false)})
-        built-in-collapsed? (and collapsed? built-in-query?)
-        table? (when-not db-graph?
-                 (or (get-in current-block [:block/properties :query-table])
-                     (and (string? query) (string/ends-with? (string/trim query) "table"))))
-        q-changed? (not= @*prev-q q)
-        result (when (or built-in-collapsed? (not collapsed?'))
-                 (or (if q-changed? false @*query-result-atom)
-                     (let [result (query-result/get-query-result config q *query-error *fulltext-query-result current-block-uuid {:table? table?})]
-                       (reset! *query-result-atom result)
-                       result)))
-        _ (when q-changed? (reset! *prev-q q))
+(rum/defc custom-query* < rum/reactive db-mixins/query
+  [{:keys [*query-error db-graph? dsl-query? built-in-query? table? current-block] :as config}
+   {:keys [builder query view collapsed?] :as q}
+   *result]
+  (let [collapsed?' (:collapsed? config)
+        result (when *result (query-result/get-query-result config q (rum/react *result)))
         ;; Args for displaying query header and results
         view-fn (if (keyword? view) (get-in (state/sub-config) [:query/views view]) view)
         view-f (and view-fn (sci/eval-string (pr-str view-fn)))
-        page-list? (and (seq result)
-                        (some? (:block/name (first result))))
+        page-list? (and (seq result) (some? (:block/name (first result))))
         opts {:query-error-atom *query-error
               :current-block current-block
               :table? table?
@@ -180,7 +150,6 @@
            (file-query/custom-query-header config
                                            q
                                            {:query-error-atom *query-error
-                                            :fulltext-query-result-atom *fulltext-query-result
                                             :current-block current-block
                                             :table? table?
                                             :view-f view-f
@@ -203,14 +172,50 @@
               (when-not collapsed?'
                 (custom-query-inner config q opts))]))]))))
 
+(rum/defc trigger-custom-query
+  [config q]
+  (let [[result set-result!] (rum/use-state nil)]
+    (rum/use-effect!
+     (fn []
+       (query-result/trigger-custom-query! config q (:*query-error config) set-result!))
+     [q])
+    (when (and (util/atom? result) (seq @result))
+      (custom-query* config q result))))
+
 (rum/defcs custom-query < rum/static
-  [state config q]
+  {:init (fn [state]
+           (let [db-graph? (config/db-based-graph? (state/get-current-repo))
+                 [{:keys [dsl-query? built-in-query?] :as config}
+                  {:keys [collapsed?]}] (:rum/args state)]
+             ;; collapsed? not needed for db graphs
+             (when (not db-graph?)
+               (when-not (or built-in-query? dsl-query?)
+                 (when collapsed?
+                   (editor-handler/collapse-block! (or (:block/uuid (:block config))
+                                                       (:block/uuid config)))))))
+           (assoc state :query-error (atom nil)))}
+  [state {:keys [built-in-query?] :as config}
+   {:keys [query collapsed?] :as q}]
   (ui/catch-error
    (ui/block-error "Query Error:" {:content (:query q)})
-   (ui/lazy-visible
-    (fn []
-      (custom-query* (merge config
-                            {:db-graph? (config/db-based-graph? (state/get-current-repo))
-                             :built-in-query? (built-in-custom-query? (:title q))})
-                     q))
-    {:debug-id q})))
+   (let [*query-error (:query-error state)
+         db-graph? (config/db-based-graph? (state/get-current-repo))
+         current-block-uuid (or (:block/uuid (:block config))
+                                (:block/uuid config))
+         current-block (db/entity [:block/uuid current-block-uuid])
+        ;; Get query result
+         collapsed?' (calculate-collapsed? current-block current-block-uuid {:collapsed? (if-not db-graph? collapsed? false)})
+         built-in-collapsed? (and collapsed? built-in-query?)
+         table? (when-not db-graph?
+                  (or (get-in current-block [:block/properties :query-table])
+                      (and (string? query) (string/ends-with? (string/trim query) "table"))))
+         config' (assoc config
+                        :db-graph? db-graph?
+                        :current-block current-block
+                        :current-block-uuid current-block-uuid
+                        :collapsed? collapsed?'
+                        :table? table?
+                        :built-in-query? (built-in-custom-query? (:title q))
+                        :*query-error *query-error)]
+     (when (or built-in-collapsed? (not collapsed?'))
+       (trigger-custom-query config' q)))))

+ 36 - 45
src/main/frontend/components/query/result.cljs

@@ -1,57 +1,51 @@
 (ns frontend.components.query.result
   "Query result related functionality for query components"
-  (:require [frontend.db.utils :as db-utils]
-            [frontend.search :as search]
+  (:require [clojure.string :as string]
             [frontend.db :as db]
-            [frontend.db.query-dsl :as query-dsl]
             [frontend.db.query-custom :as query-custom]
+            [frontend.db.query-dsl :as query-dsl]
             [frontend.db.query-react :as query-react]
+            [frontend.db.utils :as db-utils]
+            [frontend.modules.outliner.tree :as tree]
+            [frontend.search :as search]
             [frontend.state :as state]
+            [frontend.template :as template]
             [logseq.common.util :as common-util]
-            [frontend.util :as util]
-            [clojure.string :as string]
-            [promesa.core :as p]
-            [rum.core :as rum]
-            [frontend.modules.outliner.tree :as tree]
-            [frontend.template :as template]))
+            [promesa.core :as p]))
 
 (defn trigger-custom-query!
-  [config query *query-error *fulltext-query-result]
+  [config query *query-error set-result!]
   (let [repo (state/get-current-repo)
         current-block-uuid (or (:block/uuid (:block config))
                                (:block/uuid config))
-        _ (reset! *query-error nil)
-        query-atom (try
-                     (cond
-                       (:dsl-query? config)
-                       (let [q (:query query)
-                             form (common-util/safe-read-string q)]
-                         (cond
-                           (and (symbol? form)
+        _ (reset! *query-error nil)]
+    (try
+      (cond
+        (:dsl-query? config)
+        (let [q (:query query)
+              form (common-util/safe-read-string q)]
+          (cond
+            (and (symbol? form)
                                 ;; Queries only containgin template should trigger a query
-                                (not (re-matches template/template-re (string/trim q))))
-                           (atom nil)
+                 (not (re-matches template/template-re (string/trim q))))
+            nil
 
-                           (re-matches #"\".*\"" q) ; full-text search
-                           (do
-                             (p/let [blocks (search/block-search repo (string/trim form) {:limit 30})]
-                               (when (seq blocks)
-                                 (let [result (->> blocks
-                                                   (keep (fn [b]
-                                                           (when-not (= (:block/uuid b) current-block-uuid)
-                                                             (db/entity [:block/uuid (:block/uuid b)])))))]
-                                   (reset! *fulltext-query-result result))))
-                             *fulltext-query-result)
+            (re-matches #"\".*\"" q) ; full-text search
+            (p/let [blocks (search/block-search repo (string/trim form) {:limit 30})]
+              (when (seq blocks)
+                (let [result (->> blocks
+                                  (keep (fn [b]
+                                          (when-not (= (:block/uuid b) current-block-uuid)
+                                            (db/entity [:block/uuid (:block/uuid b)])))))]
+                  (set-result! (atom result)))))
 
-                           :else
-                           (query-dsl/query (state/get-current-repo) q {:cards? (:cards? config)})))
+            :else
+            (set-result! (query-dsl/query (state/get-current-repo) q {:cards? (:cards? config)}))))
 
-                       :else
-                       (query-custom/custom-query query {:current-block-uuid current-block-uuid}))
-                     (catch :default e
-                       (reset! *query-error e)
-                       (atom nil)))]
-    (or query-atom (atom nil))))
+        :else
+        (set-result! (query-custom/custom-query query {:current-block-uuid current-block-uuid})))
+      (catch :default e
+        (reset! *query-error e)))))
 
 (defn get-group-by-page [{:keys [result-transform query] :as query-m}
                          {:keys [table?]}]
@@ -64,10 +58,8 @@
 (defn get-query-result
   "Fetches a query's result, transforms it as needed and saves the result into
   an atom that is passed in as an argument"
-  [config query-m *query-error *fulltext-query-result current-block-uuid options]
-  (let [query-atom (trigger-custom-query! config query-m *query-error *fulltext-query-result)
-        query-result (and query-atom (rum/react query-atom))
-        ;; exclude the current one, otherwise it'll loop forever
+  [{:keys [current-block-uuid table?] :as config} query-m query-result]
+  (let [;; exclude the current one, otherwise it'll loop forever
         remove-blocks (if current-block-uuid [current-block-uuid] nil)
         transformed-query-result (when query-result
                                    (let [result (query-react/custom-query-result-transform query-result remove-blocks query-m)]
@@ -76,7 +68,7 @@
                                          (get query-m :remove-block-children? true)
                                          tree/filter-top-level-blocks)
                                        result)))
-        group-by-page? (get-group-by-page query-m options)
+        group-by-page? (get-group-by-page query-m {:table? table?})
         result (if (and group-by-page? (:block/uuid (first transformed-query-result)))
                  (let [result (db-utils/group-by-page transformed-query-result)]
                    (if (map? result)
@@ -85,5 +77,4 @@
                  transformed-query-result)]
     (when-let [query-result (:query-result config)]
       (reset! query-result result))
-    (when query-atom
-      (util/safe-with-meta result (meta @query-atom)))))
+    result))

+ 0 - 7
src/main/frontend/util.cljc

@@ -1509,13 +1509,6 @@ Arg *stop: atom, reset to true to stop the loop"
   [pred coll]
   `(vec (remove ~pred ~coll)))
 
-#?(:cljs
-   (defn safe-with-meta
-     [o meta]
-     (if (satisfies? IMeta o)
-       (with-meta o meta)
-       o)))
-
 ;; from rum
 #?(:cljs
    (def schedule

+ 17 - 15
src/test/frontend/components/query/result_test.cljs

@@ -12,7 +12,9 @@
   (with-redefs [query-custom/custom-query (constantly (atom result))
                 model/with-pages identity]
     (binding [rum/*reactions* (volatile! #{})]
-      (#'query-result/get-query-result config query-m (atom nil) (atom nil) current-block-uuid {:table? table?}))))
+      (#'query-result/get-query-result (assoc config :table? table? :current-block-uuid current-block-uuid
+                                              :*query-error (atom nil))
+                                       query-m))))
 
 (deftest get-query-result-with-transforms-and-grouping
   (let [result (mapv
@@ -26,36 +28,36 @@
            (= expected (mock-get-query-result result query-m {:table? false}))
 
            ;; Default list behavior is to group result
-           {}
-           {{:db/id 1} result}
+        {}
+        {{:db/id 1} result}
 
            ;; User overrides default behavior to return result
-           {:group-by-page? false}
-           result
+        {:group-by-page? false}
+        result
 
            ;; Return transformed result for list view
-           {:result-transform '(partial sort-by :block/scheduled)}
-           sorted-result
+        {:result-transform '(partial sort-by :block/scheduled)}
+        sorted-result
 
            ; User overrides transform to return grouped result
-           {:result-transform '(partial sort-by :block/scheduled) :group-by-page? true}
-           {{:db/id 1} sorted-result})
+        {:result-transform '(partial sort-by :block/scheduled) :group-by-page? true}
+        {{:db/id 1} sorted-result})
 
       (testing "For table view"
         (are [query expected]
              (= expected (mock-get-query-result result query {:table? true}))
 
              ;; Default table behavior is to return result
-             {}
-             result
+          {}
+          result
 
              ;; Return transformed result
-             {:result-transform '(partial sort-by :block/scheduled)}
-             sorted-result
+          {:result-transform '(partial sort-by :block/scheduled)}
+          sorted-result
 
              ;; Ignore override and return normal result
-             {:group-by-page? true}
-             result))
+          {:group-by-page? true}
+          result))
 
       (testing "current block in results"
         (is (= result