mirror of
https://github.com/logseq/logseq.git
synced 2026-05-15 16:32:21 +00:00
fix(sync): preserve apply-template block uuids on redo
This commit is contained in:
@@ -390,6 +390,24 @@
|
||||
distinct
|
||||
vec))
|
||||
|
||||
(defn- template-children-blocks-for-history
|
||||
[db template-ref]
|
||||
(when-let [template (d/entity db template-ref)]
|
||||
(let [template-id (:db/id template)
|
||||
template-blocks (some->> (ldb/get-block-and-children db (:block/uuid template)
|
||||
{:include-property-block? true})
|
||||
rest
|
||||
seq
|
||||
vec)]
|
||||
(when (seq template-blocks)
|
||||
(vec
|
||||
(cons (assoc (into {} (first template-blocks))
|
||||
:db/id (:db/id (first template-blocks))
|
||||
:logseq.property/used-template template-id)
|
||||
(map (fn [block]
|
||||
(assoc (into {} block) :db/id (:db/id block)))
|
||||
(rest template-blocks))))))))
|
||||
|
||||
(defn- canonicalize-insert-blocks-op
|
||||
[db tx-data args]
|
||||
(let [[blocks target-id opts] args
|
||||
@@ -460,7 +478,8 @@
|
||||
(let [[template-id target-id opts] args
|
||||
template-ref (stable-entity-ref db template-id)
|
||||
target-ref (stable-entity-ref db target-id)
|
||||
template-blocks (:template-blocks opts)
|
||||
template-blocks (or (some-> (:template-blocks opts) seq vec)
|
||||
(template-children-blocks-for-history db template-ref))
|
||||
opts-base (dissoc opts :template-id :outliner-op)
|
||||
opts' (if (seq template-blocks)
|
||||
(let [[blocks* _target-ref insert-opts]
|
||||
|
||||
@@ -284,6 +284,32 @@
|
||||
(is (= #{[:block/uuid tag-uuid]}
|
||||
(get-in inverse-outliner-ops [0 1 2 :template-blocks 0 :block/tags]))))))
|
||||
|
||||
(deftest derive-history-outliner-ops-apply-template-captures-template-blocks-when-missing-in-op-test
|
||||
(testing "apply-template forward op should capture concrete template-blocks even if original op omitted them"
|
||||
(let [conn (db-test/create-conn-with-blocks
|
||||
{:pages-and-blocks
|
||||
[{:page {:block/title "page"}
|
||||
:blocks [{:block/title "template"
|
||||
:build/children [{:block/title "template child 1"}
|
||||
{:block/title "template child 2"}]}
|
||||
{:block/title "target"}]}]})
|
||||
template (db-test/find-block-by-content @conn "template")
|
||||
target (db-test/find-block-by-content @conn "target")
|
||||
inserted-child-1-uuid (random-uuid)
|
||||
inserted-child-2-uuid (random-uuid)
|
||||
tx-data [{:e 900001 :a :block/uuid :v inserted-child-1-uuid :added true}
|
||||
{:e 900002 :a :block/uuid :v inserted-child-2-uuid :added true}]
|
||||
tx-meta {:outliner-op :apply-template
|
||||
:outliner-ops [[:apply-template [(:db/id template)
|
||||
(:db/id target)
|
||||
{:sibling? true}]]]}
|
||||
{:keys [forward-outliner-ops]}
|
||||
(op-construct/derive-history-outliner-ops @conn @conn tx-data tx-meta)]
|
||||
(is (= :apply-template (ffirst forward-outliner-ops)))
|
||||
(is (= true (get-in forward-outliner-ops [0 1 2 :keep-uuid?])))
|
||||
(is (= [inserted-child-1-uuid inserted-child-2-uuid]
|
||||
(mapv :block/uuid (get-in forward-outliner-ops [0 1 2 :template-blocks])))))))
|
||||
|
||||
(deftest derive-history-outliner-ops-builds-delete-page-inverse-for-class-property-and-today-page-test
|
||||
(testing "delete-page inverse restores hard-retracted class/property/today pages with stable db/ident"
|
||||
(let [today (date-time-util/ms->journal-day (js/Date.))
|
||||
|
||||
@@ -4881,3 +4881,39 @@
|
||||
(is (= "followup" (:block/title followup)))))
|
||||
(finally
|
||||
(reset! undo-redo/*apply-history-action! prev-apply-action))))))))
|
||||
|
||||
(deftest undo-redo-apply-template-without-template-blocks-keeps-followup-insert-target-test
|
||||
(testing "redo after apply-template (without template-blocks in original op) should preserve inserted target uuid"
|
||||
(let [{:keys [template-root-uuid empty-target-uuid seed-conn client-ops-conn]}
|
||||
(setup-rebase-apply-template-repro-state)
|
||||
conn (d/conn-from-db @seed-conn)
|
||||
followup-uuid (random-uuid)
|
||||
prev-apply-action @undo-redo/*apply-history-action!]
|
||||
(with-datascript-conns conn client-ops-conn
|
||||
(fn []
|
||||
(reset! undo-redo/*apply-history-action! sync-apply/apply-history-action!)
|
||||
(try
|
||||
;; Match editor path: apply-template op only carries target/template ids + opts.
|
||||
(d/transact! conn [[:db/add [:block/uuid empty-target-uuid] :block/title "target"]])
|
||||
(apply-ops! conn
|
||||
[[:apply-template [(:db/id (d/entity @conn [:block/uuid template-root-uuid]))
|
||||
(:db/id (d/entity @conn [:block/uuid empty-target-uuid]))
|
||||
{:sibling? true}]]]
|
||||
local-tx-meta)
|
||||
(let [inserted-three (select-offline-inserted-three conn template-root-uuid)]
|
||||
(is (some? inserted-three))
|
||||
(apply-ops! conn
|
||||
[[:insert-blocks [[{:block/uuid followup-uuid
|
||||
:block/title "followup"}]
|
||||
(:db/id inserted-three)
|
||||
{:sibling? true
|
||||
:keep-uuid? true}]]]
|
||||
local-tx-meta)
|
||||
(undo-all! test-repo)
|
||||
(is (nil? (d/entity @conn [:block/uuid followup-uuid])))
|
||||
(redo-all! test-repo)
|
||||
(let [followup (d/entity @conn [:block/uuid followup-uuid])]
|
||||
(is (some? followup))
|
||||
(is (= "followup" (:block/title followup)))))
|
||||
(finally
|
||||
(reset! undo-redo/*apply-history-action! prev-apply-action))))))))
|
||||
|
||||
Reference in New Issue
Block a user