mirror of
https://github.com/logseq/logseq.git
synced 2026-04-24 22:25:01 +00:00
Merge branch 'feat/db' into enhance/code-type-block
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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}}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
|
||||
&-filter {
|
||||
@apply flex flex-row flex-wrap items-center gap-1;
|
||||
svg {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.cp__select-main {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)))))
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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 {})))))))))
|
||||
|
||||
@@ -1036,6 +1036,9 @@
|
||||
|
||||
nil))
|
||||
|
||||
(defmethod handle :editor/run-query-command [_]
|
||||
(editor-handler/run-query-command!))
|
||||
|
||||
(defn run!
|
||||
[]
|
||||
(let [chan (state/get-events-chan)]
|
||||
|
||||
Reference in New Issue
Block a user