Browse Source

add outliner-op meta info to db txn

rcmerci 4 năm trước cách đây
mục cha
commit
7bfd14a8cf

+ 4 - 1
src/main/frontend/modules/editor/undo_redo.cljs

@@ -145,5 +145,8 @@
     (reset-redo)
     (let [updated-blocks (db-report/get-blocks tx-report)
           entity {:blocks updated-blocks :txs tx-data
-                  :editor-cursor (:editor-cursor tx-meta)}]
+                  :editor-cursor (:editor-cursor tx-meta)
+                  :outliner-op (:outliner-op tx-meta)
+                  :other-meta (:other-meta tx-meta)}]
+      (println "tx-meta: " tx-meta)
       (push-undo entity))))

+ 170 - 125
src/main/frontend/modules/outliner/core.cljs

@@ -215,12 +215,17 @@
                       (throw (js/Error. "Number of children and sorted-children are not equal."))))
                   sorted-children)))))))))
 
+(defn- get-page-name [node]
+  (:block/name (db/entity (get-in node [:data :block/page :db/id]))))
+
 (defn save-node
   [node]
   {:pre [(tree/satisfied-inode? node)]}
   (ds/auto-transact!
-    [db (ds/new-outliner-txs-state)] {:outliner-op :save-node}
-    (tree/-save node db)))
+   [db (ds/new-outliner-txs-state)] {:outliner-op :save-node
+                                     :other-meta {:page-name (get-page-name node)
+                                                  :node-id (tree/-get-id node)}}
+   (tree/-save node db)))
 
 (defn insert-node-as-first-child
   "Insert a node as first child."
@@ -284,11 +289,16 @@
    (insert-node new-node target-node sibling? nil))
   ([new-node target-node sibling? {:keys [blocks-atom skip-transact?]
                                    :or {skip-transact? false}}]
-   (ds/auto-transact!
-    [txs-state (ds/new-outliner-txs-state)]
-    {:outliner-op :insert-node
-     :skip-transact? skip-transact?}
-    (insert-node-aux new-node target-node sibling? txs-state blocks-atom))))
+   (let [page-name (get-page-name target-node)]
+     (ds/auto-transact!
+      [txs-state (ds/new-outliner-txs-state)]
+      {:outliner-op :insert-node
+       :skip-transact? skip-transact?
+       :other-meta {:page-name page-name
+                    :node-id (tree/-get-id new-node)
+                    :target-id (tree/-get-id target-node)
+                    :sibling? sibling?}}
+      (insert-node-aux new-node target-node sibling? txs-state blocks-atom)))))
 
 (defn- walk-&-insert-nodes
   [loc target-node sibling? transact]
@@ -337,38 +347,45 @@
   new-nodes-tree is an vector of blocks, e.g [1 [2 3] 4 [5 [6 7]]]"
   [new-nodes-tree target-node sibling?]
   {:pre [(> (count new-nodes-tree) 0)]}
-  (ds/auto-transact!
-   [txs-state (ds/new-outliner-txs-state)] {:outliner-op :insert-nodes}
-   (let [loc (zip/vector-zip new-nodes-tree)]
-     ;; TODO: validate new-nodes-tree structure
-     (let [updated-nodes (walk-&-insert-nodes loc target-node sibling? txs-state)
-           loc (zip/vector-zip (zip/root updated-nodes))
-           ;; topmost-last-loc=4, new-nodes-tree=[1 [2 3] 4 [5 [6 7]]]
-           topmost-last-loc (get-node-tree-topmost-last-loc loc)
-           ;; sub-topmost-last-loc=5, new-nodes-tree=[1 [2 3] 4 [5 [6 7]]]
-           sub-topmost-last-loc (get-node-tree-sub-topmost-last-loc loc)
-           right-node (tree/-get-right target-node)
-           down-node (tree/-get-down target-node)]
-       ;; update node's left&parent after inserted nodes
-       (cond
-         (and (not sibling?) (some? right-node) (nil? down-node))
-         nil            ;ignore
-         (and sibling? (some? right-node) topmost-last-loc) ;; right-node.left=N
-         (let [topmost-last-node (zip/node topmost-last-loc)
-               updated-node (tree/-set-left-id right-node (tree/-get-id topmost-last-node))]
-           (tree/-save updated-node txs-state))
-         (and (not sibling?) (some? down-node) topmost-last-loc) ;; down-node.left=N
-         (let [topmost-last-node (zip/node topmost-last-loc)
-               updated-node (tree/-set-left-id down-node (tree/-get-id topmost-last-node))]
-           (tree/-save updated-node txs-state))
-         (and sibling? (some? down-node)) ;; unchanged
-         nil)))))
+  (let [page-name (get-page-name target-node)
+        target-id (tree/-get-id target-node)]
+    (ds/auto-transact!
+     [txs-state (ds/new-outliner-txs-state)] {:outliner-op :insert-nodes
+                                              :other-meta {:new-nodes-tree new-nodes-tree
+                                                           :target-id target-id
+                                                           :sibling? sibling?}}
+     (let [loc (zip/vector-zip new-nodes-tree)]
+       ;; TODO: validate new-nodes-tree structure
+       (let [updated-nodes (walk-&-insert-nodes loc target-node sibling? txs-state)
+             loc (zip/vector-zip (zip/root updated-nodes))
+             ;; topmost-last-loc=4, new-nodes-tree=[1 [2 3] 4 [5 [6 7]]]
+             topmost-last-loc (get-node-tree-topmost-last-loc loc)
+             ;; sub-topmost-last-loc=5, new-nodes-tree=[1 [2 3] 4 [5 [6 7]]]
+             sub-topmost-last-loc (get-node-tree-sub-topmost-last-loc loc)
+             right-node (tree/-get-right target-node)
+             down-node (tree/-get-down target-node)]
+         ;; update node's left&parent after inserted nodes
+         (cond
+           (and (not sibling?) (some? right-node) (nil? down-node))
+           nil            ;ignore
+           (and sibling? (some? right-node) topmost-last-loc) ;; right-node.left=N
+           (let [topmost-last-node (zip/node topmost-last-loc)
+                 updated-node (tree/-set-left-id right-node (tree/-get-id topmost-last-node))]
+             (tree/-save updated-node txs-state))
+           (and (not sibling?) (some? down-node) topmost-last-loc) ;; down-node.left=N
+           (let [topmost-last-node (zip/node topmost-last-loc)
+                 updated-node (tree/-set-left-id down-node (tree/-get-id topmost-last-node))]
+             (tree/-save updated-node txs-state))
+           (and sibling? (some? down-node)) ;; unchanged
+           nil))))))
 
 (defn move-node
   [node up?]
   {:pre [(tree/satisfied-inode? node)]}
   (ds/auto-transact!
-    [txs-state (ds/new-outliner-txs-state)] {:outliner-op :move-node}
+   [txs-state (ds/new-outliner-txs-state)] {:outliner-op :move-node
+                                            :other-meta {:node-id (tree/-get-id node)
+                                                         :up? up?}}
     (let [left (tree/-get-left node)
           move-to-another-parent? (if up?
                                     (= left (tree/-get-parent node))
@@ -412,14 +429,19 @@
   "Delete node from the tree."
   [node children?]
   {:pre [(tree/satisfied-inode? node)]}
-  (ds/auto-transact!
-    [txs-state (ds/new-outliner-txs-state)] {:outliner-op :delete-node}
-    (let [right-node (tree/-get-right node)]
-      (tree/-del node txs-state children?)
-      (when (tree/satisfied-inode? right-node)
-        (let [left-node (tree/-get-left node)
-              new-right-node (tree/-set-left-id right-node (tree/-get-id left-node))]
-          (tree/-save new-right-node txs-state))))))
+  (let [page-name (get-page-name node)
+        node-id (tree/-get-id node)]
+    (ds/auto-transact!
+     [txs-state (ds/new-outliner-txs-state)] {:outliner-op :delete-node
+                                              :other-meta {:page-name page-name
+                                                           :node-id node-id
+                                                           :children? children?}}
+     (let [right-node (tree/-get-right node)]
+       (tree/-del node txs-state children?)
+       (when (tree/satisfied-inode? right-node)
+         (let [left-node (tree/-get-left node)
+               new-right-node (tree/-set-left-id right-node (tree/-get-id left-node))]
+           (tree/-save new-right-node txs-state)))))))
 
 (defn- get-left-nodes
   [node limit]
@@ -446,44 +468,51 @@
   [start-node end-node block-ids]
   {:pre [(tree/satisfied-inode? start-node)
          (tree/satisfied-inode? end-node)]}
-  (ds/auto-transact!
-   [txs-state (ds/new-outliner-txs-state)]
-   {:outliner-op :delete-nodes}
-   (let [end-node-parents (->>
-                           (db/get-block-parents
-                            (state/get-current-repo)
-                            (tree/-get-id end-node)
-                            1000)
-                           (map :block/uuid)
-                           (set))
-         self-block? (contains? end-node-parents (tree/-get-id start-node))]
-     (if (or (= start-node end-node)
-             self-block?)
-       (delete-node start-node true)
-       (let [sibling? (= (tree/-get-parent-id start-node)
-                         (tree/-get-parent-id end-node))
-             right-node (tree/-get-right end-node)]
-         (when (tree/satisfied-inode? right-node)
-           (let [left-node-id (if sibling?
-                                (tree/-get-id (tree/-get-left start-node))
-                                (let [end-node-left-nodes (get-left-nodes end-node (count block-ids))
-                                      parents (->>
-                                               (db/get-block-parents
-                                                (state/get-current-repo)
-                                                (tree/-get-id start-node)
-                                                1000)
-                                               (map :block/uuid)
-                                               (set))
-                                      result (first (set/intersection (set end-node-left-nodes) parents))]
-                                  (when-not result
-                                    (util/pprint {:parents parents
-                                                  :end-node-left-nodes end-node-left-nodes}))
-                                  result))]
-             (assert left-node-id "Can't find the left-node-id")
-             (let [new-right-node (tree/-set-left-id right-node left-node-id)]
-               (tree/-save new-right-node txs-state))))
-         (let [txs (db-outliner/del-blocks block-ids)]
-           (ds/add-txs txs-state txs)))))))
+  (let [page-name (get-page-name start-node)
+        start-id (tree/-get-id start-node)
+        end-id (tree/-get-id end-node)]
+    (ds/auto-transact!
+     [txs-state (ds/new-outliner-txs-state)]
+     {:outliner-op :delete-nodes
+      :other-meta {:page-name page-name
+                   :start-id start-id
+                   :end-id end-id
+                   :block-ids block-ids}}
+     (let [end-node-parents (->>
+                             (db/get-block-parents
+                              (state/get-current-repo)
+                              (tree/-get-id end-node)
+                              1000)
+                             (map :block/uuid)
+                             (set))
+           self-block? (contains? end-node-parents (tree/-get-id start-node))]
+       (if (or (= start-node end-node)
+               self-block?)
+         (delete-node start-node true)
+         (let [sibling? (= (tree/-get-parent-id start-node)
+                           (tree/-get-parent-id end-node))
+               right-node (tree/-get-right end-node)]
+           (when (tree/satisfied-inode? right-node)
+             (let [left-node-id (if sibling?
+                                  (tree/-get-id (tree/-get-left start-node))
+                                  (let [end-node-left-nodes (get-left-nodes end-node (count block-ids))
+                                        parents (->>
+                                                 (db/get-block-parents
+                                                  (state/get-current-repo)
+                                                  (tree/-get-id start-node)
+                                                  1000)
+                                                 (map :block/uuid)
+                                                 (set))
+                                        result (first (set/intersection (set end-node-left-nodes) parents))]
+                                    (when-not result
+                                      (util/pprint {:parents parents
+                                                    :end-node-left-nodes end-node-left-nodes}))
+                                    result))]
+               (assert left-node-id "Can't find the left-node-id")
+               (let [new-right-node (tree/-set-left-id right-node left-node-id)]
+                 (tree/-save new-right-node txs-state))))
+           (let [txs (db-outliner/del-blocks block-ids)]
+             (ds/add-txs txs-state txs))))))))
 
 (defn first-child?
   [node]
@@ -520,50 +549,56 @@
 
 (defn indent-outdent-nodes
   [nodes indent?]
-  (ds/auto-transact!
-   [txs-state (ds/new-outliner-txs-state)] {:outliner-op :indent-outdent-nodes}
-   (let [first-node (first nodes)
-         last-node (last nodes)]
-     (if indent?
-       (when-not (first-child? first-node)
-         (let [first-node-left-id (tree/-get-left-id first-node)
-               last-node-right (tree/-get-right last-node)
-               parent-or-last-child-id (or (-> (db/get-block-immediate-children (state/get-current-repo)
-                                                                                first-node-left-id)
-                                               last
-                                               :block/uuid)
-                                           first-node-left-id)
-               first-node (tree/-set-left-id first-node parent-or-last-child-id)]
-           (doseq [node (cons first-node (rest nodes))]
-             (-> (tree/-set-parent-id node first-node-left-id)
-                 (tree/-save txs-state)))
-           (some-> last-node-right
-                   (tree/-set-left-id first-node-left-id)
-                   (tree/-save txs-state))))
-       (when-not (first-level? first-node)
-         (let [parent (tree/-get-parent first-node)
-               parent-parent-id (tree/-get-parent-id parent)
-               parent-right (tree/-get-right parent)
-               last-node-right (tree/-get-right last-node)
-               last-node-id (tree/-get-id last-node)]
-           (logical-outdenting txs-state parent nodes first-node last-node last-node-right parent-parent-id parent-right)
-           (when-not (state/logical-outdenting?)
-             ;; direct outdenting (the old behavior)
-             (let [right-siblings (get-right-siblings last-node)
-                   right-siblings (doall
-                                   (map (fn [sibling right-siblings]
-                                          (some->
-                                           (tree/-set-parent-id sibling last-node-id)
-                                           (tree/-save txs-state)))
-                                     right-siblings))]
-               (when-let [last-node-right (first right-siblings)]
-                 (let [last-node-children (tree/-get-children last-node)
-                       left-id (if (seq last-node-children)
-                                 (tree/-get-id (last last-node-children))
-                                 last-node-id)]
-                   (when left-id
-                     (some-> (tree/-set-left-id last-node-right left-id)
-                             (tree/-save txs-state)))))))))))))
+  {:pre [(> (count nodes) 0)]}
+  (let [page-name (get-page-name (first nodes))
+        ids (mapv #(get-in % [:data :block/uuid]) nodes)]
+    (ds/auto-transact!
+     [txs-state (ds/new-outliner-txs-state)] {:outliner-op :indent-outdent-nodes
+                                              :other-meta {:page-name page-name
+                                                           :indent? indent?
+                                                           :node-ids ids}}
+     (let [first-node (first nodes)
+           last-node (last nodes)]
+       (if indent?
+         (when-not (first-child? first-node)
+           (let [first-node-left-id (tree/-get-left-id first-node)
+                 last-node-right (tree/-get-right last-node)
+                 parent-or-last-child-id (or (-> (db/get-block-immediate-children (state/get-current-repo)
+                                                                                  first-node-left-id)
+                                                 last
+                                                 :block/uuid)
+                                             first-node-left-id)
+                 first-node (tree/-set-left-id first-node parent-or-last-child-id)]
+             (doseq [node (cons first-node (rest nodes))]
+               (-> (tree/-set-parent-id node first-node-left-id)
+                   (tree/-save txs-state)))
+             (some-> last-node-right
+                     (tree/-set-left-id first-node-left-id)
+                     (tree/-save txs-state))))
+         (when-not (first-level? first-node)
+           (let [parent (tree/-get-parent first-node)
+                 parent-parent-id (tree/-get-parent-id parent)
+                 parent-right (tree/-get-right parent)
+                 last-node-right (tree/-get-right last-node)
+                 last-node-id (tree/-get-id last-node)]
+             (logical-outdenting txs-state parent nodes first-node last-node last-node-right parent-parent-id parent-right)
+             (when-not (state/logical-outdenting?)
+               ;; direct outdenting (the old behavior)
+               (let [right-siblings (get-right-siblings last-node)
+                     right-siblings (doall
+                                     (map (fn [sibling right-siblings]
+                                            (some->
+                                             (tree/-set-parent-id sibling last-node-id)
+                                             (tree/-save txs-state)))
+                                          right-siblings))]
+                 (when-let [last-node-right (first right-siblings)]
+                   (let [last-node-children (tree/-get-children last-node)
+                         left-id (if (seq last-node-children)
+                                   (tree/-get-id (last last-node-children))
+                                   last-node-id)]
+                     (when left-id
+                       (some-> (tree/-set-left-id last-node-right left-id)
+                               (tree/-save txs-state))))))))))))))
 
 (defn- set-nodes-page&file-aux
   [node page file txs-state]
@@ -597,10 +632,20 @@
                        (= (tree/-get-parent-id root) target-node-id)))
       (let [root-page (:db/id (:block/page (:data root)))
             target-page (:db/id (:block/page (:data target-node)))
+            origin-left-id (tree/-get-left-id root)
+            origin-parent-id (tree/-get-parent-id root)
+            from-page-name (get-page-name root)
+            target-page-name (get-page-name target-node)
             opts (cond-> {:outliner-op :move-subtree}
                    (not= root-page target-page)
                    (assoc :from-page root-page
-                          :target-page target-page))]
+                          :target-page target-page)
+                   :always
+                   (assoc :other-meta {:root-id (tree/-get-id root)
+                                       :origin-left-id origin-left-id
+                                       :origin-parent-id origin-parent-id
+                                       :from-page-name from-page-name
+                                       :target-page-name target-page-name}))]
         (ds/auto-transact!
         [txs-state (ds/new-outliner-txs-state)] opts
         (let [left-node-id (tree/-get-left-id root)