diff --git a/deps/graph-parser/src/logseq/graph_parser/block.cljs b/deps/graph-parser/src/logseq/graph_parser/block.cljs index cdb86d297a..2bc5d2af3b 100644 --- a/deps/graph-parser/src/logseq/graph_parser/block.cljs +++ b/deps/graph-parser/src/logseq/graph_parser/block.cljs @@ -369,7 +369,7 @@ as there's no chance to introduce timestamps via editing in page `skip-existing-page-check?`: if true, allows pages to have the same name" [original-page-name db with-timestamp? date-formatter - & {:keys [page-uuid class?] :as options}] + & {:keys [page-uuid class? created-by] :as options}] (when-not (and db (common-util/uuid-string? original-page-name) (not (ldb/page? (d/entity db [:block/uuid (uuid original-page-name)])))) (let [original-page-name (-> (string/trim original-page-name) @@ -393,7 +393,8 @@ (let [tags (if class? [:logseq.class/Tag] (or (:block/tags page) [:logseq.class/Page]))] - (assoc page :block/tags tags)) + (cond-> (assoc page :block/tags tags) + created-by (assoc :logseq.property/created-by created-by))) (assoc page :block/type (or (:block/type page) "page"))))))) (defn- db-namespace-page? diff --git a/deps/outliner/src/logseq/outliner/core.cljs b/deps/outliner/src/logseq/outliner/core.cljs index 98c8506b83..75d1c1a7c1 100644 --- a/deps/outliner/src/logseq/outliner/core.cljs +++ b/deps/outliner/src/logseq/outliner/core.cljs @@ -49,6 +49,12 @@ (let [updated-at (common-util/time-ms)] (assoc block :block/updated-at updated-at))) +(defn- update-property-created-by + [block created-by] + (cond-> block + (and created-by (nil? (:logseq.property/created-by block))) + (assoc :logseq.property/created-by created-by))) + (defn- filter-top-level-blocks [db blocks] (let [parent-ids (set/intersection (set (map (comp :db/id :block/parent) blocks)) @@ -622,8 +628,12 @@ `replace-empty-target?`: If the `target-block` is an empty block, whether to replace it, it defaults to be `false`. `update-timestamps?`: whether to update `blocks` timestamps. + `created-by`: user-uuid, update `:logseq.property/created-by` if exists ``" - [repo conn blocks target-block {:keys [_sibling? keep-uuid? keep-block-order? outliner-op replace-empty-target? update-timestamps?] :as opts + [repo conn blocks target-block {:keys [_sibling? keep-uuid? keep-block-order? + outliner-op replace-empty-target? update-timestamps? + created-by] + :as opts :or {update-timestamps? true}}] {:pre [(seq blocks) (m/validate block-map-or-entity target-block)]} @@ -642,11 +652,13 @@ blocks' (let [blocks' (blocks-with-level blocks)] (cond->> (blocks-with-ordered-list-props repo blocks' target-block sibling?) update-timestamps? - (mapv (fn [b] (block-with-timestamps (dissoc b :block/created-at :block/updated-at)))) + (mapv #(dissoc % :block/created-at :block/updated-at)) true (mapv block-with-timestamps) db-based? - (mapv (fn [b] (dissoc b :block/properties))))) + (mapv #(-> % + (dissoc :block/properties) + (update-property-created-by created-by))))) insert-opts {:sibling? sibling? :replace-empty-target? replace-empty-target? :keep-uuid? keep-uuid? diff --git a/src/main/frontend/handler/common/page.cljs b/src/main/frontend/handler/common/page.cljs index 65d9d71e05..23bc081515 100644 --- a/src/main/frontend/handler/common/page.cljs +++ b/src/main/frontend/handler/common/page.cljs @@ -3,25 +3,26 @@ and favorite fns. This ns should be agnostic of file or db concerns but there is still some file-specific tech debt to remove from create!" (:require [clojure.string :as string] - [frontend.db :as db] - [frontend.handler.config :as config-handler] - [frontend.handler.route :as route-handler] - [frontend.state :as state] - [logseq.common.util :as common-util] - [logseq.common.config :as common-config] - [frontend.handler.ui :as ui-handler] - [frontend.config :as config] - [frontend.fs :as fs] - [promesa.core :as p] - [frontend.handler.block :as block-handler] - [logseq.db :as ldb] - [frontend.db.conn :as conn] [datascript.core :as d] - [frontend.modules.outliner.ui :as ui-outliner-tx] - [frontend.modules.outliner.op :as outliner-op] + [frontend.config :as config] + [frontend.db :as db] + [frontend.db.conn :as conn] + [frontend.fs :as fs] + [frontend.handler.block :as block-handler] + [frontend.handler.config :as config-handler] [frontend.handler.db-based.editor :as db-editor-handler] + [frontend.handler.notification :as notification] + [frontend.handler.route :as route-handler] + [frontend.handler.ui :as ui-handler] + [frontend.handler.user :as user] + [frontend.modules.outliner.op :as outliner-op] + [frontend.modules.outliner.ui :as ui-outliner-tx] + [frontend.state :as state] + [logseq.common.config :as common-config] + [logseq.common.util :as common-util] [logseq.common.util.page-ref :as page-ref] - [frontend.handler.notification :as notification])) + [logseq.db :as ldb] + [promesa.core :as p])) (defn- wrap-tags "Tags might have multiple words" @@ -59,11 +60,13 @@ (if (and has-tags? (nil? title')) (notification/show! "Page name can't include \"#\"." :warning) (when-not (string/blank? title') - (p/let [options' (if db-based? - (cond-> - (update options :tags concat (:block/tags parsed-result)) + (p/let [current-user-id (user/user-uuid) + options' (if db-based? + (cond-> (update options :tags concat (:block/tags parsed-result)) (nil? (:split-namespace? options)) - (assoc :split-namespace? true)) + (assoc :split-namespace? true) + current-user-id + (assoc :created-by current-user-id)) options) result (ui-outliner-tx/transact! {:outliner-op :create-page} diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index c125770e8d..12da58965a 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -30,6 +30,7 @@ [frontend.handler.property.file :as property-file] [frontend.handler.property.util :as pu] [frontend.handler.route :as route-handler] + [frontend.handler.user :as user] [frontend.mobile.util :as mobile-util] [frontend.modules.outliner.op :as outliner-op] [frontend.modules.outliner.tree :as tree] @@ -334,14 +335,16 @@ true :else - (not has-children?))] + (not has-children?)) + current-user-id (user/user-uuid)] (ui-outliner-tx/transact! {:outliner-op :insert-blocks} (save-current-block! {:current-block current-block}) (outliner-op/insert-blocks! [new-block] current-block {:sibling? sibling? :keep-uuid? keep-uuid? :ordered-list? ordered-list? - :replace-empty-target? replace-empty-target?})))) + :replace-empty-target? replace-empty-target? + :created-by current-user-id})))) (defn- block-self-alone-when-insert? [config uuid] diff --git a/src/main/frontend/handler/profiler.cljs b/src/main/frontend/handler/profiler.cljs index 0f14191e28..773db0dc1c 100644 --- a/src/main/frontend/handler/profiler.cljs +++ b/src/main/frontend/handler/profiler.cljs @@ -48,7 +48,6 @@ (throw (ex-info (str "fn-sym not found: " fn-sym) {}))))) (defn unregister-fn! - "TODO: not working on multi-arity fns" [fn-sym] (let [ns (namespace fn-sym) s (munge (name fn-sym))] diff --git a/src/main/frontend/utils.js b/src/main/frontend/utils.js index e45bcc205b..3b61e71324 100644 --- a/src/main/frontend/utils.js +++ b/src/main/frontend/utils.js @@ -8,6 +8,22 @@ if (typeof window === 'undefined') { global.window = {} } +// js patches +;(function () { + if (!window?.console) return + const originalError = console.error + console.error = (...args) => { + if (args[0]?.startsWith( + `Warning: Each child in a list should have a unique "key" prop`)) { + console.groupCollapsed('[React] ⚠️ key warning!') + console.warn(...args) + console.groupEnd() + return + } + originalError(...args) + } +})(); + // Copy from https://github.com/primetwig/react-nestable/blob/dacea9dc191399a3520f5dc7623f5edebc83e7b7/dist/utils.js export const closest = (target, selector) => { // closest(e.target, '.field') diff --git a/src/main/frontend/worker/handler/page.cljs b/src/main/frontend/worker/handler/page.cljs index e9516bdb10..39982d40c0 100644 --- a/src/main/frontend/worker/handler/page.cljs +++ b/src/main/frontend/worker/handler/page.cljs @@ -34,6 +34,7 @@ * :tags - tag uuids that are added to :block/tags * :persist-op? - when true, add an update-page op * :properties - properties to add to the page + * :created-by - when set, set :logseq.property/created-by, only for db-based-graphs TODO: Add other options" [repo conn config title & {:as options}] (if (ldb/db-based-graph? @conn) diff --git a/src/main/frontend/worker/handler/page/db_based/page.cljs b/src/main/frontend/worker/handler/page/db_based/page.cljs index 6fce70de80..ef9be62e51 100644 --- a/src/main/frontend/worker/handler/page/db_based/page.cljs +++ b/src/main/frontend/worker/handler/page/db_based/page.cljs @@ -168,7 +168,9 @@ (defn create "Pure function without side effects" [db title* - {:keys [create-first-block? properties uuid persist-op? whiteboard? class? today-journal? split-namespace? skip-existing-page-check?] + {:keys [create-first-block? properties uuid persist-op? whiteboard? + class? today-journal? split-namespace? skip-existing-page-check? + created-by] :or {create-first-block? true properties nil uuid nil @@ -203,7 +205,8 @@ :page-uuid (when (uuid? uuid) uuid) :skip-existing-page-check? (if (some? skip-existing-page-check?) skip-existing-page-check? - true)}) + true) + :created-by created-by}) [page parents] (if (and (text/namespace-page? title) split-namespace?) (let [pages (split-namespace-pages db page date-formatter)] [(last pages) (butlast pages)])