fix: custom query not updated (#11551)

fix: custom query trigger
feat/db
Tienson Qin 2024-09-28 13:44:35 +08:00 committed by GitHub
parent 6853acd0c9
commit 22d2c83a91
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 108 additions and 117 deletions

View File

@ -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

View File

@ -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 [])))}))]])]))

View File

@ -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)))))

View File

@ -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.state :as state]
[logseq.common.util :as common-util]
[frontend.util :as util]
[clojure.string :as string]
[promesa.core :as p]
[rum.core :as rum]
[frontend.db.utils :as db-utils]
[frontend.modules.outliner.tree :as tree]
[frontend.template :as template]))
[frontend.search :as search]
[frontend.state :as state]
[frontend.template :as template]
[logseq.common.util :as common-util]
[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))

View File

@ -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

View File

@ -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