Pārlūkot izejas kodu

Merge branch 'master' into feat/capacitor-new

charlie 4 mēneši atpakaļ
vecāks
revīzija
b68c305872

+ 4 - 4
deps/db/src/logseq/db/common/initial_data.cljs

@@ -283,10 +283,10 @@
          vec
          rseq
          (keep (fn [d]
-                 (and (<= (:v d) today)
-                      (let [e (d/entity db (:e d))]
-                        (when (and (common-entity-util/journal? e) (:db/id e))
-                          e))))))))
+                 (when (<= (:v d) today)
+                   (let [e (d/entity db (:e d))]
+                     (when (and (common-entity-util/journal? e) (:db/id e))
+                       e))))))))
 
 (defn- get-structured-datoms
   [db]

+ 10 - 3
deps/db/src/logseq/db/sqlite/export.cljs

@@ -447,7 +447,9 @@
     (merge {::block (:node node-export)}
            block-export)))
 
-(defn- build-page-blocks-export [db page-entity {:keys [properties classes blocks ontology-page? include-alias?] :as options}]
+(defn- build-page-blocks-export
+  "If :include-alias? option is set, the caller fn is responsible for defining alias pages"
+  [db page-entity {:keys [properties classes blocks ontology-page? include-alias?] :as options}]
   (let [options' (cond-> (dissoc options :classes :blocks :graph-ontology)
                    (:exclude-ontology? options)
                    (assoc :properties (get-in options [:graph-ontology :properties])))
@@ -493,10 +495,15 @@
   (let [page-blocks* (get-page-blocks db eid)
         {:keys [content-ref-ents] :as content-ref-export} (build-content-ref-export db page-blocks*)
         {:keys [pvalue-uuids] :as page-export*}
-        (build-page-export* db eid page-blocks* {:include-uuid-fn (:content-ref-uuids content-ref-export)})
+        (build-page-export* db eid page-blocks* {:include-uuid-fn (:content-ref-uuids content-ref-export)
+                                                 :include-alias? true})
         page-entity (d/entity db eid)
         uuid-block-export (build-uuid-block-export db pvalue-uuids content-ref-ents {:page-entity page-entity})
-        page-export (finalize-export-maps db page-export* uuid-block-export content-ref-export)]
+        alias-export (when (:block/alias page-entity)
+                       {:pages-and-blocks (mapv #(hash-map :page (merge (shallow-copy-page %)
+                                                                        {:block/uuid (:block/uuid %) :build/keep-uuid? true}))
+                                                (:block/alias page-entity))})
+        page-export (finalize-export-maps db page-export* uuid-block-export content-ref-export alias-export)]
     page-export))
 
 (defn- build-nodes-export

+ 35 - 7
deps/outliner/src/logseq/outliner/property.cljs

@@ -8,6 +8,7 @@
             [logseq.db :as ldb]
             [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.common.order :as db-order]
+            [logseq.db.frontend.class :as db-class]
             [logseq.db.frontend.db-ident :as db-ident]
             [logseq.db.frontend.entity-util :as entity-util]
             [logseq.db.frontend.malli-schema :as db-malli-schema]
@@ -27,6 +28,30 @@
     (throw (ex-info "Read-only property value shouldn't be edited"
                     {:property property-ident}))))
 
+(defonce ^:private built-in-class-property->properties
+  (->>
+   (mapcat
+    (fn [[class-ident {:keys [properties]}]]
+      (map
+       (fn [property] [class-ident property])
+       (cons :block/tags (keys properties))))
+    db-class/built-in-classes)
+   (concat
+    (mapcat
+     (fn [[property-ident {:keys [properties]}]]
+       (map
+        (fn [property] [property-ident property])
+        (cons :block/tags (keys properties))))
+     db-property/built-in-properties))
+   set))
+
+(defn- throw-error-if-protected-property
+  [entity-idents property-ident]
+  (when (some #(built-in-class-property->properties [% property-ident]) entity-idents)
+    (throw (ex-info "Protected property shouldn't deleted"
+                    {:entity-idents entity-idents
+                     :property property-ident}))))
+
 (defn- build-property-value-tx-data
   [conn block property-id value]
   (when (some? value)
@@ -274,6 +299,7 @@
   (let [block-eids (map ->eid block-ids)
         blocks (keep (fn [id] (d/entity @conn id)) block-eids)
         block-id-set (set (map :db/id blocks))]
+    (throw-error-if-protected-property (map :db/ident blocks) property-id)
     (when (seq blocks)
       (when-let [property (d/entity @conn property-id)]
         (let [txs (mapcat
@@ -349,6 +375,7 @@
   (let [eid (->eid eid)
         block (d/entity @conn eid)
         property (d/entity @conn property-id)]
+    (throw-error-if-protected-property [(:db/ident block)] property-id)
     (cond
       (= :logseq.property/empty-placeholder (:db/ident (get block property-id)))
       nil
@@ -657,13 +684,14 @@
 
 (defn class-add-property!
   [conn class-id property-id]
-  (when-let [class (d/entity @conn class-id)]
-    (if (ldb/class? class)
-      (ldb/transact! conn
-                     [[:db/add (:db/id class) :logseq.property.class/properties property-id]]
-                     {:outliner-op :save-block})
-      (throw (ex-info "Can't add a property to a block that isn't a class"
-                      {:class-id class-id :property-id property-id})))))
+  (when-not (contains? #{:logseq.property/empty-placeholder} property-id)
+    (when-let [class (d/entity @conn class-id)]
+      (if (ldb/class? class)
+        (ldb/transact! conn
+                       [[:db/add (:db/id class) :logseq.property.class/properties property-id]]
+                       {:outliner-op :save-block})
+        (throw (ex-info "Can't add a property to a block that isn't a class"
+                        {:class-id class-id :property-id property-id}))))))
 
 (defn class-remove-property!
   [conn class-id property-id]

+ 80 - 77
src/main/frontend/components/block.cljs

@@ -320,72 +320,72 @@
       :ref *el-ref}
      [:img.rounded-sm.relative
       (merge
-        {:loading "lazy"
-         :referrerPolicy "no-referrer"
-         :src src
-         :title title}
-        metadata)]
+       {:loading "lazy"
+        :referrerPolicy "no-referrer"
+        :src src
+        :title title}
+       metadata)]
      (when (and (not breadcrumb?)
-             (not positioned?))
+                (not positioned?))
        [:<>
         (let [handle-copy!
               (fn [_e]
                 (-> (util/copy-image-to-clipboard image-src)
-                  (p/then #(notification/show! "Copied!" :success))))
+                    (p/then #(notification/show! "Copied!" :success))))
               handle-delete!
               (fn [_e]
                 (when-let [block-id (get-blockid)]
                   (let [*local-selected? (atom local?)]
                     (-> (shui/dialog-confirm!
-                          [:div.text-xs.opacity-60.-my-2
-                           (when (and local? (not= (:block/uuid asset-block) block-id))
-                             [:label.flex.gap-1.items-center
-                              (shui/checkbox
-                                {:default-checked @*local-selected?
-                                 :on-checked-change #(reset! *local-selected? %)})
-                              (t :asset/physical-delete)])]
-                          {:title (t :asset/confirm-delete (.toLocaleLowerCase (t :text/image)))
-                           :outside-cancel? true})
-                      (p/then (fn []
-                                (shui/dialog-close!)
-                                (editor-handler/delete-asset-of-block!
-                                  {:block-id block-id
-                                   :asset-block asset-block
-                                   :local? local?
-                                   :delete-local? @*local-selected?
-                                   :repo (state/get-current-repo)
-                                   :href src
-                                   :title title
-                                   :full-text full-text})))))))]
+                         [:div.text-xs.opacity-60.-my-2
+                          (when (and local? (not= (:block/uuid asset-block) block-id))
+                            [:label.flex.gap-1.items-center
+                             (shui/checkbox
+                              {:default-checked @*local-selected?
+                               :on-checked-change #(reset! *local-selected? %)})
+                             (t :asset/physical-delete)])]
+                         {:title (t :asset/confirm-delete (.toLocaleLowerCase (t :text/image)))
+                          :outside-cancel? true})
+                        (p/then (fn []
+                                  (shui/dialog-close!)
+                                  (editor-handler/delete-asset-of-block!
+                                   {:block-id block-id
+                                    :asset-block asset-block
+                                    :local? local?
+                                    :delete-local? @*local-selected?
+                                    :repo (state/get-current-repo)
+                                    :href src
+                                    :title title
+                                    :full-text full-text})))))))]
           [:.asset-action-bar {:aria-hidden "true"}
            (shui/button-group
-             (shui/button
-               {:variant :outline
-                :size :icon
-                :class "h-7 w-7"
-                :on-pointer-down util/stop
-                :on-click (fn [e]
-                            (shui/popup-show! (.closest (.-target e) ".asset-action-bar")
-                              (fn []
-                                [:div
-                                 {:on-click #(shui/popup-hide!)}
-                                 (shui/dropdown-menu-item
-                                   {:on-click #(some-> (db/entity [:block/uuid (get-blockid)]) (editor-handler/edit-block! :max))}
-                                   [:span.flex.items-center.gap-1
-                                    (ui/icon "edit") (t :asset/edit-block)])
-                                 (shui/dropdown-menu-item
-                                   {:on-click handle-copy!}
-                                   [:span.flex.items-center.gap-1
-                                    (ui/icon "copy") (t :asset/copy)])
-                                 (when (util/electron?)
-                                   (shui/dropdown-menu-item
-                                     {:on-click (fn [e]
-                                                  (util/stop e)
-                                                  (if local?
-                                                    (ipc/ipc "openFileInFolder" image-src)
-                                                    (js/window.apis.openExternal image-src)))}
-                                     [:span.flex.items-center.gap-1
-                                      (ui/icon "folder-pin") (t (if local? :asset/show-in-folder :asset/open-in-browser))]))
+            (shui/button
+             {:variant :outline
+              :size :icon
+              :class "h-7 w-7"
+              :on-pointer-down util/stop
+              :on-click (fn [e]
+                          (shui/popup-show! (.closest (.-target e) ".asset-action-bar")
+                                            (fn []
+                                              [:div
+                                               {:on-click #(shui/popup-hide!)}
+                                               (shui/dropdown-menu-item
+                                                {:on-click #(some-> (db/entity [:block/uuid (get-blockid)]) (editor-handler/edit-block! :max))}
+                                                [:span.flex.items-center.gap-1
+                                                 (ui/icon "edit") (t :asset/edit-block)])
+                                               (shui/dropdown-menu-item
+                                                {:on-click handle-copy!}
+                                                [:span.flex.items-center.gap-1
+                                                 (ui/icon "copy") (t :asset/copy)])
+                                               (when (util/electron?)
+                                                 (shui/dropdown-menu-item
+                                                  {:on-click (fn [e]
+                                                               (util/stop e)
+                                                               (if local?
+                                                                 (ipc/ipc "openFileInFolder" image-src)
+                                                                 (js/window.apis.openExternal image-src)))}
+                                                  [:span.flex.items-center.gap-1
+                                                   (ui/icon "folder-pin") (t (if local? :asset/show-in-folder :asset/open-in-browser))]))
 
                                  (when-not config/publishing?
                                    [:<>
@@ -410,32 +410,33 @@
         positioned? (:property-position config)
         asset-block (:asset-block config)
         width (or (get-in asset-block [:logseq.property.asset/resize-metadata :width])
-                (:width metadata))
+                  (:width metadata))
         *width (get state ::size)
         width (or @*width width 250)
         metadata' (merge
-                    (cond->
-                      {:height 125}
-                      width
-                      (assoc :width width))
-                    metadata)
+                   (cond->
+                    {:height 125}
+                     width
+                     (assoc :width width))
+                   metadata)
         resizable? (and (not (mobile-util/native-platform?))
-                     (not breadcrumb?)
-                     (not positioned?))
+                        (not breadcrumb?)
+                        (not positioned?))
         asset-container-cp (asset-container asset-block src title metadata'
-                             {:breadcrumb? breadcrumb?
-                              :positioned? positioned?
-                              :local? local?
-                              :full-text full-text})]
+                                            {:breadcrumb? breadcrumb?
+                                             :positioned? positioned?
+                                             :local? local?
+                                             :full-text full-text})]
     (if (or (:disable-resize? config)
-          (not resizable?))
+            (:table-view? config)
+            (not resizable?))
       asset-container-cp
       [:div.ls-resize-image.rounded-md
        asset-container-cp
        (resize-image-handles
-         (fn [k ^js event]
-           (let [dx (.-dx event)
-                 ^js target (.-target event)]
+        (fn [k ^js event]
+          (let [dx (.-dx event)
+                ^js target (.-target event)]
 
             (case k
               :start
@@ -1961,11 +1962,13 @@
       (contains? #{"tweet" "twitter"} name)
       (when-let [url (first arguments)]
         (let [id-regex #"/status/(\d+)"]
-          (when-let [id (cond
-                          (<= (count url) 15) url
-                          :else
-                          (last (util/safe-re-find id-regex url)))]
-            (ui/tweet-embed id))))
+          (if (:table? config)
+            (util/format "{{twitter %s}}" url)
+            (when-let [id (cond
+                            (<= (count url) 15) url
+                            :else
+                            (last (util/safe-re-find id-regex url)))]
+              (ui/tweet-embed id)))))
 
       (= name "embed")
       (if (config/db-based-graph? (state/get-current-repo))
@@ -4076,8 +4079,8 @@
   (map #(inline config %) col))
 
 (rum/defc inline-title
-  [title]
-  (map-inline {}
+  [config title]
+  (map-inline config
               (gp-mldoc/inline->edn title
                                     (mldoc/get-default-config :markdown))))
 

+ 23 - 23
src/main/frontend/components/block.css

@@ -25,29 +25,6 @@
     }
   }
 
-  .asset-container {
-    @apply relative inline-block mt-2 w-full;
-
-    .asset-action-bar {
-      @apply top-1 right-1 absolute flex items-center opacity-0 transition-opacity;
-
-      &[data-popup-active] {
-        @apply opacity-100;
-      }
-    }
-
-    .asset-action-btn {
-      @apply m-1 p-0.5 truncate flex items-center opacity-70 select-none
-      hover:opacity-90 active:opacity-60;
-    }
-
-    &:hover, &:active {
-      .asset-action-bar {
-        @apply opacity-100;
-      }
-    }
-  }
-
   .draw [aria-labelledby="shapes-title"] {
     position: absolute;
     left: 50%;
@@ -1169,3 +1146,26 @@ html.is-mac {
 .ls-dialog-block {
   @apply !w-[90dvw] !h-[75%] !max-w-4xl bg-gray-02 overflow-scroll;
 }
+
+.asset-container {
+    @apply relative inline-block mt-2 w-full;
+
+    .asset-action-bar {
+        @apply top-1 right-1 absolute flex items-center opacity-0 transition-opacity;
+
+        &[data-popup-active] {
+            @apply opacity-100;
+        }
+    }
+
+    .asset-action-btn {
+        @apply m-1 p-0.5 truncate flex items-center opacity-70 select-none
+        hover:opacity-90 active:opacity-60;
+    }
+
+    &:hover, &:active {
+        .asset-action-bar {
+            @apply opacity-100;
+        }
+    }
+}

+ 8 - 3
src/main/frontend/components/dnd.cljs

@@ -35,9 +35,14 @@
      children]))
 
 (rum/defc items
-  [col {:keys [on-drag-end parent-node vertical? sort-by-inner-element?]
-        :or {vertical? true}}]
-  (let [ids (mapv :id col)
+  [col* {:keys [on-drag-end parent-node vertical? sort-by-inner-element?]
+         :or {vertical? true}}]
+  (assert (every? :id col*))
+  (when (some #(nil? (:id %)) col*)
+    (js/console.error "dnd-kit items without id")
+    (prn :col col*))
+  (let [col (filter :id col*)
+        ids (mapv :id col)
         items' (bean/->js ids)
         id->item (zipmap ids col)
         [items-state set-items] (rum/use-state items')

+ 2 - 1
src/main/frontend/components/library.cljs

@@ -55,7 +55,8 @@
       :input-default-placeholder "Add pages"
       :show-new-when-not-exact-match? false
       :on-input set-input!
-      :input-opts {:class "!p-1 !text-sm"}})))
+      :input-opts {:class "!p-1 !text-sm"}
+      :clear-input-on-chosen? false})))
 
 (rum/defc add-pages
   [library-page]

+ 1 - 1
src/main/frontend/components/page_menu.cljs

@@ -79,7 +79,7 @@
                            (page-handler/<unfavorite-page! page-title)
                            (page-handler/<favorite-page! page-title)))}})
 
-          (when (or (util/electron?) file-sync-graph-uuid)
+          (when (and (or (util/electron?) file-sync-graph-uuid) (not db-based?))
             {:title   (t :page/version-history)
              :options {:on-click
                        (fn []

+ 5 - 4
src/main/frontend/components/property.cljs

@@ -489,11 +489,12 @@
 
          (let [property-desc (when-not (= (:db/ident property) :logseq.property/description)
                                (:logseq.property/description property))]
-           [:div.ls-block.property-value-container.flex.flex-row.gap-1.items-center
+           [:div.ls-block.property-value-container.flex.flex-row.gap-1.items-start
 
             (when-not (or block? (and property-desc (:class-schema? opts)))
-              [:div {:class "pl-1.5 -mr-[3px] opacity-60"}
-               [:span.bullet-container [:span.bullet]]])
+              [:div.flex.h-6.items-center
+               [:div {:class "pl-1.5 -mr-[3px] opacity-60"}
+                [:span.bullet-container [:span.bullet]]]])
             [:div.flex.flex-1
              [:div.property-value.flex.flex-1
               (if (:class-schema? opts)
@@ -680,7 +681,7 @@
                  [:div.property-key.text-sm
                   (property-key-cp block (db/entity :logseq.property.class/properties) {})]]
                 [:div.text-muted-foreground {:style {:margin-left 26}}
-                 "Tag properties are inherited by all nodes using the tag — for example, each #Task node inherits 'Status' and 'Priority'."]]
+                 "Tag properties are inherited by all nodes using the tag. For example, each #Task node inherits 'Status' and 'Priority'."]]
                [:div.ml-4
                 (properties-section block properties opts')
                 (rum/with-key (new-property block opts') (str id "-class-add-property"))]]))]]))))

+ 3 - 3
src/main/frontend/components/repo.cljs

@@ -112,8 +112,8 @@
              :class "delete-local-graph-menu-item"
              :on-click (fn []
                          (let [prompt-str (if db-based?
-                                            (str "Are you sure to permanently delete the graph \"" graph-name "\" from Logseq?")
-                                            (str "Are you sure to unlink the graph \"" url "\" from local folder?"))]
+                                            (str "Are you sure you want to permanently delete the graph \"" graph-name "\" from Logseq?")
+                                            (str "Are you sure you want to unlink the graph \"" url "\" from local folder?"))]
                            (-> (shui/dialog-confirm!
                                 [:p.font-medium.-my-4 prompt-str
                                  [:span.my-2.flex.font-normal.opacity-75
@@ -129,7 +129,7 @@
               {:key "delete-remotely"
                :class "delete-remote-graph-menu-item"
                :on-click (fn []
-                           (let [prompt-str (str "Are you sure to permanently delete the graph \"" graph-name "\" from our server?")]
+                           (let [prompt-str (str "Are you sure you want to permanently delete the graph \"" graph-name "\" from our server?")]
                              (-> (shui/dialog-confirm!
                                   [:p.font-medium.-my-4 prompt-str
                                    [:span.my-2.flex.font-normal.opacity-75

+ 18 - 15
src/main/frontend/components/select.cljs

@@ -107,7 +107,8 @@
                  item-cp transform-fn tap-*input-val
                  multiple-choices? on-apply new-case-sensitive?
                  dropdown? show-new-when-not-exact-match? exact-match-exclude-items
-                 input-container initial-open? loading?]
+                 input-container initial-open? loading?
+                 clear-input-on-chosen?]
           :or {limit 100
                prompt-key :select/default-prompt
                empty-placeholder (fn [_t] [:div])
@@ -115,44 +116,45 @@
                extract-fn :value
                extract-chosen-fn identity
                exact-match-exclude-items #{}
-               initial-open? true}}]
-  (let [input (::input state)
+               initial-open? true
+               clear-input-on-chosen? true}}]
+  (let [*input (::input state)
         *toggle (::toggle state)
         *selected-choices (::selected-choices state)
         selected-choices (rum/react *selected-choices)
         full-choices (cond->>
                       (remove nil? items)
-                       (seq @input)
+                       (seq @*input)
                        (remove :clear?))
         search-result' (->>
-                        (cond-> (search/fuzzy-search full-choices @input :limit limit :extract-fn extract-fn)
+                        (cond-> (search/fuzzy-search full-choices @*input :limit limit :extract-fn extract-fn)
                           (fn? transform-fn)
-                          (transform-fn @input))
+                          (transform-fn @*input))
                         (remove nil?))
         exact-transform-fn (if new-case-sensitive? identity string/lower-case)
         exact-match? (contains? (set (map (comp exact-transform-fn str extract-fn) search-result'))
-                                (exact-transform-fn @input))
-        search-result' (if (and multiple-choices? (not (string/blank? @input)))
+                                (exact-transform-fn @*input))
+        search-result' (if (and multiple-choices? (not (string/blank? @*input)))
                          (sort-by (fn [item]
                                     (not (contains? selected-choices (:value item))))
                                   search-result')
                          search-result')
         search-result (if (and show-new-when-not-exact-match?
                                (not exact-match?)
-                               (not (string/blank? @input))
-                               (not (exact-match-exclude-items @input)))
+                               (not (string/blank? @*input))
+                               (not (exact-match-exclude-items @*input)))
                         (->>
                          (cons
                           (first search-result')
-                          (cons {:value @input
-                                 :label (str "+ New option: " @input)}
+                          (cons {:value @*input
+                                 :label (str "+ New option: " @*input)}
                                 (rest search-result')))
                          (remove nil?))
                         search-result')
         input-opts' (if (fn? input-opts) (input-opts (empty? search-result)) input-opts)
         input-container (or
                          input-container
-                         (search-input input
+                         (search-input *input
                                        {:prompt-key prompt-key
                                         :input-default-placeholder input-default-placeholder
                                         :input-opts input-opts'
@@ -171,7 +173,8 @@
                                                                      (render-item result chosen? multiple-choices? *selected-choices)))
                                     :class             "cp__select-results"
                                     :on-chosen         (fn [raw-chosen e]
-                                                         (reset! input "")
+                                                         (when clear-input-on-chosen?
+                                                           (reset! *input ""))
                                                          (let [chosen (extract-chosen-fn raw-chosen)]
                                                            (if multiple-choices?
                                                              (if (selected-choices chosen)
@@ -197,7 +200,7 @@
                                                                             (on-apply selected-choices)
                                                                             (when close-modal? (state/close-modal!)))})])]))]
     (when (fn? tap-*input-val)
-      (tap-*input-val input))
+      (tap-*input-val *input))
     [:div.cp__select
      (merge {:class "cp__select-main"}
             host-opts)

+ 3 - 0
src/main/frontend/components/table.css

@@ -81,6 +81,9 @@
     @apply cursor-pointer transition-colors hover:bg-muted/50 text-left align-middle font-medium text-muted-foreground border-r;
   }
 
+  .ls-table-cell {
+    @apply overflow-hidden;
+  }
   .ls-table-footer {
     @apply absolute left-0 bottom-[8px] w-full;
   }

+ 3 - 1
src/main/frontend/components/views.cljs

@@ -294,6 +294,7 @@
         (let [render (fn [block]
                        [:div
                         (inline-title
+                         {:table? true}
                          (some->> (:block/title block)
                                   string/trim
                                   string/split-lines
@@ -1913,7 +1914,8 @@
         {pinned true unpinned false} (group-by (fn [item]
                                                  (contains? pinned-properties (:id item)))
                                                (remove (fn [column]
-                                                         (false? (get visible-columns (:id column))))
+                                                         (or (false? (get visible-columns (:id column)))
+                                                             (nil? (:name column))))
                                                        columns))
         group-by-property (or (:logseq.property.view/group-by-property view-entity)
                               (db/entity group-by-property-ident))

+ 22 - 7
src/main/frontend/worker/db/validate.cljs

@@ -7,22 +7,37 @@
 
 (defn- fix-invalid-blocks!
   [conn errors]
-  (let [tx-data (keep
+  (let [tx-data (mapcat
                  (fn [{:keys [entity dispatch-key]}]
                    (let [entity (d/entity @conn (:db/id entity))]
                      (cond
+                       (and (= dispatch-key :block) (nil? (:block/title entity)))
+                       [[:db/retractEntity (:db/id entity)]]
+
+                       (and (= dispatch-key :block) (nil? (:block/page entity)))
+                       (let [latest-journal-id (:db/id (first (ldb/get-latest-journals @conn)))
+                             page-id (:db/id (:block/page (:block/parent entity)))]
+                         (cond
+                           page-id
+                           [[:db/add (:db/id entity) :block/page page-id]]
+                           latest-journal-id
+                           [[:db/add (:db/id entity) :block/page latest-journal-id]
+                            [:db/add (:db/id entity) :block/parent latest-journal-id]]
+                           :else
+                           (js/console.error (str "Don't know where to put the block " (:db/id entity)))))
+
                        (:block.temp/fully-loaded? entity)
-                       [:db/retract (:db/id entity) :block.temp/fully-loaded?]
+                       [[:db/retract (:db/id entity) :block.temp/fully-loaded?]]
                        (and (:block/page entity) (not (:block/parent entity)))
-                       [:db/add (:db/id entity) :block/parent (:db/id (:block/page entity))]
+                       [[:db/add (:db/id entity) :block/parent (:db/id (:block/page entity))]]
                        (and (not (:block/page entity)) (not (:block/parent entity)) (not (:block/name entity)))
-                       [:db/retractEntity (:db/id entity)]
+                       [[:db/retractEntity (:db/id entity)]]
                        (and (= dispatch-key :property-value-block) (:block/title entity))
-                       [:db/retract (:db/id entity) :block/title]
+                       [[:db/retract (:db/id entity) :block/title]]
                        (and (ldb/class? entity) (not (:logseq.property.class/extends entity)))
-                       [:db/add (:db/id entity) :logseq.property.class/extends :logseq.class/Root]
+                       [[:db/add (:db/id entity) :logseq.property.class/extends :logseq.class/Root]]
                        (and (or (ldb/class? entity) (ldb/property? entity)) (ldb/internal-page? entity))
-                       [:db/retract (:db/id entity) :block/tags :logseq.class/Page]
+                       [[:db/retract (:db/id entity) :block/tags :logseq.class/Page]]
                        :else
                        nil)))
                  errors)]

+ 2 - 4
src/test/frontend/worker/migrate_test.cljs

@@ -11,8 +11,7 @@
   (testing "Rename parent to extends"
     (let [db-transit (str (fs-node/readFileSync "src/test/migration/64.8.transit"))
           db (ldb/read-transit-str db-transit)
-          conn (d/conn-from-db db)
-          tx-data (db-migrate/fix-rename-parent-to-extends conn nil)]
+          tx-data (db-migrate/fix-rename-parent-to-extends db)]
       (is (= (->> tx-data
                   (map (fn [data]
                          (cond
@@ -110,8 +109,7 @@
   (testing "Separate properties from classes"
     (let [db-transit (str (fs-node/readFileSync "src/test/migration/65.0.transit"))
           db (ldb/read-transit-str db-transit)
-          conn (d/conn-from-db db)
-          tx-data (db-migrate/separate-classes-and-properties conn nil)
+          tx-data (db-migrate/separate-classes-and-properties db)
           new-property (first tx-data)]
       (is (= (dissoc new-property
                      :block/updated-at