mirror of
https://github.com/penpot/penpot.git
synced 2025-03-11 15:21:18 -05:00
♻️ Refactor page deletion.
This commit is contained in:
parent
b7c6204b6c
commit
d987e08461
4 changed files with 137 additions and 148 deletions
|
@ -106,16 +106,16 @@
|
|||
(defn purge-page
|
||||
"Remove page and all related stuff from the state."
|
||||
[state id]
|
||||
(let [shapes (get state :shapes)]
|
||||
(let [pid (get-in state [:pages id :project])]
|
||||
(-> state
|
||||
(update-in [:projects pid :pages] #(filterv (partial not= id) %))
|
||||
(update :pages dissoc id)
|
||||
(update :packed-pages dissoc id)
|
||||
(assoc :shapes (reduce-kv (fn [acc k v]
|
||||
(if (= (:page v) id)
|
||||
(dissoc acc k)
|
||||
acc))
|
||||
shapes
|
||||
shapes)))))
|
||||
(update :shapes (fn [shapes] (->> shapes
|
||||
(map second)
|
||||
(filter #(= (:page %) id))
|
||||
(map :id)
|
||||
(apply dissoc shapes)))))))
|
||||
|
||||
(defn assoc-packed-page
|
||||
[state {:keys [id] :as page}]
|
||||
|
@ -125,6 +125,8 @@
|
|||
[state id]
|
||||
(update state :packed-pages dissoc id))
|
||||
|
||||
|
||||
|
||||
;; --- Pages Fetched
|
||||
|
||||
(deftype PagesFetched [id pages]
|
||||
|
@ -138,8 +140,6 @@
|
|||
page-ids (into [] (map :id) pages)]
|
||||
(as-> state $
|
||||
(assoc-in $ [:projects id :pages] page-ids)
|
||||
;; TODO: this is a workaround
|
||||
(assoc-in $ [:projects id :page-id] (first page-ids))
|
||||
(reduce unpack-page $ pages)
|
||||
(reduce assoc-packed-page $ pages)))))
|
||||
|
||||
|
@ -168,18 +168,19 @@
|
|||
|
||||
;; --- Page Created
|
||||
|
||||
(declare reorder-pages)
|
||||
(declare rehash-pages)
|
||||
|
||||
(deftype PageCreated [data]
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(unpack-page data)
|
||||
(assoc-packed-page data)))
|
||||
(let [project-id (:project data)]
|
||||
(-> (update-in state [:projects project-id :pages] conj (:id data))
|
||||
(unpack-page data)
|
||||
(assoc-packed-page data))))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(rx/of (reorder-pages (:project data)))))
|
||||
(rx/of (rehash-pages (:project data)))))
|
||||
|
||||
(s/def ::page-created
|
||||
(s/keys :req-un [::id
|
||||
|
@ -192,57 +193,66 @@
|
|||
{:pre [(us/valid? ::page-created data)]}
|
||||
(PageCreated. data))
|
||||
|
||||
(defn page-created?
|
||||
[o]
|
||||
(instance? PageCreated o))
|
||||
|
||||
;; --- Create Page
|
||||
|
||||
(deftype CreatePage [name project width height layout]
|
||||
ptk/WatchEvent
|
||||
(watch [this state s]
|
||||
(let [params {:name name
|
||||
:project project
|
||||
:data {}
|
||||
:metadata {:width width
|
||||
:height height
|
||||
:layout layout
|
||||
:order -100}}]
|
||||
(->> (rp/req :create/page params)
|
||||
(rx/map :payload)
|
||||
(rx/map page-created)))))
|
||||
|
||||
(s/def ::create-page
|
||||
(s/def ::create-page-params
|
||||
(s/keys :req-un [::name
|
||||
::project
|
||||
::width
|
||||
::height
|
||||
::layout]))
|
||||
::height]))
|
||||
|
||||
(defn create-page
|
||||
[{:keys [name project width height layout] :as data}]
|
||||
{:pre [(us/valid? ::create-page data)]}
|
||||
(CreatePage. name project width height layout))
|
||||
{:pre [(us/valid? ::create-page-params data)]}
|
||||
(reify
|
||||
ptk/WatchEvent
|
||||
(watch [this state s]
|
||||
(let [canvas {:id (uuid/random)
|
||||
:name "Canvas 1"
|
||||
:type :canvas
|
||||
:x1 200
|
||||
:y1 200
|
||||
:x2 (+ 200 width)
|
||||
:y2 (+ 200 height)}
|
||||
metadata {:width width
|
||||
:height height
|
||||
:order -100}
|
||||
params {:name name
|
||||
:project project
|
||||
:data {:shapes [canvas]}
|
||||
:metadata metadata}]
|
||||
(->> (rp/req :create/page params)
|
||||
(rx/map :payload)
|
||||
(rx/map page-created))))))
|
||||
|
||||
;; --- Page Persisted
|
||||
|
||||
(deftype PagePersisted [data]
|
||||
IDeref
|
||||
(-deref [_] data)
|
||||
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [{:keys [id version]} data]
|
||||
(-> state
|
||||
(assoc-in [:pages id :version] version)
|
||||
(assoc-packed-page data)))))
|
||||
|
||||
(defn- page-persisted?
|
||||
[event]
|
||||
(instance? PagePersisted event))
|
||||
|
||||
;; TODO: add page spec
|
||||
|
||||
(defn page-persisted
|
||||
[data]
|
||||
{:pre [(map? data)]}
|
||||
(PagePersisted. data))
|
||||
(reify
|
||||
cljs.core/IDeref
|
||||
(-deref [_] data)
|
||||
|
||||
ptk/EventType
|
||||
(type [_] ::page-persisted)
|
||||
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [{:keys [id version]} data]
|
||||
(-> state
|
||||
(assoc-in [:pages id :version] version)
|
||||
(assoc-packed-page data))))))
|
||||
|
||||
(defn- page-persisted?
|
||||
[event]
|
||||
(= (ptk/type event) ::page-persisted))
|
||||
|
||||
;; --- Persist Page
|
||||
|
||||
|
@ -333,28 +343,27 @@
|
|||
{:pre [(uuid? id) (us/valid? ::metadata metadata)]}
|
||||
(UpdateMetadata. id metadata))
|
||||
|
||||
;; --- Reorder Pages
|
||||
;; --- Rehash Pages
|
||||
;;
|
||||
;; A post processing event that normalizes the
|
||||
;; page order numbers after a user sorting
|
||||
;; operation for a concrete project.
|
||||
|
||||
(defn reorder-pages
|
||||
[project-id]
|
||||
{:pre [(uuid? project-id)]}
|
||||
(defn rehash-pages
|
||||
[id]
|
||||
{:pre [(uuid? id)]}
|
||||
(reify
|
||||
ptk/UpdateEvent
|
||||
(update [this state]
|
||||
(let [page-ids (get-in state [:projects project-id :pages])]
|
||||
(let [page-ids (get-in state [:projects id :pages])]
|
||||
(reduce (fn [state [index id]]
|
||||
(assoc-in state [:pages id :metadata :order] index))
|
||||
;; TODO: this is workaround
|
||||
(assoc-in state [:projects project-id :page-id] (first page-ids))
|
||||
state
|
||||
(map-indexed vector page-ids))))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [page-ids (get-in state [:projects project-id :pages])]
|
||||
(let [page-ids (get-in state [:projects id :pages])]
|
||||
(->> (rx/from-coll page-ids)
|
||||
(rx/map persist-metadata))))))
|
||||
|
||||
|
@ -376,39 +385,36 @@
|
|||
;; A specialized event for persist data
|
||||
;; from the update page form.
|
||||
|
||||
(deftype PersistPageUpdateForm [id name width height layout]
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [page (-> (get-in state [:pages id])
|
||||
(assoc-in [:name] name)
|
||||
(assoc-in [:metadata :width] width)
|
||||
(assoc-in [:metadata :height] height)
|
||||
(assoc-in [:metadata :layout] layout))]
|
||||
(rx/of (update-page id page)))))
|
||||
|
||||
(s/def ::persist-page-update-form
|
||||
(s/keys :req-un [::name ::width ::height ::layout]))
|
||||
(s/def ::persist-page-update-form-params
|
||||
(s/keys :req-un [::id ::name ::width ::height]))
|
||||
|
||||
(defn persist-page-update-form
|
||||
[id {:keys [name width height layout] :as data}]
|
||||
{:pre [(uuid? id) (us/valid? ::persist-page-update-form data)]}
|
||||
(PersistPageUpdateForm. id name width height layout))
|
||||
[{:keys [id name width height] :as data}]
|
||||
{:pre [(us/valid? ::persist-page-update-form-params data)]}
|
||||
(reify
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [page (-> (get-in state [:pages id])
|
||||
(assoc-in [:name] name)
|
||||
(assoc-in [:metadata :width] width)
|
||||
(assoc-in [:metadata :height] height))]
|
||||
(rx/of (update-page id page))))))
|
||||
|
||||
|
||||
;; --- Delete Page (by id)
|
||||
|
||||
(deftype DeletePage [id callback]
|
||||
ptk/WatchEvent
|
||||
(watch [_ state s]
|
||||
(letfn [(on-success [_]
|
||||
#(purge-page % id))]
|
||||
(->> (rp/req :delete/page id)
|
||||
(rx/map on-success)
|
||||
(rx/tap callback)
|
||||
(rx/filter identity)))))
|
||||
|
||||
(defn delete-page
|
||||
([id] (DeletePage. id (constantly nil)))
|
||||
([id callback] (DeletePage. id callback)))
|
||||
[id]
|
||||
{:pre [(uuid? id)]}
|
||||
(reify
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(purge-page state id))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state s]
|
||||
(->> (rp/req :delete/page id)
|
||||
(rx/map (constantly ::delete-completed))))))
|
||||
|
||||
;; --- Watch Page Changes
|
||||
|
||||
|
|
|
@ -160,74 +160,38 @@
|
|||
|
||||
;; --- Create Project
|
||||
|
||||
(defrecord CreateProject [name width height layout]
|
||||
ptk/WatchEvent
|
||||
(watch [this state s]
|
||||
(let [project-data {:name name}
|
||||
page-data {:name "Page 0"
|
||||
:data {}
|
||||
:metadata {:width width
|
||||
:height height
|
||||
:layout layout
|
||||
:order 0}}]
|
||||
(->> (rp/req :create/project {:name name})
|
||||
(rx/map :payload)
|
||||
(rx/mapcat (fn [{:keys [id] :as project}]
|
||||
(rp/req :create/page (assoc page-data :project id))))
|
||||
(rx/map #(fetch-projects))))))
|
||||
|
||||
(s/def ::create-project-event
|
||||
(s/keys :req-un [::name
|
||||
::udp/width
|
||||
::udp/height
|
||||
::udp/layout]))
|
||||
(s/def ::create-project-params
|
||||
(s/keys :req-un [::name ::udp/width ::udp/height]))
|
||||
|
||||
(defn create-project
|
||||
[data]
|
||||
{:pre [(us/valid? ::create-project-event data)]}
|
||||
(map->CreateProject data))
|
||||
[{:keys [name] :as params}]
|
||||
{:pre [(us/valid? ::create-project-params params)]}
|
||||
(reify
|
||||
ptk/WatchEvent
|
||||
(watch [this state stream]
|
||||
(rx/merge
|
||||
(->> (rp/req :create/project {:name name})
|
||||
(rx/map :payload)
|
||||
(rx/map (fn [{:keys [id] :as project}]
|
||||
(udp/create-page (assoc params :project id)))))
|
||||
(->> stream
|
||||
(rx/filter udp/page-created?)
|
||||
(rx/take 1)
|
||||
(rx/map #(fetch-projects)))))))
|
||||
|
||||
;; --- Go To & Go To Page
|
||||
|
||||
(deftype GoToFirstPage [pages]
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [[page & rest] (sort-by #(get-in % [:metadata :order]) pages)
|
||||
params {:project (:project page)
|
||||
:page (:id page)}]
|
||||
(rx/of (rt/navigate :workspace/page params)))))
|
||||
|
||||
(defn go-to-first-page
|
||||
[pages]
|
||||
(GoToFirstPage. pages))
|
||||
|
||||
(defrecord GoTo [project-id]
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [page-id (get-in state [:projects project-id :page-id])]
|
||||
(if-not page-id
|
||||
(rx/empty)
|
||||
(let [params {:project project-id
|
||||
:page page-id}]
|
||||
(rx/of (rt/navigate :workspace/page params)))))))
|
||||
|
||||
(defrecord GoToPage [project-id page-id]
|
||||
ptk/WatchEvent
|
||||
(watch [_ state s]
|
||||
(let [params {:project project-id
|
||||
:page page-id}]
|
||||
(rx/of (rt/navigate :workspace/page params)))))
|
||||
;; --- Go To Project
|
||||
|
||||
(defn go-to
|
||||
"A shortcut event that redirects the user to the
|
||||
first page of the project."
|
||||
([project-id]
|
||||
{:pre [(uuid? project-id)]}
|
||||
(GoTo. project-id))
|
||||
([project-id page-id]
|
||||
{:pre [(uuid? project-id)
|
||||
(uuid? page-id)]}
|
||||
(GoToPage. project-id page-id)))
|
||||
[id]
|
||||
{:pre [(uuid? id)]}
|
||||
(reify
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [[page & rest-pages] (get-in state [:projects id :pages])]
|
||||
(when page
|
||||
(let [params {:project id :page page}]
|
||||
(rx/of (rt/nav :workspace/page params))))))))
|
||||
|
||||
|
||||
;; --- Update Opts (Filtering & Ordering)
|
||||
|
||||
|
|
|
@ -899,6 +899,25 @@
|
|||
{:pre [(uuid? id)]}
|
||||
(UnlockShape. id))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Pages
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn delete-page
|
||||
[id]
|
||||
{:pre [(uuid? id)]}
|
||||
(reify
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [pid (get-in state [:pages id :project])]
|
||||
(rx/merge
|
||||
(rx/of (udp/delete-page id))
|
||||
(->> stream
|
||||
(rx/filter #(= % ::udp/delete-completed))
|
||||
(rx/map #(dp/go-to pid))
|
||||
(rx/take 1)))))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Selection Rect IMPL
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
|
|
@ -158,7 +158,7 @@
|
|||
(def figwheel-options
|
||||
{:open-url false
|
||||
:pprint-config false
|
||||
:load-warninged-code true
|
||||
:load-warninged-code false
|
||||
:auto-testing false
|
||||
:css-dirs ["resources/public/css"]
|
||||
:ring-server-options {:port 3449 :host "0.0.0.0"}
|
||||
|
|
Loading…
Add table
Reference in a new issue