Преглед изворни кода

Merge branch 'feat/db' into enhance/code-type-block

Tienson Qin пре 1 година
родитељ
комит
f459444a42

+ 65 - 12
deps/graph-parser/src/logseq/graph_parser/exporter.cljs

@@ -82,14 +82,18 @@
       (throw (ex-info (str "No uuid found for page name " (pr-str page-name))
                       {:page-name page-name}))))
 
+(defn- logseq-class-ident?
+  [k]
+  (and (qualified-keyword? k) (= "logseq.class" (namespace k))))
+
 (defn- update-page-tags
   [block db tag-classes page-names-to-uuids all-idents]
   (if (seq (:block/tags block))
     (let [page-tags (->> (:block/tags block)
                          (remove #(or (:block.temp/new-class %)
                                       (contains? tag-classes (:block/name %))
-                                      ;; Ignore new class tags from extract
-                                      (= % :logseq.class/Journal)))
+                                      ;; Ignore new class tags from extract e.g. :logseq.class/Journal
+                                      (logseq-class-ident? %)))
                          (map #(vector :block/uuid (get-page-uuid page-names-to-uuids (:block/name %))))
                          set)]
       (cond-> block
@@ -97,7 +101,7 @@
         (update :block/tags
                 (fn [tags]
                   ;; Don't lazy load as this needs to build before the page does
-                  (vec (keep #(if (= % :logseq.class/Journal)
+                  (vec (keep #(if (logseq-class-ident? %)
                                 %
                                 (convert-tag-to-class db % page-names-to-uuids tag-classes all-idents)) tags))))
         (seq page-tags)
@@ -124,7 +128,10 @@
   [block db tag-classes page-names-to-uuids all-idents]
   (let [block'
         (if (seq (:block/tags block))
-          (let [original-tags (remove :block.temp/new-class (:block/tags block))]
+          (let [original-tags (remove #(or (:block.temp/new-class %)
+                                           ;; Filter out new classes already set on a block e.g. :logseq.class/Query
+                                           (logseq-class-ident? %))
+                                      (:block/tags block))]
             (-> block
                 (update :block/title
                         content-without-tags-ignore-case
@@ -138,11 +145,12 @@
                              (map #(add-uuid-to-page-map % page-names-to-uuids))))
                 (update :block/tags
                         (fn [tags]
-                          (vec (keep #(convert-tag-to-class db % page-names-to-uuids tag-classes all-idents) tags))))))
+                          (vec (keep #(if (logseq-class-ident? %)
+                                        %
+                                        (convert-tag-to-class db % page-names-to-uuids tag-classes all-idents))
+                                     tags))))))
           block)]
-    (cond-> block'
-      (macro-util/query-macro? (:block/title block))
-      (update :block/tags (fnil conj []) :logseq.class/Query))))
+    block'))
 
 (defn- update-block-marker
   "If a block has a marker, convert it to a task object"
@@ -614,14 +622,59 @@
 
 (defn- handle-block-properties
   "Does everything page properties does and updates a couple of block specific attributes"
-  [block* db page-names-to-uuids refs {:keys [property-classes] :as options}]
-  (let [{:keys [block properties-tx]} (handle-page-and-block-properties block* db page-names-to-uuids refs options)]
+  [{:block/keys [title] :as block*} db page-names-to-uuids refs {:keys [property-classes] :as options}]
+  (let [{:keys [block properties-tx]} (handle-page-and-block-properties block* db page-names-to-uuids refs options)
+        advanced-query (some->> (second (re-find #"(?s)#\+BEGIN_QUERY(.*)#\+END_QUERY" title)) string/trim)
+        additional-props (cond-> {}
+                           ;; Order matters as we ensure a simple query gets priority
+                           (macro-util/query-macro? title)
+                           (assoc :logseq.property/query
+                                  (or (some->> (second (re-find #"\{\{query(.*)\}\}" title))
+                                               string/trim)
+                                      title))
+                           (seq advanced-query)
+                           (assoc :logseq.property/query
+                                  (if-let [query-map (not-empty (common-util/safe-read-map-string advanced-query))]
+                                    (pr-str (dissoc query-map :title :group-by-page? :collapsed?))
+                                    advanced-query)))
+        {:keys [block-properties pvalues-tx]}
+        (when (seq additional-props)
+          (build-properties-and-values additional-props db page-names-to-uuids
+                                       (select-keys block [:block/properties-text-values :block/name :block/title :block/uuid])
+                                       options))
+        pvalues-tx' (if (and pvalues-tx (seq advanced-query))
+                      (concat pvalues-tx [{:block/uuid (second (:logseq.property/query block-properties))
+                                           :logseq.property.code/mode "clojure"
+                                           :logseq.property.node/display-type :code}])
+                      pvalues-tx)]
     {:block
      (cond-> block
+       (seq block-properties)
+       (merge block-properties)
+
+       (macro-util/query-macro? title)
+       ((fn [b]
+          (merge (update b :block/tags (fnil conj []) :logseq.class/Query)
+                 ;; Put all non-query content in title. Could just be a blank string
+                 {:block/title (string/trim (string/replace-first title #"\{\{query(.*)\}\}" ""))})))
+
+       (seq advanced-query)
+       ((fn [b]
+          (let [query-map (common-util/safe-read-map-string advanced-query)]
+            (cond-> (update b :block/tags (fnil conj []) :logseq.class/Query)
+              true
+              (assoc :block/title
+                     (or (when-let [title' (:title query-map)]
+                           (if (string? title') title' (pr-str title')))
+                         ;; Put all non-query content in title for now
+                         (string/trim (string/replace-first title #"(?s)#\+BEGIN_QUERY(.*)#\+END_QUERY" ""))))
+              (:collapsed? query-map)
+              (assoc :block/collapsed? true)))))
+
        (and (seq property-classes) (seq (:block/refs block*)))
        ;; remove unused, nonexistent property page
        (update :block/refs (fn [refs] (remove #(property-classes (keyword (:block/name %))) refs))))
-     :properties-tx properties-tx}))
+     :properties-tx (concat properties-tx (when pvalues-tx' pvalues-tx'))}))
 
 (defn- update-block-refs
   "Updates the attributes of a block ref as this is where a new page is defined. Also
@@ -675,7 +728,7 @@
 
 (defn- build-block-tx
   [db block* pre-blocks page-names-to-uuids {:keys [tag-classes import-state] :as options}]
-  ;; (prn ::block-in block)
+  ;; (prn ::block-in block*)
   (let [;; needs to come before update-block-refs to detect new property schemas
         {:keys [block properties-tx]}
         (handle-block-properties block* db page-names-to-uuids (:block/refs block*) options)

+ 34 - 14
deps/graph-parser/test/logseq/graph_parser/exporter_test.cljs

@@ -17,7 +17,8 @@
             [logseq.common.config :as common-config]
             [logseq.db :as ldb]
             [logseq.outliner.db-pipeline :as db-pipeline]
-            [logseq.db.test.helper :as db-test]))
+            [logseq.db.test.helper :as db-test]
+            [logseq.db.frontend.rules :as rules]))
 
 ;; Helpers
 ;; =======
@@ -40,6 +41,13 @@
               db)
          first)))
 
+(defn- find-block-by-property [db property property-value]
+  (->> (d/q '[:find [(pull ?b [*]) ...]
+              :in $ ?prop ?prop-value %
+              :where (property ?b ?prop ?prop-value)]
+            db property property-value (rules/extract-rules rules/db-query-dsl-rules [:property]))
+       first))
+
 (defn- find-page-by-name [db name]
   (->> name
        (d/q '[:find [(pull ?b [*]) ...]
@@ -124,13 +132,13 @@
               (if (boolean? v)
                 [k v]
                 [k
-                (if-let [built-in-type (get-in db-property/built-in-properties [k :schema :type])]
-                  (if (= :block/tags k)
-                    (mapv #(:db/ident (d/entity db (:db/id %))) v)
-                    (if (db-property-type/all-ref-property-types built-in-type)
-                      (db-property/ref->property-value-contents db v)
-                      v))
-                  (db-property/ref->property-value-contents db v))])))
+                 (if-let [built-in-type (get-in db-property/built-in-properties [k :schema :type])]
+                   (if (= :block/tags k)
+                     (mapv #(:db/ident (d/entity db (:db/id %))) v)
+                     (if (db-property-type/all-ref-property-types built-in-type)
+                       (db-property/ref->property-value-contents db v)
+                       v))
+                   (db-property/ref->property-value-contents db v))])))
        (into {})))
 
 ;; Tests
@@ -168,7 +176,7 @@
       (is (= 18 (count (d/q '[:find ?b :where [?b :block/tags :logseq.class/Journal]] @conn))))
 
       (is (= 4 (count (d/q '[:find ?b :where [?b :block/tags :logseq.class/Task]] @conn))))
-      (is (= 1 (count (d/q '[:find ?b :where [?b :block/tags :logseq.class/Query]] @conn))))
+      (is (= 3 (count (d/q '[:find ?b :where [?b :block/tags :logseq.class/Query]] @conn))))
 
       ;; Don't count pages like url.md that have properties but no content
       (is (= 8
@@ -286,12 +294,26 @@
       (is (= #{"gpt"}
              (:block/alias (readable-properties @conn (find-page-by-name @conn "chat-gpt")))))
 
+      ;; Queries
       (is (= {:logseq.property.table/sorting [{:id :user.property/prop-num, :asc? false}]
               :logseq.property.view/type "Table View"
               :logseq.property.table/ordered-columns [:block/title :user.property/prop-string :user.property/prop-num]
+              :logseq.property/query "(property :prop-string)"
               :block/tags [:logseq.class/Query]}
-             (readable-properties @conn (find-block-by-content @conn "{{query (property :prop-string)}}")))
-          "query block has correct query properties"))
+             (readable-properties @conn (find-block-by-property @conn :logseq.property/query "(property :prop-string)")))
+          "simple query block has correct query properties")
+      (is (= "For example, here's a query with title text:"
+             (:block/title (find-block-by-content @conn #"query with title text")))
+          "Text around a simple query block is set as a query's title")
+      (is (= {:logseq.property.view/type "List View"
+              :logseq.property/query "{:query (task todo doing)}"
+              :block/tags [:logseq.class/Query]
+              :logseq.property.table/ordered-columns [:block/title]}
+             (readable-properties @conn (find-block-by-content @conn #"tasks with")))
+          "Advanced query has correct query properties")
+      (is (= "tasks with todo and doing"
+             (:block/title (find-block-by-content @conn #"tasks with")))
+          "Advanced query has custom title migrated"))
 
     (testing "db attributes"
       (is (= true
@@ -359,9 +381,7 @@
     (testing "multiline blocks"
       (is (= "|markdown| table|\n|some|thing|" (:block/title (find-block-by-content @conn #"markdown.*table"))))
       (is (= "multiline block\na 2nd\nand a 3rd" (:block/title (find-block-by-content @conn #"multiline block"))))
-      (is (= "logbook block" (:block/title (find-block-by-content @conn #"logbook block"))))
-      (is (re-find #"(?s)^Text before\n#\+BEGIN_QUERY.*END_QUERY\nText after$"
-                   (:block/title (find-block-by-content @conn #":title \"tasks")))))
+      (is (= "logbook block" (:block/title (find-block-by-content @conn #"logbook block")))))
 
     (testing "block refs and path-refs"
       (let [block (find-block-by-content @conn "old todo block")]

+ 3 - 1
deps/graph-parser/test/resources/exporter-test-graph/journals/2024_08_07.md

@@ -1,3 +1,5 @@
+- For example, here's a query with title text:
+{{query (property type book)}}
 - test multilines in this page
 - |markdown| table|
   |some|thing|
@@ -18,4 +20,4 @@
   {:title "tasks with todo and doing"
   :query (task todo doing)}
   #+END_QUERY
-  Text after
+  Text after

+ 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
   []
@@ -790,6 +789,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

@@ -1415,9 +1415,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
@@ -2142,47 +2143,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/lang 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))))
@@ -2584,14 +2575,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)
@@ -3153,6 +3144,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)
@@ -3193,6 +3202,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)
@@ -3325,7 +3335,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?
@@ -3338,21 +3349,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/lang 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}})
@@ -3361,11 +3358,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 {

+ 7 - 1
src/main/frontend/components/views.cljs

@@ -225,8 +225,14 @@
   [column sized-columns]
   (let [id (:id column)
         size (get sized-columns id)]
-    (if (number? size)
+    (cond
+      (number? size)
       size
+
+      (= id :logseq.property/query)
+      400
+
+      :else
       (case id
         :select 32
         :add-property 160

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

+ 20 - 15
src/main/frontend/format/block.cljs

@@ -29,13 +29,13 @@ and handles unexpected failure."
                                              :db-graph-mode? (config/db-based-graph? repo)})]
         (if (config/db-based-graph? repo)
           (map (fn [block]
-                (cond-> (dissoc block :block/properties :block/macros :block/properties-order)
-                  (:block/properties block)
-                  (merge (update-keys (:block/properties block)
-                                      (fn [k]
-                                        (or ({:heading :logseq.property/heading} k)
-                                            (throw (ex-info (str "Don't know how to save graph-parser property " (pr-str k)) {}))))))))
-              blocks)
+                 (cond-> (dissoc block :block/properties :block/macros :block/properties-order)
+                   (:block/properties block)
+                   (merge (update-keys (:block/properties block)
+                                       (fn [k]
+                                         (or ({:heading :logseq.property/heading} k)
+                                             (throw (ex-info (str "Don't know how to save graph-parser property " (pr-str k)) {}))))))))
+               blocks)
           blocks))
       (catch :default e
         (log/error :exception e)
@@ -78,7 +78,12 @@ and handles unexpected failure."
           format (or format :markdown)
           parse-config (mldoc/get-default-config format)
           ast (format/to-edn title format parse-config)
-          blocks (extract-blocks ast title format {:parse-block block})
+          ;; Disable extraction for display-type blocks as there isn't a reason to have
+          ;; it enabled yet and can cause visible bugs when '#' is used
+          blocks (if (and (config/db-based-graph? (state/get-current-repo))
+                          (:logseq.property.node/display-type block))
+                   [block]
+                   (extract-blocks ast title format {:parse-block block}))
           new-block (first blocks)
           block (cond->
                  (merge block new-block)
@@ -126,13 +131,13 @@ and handles unexpected failure."
     (if (= typ "Paragraph")
       (let [indexed-paras (map-indexed vector paras)]
         [typ (->> (filter
-                            #(let [[index value] %]
-                               (not (and (> index 0)
-                                         (= value ["Break_Line"])
-                                         (contains? #{"Timestamp" "Macro"}
-                                                    (first (nth paras (dec index)))))))
-                            indexed-paras)
-                           (map #(last %)))])
+                   #(let [[index value] %]
+                      (not (and (> index 0)
+                                (= value ["Break_Line"])
+                                (contains? #{"Timestamp" "Macro"}
+                                           (first (nth paras (dec index)))))))
+                   indexed-paras)
+                  (map #(last %)))])
       ast)))
 
 (defn trim-break-lines!

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

@@ -3837,15 +3837,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

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