Skip to content

Commit

Permalink
Merge pull request logseq#11517 from logseq/feat/namespace
Browse files Browse the repository at this point in the history
feat: support namespace pages and tags
  • Loading branch information
tiensonqin authored Sep 20, 2024
2 parents f33ce44 + 7e26022 commit 582e3a9
Show file tree
Hide file tree
Showing 18 changed files with 349 additions and 172 deletions.
36 changes: 32 additions & 4 deletions deps/db/src/logseq/db/frontend/entity_plus.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,40 @@

(defn- get-block-title
[^Entity e k default-value]
(let [db (.-db e)]
(if (and (db-based-graph? db) (= "journal" (:block/type e)))
(let [db (.-db e)
db-based? (db-based-graph? db)]
(if (and db-based? (= "journal" (:block/type e)))
(get-journal-title db e)
(or
(get (.-kv e) k)
(let [result (lookup-entity e k default-value)]
(let [result (lookup-entity e k default-value)
parent-title? (:block.temp/parent-title? e)]
(or
(let [result' (if (string? result)
(db-content/special-id-ref->page-ref result
(:block/refs e))
result)
parent (when (= (:block/type e) "page")
(:logseq.property/parent e))]
(if (and db-based? parent parent-title?)
(str (:block/title parent) "/" result')
result'))
default-value))))))

(defn- get-block-title-parent-refs
"Add parent to block ref titles"
[^Entity e k default-value]
(let [db (.-db e)
db-based? (db-based-graph? db)]
(if (and db-based? (= "journal" (:block/type e)))
(get-journal-title db e)
(or
(get (.-kv e) k)
(let [result (lookup-entity e :block/title default-value)]
(or
(if (string? result)
(db-content/special-id-ref->page-ref result (:block/refs e))
(db-content/special-id-ref->page-ref result
(map (fn [e] (assoc e :block.temp/parent-title? true)) (:block/refs e)))
result)
default-value))))))

Expand Down Expand Up @@ -61,6 +86,9 @@
:block/title
(get-block-title e k default-value)

:block/title-with-refs-parent
(get-block-title-parent-refs e k default-value)

:block/_parent
(->> (lookup-entity e k default-value)
(remove (fn [e] (or (:logseq.property/created-from-property e)
Expand Down
3 changes: 2 additions & 1 deletion deps/db/src/logseq/db/sqlite/util.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@
(cond-> (merge block
{:block/type "class"
:block/format :markdown})
(not= (:db/ident block) :logseq.class/Root)
(and (not= (:db/ident block) :logseq.class/Root)
(nil? (:logseq.property/parent block)))
(assoc :logseq.property/parent :logseq.class/Root))))

(defn build-new-page
Expand Down
111 changes: 105 additions & 6 deletions deps/outliner/src/logseq/outliner/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
[logseq.outliner.batch-tx :include-macros true :as batch-tx]
[logseq.db.frontend.order :as db-order]
[logseq.outliner.pipeline :as outliner-pipeline]
[logseq.common.util.macro :as macro-util]))
[logseq.graph-parser.text :as text]
[logseq.common.util.macro :as macro-util]
[logseq.db.frontend.class :as db-class]))

(def ^:private block-map
(mu/optional-keys
Expand Down Expand Up @@ -246,10 +248,104 @@
(map (fn [tag]
[:db/retract (:db/id block) :block/tags (:db/id tag)])))))

(defn- get-page-by-parent-name
[db parent-title child-title]
(some->>
(d/q
'[:find [?b ...]
:in $ ?parent-name ?child-name
:where
[?b :logseq.property/parent ?p]
[?b :block/name ?child-name]
[?p :block/name ?parent-name]]
db
(common-util/page-name-sanity-lc parent-title)
(common-util/page-name-sanity-lc child-title))
first
(d/entity db)))

(defn ^:api split-namespace-pages
[db page-or-pages tags date-formatter & {:keys [*changed-uuids]}]
(let [pages (if (map? page-or-pages) [page-or-pages] page-or-pages)
tags-set (set (map :block/uuid tags))]
(->>
(mapcat
(fn [{:block/keys [title] :as page}]
(let [block-uuid (:block/uuid page)
block-type (if (contains? tags-set (:block/uuid page))
"class"
(:block/type page))]
(if (and (contains? #{"page" "class"} block-type) (text/namespace-page? title))
(let [class? (= block-type "class")
parts (->> (string/split title #"/")
(map string/trim)
(remove string/blank?))
pages (doall
(map-indexed
(fn [idx part]
(let [last-part? (= idx (dec (count parts)))
page (if (zero? idx)
(ldb/get-page db part)
(get-page-by-parent-name db (nth parts (dec idx)) part))
result (or page
(when last-part? (ldb/get-page db part))
(-> (gp-block/page-name->map part db true date-formatter
{:page-uuid (when last-part? block-uuid)})
(assoc :block/format :markdown)))]
(when (and last-part? (not= (:block/uuid result) block-uuid)
*changed-uuids)
(swap! *changed-uuids assoc block-uuid (:block/uuid result)))
result))
parts))]
(map-indexed
(fn [idx page]
(let [parent-eid (when (> idx 0)
(when-let [id (:block/uuid (nth pages (dec idx)))]
[:block/uuid id]))]
(if class?
(cond
(and (de/entity? page) (ldb/class? page))
page
(de/entity? page) ; page exists but not a class, avoid converting here becuase this could be troublesome.
nil
(zero? idx)
(db-class/build-new-class db page)
:else
(db-class/build-new-class db (assoc page :logseq.property/parent parent-eid)))
(if (or (de/entity? page) (zero? idx))
page
(assoc page :logseq.property/parent parent-eid)))))
pages))
[page])))
pages)
(remove nil?))))

(defn- build-page-parents
[db m date-formatter raw-title]
(let [refs (:block/refs m)
tags (:block/tags m)
*changed-uuids (atom {})
refs' (split-namespace-pages db refs tags date-formatter
{:*changed-uuids *changed-uuids})
tags' (map (fn [tag]
(or (first (filter (fn [ref] (= (:block/uuid ref) (:block/uuid tag))) refs')) tag))
tags)
raw-title' (if (seq @*changed-uuids)
(reduce
(fn [raw-content [old-id new-id]]
(string/replace raw-content (str old-id) (str new-id)))
raw-title
@*changed-uuids)
raw-title)]
(assoc m
:block/refs refs'
:block/title raw-title'
:block/tags tags')))

(extend-type Entity
otree/INode
(-save [this txs-state conn repo _date-formatter {:keys [retract-attributes? retract-attributes]
:or {retract-attributes? true}}]
(-save [this txs-state conn repo date-formatter {:keys [retract-attributes? retract-attributes]
:or {retract-attributes? true}}]
(assert (ds/outliner-txs-state? txs-state)
"db should be satisfied outliner-tx-state?")
(let [data this
Expand All @@ -261,7 +357,7 @@
db-based?
(dissoc :block/properties))
m* (-> data'
(dissoc :block/children :block/meta :block.temp/top? :block.temp/bottom? :block/unordered
(dissoc :block/children :block/meta :block.temp/top? :block.temp/bottom? :block/unordered :block.temp/parent-title?
:block.temp/ast-title :block.temp/ast-body :block/level :block.temp/fully-loaded?)
common-util/remove-nils
block-with-updated-at
Expand All @@ -283,14 +379,17 @@
(assoc m* :block/name page-name))
m*)
_ (when (and db-based?
;; page or object changed?
;; page or object changed?
(and (or (ldb/page? block-entity) (ldb/object? block-entity))
(:block/title m*)
(not= (:block/title m*) (:block/title block-entity))))
(outliner-validate/validate-block-title db (:block/title m*) block-entity))
m (cond-> m*
db-based?
(dissoc :block/pre-block? :block/priority :block/marker :block/properties-order))]
(dissoc :block/pre-block? :block/priority :block/marker :block/properties-order))
m (if db-based?
(build-page-parents db m date-formatter (:block/title m))
m)]
;; Ensure block UUID never changes
(let [e (d/entity db db-id)]
(when (and e block-uuid)
Expand Down
3 changes: 2 additions & 1 deletion scripts/src/logseq/tasks/dev/db_and_file_graphs.clj
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@
;; anything org mode
"org"
"pre-block"
"namespace"
;; TODO: rename split-namespace?
;; "namespace"
"db/get-page"
"/page-name-sanity-lc"]))
res (apply shell {:out :string :continue true}
Expand Down
104 changes: 56 additions & 48 deletions src/main/frontend/components/block.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -553,8 +553,10 @@
All page-names are sanitized except page-name-in-block"
[state
{:keys [contents-page? whiteboard-page? html-export? meta-click? show-unique-title? stop-click-event?]
:or {stop-click-event? true}
{:keys [contents-page? whiteboard-page? html-export? meta-click? show-unique-title? stop-click-event?
display-parent?]
:or {stop-click-event? true
display-parent? true}
:as config}
page-entity children label]
(let [*hover? (::hover? state)
Expand Down Expand Up @@ -610,55 +612,61 @@
(let [{:keys [content children]} (last child)
page-name (subs content 2 (- (count content) 2))]
(rum/with-key (page-reference html-export? page-name (assoc config :children children) nil) page-name))))
(cond
(and label
(string? label)
(not (string/blank? label))) ; alias
label
(let [page-component (cond
(and label
(string? label)
(not (string/blank? label))) ; alias
label

(coll? label)
(->elem :span (map-inline config label))
(coll? label)
(->elem :span (map-inline config label))

show-unique-title?
(title/block-unique-title page-entity)
show-unique-title?
(title/block-unique-title page-entity)

:else
(let [title (:block/title page-entity)
s (cond untitled?
(t :untitled)
:else
(let [title (:block/title page-entity)
s (cond untitled?
(t :untitled)

;; The page-name-in-block generated by the auto-complete is not page-name-sanitized
(pdf-utils/hls-file? page-name)
(pdf-utils/fix-local-asset-pagename page-name)

(not= (util/safe-page-name-sanity-lc title) page-name)
page-name ;; page-name-in-block might be overridden (legacy))

title
(util/trim-safe title)

:else
(util/trim-safe page-name))
_ (when-not page-entity (js/console.warn "page-inner's page-entity is nil, given page-name: " page-name))
s (cond
(not (string? s))
(do
(prn :debug :unknown-title-error :title s
:data (db/pull (:db/id page-entity)))
(db/transact! [{:db/id (:db/id page-entity)
:block/title "FIX unknown page"
:block/name "fix unknown page"}])
"Unknown title")
(re-find db-content/special-id-ref-pattern s)
(db-content/special-id-ref->page s (:block/refs page-entity))
:else
s)
s (if tag? (str "#" s) s)]
(if (ldb/page? page-entity)
s
(let [inline-list (gp-mldoc/inline->edn (first (string/split-lines s))
(mldoc/get-default-config (get page-entity :block/format :markdown)))]
(->elem :span (map-inline config inline-list)))))))]]))
(pdf-utils/hls-file? page-name)
(pdf-utils/fix-local-asset-pagename page-name)

(not= (util/safe-page-name-sanity-lc title) page-name)
page-name ;; page-name-in-block might be overridden (legacy))

title
(util/trim-safe title)

:else
(util/trim-safe page-name))
_ (when-not page-entity (js/console.warn "page-inner's page-entity is nil, given page-name: " page-name))
s (cond
(not (string? s))
(do
(prn :debug :unknown-title-error :title s
:data (db/pull (:db/id page-entity)))
(db/transact! [{:db/id (:db/id page-entity)
:block/title "FIX unknown page"
:block/name "fix unknown page"}])
"Unknown title")
(re-find db-content/special-id-ref-pattern s)
(db-content/special-id-ref->page s (:block/refs page-entity))
:else
s)
s (if tag? (str "#" s) s)]
(if (ldb/page? page-entity)
s
(let [inline-list (gp-mldoc/inline->edn (first (string/split-lines s))
(mldoc/get-default-config (get page-entity :block/format :markdown)))]
(->elem :span (map-inline config inline-list))))))]
(let [parent (:logseq.property/parent page-entity)]
(if (and display-parent? parent (not (ldb/class? page-entity)))
[:span
(str (:block/title parent) "/")
page-component]
page-component))))]]))

(rum/defc popup-preview-impl
[children {:keys [*timer *timer1 visible? set-visible! render *el-popup]}]
Expand Down Expand Up @@ -2250,7 +2258,7 @@
{:on-pointer-down (fn [e]
(util/stop e)
(state/clear-editor-action!)
(editor-handler/escape-editing false)
(editor-handler/escape-editing)
(reset! *show-datapicker? true)
(reset! commands/*current-command typ)
(state/set-timestamp-block! {:block block
Expand Down Expand Up @@ -2329,7 +2337,7 @@
util/caret-range)
{:block/keys [title format]} block
content (if (config/db-based-graph? (state/get-current-repo))
(or (:block/title block) title)
(:block/title-with-refs-parent block)
(->> title
(property-file/remove-built-in-properties-when-file-based
(state/get-current-repo) format)
Expand Down
3 changes: 2 additions & 1 deletion src/main/frontend/components/class.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
(when (seq children)
[:ul
(for [child (sort-by :block/title children)]
(let [title [:li.ml-2 (block/page-reference false (:block/title child) {:show-brackets? false} nil)]]
(let [title [:li.ml-2 (block/page-reference false (:block/title child) {:show-brackets? false
:display-parent? false} nil)]]
(if (seq (:logseq.property/_parent child))
(ui/foldable
title
Expand Down
Loading

0 comments on commit 582e3a9

Please sign in to comment.