feat: merging pages when renaming one page to the name of another page

Close #476
pull/3142/head
Tienson Qin 2021-11-16 22:20:58 +08:00
parent 408eb51997
commit dd83ce4c44
5 changed files with 80 additions and 23 deletions

View File

@ -209,25 +209,28 @@
(pdf-assets/human-hls-filename-display title) (pdf-assets/human-hls-filename-display title)
(if fmt-journal? (date/journal-title->custom-format title) title)) (if fmt-journal? (date/journal-title->custom-format title) title))
old-name (or title page-name) old-name (or title page-name)
confirm-fn (ui/make-confirm-modal confirm-fn (fn []
{:title "Do you really want to change the page name?" (let [merge? (and (not= (string/lower-case page-name) (string/lower-case @*title-value))
(page-handler/page-exists? page-name)
(page-handler/page-exists? @*title-value))]
(ui/make-confirm-modal
{:title (if merge?
(str "Page \"" @*title-value "\" already exists, merge them?")
"Do you really want to change the page name?")
:on-confirm (fn [_e {:keys [close-fn]}] :on-confirm (fn [_e {:keys [close-fn]}]
(close-fn) (close-fn)
(page-handler/rename! (or title page-name) @*title-value) (page-handler/rename! (or title page-name) @*title-value)
(reset! *edit? false)) (reset! *edit? false))
:on-cancel (fn [] :on-cancel (fn []
(reset! *title-value old-name) (reset! *title-value old-name)
(reset! *edit? true))}) (reset! *edit? true))})))
blur-fn (fn [e] blur-fn (fn [e]
(cond (cond
(= old-name @*title-value) (= old-name @*title-value)
nil nil
(page-handler/page-exists? @*title-value)
(notification/show! "Page already exists!" :error)
:else :else
(state/set-modal! confirm-fn)) (state/set-modal! (confirm-fn)))
(util/stop e))] (util/stop e))]
(if @*edit? (if @*edit?
[:h1.title {:style {:margin-left -2}} [:h1.title {:style {:margin-left -2}}

View File

@ -172,7 +172,11 @@
(let [pages (->> (db/sub-key-value :recent/pages) (let [pages (->> (db/sub-key-value :recent/pages)
(remove string/blank?) (remove string/blank?)
(filter string?))] (filter string?)
(map (fn [page] {:lowercase (string/lower-case page)
:page page}))
(util/distinct-by :lowercase)
(map :page))]
[:ul.text-sm [:ul.text-sm
(for [name pages] (for [name pages]
(when-let [entity (db/entity [:block/name (util/safe-lower-case name)])] (when-let [entity (db/entity [:block/name (util/safe-lower-case name)])]

View File

@ -1458,3 +1458,11 @@
([repo orphaned-pages] ([repo orphaned-pages]
(let [transaction (mapv (fn [page] [:db/retractEntity (:db/id page)]) orphaned-pages)] (let [transaction (mapv (fn [page] [:db/retractEntity (:db/id page)]) orphaned-pages)]
(db-utils/transact! transaction)))) (db-utils/transact! transaction))))
(defn get-block-last-direct-child
[db-id]
(when-let [block (db-utils/entity db-id)]
(let [children (:block/_parent block)
all-left (set (concat (map (comp :db/id :block/left) children) [db-id]))
all-ids (set (map :db/id children))]
(first (set/difference all-ids all-left)))))

View File

@ -9,6 +9,8 @@
[frontend.db :as db] [frontend.db :as db]
[frontend.db-schema :as db-schema] [frontend.db-schema :as db-schema]
[frontend.db.model :as model] [frontend.db.model :as model]
[frontend.db.utils :as db-utils]
[frontend.db.conn :as conn]
[frontend.format.block :as block] [frontend.format.block :as block]
[frontend.fs :as fs] [frontend.fs :as fs]
[frontend.git :as git] [frontend.git :as git]
@ -296,7 +298,7 @@
(when page-name (when page-name
(when-let [repo (state/get-current-repo)] (when-let [repo (state/get-current-repo)]
(let [page-name (string/lower-case page-name) (let [page-name (string/lower-case page-name)
blocks (db/get-page-blocks page-name) blocks (db/get-page-blocks-no-cache page-name)
tx-data (mapv tx-data (mapv
(fn [block] (fn [block]
[:db.fn/retractEntity [:block/uuid (:block/uuid block)]]) [:db.fn/retractEntity [:block/uuid (:block/uuid block)]])
@ -317,7 +319,7 @@
(unfavorite-page! page-name) (unfavorite-page! page-name)
(ok-handler) (when (fn? ok-handler) (ok-handler))
(ui-handler/re-render-root!))))) (ui-handler/re-render-root!)))))
(defn- rename-page-aux [old-name new-name] (defn- rename-page-aux [old-name new-name]
@ -420,6 +422,51 @@
(p/let [_ (rename-page-aux old-page-title new-page-title)] (p/let [_ (rename-page-aux old-page-title new-page-title)]
(println "Renamed " old-page-title " to " new-page-title))))))) (println "Renamed " old-page-title " to " new-page-title)))))))
(defn page-exists?
[page-name]
(when page-name
(db/entity [:block/name (string/lower-case page-name)])))
(defn merge-pages!
[from to]
(when (and (page-exists? from) (page-exists? to) (not= from to))
(let [to-id (:db/id (db/entity [:block/name (string/lower-case to)]))
from-id (:db/id (db/entity [:block/name (string/lower-case from)]))
from-first-child (some->> (db/pull from-id)
(outliner-core/block)
(outliner-tree/-get-down)
(outliner-core/get-data))
to-last-direct-child-id (model/get-block-last-direct-child to-id)
repo (state/get-current-repo)
conn (conn/get-conn repo false)
datoms (d/datoms @conn :avet :block/page from-id)
block-eids (mapv :e datoms)
blocks (db-utils/pull-many repo '[:db/id :block/page :block/path-refs :block/left :block/parent] block-eids)
tx-data (map (fn [block]
(let [id (:db/id block)]
(cond->
{:db/id id
:block/page {:db/id to-id}
:block/path-refs (->> (:block/path-refs block)
(remove #{{:db/id from-id}})
(cons {:db/id to-id})
(distinct)
(vec))}
(and from-first-child (= id (:db/id from-first-child)))
(assoc :block/left {:db/id (or to-last-direct-child-id to-id)})
(= (:block/parent block) {:db/id from-id})
(assoc :block/parent {:db/id to-id})))) blocks)]
(d/transact! conn tx-data)
(outliner-file/sync-to-file {:db/id to-id}))
(delete! from nil)
(route-handler/redirect! {:to :page
:push false
:path-params {:name (string/lower-case to)}})))
(defn rename! (defn rename!
[old-name new-name] [old-name new-name]
(let [repo (state/get-current-repo) (let [repo (state/get-current-repo)
@ -438,7 +485,7 @@
(rename-page-aux old-name new-name) (rename-page-aux old-name new-name)
(db/pull [:block/name (string/lower-case new-name)]) (db/pull [:block/name (string/lower-case new-name)])
(notification/show! "Page already exists!" :error) (merge-pages! old-name new-name)
namespace namespace
(rename-namespace-pages! repo old-name new-name) (rename-namespace-pages! repo old-name new-name)
@ -546,11 +593,6 @@
[page-name filter-state] [page-name filter-state]
(page-property/add-property! page-name :filters filter-state)) (page-property/add-property! page-name :filters filter-state))
(defn page-exists?
[page-name]
(when page-name
(db/entity [:block/name page-name])))
;; Editor ;; Editor
(defn page-not-exists-handler (defn page-not-exists-handler
[input id q current-pos] [input id q current-pos]

View File

@ -114,7 +114,7 @@
(defn page-search (defn page-search
([q] ([q]
(page-search q 3)) (page-search q 10))
([q limit] ([q limit]
(when-let [repo (state/get-current-repo)] (when-let [repo (state/get-current-repo)]
(let [q (string/lower-case q) (let [q (string/lower-case q)