mirror of
https://github.com/logseq/logseq.git
synced 2026-04-24 22:25:01 +00:00
Merge branch 'master' into refactor/separate-og-and-db-version
This commit is contained in:
@@ -335,3 +335,71 @@
|
|||||||
result (ls-api-call! :editor.get_tag_objects "logseq.class/Task")]
|
result (ls-api-call! :editor.get_tag_objects "logseq.class/Task")]
|
||||||
(is (= (count result) 1))
|
(is (= (count result) 1))
|
||||||
(is (= "task 1" (get (first result) "title"))))))
|
(is (= "task 1" (get (first result) "title"))))))
|
||||||
|
|
||||||
|
(deftest create-and-get-tag-test
|
||||||
|
(testing "create and get tag with title or ident"
|
||||||
|
(let [title "book1"
|
||||||
|
title-ident (str :plugin.class._test_plugin/book1)
|
||||||
|
tag1 (ls-api-call! :editor.createTag title)
|
||||||
|
tag2 (ls-api-call! :editor.getTag title)
|
||||||
|
tag3 (ls-api-call! :editor.getTag title-ident)
|
||||||
|
tag4 (ls-api-call! :editor.getTag (get tag1 "uuid"))]
|
||||||
|
(is (= (get tag1 "ident") title-ident) "create tag with title from test as plugin")
|
||||||
|
(is (= (get tag2 "ident") title-ident) "get tag with title")
|
||||||
|
(is (= (get tag3 "title") title) "get tag with ident")
|
||||||
|
(is (= (get tag4 "title") title) "get tag with uuid")))
|
||||||
|
|
||||||
|
(testing "add and remove tag extends"
|
||||||
|
(let [tag1 (ls-api-call! :editor.createTag "tag1")
|
||||||
|
tag2 (ls-api-call! :editor.createTag "tag2")
|
||||||
|
tag3 (ls-api-call! :editor.createTag "tag3")
|
||||||
|
id1 (get tag1 "id")
|
||||||
|
id2 (get tag2 "id")
|
||||||
|
id3 (get tag3 "id")
|
||||||
|
_ (ls-api-call! :editor.addTagExtends id1 id2)
|
||||||
|
tag1 (ls-api-call! :editor.getTag id1)]
|
||||||
|
(is (= (get tag1 ":logseq.property.class/extends") [id2]) "tag1 extends tag2 with db id")
|
||||||
|
(let [_ (ls-api-call! :editor.addTagExtends id1 id3)
|
||||||
|
tag1 (ls-api-call! :editor.getTag id1)]
|
||||||
|
(is (= (get tag1 ":logseq.property.class/extends") [id2 id3]) "tag1 extends tag2,tag3 with db ids")))))
|
||||||
|
|
||||||
|
(deftest get-tags-by-name-test
|
||||||
|
(testing "get tags by exact name"
|
||||||
|
(let [tag-name "product"
|
||||||
|
tag1 (ls-api-call! :editor.createTag tag-name)
|
||||||
|
result (ls-api-call! :editor.getTagsByName tag-name)]
|
||||||
|
(is (= 1 (count result)) "should return exactly one tag")
|
||||||
|
(is (= (get tag1 "uuid") (get (first result) "uuid")) "should return the created tag")
|
||||||
|
(is (= (get tag1 "title") (get (first result) "title")) "tag title should match")))
|
||||||
|
|
||||||
|
(testing "get tags by name is case-insensitive"
|
||||||
|
(let [tag-name "TestTag123"
|
||||||
|
_ (ls-api-call! :editor.createTag tag-name)
|
||||||
|
result-lower (ls-api-call! :editor.getTagsByName "testtag123")
|
||||||
|
result-upper (ls-api-call! :editor.getTagsByName "TESTTAG123")
|
||||||
|
result-mixed (ls-api-call! :editor.getTagsByName "TeStTaG123")]
|
||||||
|
(is (= 1 (count result-lower)) "should find tag with lowercase search")
|
||||||
|
(is (= 1 (count result-upper)) "should find tag with uppercase search")
|
||||||
|
(is (= 1 (count result-mixed)) "should find tag with mixed case search")
|
||||||
|
(is (= (get (first result-lower) "uuid") (get (first result-upper) "uuid")) "all searches should return same tag")
|
||||||
|
(is (= (get (first result-lower) "uuid") (get (first result-mixed) "uuid")) "all searches should return same tag")))
|
||||||
|
|
||||||
|
(testing "get tags by name returns empty array for non-existent tag"
|
||||||
|
(let [result (ls-api-call! :editor.getTagsByName "NonExistentTag12345")]
|
||||||
|
(is (empty? result) "should return empty array for non-existent tag")))
|
||||||
|
|
||||||
|
(testing "get tags by name filters out non-tag pages"
|
||||||
|
(let [page-name "regular-page"
|
||||||
|
_ (page/new-page page-name)
|
||||||
|
result (ls-api-call! :editor.getTagsByName page-name)]
|
||||||
|
(is (empty? result) "should not return regular pages, only tags")))
|
||||||
|
|
||||||
|
(testing "get tags by name with multiple tags having similar names"
|
||||||
|
(let [tag1 (ls-api-call! :editor.createTag "category")
|
||||||
|
tag2 (ls-api-call! :editor.createTag "Category")
|
||||||
|
result (ls-api-call! :editor.getTagsByName "category")]
|
||||||
|
;; Due to case-insensitive name normalization, both tags should be the same
|
||||||
|
(is (>= (count result) 1) "should return at least one tag")
|
||||||
|
;; Verify the result contains valid tag structure
|
||||||
|
(is (string? (get (first result) "uuid")) "returned tag should have uuid")
|
||||||
|
(is (string? (get (first result) "title")) "returned tag should have title"))))
|
||||||
|
|||||||
44
deps/outliner/src/logseq/outliner/page.cljs
vendored
44
deps/outliner/src/logseq/outliner/page.cljs
vendored
@@ -247,6 +247,7 @@
|
|||||||
(map (fn [id] (d/entity db [:block/uuid id])) tags)
|
(map (fn [id] (d/entity db [:block/uuid id])) tags)
|
||||||
tags)
|
tags)
|
||||||
class? (or class? (some (fn [t] (= :logseq.class/Tag (:db/ident t))) tags))
|
class? (or class? (some (fn [t] (= :logseq.class/Tag (:db/ident t))) tags))
|
||||||
|
class-ident-namespace? (and class? class-ident-namespace (string? class-ident-namespace))
|
||||||
title (sanitize-title title*)
|
title (sanitize-title title*)
|
||||||
types (cond class?
|
types (cond class?
|
||||||
#{:logseq.class/Tag}
|
#{:logseq.class/Tag}
|
||||||
@@ -258,29 +259,38 @@
|
|||||||
(set (map :db/ident tags))
|
(set (map :db/ident tags))
|
||||||
:else
|
:else
|
||||||
#{:logseq.class/Page})
|
#{:logseq.class/Page})
|
||||||
existing-page-id (first (ldb/page-exists? db title types))
|
existing-names-page (ldb/page-exists? db title types)
|
||||||
|
existing-page-id (some->> existing-names-page
|
||||||
|
(filter #(try (when-let [e (and class-ident-namespace? (d/entity db %))]
|
||||||
|
(let [ns' (namespace (:db/ident e))]
|
||||||
|
(= (str ns') class-ident-namespace)))
|
||||||
|
(catch :default _ false)))
|
||||||
|
(first))
|
||||||
existing-page (some->> existing-page-id (d/entity db))]
|
existing-page (some->> existing-page-id (d/entity db))]
|
||||||
(if (and existing-page (not (:block/parent existing-page)))
|
(if (and existing-page (not (:block/parent existing-page)))
|
||||||
(let [tx-meta {:persist-op? persist-op?
|
(let [tx-meta {:persist-op? persist-op?
|
||||||
:outliner-op :save-block}]
|
:outliner-op :save-block}]
|
||||||
(when (and class?
|
(if (and class?
|
||||||
(not (ldb/class? existing-page))
|
(not (ldb/class? existing-page))
|
||||||
(ldb/internal-page? existing-page))
|
(ldb/internal-page? existing-page))
|
||||||
;; Convert existing page to class
|
;; Convert existing page to class
|
||||||
(let [tx-data [(merge (db-class/build-new-class db
|
(let [tx-data [(merge (db-class/build-new-class db
|
||||||
(select-keys existing-page [:block/title :block/uuid :block/created-at])
|
(select-keys existing-page [:block/title :block/uuid :block/created-at])
|
||||||
(when (and class? class-ident-namespace (string? class-ident-namespace))
|
(when class-ident-namespace?
|
||||||
{:ident-namespace class-ident-namespace}))
|
{:ident-namespace class-ident-namespace}))
|
||||||
(select-keys existing-page [:db/ident]))
|
(select-keys existing-page [:db/ident]))
|
||||||
[:db/retract [:block/uuid (:block/uuid existing-page)] :block/tags :logseq.class/Page]]]
|
[:db/retract [:block/uuid (:block/uuid existing-page)] :block/tags :logseq.class/Page]]]
|
||||||
{:tx-meta tx-meta
|
{:tx-meta tx-meta
|
||||||
:tx-data tx-data
|
:tx-data tx-data
|
||||||
:page-uuid (:block/uuid existing-page)
|
:page-uuid (:block/uuid existing-page)
|
||||||
:title (:block/title existing-page)})))
|
:title (:block/title existing-page)})
|
||||||
(let [page (gp-block/page-name->map title db true date-formatter
|
;; Just return existing page info
|
||||||
{:class? class?
|
{:page-uuid (:block/uuid existing-page)
|
||||||
:page-uuid (when (uuid? uuid') uuid')
|
:title (:block/title existing-page)}))
|
||||||
:skip-existing-page-check? true})
|
(let [page (gp-block/page-name->map title db true date-formatter
|
||||||
|
{:class? class?
|
||||||
|
:page-uuid (when (uuid? uuid') uuid')
|
||||||
|
:skip-existing-page-check? true})
|
||||||
[page parents'] (if (and (text/namespace-page? title) split-namespace?)
|
[page parents'] (if (and (text/namespace-page? title) split-namespace?)
|
||||||
(let [pages (split-namespace-pages db page date-formatter class?)]
|
(let [pages (split-namespace-pages db page date-formatter class?)]
|
||||||
[(last pages) (butlast pages)])
|
[(last pages) (butlast pages)])
|
||||||
@@ -296,11 +306,11 @@
|
|||||||
(outliner-validate/validate-page-title-characters (str (:block/title parent)) {:node parent})))
|
(outliner-validate/validate-page-title-characters (str (:block/title parent)) {:node parent})))
|
||||||
|
|
||||||
(let [page-uuid (:block/uuid page)
|
(let [page-uuid (:block/uuid page)
|
||||||
page-txs (build-page-tx db properties page (select-keys options [:whiteboard? :class? :tags :class-ident-namespace]))
|
page-txs (build-page-tx db properties page (select-keys options [:whiteboard? :class? :tags :class-ident-namespace]))
|
||||||
txs (concat
|
txs (concat
|
||||||
;; transact doesn't support entities
|
;; transact doesn't support entities
|
||||||
(remove de/entity? parents')
|
(remove de/entity? parents')
|
||||||
page-txs)
|
page-txs)
|
||||||
tx-meta (cond-> {:persist-op? persist-op?
|
tx-meta (cond-> {:persist-op? persist-op?
|
||||||
:outliner-op :create-page}
|
:outliner-op :create-page}
|
||||||
today-journal?
|
today-journal?
|
||||||
@@ -315,5 +325,5 @@
|
|||||||
[conn title opts]
|
[conn title opts]
|
||||||
(let [{:keys [tx-meta tx-data title' page-uuid]} (create @conn title opts)]
|
(let [{:keys [tx-meta tx-data title' page-uuid]} (create @conn title opts)]
|
||||||
(when (seq tx-data)
|
(when (seq tx-data)
|
||||||
(ldb/transact! conn tx-data tx-meta)
|
(ldb/transact! conn tx-data tx-meta))
|
||||||
[title' page-uuid])))
|
[title' page-uuid]))
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
"build": "tsc && rm dist/*.js && npm run build:user",
|
"build": "tsc && rm dist/*.js && npm run build:user",
|
||||||
"lint": "prettier --check \"src/**/*.{ts, js}\"",
|
"lint": "prettier --check \"src/**/*.{ts, js}\"",
|
||||||
"fix": "prettier --write \"src/**/*.{ts, js}\"",
|
"fix": "prettier --write \"src/**/*.{ts, js}\"",
|
||||||
"build:docs": "typedoc src/LSPlugin.user.ts",
|
"build:docs": "typedoc --plugin typedoc-plugin-lsp-docs src/LSPlugin.user.ts",
|
||||||
"build:docs:json": "typedoc --plugin typedoc-plugin-lsp-docs src/LSPlugin.user.ts && typedoc --json docs/out.json ./src/LSPlugin.user.ts"
|
"build:docs:json": "typedoc --json docs/out.json ./src/LSPlugin.user.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csstype": "3.1.0",
|
"csstype": "3.1.0",
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
"terser-webpack-plugin": "^5.3.6",
|
"terser-webpack-plugin": "^5.3.6",
|
||||||
"ts-loader": "9.3.0",
|
"ts-loader": "9.3.0",
|
||||||
"typedoc": "0.28.15",
|
"typedoc": "0.28.15",
|
||||||
"typedoc-plugin-lsp-docs": "^0.0.1",
|
"typedoc-plugin-lsp-docs": "^0.0.2",
|
||||||
"typescript": "5.9.3",
|
"typescript": "5.9.3",
|
||||||
"webpack": "5.94.0",
|
"webpack": "5.94.0",
|
||||||
"webpack-bundle-analyzer": "4.5.0",
|
"webpack-bundle-analyzer": "4.5.0",
|
||||||
|
|||||||
@@ -697,15 +697,13 @@ export interface IEditorProxy extends Record<string, any> {
|
|||||||
* @param opts
|
* @param opts
|
||||||
*/
|
*/
|
||||||
insertBlock: (
|
insertBlock: (
|
||||||
srcBlock: BlockIdentity,
|
srcBlock: BlockIdentity | EntityID,
|
||||||
content: string,
|
content: string,
|
||||||
opts?: Partial<{
|
opts?: Partial<{
|
||||||
before: boolean
|
before: boolean
|
||||||
sibling: boolean
|
sibling: boolean
|
||||||
start: boolean
|
start: boolean
|
||||||
end: boolean
|
end: boolean
|
||||||
isPageBlock: boolean
|
|
||||||
focus: boolean
|
|
||||||
customUUID: string
|
customUUID: string
|
||||||
properties: {}
|
properties: {}
|
||||||
}>
|
}>
|
||||||
@@ -723,30 +721,20 @@ export interface IEditorProxy extends Record<string, any> {
|
|||||||
) => Promise<Array<BlockEntity> | null>
|
) => Promise<Array<BlockEntity> | null>
|
||||||
|
|
||||||
updateBlock: (
|
updateBlock: (
|
||||||
srcBlock: BlockIdentity,
|
srcBlock: BlockIdentity | EntityID,
|
||||||
content: string,
|
content: string,
|
||||||
opts?: Partial<{ properties: {} }>
|
opts?: Partial<{ properties: {} }>
|
||||||
) => Promise<void>
|
) => Promise<void>
|
||||||
|
|
||||||
removeBlock: (srcBlock: BlockIdentity) => Promise<void>
|
removeBlock: (srcBlock: BlockIdentity | EntityID) => Promise<void>
|
||||||
|
|
||||||
getBlock: (
|
getBlock: (
|
||||||
srcBlock: BlockIdentity | EntityID,
|
srcBlock: BlockIdentity | EntityID,
|
||||||
opts?: Partial<{ includeChildren: boolean }>
|
opts?: Partial<{ includeChildren: boolean }>
|
||||||
) => Promise<BlockEntity | null>
|
) => Promise<BlockEntity | null>
|
||||||
|
|
||||||
/**
|
|
||||||
* @example
|
|
||||||
*
|
|
||||||
* ```ts
|
|
||||||
* logseq.Editor.setBlockCollapsed('uuid', true)
|
|
||||||
* logseq.Editor.setBlockCollapsed('uuid', 'toggle')
|
|
||||||
* ```
|
|
||||||
* @param uuid
|
|
||||||
* @param opts
|
|
||||||
*/
|
|
||||||
setBlockCollapsed: (
|
setBlockCollapsed: (
|
||||||
uuid: BlockUUID,
|
srcBlock: BlockIdentity | EntityID,
|
||||||
opts: { flag: boolean | 'toggle' } | boolean | 'toggle'
|
opts: { flag: boolean | 'toggle' } | boolean | 'toggle'
|
||||||
) => Promise<void>
|
) => Promise<void>
|
||||||
|
|
||||||
@@ -780,7 +768,8 @@ export interface IEditorProxy extends Record<string, any> {
|
|||||||
getAllProperties: () => Promise<PageEntity[] | null>
|
getAllProperties: () => Promise<PageEntity[] | null>
|
||||||
getTagObjects: (nameOrIdent: string) => Promise<BlockEntity[] | null>
|
getTagObjects: (nameOrIdent: string) => Promise<BlockEntity[] | null>
|
||||||
createTag: (tagName: string, opts?: Partial<{ uuid: string }>) => Promise<PageEntity | null>
|
createTag: (tagName: string, opts?: Partial<{ uuid: string }>) => Promise<PageEntity | null>
|
||||||
getTag: (nameOrIdent: string) => Promise<PageEntity | null>
|
getTag: (nameOrIdent: string | EntityID) => Promise<PageEntity | null>
|
||||||
|
getTagsByName: (tagName: string) => Promise<Array<PageEntity> | null>
|
||||||
addTagProperty: (tagId: BlockIdentity, propertyIdOrName: BlockIdentity) => Promise<void>
|
addTagProperty: (tagId: BlockIdentity, propertyIdOrName: BlockIdentity) => Promise<void>
|
||||||
removeTagProperty: (tagId: BlockIdentity, propertyIdOrName: BlockIdentity) => Promise<void>
|
removeTagProperty: (tagId: BlockIdentity, propertyIdOrName: BlockIdentity) => Promise<void>
|
||||||
addTagExtends: (tagId: BlockIdentity, parentTagIdOrName: BlockIdentity) => Promise<void>
|
addTagExtends: (tagId: BlockIdentity, parentTagIdOrName: BlockIdentity) => Promise<void>
|
||||||
@@ -806,11 +795,11 @@ export interface IEditorProxy extends Record<string, any> {
|
|||||||
) => Promise<BlockEntity | null>
|
) => Promise<BlockEntity | null>
|
||||||
|
|
||||||
getPreviousSiblingBlock: (
|
getPreviousSiblingBlock: (
|
||||||
srcBlock: BlockIdentity
|
srcBlock: BlockIdentity | EntityID
|
||||||
) => Promise<BlockEntity | null>
|
) => Promise<BlockEntity | null>
|
||||||
|
|
||||||
getNextSiblingBlock: (
|
getNextSiblingBlock: (
|
||||||
srcBlock: BlockIdentity
|
srcBlock: BlockIdentity | EntityID
|
||||||
) => Promise<BlockEntity | null>
|
) => Promise<BlockEntity | null>
|
||||||
|
|
||||||
moveBlock: (
|
moveBlock: (
|
||||||
@@ -843,17 +832,15 @@ export interface IEditorProxy extends Record<string, any> {
|
|||||||
|
|
||||||
// block property related APIs
|
// block property related APIs
|
||||||
upsertBlockProperty: (
|
upsertBlockProperty: (
|
||||||
block: BlockIdentity,
|
block: BlockIdentity | EntityID,
|
||||||
key: string,
|
key: string,
|
||||||
value: any
|
value: any
|
||||||
) => Promise<void>
|
) => Promise<void>
|
||||||
|
|
||||||
removeBlockProperty: (block: BlockIdentity, key: string) => Promise<void>
|
removeBlockProperty: (block: BlockIdentity | EntityID, key: string) => Promise<void>
|
||||||
|
getBlockProperty: (block: BlockIdentity | EntityID, key: string) => Promise<BlockEntity | null>
|
||||||
getBlockProperty: (block: BlockIdentity, key: string) => Promise<BlockEntity | unknown>
|
getBlockProperties: (block: BlockIdentity | EntityID) => Promise<Record<string, any> | null>
|
||||||
|
getPageProperties: (page: PageIdentity | EntityID) => Promise<Record<string, any> | null>
|
||||||
getBlockProperties: (block: BlockIdentity) => Promise<Record<string, any> | null>
|
|
||||||
getPageProperties: (page: PageIdentity) => Promise<Record<string, any> | null>
|
|
||||||
|
|
||||||
scrollToBlockInPage: (
|
scrollToBlockInPage: (
|
||||||
pageName: BlockPageName,
|
pageName: BlockPageName,
|
||||||
@@ -862,6 +849,7 @@ export interface IEditorProxy extends Record<string, any> {
|
|||||||
) => void
|
) => void
|
||||||
|
|
||||||
openInRightSidebar: (id: BlockUUID | EntityID) => void
|
openInRightSidebar: (id: BlockUUID | EntityID) => void
|
||||||
|
openPDFViewer: (assetBlockIdOrFileUrl: string | EntityID) => Promise<void>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @example https://github.com/logseq/logseq-plugin-samples/tree/master/logseq-a-translator
|
* @example https://github.com/logseq/logseq-plugin-samples/tree/master/logseq-a-translator
|
||||||
|
|||||||
@@ -1279,6 +1279,13 @@
|
|||||||
(fn []
|
(fn []
|
||||||
#(set-property-value! @*value))
|
#(set-property-value! @*value))
|
||||||
[])
|
[])
|
||||||
|
|
||||||
|
(hooks/use-effect!
|
||||||
|
(fn []
|
||||||
|
(set-value! number-value)
|
||||||
|
#())
|
||||||
|
[number-value])
|
||||||
|
|
||||||
[:div.ls-number.flex.flex-1.jtrigger
|
[:div.ls-number.flex.flex-1.jtrigger
|
||||||
{:ref *ref
|
{:ref *ref
|
||||||
:on-click #(do
|
:on-click #(do
|
||||||
@@ -1291,6 +1298,7 @@
|
|||||||
:class (str "ls-number-input h-6 px-0 py-0 border-none bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0 text-base"
|
:class (str "ls-number-input h-6 px-0 py-0 border-none bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0 text-base"
|
||||||
(when table-view? " text-sm"))
|
(when table-view? " text-sm"))
|
||||||
:value value
|
:value value
|
||||||
|
:type "number"
|
||||||
:on-change (fn [e]
|
:on-change (fn [e]
|
||||||
(set-value! (util/evalue e))
|
(set-value! (util/evalue e))
|
||||||
(reset! *value (util/evalue e)))
|
(reset! *value (util/evalue e)))
|
||||||
|
|||||||
@@ -3327,10 +3327,11 @@
|
|||||||
|
|
||||||
(defn toggle-open-block-children! [block-id]
|
(defn toggle-open-block-children! [block-id]
|
||||||
(p/let [blocks (<all-blocks-with-level {:incremental? false
|
(p/let [blocks (<all-blocks-with-level {:incremental? false
|
||||||
:collapse? true
|
:expanded? true
|
||||||
:root-block block-id})
|
:root-block block-id})
|
||||||
all-expanded? (empty? blocks)]
|
children-blocks (remove #(= block-id (:block/uuid %)) blocks)
|
||||||
(if all-expanded?
|
any-expanded? (seq (filter (complement util/collapsed?) children-blocks))]
|
||||||
|
(if any-expanded?
|
||||||
(collapse-all! block-id {:collapse-self? false})
|
(collapse-all! block-id {:collapse-self? false})
|
||||||
(expand-all! block-id))))
|
(expand-all! block-id))))
|
||||||
|
|
||||||
|
|||||||
@@ -132,6 +132,7 @@
|
|||||||
(def ^:export set_block_collapsed api-editor/set_block_collapsed)
|
(def ^:export set_block_collapsed api-editor/set_block_collapsed)
|
||||||
(def ^:export update_block api-editor/update_block)
|
(def ^:export update_block api-editor/update_block)
|
||||||
(def ^:export upsert_block_property api-editor/upsert_block_property)
|
(def ^:export upsert_block_property api-editor/upsert_block_property)
|
||||||
|
(def ^:export open_pdf_viewer api-editor/open_pdf_viewer)
|
||||||
|
|
||||||
;; ui
|
;; ui
|
||||||
(def ^:export show_msg sdk-ui/-show_msg)
|
(def ^:export show_msg sdk-ui/-show_msg)
|
||||||
@@ -200,6 +201,7 @@
|
|||||||
(def ^:export get_tag_objects db-based-api/get-tag-objects)
|
(def ^:export get_tag_objects db-based-api/get-tag-objects)
|
||||||
(def ^:export create_tag db-based-api/create-tag)
|
(def ^:export create_tag db-based-api/create-tag)
|
||||||
(def ^:export get_tag db-based-api/get-tag)
|
(def ^:export get_tag db-based-api/get-tag)
|
||||||
|
(def ^:export get_tags_by_name db-based-api/get-tags-by-name)
|
||||||
(def ^:export add_tag_extends db-based-api/add-tag-extends)
|
(def ^:export add_tag_extends db-based-api/add-tag-extends)
|
||||||
(def ^:export remove_tag_extends db-based-api/remove-tag-extends)
|
(def ^:export remove_tag_extends db-based-api/remove-tag-extends)
|
||||||
(def ^:export add_block_tag db-based-api/add-block-tag)
|
(def ^:export add_block_tag db-based-api/add-block-tag)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
[datascript.core :as d]
|
[datascript.core :as d]
|
||||||
[frontend.db :as db]
|
[frontend.db :as db]
|
||||||
[frontend.db.async :as db-async]
|
[frontend.db.async :as db-async]
|
||||||
|
[frontend.db.conn :as db-conn]
|
||||||
[frontend.db.model :as db-model]
|
[frontend.db.model :as db-model]
|
||||||
[frontend.handler.common.page :as page-common-handler]
|
[frontend.handler.common.page :as page-common-handler]
|
||||||
[frontend.handler.db-based.page :as db-page-handler]
|
[frontend.handler.db-based.page :as db-page-handler]
|
||||||
@@ -21,6 +22,7 @@
|
|||||||
[logseq.api.block :as api-block]
|
[logseq.api.block :as api-block]
|
||||||
[logseq.db :as ldb]
|
[logseq.db :as ldb]
|
||||||
[logseq.db.common.entity-util :as common-entity-util]
|
[logseq.db.common.entity-util :as common-entity-util]
|
||||||
|
[logseq.db.frontend.entity-util :as entity-util]
|
||||||
[logseq.graph-parser.text :as text]
|
[logseq.graph-parser.text :as text]
|
||||||
[logseq.outliner.core :as outliner-core]
|
[logseq.outliner.core :as outliner-core]
|
||||||
[logseq.sdk.core]
|
[logseq.sdk.core]
|
||||||
@@ -219,9 +221,12 @@
|
|||||||
(when (text/namespace-page? title)
|
(when (text/namespace-page? title)
|
||||||
(throw (ex-info "Tag title shouldn't include forward slash" {:title title})))
|
(throw (ex-info "Tag title shouldn't include forward slash" {:title title})))
|
||||||
(let [opts (bean/->clj opts)
|
(let [opts (bean/->clj opts)
|
||||||
|
custom-ident-namespace (:customIdentNamespace opts)
|
||||||
|
class-ident-namespace (or (some-> custom-ident-namespace (api-block/sanitize-user-property-name))
|
||||||
|
(api-block/resolve-class-prefix-for-db this))
|
||||||
opts' (assoc opts
|
opts' (assoc opts
|
||||||
:redirect? false
|
:redirect? false
|
||||||
:class-ident-namespace (api-block/resolve-class-prefix-for-db this))]
|
:class-ident-namespace class-ident-namespace)]
|
||||||
(p/let [tag (db-page-handler/<create-class! title opts')]
|
(p/let [tag (db-page-handler/<create-class! title opts')]
|
||||||
(sdk-utils/result->js tag)))))
|
(sdk-utils/result->js tag)))))
|
||||||
|
|
||||||
@@ -254,21 +259,28 @@
|
|||||||
(:db/id extend))))
|
(:db/id extend))))
|
||||||
|
|
||||||
(defn get-tag [class-uuid-or-ident-or-title]
|
(defn get-tag [class-uuid-or-ident-or-title]
|
||||||
(this-as
|
(this-as this
|
||||||
this
|
(let [eid (if (number? class-uuid-or-ident-or-title)
|
||||||
(let [title-or-ident (-> (if-not (string? class-uuid-or-ident-or-title)
|
class-uuid-or-ident-or-title
|
||||||
(str class-uuid-or-ident-or-title)
|
(let [title-or-ident (-> (if-not (string? class-uuid-or-ident-or-title)
|
||||||
class-uuid-or-ident-or-title)
|
(str class-uuid-or-ident-or-title)
|
||||||
(string/replace #"^:+" ""))
|
class-uuid-or-ident-or-title)
|
||||||
eid (if (text/namespace-page? title-or-ident)
|
(string/replace #"^:+" ""))]
|
||||||
(keyword title-or-ident)
|
(if (text/namespace-page? title-or-ident)
|
||||||
(if (util/uuid-string? title-or-ident)
|
(keyword title-or-ident)
|
||||||
(when-let [id (sdk-utils/uuid-or-throw-error title-or-ident)]
|
(if (util/uuid-string? title-or-ident)
|
||||||
[:block/uuid id])
|
(when-let [id (sdk-utils/uuid-or-throw-error title-or-ident)]
|
||||||
(keyword (api-block/resolve-class-prefix-for-db this) title-or-ident)))
|
[:block/uuid id])
|
||||||
tag (db/entity eid)]
|
(keyword (api-block/resolve-class-prefix-for-db this) title-or-ident)))))
|
||||||
(when (ldb/class? tag)
|
tag (db/entity eid)]
|
||||||
(sdk-utils/result->js tag)))))
|
(when (ldb/class? tag)
|
||||||
|
(sdk-utils/result->js tag)))))
|
||||||
|
|
||||||
|
(defn get-tags-by-name [name]
|
||||||
|
(when-let [tags (some->> (entity-util/get-pages-by-name (db-conn/get-db) name)
|
||||||
|
(map #(some-> % (first) (db/entity)))
|
||||||
|
(filter ldb/class?))]
|
||||||
|
(sdk-utils/result->js tags)))
|
||||||
|
|
||||||
(defn tag-add-property [tag-id property-id-or-name]
|
(defn tag-add-property [tag-id property-id-or-name]
|
||||||
(p/let [tag (db/get-case-page tag-id)
|
(p/let [tag (db/get-case-page tag-id)
|
||||||
|
|||||||
@@ -2,13 +2,14 @@
|
|||||||
"Editor related APIs"
|
"Editor related APIs"
|
||||||
(:require [cljs-bean.core :as bean]
|
(:require [cljs-bean.core :as bean]
|
||||||
[cljs.reader]
|
[cljs.reader]
|
||||||
[clojure.string :as string]
|
|
||||||
[frontend.commands :as commands]
|
[frontend.commands :as commands]
|
||||||
[frontend.date :as date]
|
[frontend.date :as date]
|
||||||
[frontend.db :as db]
|
[frontend.db :as db]
|
||||||
[frontend.db.async :as db-async]
|
[frontend.db.async :as db-async]
|
||||||
[frontend.db.model :as db-model]
|
[frontend.db.model :as db-model]
|
||||||
[frontend.db.utils :as db-utils]
|
[frontend.db.utils :as db-utils]
|
||||||
|
[frontend.extensions.pdf.assets :as pdf-assets]
|
||||||
|
[frontend.handler.assets :as assets-handler]
|
||||||
[frontend.handler.code :as code-handler]
|
[frontend.handler.code :as code-handler]
|
||||||
[frontend.handler.dnd :as editor-dnd-handler]
|
[frontend.handler.dnd :as editor-dnd-handler]
|
||||||
[frontend.handler.editor :as editor-handler]
|
[frontend.handler.editor :as editor-handler]
|
||||||
@@ -24,6 +25,7 @@
|
|||||||
[goog.dom :as gdom]
|
[goog.dom :as gdom]
|
||||||
[logseq.api.block :as api-block]
|
[logseq.api.block :as api-block]
|
||||||
[logseq.api.db-based :as db-based-api]
|
[logseq.api.db-based :as db-based-api]
|
||||||
|
[logseq.common.path :as path]
|
||||||
[logseq.common.util.date-time :as date-time-util]
|
[logseq.common.util.date-time :as date-time-util]
|
||||||
[logseq.db :as ldb]
|
[logseq.db :as ldb]
|
||||||
[logseq.sdk.core]
|
[logseq.sdk.core]
|
||||||
@@ -185,26 +187,13 @@
|
|||||||
block))
|
block))
|
||||||
|
|
||||||
(defn insert_block
|
(defn insert_block
|
||||||
[block-uuid-or-page-name content ^js opts]
|
[id content ^js opts]
|
||||||
(this-as this
|
(this-as this
|
||||||
(when (string/blank? block-uuid-or-page-name)
|
(p/let [block (<get-block id)]
|
||||||
(throw (js/Error. "Page title or block UUID shouldn't be empty.")))
|
(when-let [block-uuid (:block/uuid block)]
|
||||||
|
(p/let [{:keys [before start end sibling customUUID properties autoOrderedList schema]} (bean/->clj opts)
|
||||||
(p/let [block? (util/uuid-string? (str block-uuid-or-page-name))
|
|
||||||
block (<get-block (str block-uuid-or-page-name))]
|
|
||||||
(if (and block? (not block))
|
|
||||||
(throw (js/Error. "Block not exists"))
|
|
||||||
(p/let [{:keys [before start end sibling focus customUUID properties autoOrderedList schema]} (bean/->clj opts)
|
|
||||||
[page-name block-uuid] (if (util/uuid-string? block-uuid-or-page-name)
|
|
||||||
[nil (uuid block-uuid-or-page-name)]
|
|
||||||
[block-uuid-or-page-name nil])
|
|
||||||
page-name (when page-name (util/page-name-sanity-lc page-name))
|
|
||||||
_ (when (and page-name
|
|
||||||
(nil? (ldb/get-page (db/get-db) page-name)))
|
|
||||||
(page-handler/<create! block-uuid-or-page-name {}))
|
|
||||||
custom-uuid (or customUUID (:id properties))
|
custom-uuid (or customUUID (:id properties))
|
||||||
custom-uuid (when custom-uuid (sdk-utils/uuid-or-throw-error custom-uuid))
|
custom-uuid (when custom-uuid (sdk-utils/uuid-or-throw-error custom-uuid))
|
||||||
edit-block? (if (nil? focus) true focus)
|
|
||||||
_ (when (and custom-uuid (db-model/query-block-by-uuid custom-uuid))
|
_ (when (and custom-uuid (db-model/query-block-by-uuid custom-uuid))
|
||||||
(throw (js/Error.
|
(throw (js/Error.
|
||||||
(util/format "Custom block UUID already exists (%s)." custom-uuid))))
|
(util/format "Custom block UUID already exists (%s)." custom-uuid))))
|
||||||
@@ -227,8 +216,7 @@
|
|||||||
:before? before?
|
:before? before?
|
||||||
:start? start
|
:start? start
|
||||||
:end? end
|
:end? end
|
||||||
:edit-block? edit-block?
|
:edit-block? false
|
||||||
:page page-name
|
|
||||||
:custom-uuid custom-uuid
|
:custom-uuid custom-uuid
|
||||||
:ordered-list? (if (boolean? autoOrderedList) autoOrderedList false)}]
|
:ordered-list? (if (boolean? autoOrderedList) autoOrderedList false)}]
|
||||||
(db-based-api/insert-block this content properties schema opts'))))))
|
(db-based-api/insert-block this content properties schema opts'))))))
|
||||||
@@ -245,17 +233,18 @@
|
|||||||
(db-based-api/insert-batch-blocks this block blocks' opts))))))))
|
(db-based-api/insert-batch-blocks this block blocks' opts))))))))
|
||||||
|
|
||||||
(def remove_block
|
(def remove_block
|
||||||
(fn [block-uuid ^js _opts]
|
(fn [id ^js _opts]
|
||||||
(p/let [repo (state/get-current-repo)
|
(p/let [repo (state/get-current-repo)
|
||||||
_ (<get-block block-uuid {:children? false})]
|
block (<get-block id {:children? false})]
|
||||||
(editor-handler/delete-block-aux!
|
(when-let [block-uuid (:block/uuid block)]
|
||||||
{:block/uuid (sdk-utils/uuid-or-throw-error block-uuid) :repo repo}))))
|
(editor-handler/delete-block-aux!
|
||||||
|
{:block/uuid block-uuid :repo repo})))))
|
||||||
|
|
||||||
(def update_block
|
(def update_block
|
||||||
(fn [block-uuid content ^js opts]
|
(fn [id content ^js opts]
|
||||||
(this-as
|
(this-as
|
||||||
this
|
this
|
||||||
(p/let [block (<get-block block-uuid {:children? false})
|
(p/let [block (<get-block id {:children? false})
|
||||||
opts' (bean/->clj opts)]
|
opts' (bean/->clj opts)]
|
||||||
(when block
|
(when block
|
||||||
(db-based-api/update-block this block content opts'))))))
|
(db-based-api/update-block this block content opts'))))))
|
||||||
@@ -295,9 +284,8 @@
|
|||||||
(get_block (:block/uuid block) opts))))
|
(get_block (:block/uuid block) opts))))
|
||||||
|
|
||||||
(def get_previous_sibling_block
|
(def get_previous_sibling_block
|
||||||
(fn [block-uuid ^js opts]
|
(fn [id ^js opts]
|
||||||
(p/let [id (sdk-utils/uuid-or-throw-error block-uuid)
|
(p/let [block (<get-block id)
|
||||||
block (<get-block id)
|
|
||||||
;; Load all children blocks
|
;; Load all children blocks
|
||||||
_ (api-block/<sync-children-blocks! block)]
|
_ (api-block/<sync-children-blocks! block)]
|
||||||
(when block
|
(when block
|
||||||
@@ -305,9 +293,8 @@
|
|||||||
(get_block (:block/uuid sibling) opts))))))
|
(get_block (:block/uuid sibling) opts))))))
|
||||||
|
|
||||||
(def get_next_sibling_block
|
(def get_next_sibling_block
|
||||||
(fn [block-uuid ^js opts]
|
(fn [id ^js opts]
|
||||||
(p/let [id (sdk-utils/uuid-or-throw-error block-uuid)
|
(p/let [block (<get-block id)
|
||||||
block (<get-block id)
|
|
||||||
;; Load all children blocks
|
;; Load all children blocks
|
||||||
_ (api-block/<sync-children-blocks! block)]
|
_ (api-block/<sync-children-blocks! block)]
|
||||||
(when block
|
(when block
|
||||||
@@ -315,11 +302,11 @@
|
|||||||
(get_block (:block/uuid sibling) opts))))))
|
(get_block (:block/uuid sibling) opts))))))
|
||||||
|
|
||||||
(def set_block_collapsed
|
(def set_block_collapsed
|
||||||
(fn [block-uuid ^js opts]
|
(fn [id ^js opts]
|
||||||
(p/let [block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
|
(p/let [block (<get-block id {:children? false})]
|
||||||
block (<get-block block-uuid {:children? false})]
|
|
||||||
(when block
|
(when block
|
||||||
(let [opts (bean/->clj opts)
|
(let [block-uuid (:block/uuid block)
|
||||||
|
opts (bean/->clj opts)
|
||||||
opts (if (or (string? opts) (boolean? opts)) {:flag opts} opts)
|
opts (if (or (string? opts) (boolean? opts)) {:flag opts} opts)
|
||||||
{:keys [flag]} opts
|
{:keys [flag]} opts
|
||||||
flag (if (= "toggle" flag)
|
flag (if (= "toggle" flag)
|
||||||
@@ -422,35 +409,29 @@
|
|||||||
|
|
||||||
;; block properties
|
;; block properties
|
||||||
(defn upsert_block_property
|
(defn upsert_block_property
|
||||||
[block-uuid key ^js value ^js options]
|
[id key ^js value ^js options]
|
||||||
(this-as
|
(this-as this
|
||||||
this
|
(p/let [key' (api-block/sanitize-user-property-name key)
|
||||||
(p/let [key' (api-block/sanitize-user-property-name key)
|
opts (bean/->clj options)
|
||||||
opts (bean/->clj options)
|
block (<get-block id {:children? false})
|
||||||
block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
|
value (bean/->clj value)]
|
||||||
block (<get-block block-uuid {:children? false})
|
(when block
|
||||||
value (bean/->clj value)]
|
(db-based-api/upsert-block-property this block key' value opts)))))
|
||||||
(when block
|
|
||||||
(db-based-api/upsert-block-property this block key' value opts)))))
|
|
||||||
|
|
||||||
(defn remove_block_property
|
(defn remove_block_property
|
||||||
[block-uuid key]
|
[id key]
|
||||||
(this-as this
|
(this-as this
|
||||||
(p/let [key (api-block/sanitize-user-property-name key)
|
(p/let [block (<get-block id {:children? false})]
|
||||||
block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
|
(when-let [block-uuid (:block/uuid block)]
|
||||||
_block (<get-block block-uuid {:children? false})
|
(let [key (api-block/sanitize-user-property-name key)
|
||||||
key-ns? (namespace (keyword key))
|
key (api-block/get-db-ident-from-property-name key this)]
|
||||||
key (if (not key-ns?)
|
(property-handler/remove-block-property! block-uuid key))))))
|
||||||
(api-block/get-db-ident-from-property-name key this)
|
|
||||||
key)]
|
|
||||||
(property-handler/remove-block-property! block-uuid key))))
|
|
||||||
|
|
||||||
(defn get_block_property
|
(defn get_block_property
|
||||||
[block-uuid key]
|
[id key]
|
||||||
(this-as this
|
(this-as this
|
||||||
(p/let [block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
|
(p/let [block (<get-block id {:children? false})]
|
||||||
_block (<get-block block-uuid {:children? false})]
|
(when-let [properties (some-> block (:block/uuid) (db-model/get-block-by-uuid) (:block/properties))]
|
||||||
(when-let [properties (some-> block-uuid (db-model/get-block-by-uuid) (:block/properties))]
|
|
||||||
(when (seq properties)
|
(when (seq properties)
|
||||||
(let [property-name (api-block/sanitize-user-property-name key)
|
(let [property-name (api-block/sanitize-user-property-name key)
|
||||||
ident (api-block/get-db-ident-from-property-name property-name this)
|
ident (api-block/get-db-ident-from-property-name property-name this)
|
||||||
@@ -470,9 +451,8 @@
|
|||||||
(bean/->js (sdk-utils/normalize-keyword-for-json property-value)))))))))
|
(bean/->js (sdk-utils/normalize-keyword-for-json property-value)))))))))
|
||||||
|
|
||||||
(def get_block_properties
|
(def get_block_properties
|
||||||
(fn [block-uuid]
|
(fn [id]
|
||||||
(p/let [block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
|
(p/let [block (<get-block id {:children? false})]
|
||||||
block (<get-block block-uuid {:children? false})]
|
|
||||||
(when block
|
(when block
|
||||||
(let [properties (api-block/into-readable-db-properties (:block/properties block))]
|
(let [properties (api-block/into-readable-db-properties (:block/properties block))]
|
||||||
(sdk-utils/result->js properties))))))
|
(sdk-utils/result->js properties))))))
|
||||||
@@ -482,3 +462,17 @@
|
|||||||
(p/let [page (<get-block id-or-page-name {:children? false})]
|
(p/let [page (<get-block id-or-page-name {:children? false})]
|
||||||
(when-let [id (:block/uuid page)]
|
(when-let [id (:block/uuid page)]
|
||||||
(get_block_properties id))))
|
(get_block_properties id))))
|
||||||
|
|
||||||
|
(defn open_pdf_viewer
|
||||||
|
[block-identity-or-file-url]
|
||||||
|
(p/let [[block href] (if (and (string? block-identity-or-file-url)
|
||||||
|
(or (path/protocol-url? block-identity-or-file-url)
|
||||||
|
(path/absolute? block-identity-or-file-url)))
|
||||||
|
[nil block-identity-or-file-url]
|
||||||
|
(p/let [block (<get-block block-identity-or-file-url {:children? false})]
|
||||||
|
[block (if block
|
||||||
|
(util/format "../assets/%s.pdf" (:block/uuid block))
|
||||||
|
block-identity-or-file-url)]))
|
||||||
|
href' (assets-handler/<make-asset-url href)]
|
||||||
|
(when-let [current (pdf-assets/inflate-asset href {:block block :href href'})]
|
||||||
|
(state/set-current-pdf! current))))
|
||||||
|
|||||||
Reference in New Issue
Block a user