mirror of
https://github.com/penpot/penpot.git
synced 2025-01-10 00:40:30 -05:00
Add proper history loading and history state management.
This commit is contained in:
parent
95263402b7
commit
6ef76673e8
4 changed files with 83 additions and 44 deletions
|
@ -26,7 +26,9 @@
|
||||||
(defrecord PagesFetched [pages]
|
(defrecord PagesFetched [pages]
|
||||||
rs/UpdateEvent
|
rs/UpdateEvent
|
||||||
(-apply-update [_ state]
|
(-apply-update [_ state]
|
||||||
(reduce stpr/unpack-page state pages)))
|
(as-> state $
|
||||||
|
(reduce stpr/unpack-page $ pages)
|
||||||
|
(reduce stpr/assoc-page $ pages))))
|
||||||
|
|
||||||
(defn pages-fetched?
|
(defn pages-fetched?
|
||||||
[v]
|
[v]
|
||||||
|
@ -56,14 +58,16 @@
|
||||||
rs/WatchEvent
|
rs/WatchEvent
|
||||||
(-apply-watch [this state s]
|
(-apply-watch [this state s]
|
||||||
(letfn [(on-created [{page :payload}]
|
(letfn [(on-created [{page :payload}]
|
||||||
#(stpr/unpack-page % page))
|
(rx/of
|
||||||
|
#(stpr/unpack-page % page)
|
||||||
|
#(stpr/assoc-page % page)))
|
||||||
(on-failed [page]
|
(on-failed [page]
|
||||||
(uum/error (tr "errors.auth"))
|
(uum/error (tr "errors.auth"))
|
||||||
(rx/empty))]
|
(rx/empty))]
|
||||||
(let [params (-> (into {} this)
|
(let [params (-> (into {} this)
|
||||||
(assoc :data {}))]
|
(assoc :data {}))]
|
||||||
(->> (rp/do :create/page params)
|
(->> (rp/do :create/page params)
|
||||||
(rx/map on-created)
|
(rx/mapcat on-created)
|
||||||
(rx/catch on-failed))))))
|
(rx/catch on-failed))))))
|
||||||
|
|
||||||
(def ^:static +create-page-schema+
|
(def ^:static +create-page-schema+
|
||||||
|
@ -80,12 +84,11 @@
|
||||||
|
|
||||||
;; --- Update Page
|
;; --- Update Page
|
||||||
|
|
||||||
(defrecord UpdatePage [id name width height layout data]
|
(defrecord UpdatePage [id name width height layout]
|
||||||
rs/UpdateEvent
|
rs/UpdateEvent
|
||||||
(-apply-update [_ state]
|
(-apply-update [_ state]
|
||||||
(letfn [(updater [page]
|
(letfn [(updater [page]
|
||||||
(merge page
|
(merge page
|
||||||
(when data {:data data})
|
|
||||||
(when width {:width width})
|
(when width {:width width})
|
||||||
(when height {:height height})
|
(when height {:height height})
|
||||||
(when name {:name name})))]
|
(when name {:name name})))]
|
||||||
|
@ -94,13 +97,16 @@
|
||||||
rs/WatchEvent
|
rs/WatchEvent
|
||||||
(-apply-watch [this state s]
|
(-apply-watch [this state s]
|
||||||
(letfn [(on-success [{page :payload}]
|
(letfn [(on-success [{page :payload}]
|
||||||
#(assoc-in % [:pages-by-id id :version] (:version page)))
|
(rx/of
|
||||||
|
#(assoc-in % [:pages-by-id id :version] (:version page))
|
||||||
|
#(stpr/assoc-page % page)))
|
||||||
(on-failure [e]
|
(on-failure [e]
|
||||||
(uum/error (tr "errors.page-update"))
|
(uum/error (tr "errors.page-update"))
|
||||||
(rx/empty))]
|
(rx/empty))]
|
||||||
(->> (rp/do :update/page (into {} this))
|
(let [page (stpr/pack-page state id)]
|
||||||
(rx/map on-success)
|
(->> (rp/do :update/page page)
|
||||||
(rx/catch on-failure)))))
|
(rx/mapcat on-success)
|
||||||
|
(rx/catch on-failure))))))
|
||||||
|
|
||||||
(def ^:const +update-page-schema+
|
(def ^:const +update-page-schema+
|
||||||
{:name [sc/required sc/string]
|
{:name [sc/required sc/string]
|
||||||
|
@ -181,37 +187,67 @@
|
||||||
[id]
|
[id]
|
||||||
(DeletePage. id))
|
(DeletePage. id))
|
||||||
|
|
||||||
;; --- Page History Fetched
|
;; --- Pinned Page History Fetched
|
||||||
|
|
||||||
(defrecord PageHistoryFetched [history]
|
(defrecord PinnedPageHistoryFetched [history]
|
||||||
rs/UpdateEvent
|
rs/UpdateEvent
|
||||||
(-apply-update [_ state]
|
(-apply-update [_ state]
|
||||||
(-> state
|
(assoc-in state [:workspace :history :pinned-items] history)))
|
||||||
(assoc-in [:workspace :history :items] history))))
|
|
||||||
;; (assoc-in [:workspace :history :selected] nil))))
|
;; --- Fetch Pinned Page History
|
||||||
|
|
||||||
|
(defrecord FetchPinnedPageHistory [id]
|
||||||
|
rs/WatchEvent
|
||||||
|
(-apply-watch [_ state s]
|
||||||
|
(println "FetchPinnedPageHistory" id)
|
||||||
|
(letfn [(on-success [{history :payload}]
|
||||||
|
(->PinnedPageHistoryFetched history))
|
||||||
|
(on-failure [e]
|
||||||
|
(uum/error (tr "errors.fetch-page-history"))
|
||||||
|
(rx/empty))]
|
||||||
|
(let [params {:page id :pinned true}]
|
||||||
|
(->> (rp/do :fetch/page-history params)
|
||||||
|
(rx/map on-success)
|
||||||
|
(rx/catch on-failure))))))
|
||||||
|
|
||||||
|
(defn fetch-pinned-page-history
|
||||||
|
[id]
|
||||||
|
(->FetchPinnedPageHistory id))
|
||||||
|
|
||||||
|
;; --- Page History Fetched
|
||||||
|
|
||||||
|
(defrecord PageHistoryFetched [history append?]
|
||||||
|
rs/UpdateEvent
|
||||||
|
(-apply-update [_ state]
|
||||||
|
(println "PageHistoryFetched" "append=" append?)
|
||||||
|
(let [items (into [] history)
|
||||||
|
minv (apply min (map :version history))
|
||||||
|
state (assoc-in state [:workspace :history :min-version] minv)]
|
||||||
|
(if-not append?
|
||||||
|
(assoc-in state [:workspace :history :items] items)
|
||||||
|
(update-in state [:workspace :history :items] #(reduce conj % items))))))
|
||||||
|
|
||||||
;; --- Fetch Page History
|
;; --- Fetch Page History
|
||||||
|
|
||||||
(defrecord FetchPageHistory [id]
|
(defrecord FetchPageHistory [id since max]
|
||||||
rs/WatchEvent
|
rs/WatchEvent
|
||||||
(-apply-watch [_ state s]
|
(-apply-watch [_ state s]
|
||||||
(println "FetchPageHistory" id)
|
(println "FetchPageHistory" id)
|
||||||
(letfn [(on-success [{history :payload}]
|
(letfn [(on-success [{history :payload}]
|
||||||
(->PageHistoryFetched history))
|
(->PageHistoryFetched history (not (nil? since))))
|
||||||
(on-failure [e]
|
(on-failure [e]
|
||||||
(uum/error (tr "errors.fetch-page-history"))
|
(uum/error (tr "errors.fetch-page-history"))
|
||||||
(rx/empty))]
|
(rx/empty))]
|
||||||
(->> (rp/do :fetch/page-history {:page id :max 15})
|
(let [params {:page id :max (or max 15)}]
|
||||||
(rx/map on-success)
|
(->> (rp/do :fetch/page-history params)
|
||||||
(rx/catch on-failure))))
|
(rx/map on-success)
|
||||||
|
(rx/catch on-failure))))))
|
||||||
rs/EffectEvent
|
|
||||||
(-apply-effect [_ state]
|
|
||||||
))
|
|
||||||
|
|
||||||
(defn fetch-page-history
|
(defn fetch-page-history
|
||||||
[id]
|
([id]
|
||||||
(FetchPageHistory. id))
|
(fetch-page-history id nil))
|
||||||
|
([id params]
|
||||||
|
(map->FetchPageHistory (assoc params :id id))))
|
||||||
|
|
||||||
;; --- Clean Page History
|
;; --- Clean Page History
|
||||||
|
|
||||||
|
@ -229,30 +265,22 @@
|
||||||
|
|
||||||
;; --- Select Page History
|
;; --- Select Page History
|
||||||
|
|
||||||
;; TODO: seems like it is inefficient packing the current
|
|
||||||
;; page every time, but a this moment it works. Maybe in
|
|
||||||
;; future it will need some refactor.
|
|
||||||
|
|
||||||
(defrecord SelectPageHistory [id history]
|
(defrecord SelectPageHistory [id history]
|
||||||
rs/UpdateEvent
|
rs/UpdateEvent
|
||||||
(-apply-update [_ state]
|
(-apply-update [_ state]
|
||||||
(if (nil? history)
|
(if (nil? history)
|
||||||
(let [packed (get-in state [:workspace :history :current])]
|
(let [packed (get-in state [:pagedata-by-id id])]
|
||||||
(-> state
|
(-> state
|
||||||
(stpr/unpack-page packed)
|
(stpr/unpack-page packed)
|
||||||
(assoc-in [:workspace :history :selected] nil)
|
(assoc-in [:workspace :history :selected] nil)))
|
||||||
(assoc-in [:workspace :history :current] nil)))
|
(let [page (get-in state [:pages-by-id id])
|
||||||
|
|
||||||
(let [packed (stpr/pack-page state id)
|
|
||||||
page (get-in state [:pages-by-id id])
|
|
||||||
page' (assoc page
|
page' (assoc page
|
||||||
:history true
|
:history true
|
||||||
:data (:data history)
|
:data (:data history)
|
||||||
:version (:version history))]
|
:version (:version history))]
|
||||||
(-> state
|
(-> state
|
||||||
(stpr/unpack-page page')
|
(stpr/unpack-page page')
|
||||||
(assoc-in [:workspace :history :selected] (:id history))
|
(assoc-in [:workspace :history :selected] (:id history)))))))
|
||||||
(update-in [:workspace :history :current] (fnil identity packed)))))))
|
|
||||||
|
|
||||||
(defn select-page-history
|
(defn select-page-history
|
||||||
[id history]
|
[id history]
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
(defmethod -do :fetch/page-history
|
(defmethod -do :fetch/page-history
|
||||||
[type {:keys [page] :as params}]
|
[type {:keys [page] :as params}]
|
||||||
(let [url (str url "/pages/" page "/history")
|
(let [url (str url "/pages/" page "/history")
|
||||||
query (select-keys params [:max :since])]
|
query (select-keys params [:max :since :pinned])]
|
||||||
(send! {:method :get :url url :query query })))
|
(send! {:method :get :url url :query query })))
|
||||||
|
|
||||||
(defmethod -do :delete/page
|
(defmethod -do :delete/page
|
||||||
|
|
|
@ -23,10 +23,19 @@
|
||||||
acc))
|
acc))
|
||||||
shapes
|
shapes
|
||||||
shapes))))
|
shapes))))
|
||||||
|
(defn assoc-page
|
||||||
|
[state {:keys [id] :as page}]
|
||||||
|
(assoc-in state [:pagedata-by-id id] page))
|
||||||
|
|
||||||
|
(defn dissoc-page
|
||||||
|
[state id]
|
||||||
|
(update state :pagedata-by-id dissoc id))
|
||||||
|
|
||||||
(defn pack-page
|
(defn pack-page
|
||||||
"Return a packed version of page object ready
|
"Return a packed version of page object ready
|
||||||
for send to remore storage service."
|
for send to remore storage service."
|
||||||
[state id]
|
[state id]
|
||||||
|
(time
|
||||||
(let [page (get-in state [:pages-by-id id])
|
(let [page (get-in state [:pages-by-id id])
|
||||||
xf (filter #(= (:page (second %)) id))
|
xf (filter #(= (:page (second %)) id))
|
||||||
shapes (into {} xf (:shapes-by-id state))]
|
shapes (into {} xf (:shapes-by-id state))]
|
||||||
|
@ -34,7 +43,7 @@
|
||||||
(assoc-in [:data :shapes] (into [] (:shapes page)))
|
(assoc-in [:data :shapes] (into [] (:shapes page)))
|
||||||
(assoc-in [:data :shapes-by-id] shapes)
|
(assoc-in [:data :shapes-by-id] shapes)
|
||||||
(update-in [:data] dissoc :items)
|
(update-in [:data] dissoc :items)
|
||||||
(dissoc :shapes))))
|
(dissoc :shapes)))))
|
||||||
|
|
||||||
(defn unpack-page
|
(defn unpack-page
|
||||||
"Unpacks packed page object and assocs it to the
|
"Unpacks packed page object and assocs it to the
|
||||||
|
|
|
@ -39,7 +39,8 @@
|
||||||
(defn- history-toolbox-will-mount
|
(defn- history-toolbox-will-mount
|
||||||
[own]
|
[own]
|
||||||
(let [page @wb/page-l]
|
(let [page @wb/page-l]
|
||||||
(rs/emit! (dpg/fetch-page-history (:id page)))
|
(rs/emit! (dpg/fetch-page-history (:id page))
|
||||||
|
(dpg/fetch-pinned-page-history (:id page)))
|
||||||
(add-watch wb/page-l ::key (fn [_ _ ov nv]
|
(add-watch wb/page-l ::key (fn [_ _ ov nv]
|
||||||
(when (and (> (:version nv) (:version ov))
|
(when (and (> (:version nv) (:version ov))
|
||||||
(not (:history nv)))
|
(not (:history nv)))
|
||||||
|
@ -54,7 +55,8 @@
|
||||||
|
|
||||||
(defn history-list-render
|
(defn history-list-render
|
||||||
[own page history]
|
[own page history]
|
||||||
(let [select #(rs/emit! (dpg/select-page-history (:id page) %))]
|
(let [select #(rs/emit! (dpg/select-page-history (:id page) %))
|
||||||
|
show-more? (> (count (:items history)) 15)]
|
||||||
(html
|
(html
|
||||||
[:ul.history-content
|
[:ul.history-content
|
||||||
[:li {:class (when-not (:selected history) "current")
|
[:li {:class (when-not (:selected history) "current")
|
||||||
|
@ -68,9 +70,9 @@
|
||||||
[:div.pin-icon i/pin]
|
[:div.pin-icon i/pin]
|
||||||
[:span (str "Version " (:version item)
|
[:span (str "Version " (:version item)
|
||||||
" (" (dt/timeago (:created-at item)) ")")]])
|
" (" (dt/timeago (:created-at item)) ")")]])
|
||||||
|
(if show-more?
|
||||||
[:li
|
[:li
|
||||||
[:a.btn-primary.btn-small "view more"]]])))
|
[:a.btn-primary.btn-small "view more"]])])))
|
||||||
|
|
||||||
(def history-list
|
(def history-list
|
||||||
(mx/component
|
(mx/component
|
||||||
|
|
Loading…
Reference in a new issue