Преглед на файлове

enhance(ux): query

1. allow editing dsl query with both the query builder and the default text
editor
2. displays placeholder `Set query title` when a query doesn't have a
title yet
Tienson Qin преди 1 година
родител
ревизия
1bb69c74f2

+ 4 - 2
src/main/frontend/commands.cljs

@@ -141,8 +141,7 @@
 (defn db-based-query
   []
   [[:editor/input "" {:last-pattern command-trigger}]
-   [:editor/set-property :block/tags :logseq.class/Query]
-   [:editor/exit]])
+   [:editor/run-query-command]])
 
 (defn file-based-query
   []
@@ -785,6 +784,9 @@
     (state/pub-event! [:editor/new-property {:property-key "Deadline"}])
     (handle-step [:editor/show-date-picker :deadline])))
 
+(defmethod handle-step :editor/run-query-command [[_]]
+  (state/pub-event! [:editor/run-query-command]))
+
 (defmethod handle-step :editor/insert-properties [[_ _] _format]
   (when-let [input-id (state/get-edit-input-id)]
     (when-let [current-input (gdom/getElement input-id)]

+ 48 - 54
src/main/frontend/components/block.cljs

@@ -1413,9 +1413,10 @@
   [config arguments]
   [:div.dsl-query.pr-3.sm:pr-0
    (let [query (->> (string/join ", " arguments)
-                    (string/trim))]
+                    (string/trim))
+         build-option (assoc (:block config) :file-version/query-macro-title query)]
      (query/custom-query (wrap-query-components (assoc config :dsl-query? true))
-                         {:builder (query-builder-component/builder query config)
+                         {:builder (query-builder-component/builder build-option {})
                           :query query}))])
 
 (defn- macro-function-cp
@@ -2140,47 +2141,37 @@
               "Practice")
              [:div "Practice cards"])])))))))
 
-(rum/defcs block-title < rum/reactive db-mixins/query
-  (rum/local false ::hover?)
-  [state config block]
-  (let [*hover? (::hover? state)
+(rum/defc block-title < rum/reactive db-mixins/query
+  [config block]
+  (let [collapsed? (:collapsed? config)
         block' (db/entity (:db/id block))
         node-type (:logseq.property.node/display-type block')
         query? (ldb/class-instance? (db/entity :logseq.class/Query) block')
         query (:logseq.property/query block')
-        empty-query-title? (and query? (string/blank? (:block/title query)))
-        query-block? (:logseq.property/_query block')
-        advanced-query? (= :code (:logseq.property.node/display-type query))]
+        advanced-query? (and query? (= :code node-type))]
     (cond
       (= :code node-type)
       [:div.flex.flex-1.w-full
        (src-cp (assoc config :block block) {:language (:logseq.property.code/mode block)})]
 
-      query-block?
-      (query-builder-component/builder (:block/title block')
-                                       {:block block
-                                        :query-object? true})
-
-        ;; TODO: switched to https://cortexjs.io/mathlive/ for editing
+      ;; TODO: switched to https://cortexjs.io/mathlive/ for editing
       (= :math node-type)
       (latex/latex (str (:container-id config) "-" (:db/id block)) (:block/title block) true false)
 
-      (and empty-query-title? (not advanced-query?))
-      [:div.flex.flex-row.w-full.gap-1.flex-wrap
-       {:on-mouse-over #(reset! *hover? true)
-        :on-mouse-out #(reset! *hover? false)}
-       (query-builder-component/builder (:block/title block')
-                                        {:block block
-                                         :query-object? true})
-       (when (and @*hover? (not (string/blank? (:block/title block))))
-         (shui/button
-          {:variant "outline"
-           :size :sm
-           :class "!h-6"
-           :on-pointer-down (fn [e]
-                              (util/stop e)
-                              (editor-handler/query-edit-title! block))}
-          [:span "Edit query title"]))]
+      (and query?
+           collapsed?
+           (not advanced-query?)
+           (string/blank? (:block/title block'))
+           (seq (:block/title query)))
+      (text-block-title config
+                        (merge query
+                               (block/parse-title-and-body (:block/uuid query) :markdown false (:block/title query))))
+
+      (seq (:logseq.property/_query block'))
+      (query-builder-component/builder block' {})
+
+      (and query? (string/blank? (:block/title block')))
+      [:span.opacity-50 "Set query title"]
 
       :else
       (text-block-title config block))))
@@ -2581,14 +2572,14 @@
 
 (rum/defc ^:large-vars/cleanup-todo block-content < rum/reactive
   [config {:block/keys [uuid properties scheduled deadline format pre-block?] :as block} edit-input-id block-id slide?]
-  (let [repo (state/get-current-repo)
+  (let [collapsed? (:collapsed? config)
+        repo (state/get-current-repo)
         content (if (config/db-based-graph? (state/get-current-repo))
                   (:block/raw-title block)
                   (property-util/remove-built-in-properties format (:block/raw-title block)))
         block (merge block (block/parse-title-and-body uuid format pre-block? content))
         ast-body (:block.temp/ast-body block)
         ast-title (:block.temp/ast-title block)
-        collapsed? (util/collapsed? block)
         block (assoc block :block/title content)
         plugin-slotted? (and config/lsp-enabled? (state/slot-hook-exist? uuid))
         block-ref? (:block-ref? config)
@@ -3146,6 +3137,24 @@
       [block* result]
       [nil result])))
 
+(rum/defc query-property-cp < rum/reactive db-mixins/query
+  [block config collapsed?]
+  (let [block (db/entity (:db/id block))
+        query? (ldb/class-instance? (db/entity :logseq.class/Query) block)]
+    (when (and query? (not collapsed?))
+      (let [query-id (:db/id (:logseq.property/query block))
+            query (some-> query-id db/sub-block)
+            advanced-query? (= :code (:logseq.property.node/display-type query))]
+        (cond
+          (and advanced-query? (not collapsed?))
+          [:div.flex.flex-1.my-1 {:style {:margin-left 42}}
+           (src-cp (assoc config :block query)
+                   {:language "clojure"})]
+
+          (and (not advanced-query?) (not collapsed?))
+          [:div.my-1 {:style {:margin-left 42}}
+           (block-container (assoc config :property? true) query)])))))
+
 (rum/defcs ^:large-vars/cleanup-todo block-container-inner < rum/reactive db-mixins/query
   {:init (fn [state]
            (let [*ref (atom nil)
@@ -3186,6 +3195,7 @@
 
                      :else
                      db-collapsed?)
+        config (assoc config :collapsed? collapsed?)
         breadcrumb-show? (:breadcrumb-show? config)
         *show-left-menu? (::show-block-left-menu? container-state)
         *show-right-menu? (::show-block-right-menu? container-state)
@@ -3318,7 +3328,8 @@
                    hide-block-refs-count? (or (and (:embed? config)
                                                    (= (:block/uuid block) (:embed-id config)))
                                               table?)]
-               (block-content-or-editor config block
+               (block-content-or-editor config
+                                        block
                                         {:edit-input-id edit-input-id
                                          :block-id block-id
                                          :edit? editing?
@@ -3331,21 +3342,7 @@
           (block-right-menu config block editing?))])
 
      (when-not (:table? config)
-       (let [query* (:logseq.property/query (db/entity (:db/id block)))
-             query (when query* (db/sub-block (:db/id query*)))
-             advanced-query? (= :code (:logseq.property.node/display-type query))]
-         (when query
-           (cond
-             (and advanced-query? (not collapsed?))
-             [:div.flex.flex-1.my-1 {:style {:margin-left 42}}
-              (src-cp (assoc config :block query)
-                      {:language (:logseq.property.code/mode query)})]
-
-             (and (not advanced-query?) (not collapsed?) (not (string/blank? (:block/title query))))
-             [:div.flex.flex-1.my-1 {:style {:margin-left 42}}
-              (query-builder-component/builder (:block/title (db/entity (:db/id query)))
-                                               {:block query
-                                                :query-object? true})]))))
+       (query-property-cp block config collapsed?))
 
      (when (and db-based? (not collapsed?) (not (or table? property?)))
        [:div (when-not (:page-title? config) {:style {:padding-left 45}})
@@ -3354,11 +3351,8 @@
      (when (and db-based? (not collapsed?) (not (or table? property?))
                 (ldb/class-instance? (db/entity :logseq.class/Query) block))
        (let [query-block (:logseq.property/query (db/entity (:db/id block)))
-             query-block-title (:block/title query-block)
-             query (if (and (string/blank? query-block-title)
-                            (not (= :code (:logseq.property.node/display-type query-block))))
-                     (:block/title (db/entity (:db/id block)))
-                     query-block-title)
+             query-block (if query-block (db/sub-block (:db/id query-block)) query-block)
+             query (:block/title query-block)
              result (common-util/safe-read-string query)
              advanced-query? (map? result)]
          [:div {:style {:padding-left 42}}

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

@@ -344,15 +344,15 @@
   (shui/button
    {:class "jtrigger !px-1 h-6 add-filter text-muted-foreground"
     :size :sm
-    :variant :ghost
-    :title "Add clause"
+    :variant :outline
     :on-pointer-down util/stop-propagation
     :on-click (fn [^js e]
                 (shui/popup-show! (.-target e)
                                   (fn [{:keys [id]}]
                                     (picker *find *tree loc clause {:toggle-fn #(shui/popup-hide! id)}))
                                   {:align :start}))}
-   (ui/icon "plus" {:size 12})))
+   (ui/icon "plus" {:size 14})
+   (when (= [0] loc) "Filter")))
 
 (declare clauses-group)
 
@@ -527,10 +527,17 @@
       q-str
       (str "\"" q-str "\""))))
 
+(defn- get-q
+  [block]
+  (sanitize-q (or (:file-version/query-macro-title block)
+                  (:block/title block)
+                  "")))
+
 (rum/defcs builder <
   (rum/local nil ::find)
   {:init (fn [state]
-           (let [q-str (sanitize-q (first (:rum/args state)))
+           (let [block (first (:rum/args state))
+                 q-str (get-q block)
                  query (common-util/safe-read-string
                         query-dsl/custom-readers
                         (query-dsl/pre-transform-query q-str))
@@ -544,10 +551,9 @@
                           :else
                           [:and])
                  tree (query-builder/from-dsl query')
-                 *tree (atom tree)
-                 config (last (:rum/args state))]
+                 *tree (atom tree)]
              (add-watch *tree :updated (fn [_ _ _old _new]
-                                         (when-let [block (:block config)]
+                                         (when block
                                            (let [q (if (= [:and] @*tree)
                                                      ""
                                                      (let [result (query-builder/->dsl @*tree)]
@@ -555,17 +561,16 @@
                                                          (util/format "\"%s\"" result)
                                                          (str result))))
                                                  repo (state/get-current-repo)
-                                                 block (db/pull [:block/uuid (:block/uuid block)])]
-                                             (when block
-                                               (if (:query-object? config)
-                                                 (editor-handler/save-block! repo (:block/uuid block) q)
-                                                 (let [content (string/replace (:block/title block)
-                                                                               #"\{\{query[^}]+\}\}"
-                                                                               (util/format "{{query %s}}" q))]
-                                                   (editor-handler/save-block! repo (:block/uuid block) content))))))))
+                                                 block (db/entity [:block/uuid (:block/uuid block)])]
+                                             (if (config/db-based-graph? (state/get-current-repo))
+                                               (editor-handler/save-block! repo (:block/uuid block) q)
+                                               (let [content (string/replace (:block/title block)
+                                                                             #"\{\{query[^}]+\}\}"
+                                                                             (util/format "{{query %s}}" q))]
+                                                 (editor-handler/save-block! repo (:block/uuid block) content)))))))
              (assoc state ::tree *tree)))
    :will-mount (fn [state]
-                 (let [q-str (sanitize-q (first (:rum/args state)))
+                 (let [q-str (get-q (first (:rum/args state)))
                        blocks-query? (:blocks? (query-dsl/parse-query q-str))
                        find-mode (cond
                                    blocks-query?
@@ -576,7 +581,7 @@
                                    nil)]
                    (when find-mode (reset! (::find state) find-mode))
                    state))}
-  [state _query _config]
+  [state _block _option]
   (let [*find (::find state)
         *tree (::tree state)]
     [:div.cp__query-builder

+ 4 - 0
src/main/frontend/components/query/builder.css

@@ -3,6 +3,10 @@
 
     &-filter {
         @apply flex flex-row flex-wrap items-center gap-1;
+        svg {
+          width: 14px;
+          height: 14px;
+        }
     }
 
     .cp__select-main {

+ 23 - 24
src/main/frontend/db/model.cljs

@@ -243,17 +243,17 @@ independent of format as format specific heading characters are stripped"
 (def sort-by-order ldb/sort-by-order)
 
 (defn sub-block
-  [id & {:keys [ref?]}]
+  [id]
   (when-let [repo (state/get-current-repo)]
     (when id
       (let [ref (react/q repo [:frontend.worker.react/block id]
                          {:query-fn (fn [_]
                                       (let [e (db-utils/entity id)]
                                         [e (:block/tx-id e)]))}
-                         nil)]
-        (if ref?
-          ref
-          (-> ref react first))))))
+                         nil)
+            e (-> ref react first)]
+        (when-let [id (:db/id e)]
+          (db-utils/entity id))))))
 
 (defn sort-by-order-recursive
   [form]
@@ -386,7 +386,7 @@ independent of format as format specific heading characters are stripped"
   [page-name type]
   (let [repo (state/get-current-repo)]
     (when-let [db (conn/get-db repo)]
-     (ldb/page-exists? db page-name type))))
+      (ldb/page-exists? db page-name type))))
 
 (defn page-empty?
   "Whether a page is empty. Does it has a non-page block?
@@ -418,9 +418,9 @@ independent of format as format specific heading characters are stripped"
   [repo block-uuid]
   (when-let [db (conn/get-db repo)]
     (let [ids (ldb/get-block-children-ids db block-uuid)]
-     (when (seq ids)
-       (let [ids' (map (fn [id] [:block/uuid id]) ids)]
-         (db-utils/pull-many repo '[*] ids'))))))
+      (when (seq ids)
+        (let [ids' (map (fn [id] [:block/uuid id]) ids)]
+          (db-utils/pull-many repo '[*] ids'))))))
 
 (defn get-block-and-children
   [repo block-uuid]
@@ -750,16 +750,16 @@ independent of format as format specific heading characters are stripped"
 (defn get-all-whiteboards
   [repo]
   (d/q
-    '[:find [(pull ?page [:db/id
-                          :block/uuid
-                          :block/name
-                          :block/title
-                          :block/created-at
-                          :block/updated-at]) ...]
-      :where
-      [?page :block/name]
-      [?page :block/type "whiteboard"]]
-    (conn/get-db repo)))
+   '[:find [(pull ?page [:db/id
+                         :block/uuid
+                         :block/name
+                         :block/title
+                         :block/created-at
+                         :block/updated-at]) ...]
+     :where
+     [?page :block/name]
+     [?page :block/type "whiteboard"]]
+   (conn/get-db repo)))
 
 (defn get-whiteboard-id-nonces
   [repo page-id]
@@ -833,14 +833,14 @@ independent of format as format specific heading characters are stripped"
   (d/q '[:find ?page ?parent
          :where
          [?page :block/namespace ?parent]]
-    (conn/get-db repo)))
+       (conn/get-db repo)))
 
 (defn get-all-namespace-parents
   [repo]
   (let [db (conn/get-db repo)]
     (->> (get-all-namespace-relation repo)
-        (map (fn [[_ ?parent]]
-               (db-utils/entity db ?parent))))))
+         (map (fn [[_ ?parent]]
+                (db-utils/entity db ?parent))))))
 
 ;; Ignore files with empty blocks for now
 (defn get-pages-relation
@@ -915,5 +915,4 @@ independent of format as format specific heading characters are stripped"
        '[:find [(pull ?b [*]) ...]
          :where
          [?b :block/uuid]]
-        (conn/get-db repo))))
-  )
+       (conn/get-db repo)))))

+ 21 - 12
src/main/frontend/handler/editor.cljs

@@ -3830,15 +3830,24 @@
             (if page? "page-name" "block-uuid")
             (str block-or-page-name)))
 
-(defn query-edit-title!
-  [block]
-  (let [query-block (:logseq.property/query block)
-        current-query (:block/title (db/entity (:db/id block)))]
-    (p/do!
-     (state/clear-edit!)
-     (ui-outliner-tx/transact!
-      {:outliner-op :save-block}
-      (save-block-inner! block "" {})
-      (when query-block
-        (save-block-inner! query-block current-query {})))
-     (js/setTimeout #(edit-block! (db/entity (:db/id block)) :max) 100))))
+(defn run-query-command!
+  []
+  (let [repo (state/get-current-repo)]
+    (when-let [block (some-> (state/get-edit-block)
+                             :db/id
+                             (db/entity))]
+      (p/do!
+       (save-current-block!)
+       (state/clear-edit!)
+       (p/let [query-block (or (:logseq.property/query block)
+                               (p/do!
+                                (property-handler/set-block-property! repo (:db/id block) :logseq.property/query "")
+                                (:logseq.property/query (db/entity (:db/id block)))))
+               current-query (:block/title (db/entity (:db/id block)))]
+         (p/do!
+          (ui-outliner-tx/transact!
+           {:outliner-op :save-block}
+           (property-handler/set-block-property! repo (:db/id block) :block/tags :logseq.class/Query)
+           (save-block-inner! block "" {})
+           (when query-block
+             (save-block-inner! query-block current-query {})))))))))

+ 3 - 0
src/main/frontend/handler/events.cljs

@@ -987,6 +987,9 @@
 
     nil))
 
+(defmethod handle :editor/run-query-command [_]
+  (editor-handler/run-query-command!))
+
 (defn run!
   []
   (let [chan (state/get-events-chan)]