From 6ef76673e88c9cc4e6c52df056abd4c4d7691644 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 28 Mar 2016 18:49:09 +0300 Subject: [PATCH] Add proper history loading and history state management. --- src/uxbox/data/pages.cljs | 102 +++++++++++++------- src/uxbox/repo/pages.cljs | 2 +- src/uxbox/state/project.cljs | 11 ++- src/uxbox/ui/workspace/sidebar/history.cljs | 12 ++- 4 files changed, 83 insertions(+), 44 deletions(-) diff --git a/src/uxbox/data/pages.cljs b/src/uxbox/data/pages.cljs index d5b5fd034..6adec5059 100644 --- a/src/uxbox/data/pages.cljs +++ b/src/uxbox/data/pages.cljs @@ -26,7 +26,9 @@ (defrecord PagesFetched [pages] rs/UpdateEvent (-apply-update [_ state] - (reduce stpr/unpack-page state pages))) + (as-> state $ + (reduce stpr/unpack-page $ pages) + (reduce stpr/assoc-page $ pages)))) (defn pages-fetched? [v] @@ -56,14 +58,16 @@ rs/WatchEvent (-apply-watch [this state s] (letfn [(on-created [{page :payload}] - #(stpr/unpack-page % page)) + (rx/of + #(stpr/unpack-page % page) + #(stpr/assoc-page % page))) (on-failed [page] (uum/error (tr "errors.auth")) (rx/empty))] (let [params (-> (into {} this) (assoc :data {}))] (->> (rp/do :create/page params) - (rx/map on-created) + (rx/mapcat on-created) (rx/catch on-failed)))))) (def ^:static +create-page-schema+ @@ -80,12 +84,11 @@ ;; --- Update Page -(defrecord UpdatePage [id name width height layout data] +(defrecord UpdatePage [id name width height layout] rs/UpdateEvent (-apply-update [_ state] (letfn [(updater [page] (merge page - (when data {:data data}) (when width {:width width}) (when height {:height height}) (when name {:name name})))] @@ -94,13 +97,16 @@ rs/WatchEvent (-apply-watch [this state s] (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] (uum/error (tr "errors.page-update")) (rx/empty))] - (->> (rp/do :update/page (into {} this)) - (rx/map on-success) - (rx/catch on-failure))))) + (let [page (stpr/pack-page state id)] + (->> (rp/do :update/page page) + (rx/mapcat on-success) + (rx/catch on-failure)))))) (def ^:const +update-page-schema+ {:name [sc/required sc/string] @@ -181,37 +187,67 @@ [id] (DeletePage. id)) -;; --- Page History Fetched +;; --- Pinned Page History Fetched -(defrecord PageHistoryFetched [history] +(defrecord PinnedPageHistoryFetched [history] rs/UpdateEvent (-apply-update [_ state] - (-> state - (assoc-in [:workspace :history :items] history)))) - ;; (assoc-in [:workspace :history :selected] nil)))) + (assoc-in state [:workspace :history :pinned-items] history))) + +;; --- 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 -(defrecord FetchPageHistory [id] +(defrecord FetchPageHistory [id since max] rs/WatchEvent (-apply-watch [_ state s] (println "FetchPageHistory" id) (letfn [(on-success [{history :payload}] - (->PageHistoryFetched history)) + (->PageHistoryFetched history (not (nil? since)))) (on-failure [e] (uum/error (tr "errors.fetch-page-history")) (rx/empty))] - (->> (rp/do :fetch/page-history {:page id :max 15}) - (rx/map on-success) - (rx/catch on-failure)))) - - rs/EffectEvent - (-apply-effect [_ state] - )) + (let [params {:page id :max (or max 15)}] + (->> (rp/do :fetch/page-history params) + (rx/map on-success) + (rx/catch on-failure)))))) (defn fetch-page-history - [id] - (FetchPageHistory. id)) + ([id] + (fetch-page-history id nil)) + ([id params] + (map->FetchPageHistory (assoc params :id id)))) ;; --- Clean Page History @@ -229,30 +265,22 @@ ;; --- 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] rs/UpdateEvent (-apply-update [_ state] (if (nil? history) - (let [packed (get-in state [:workspace :history :current])] + (let [packed (get-in state [:pagedata-by-id id])] (-> state (stpr/unpack-page packed) - (assoc-in [:workspace :history :selected] nil) - (assoc-in [:workspace :history :current] nil))) - - (let [packed (stpr/pack-page state id) - page (get-in state [:pages-by-id id]) + (assoc-in [:workspace :history :selected] nil))) + (let [page (get-in state [:pages-by-id id]) page' (assoc page :history true :data (:data history) :version (:version history))] (-> state (stpr/unpack-page page') - (assoc-in [:workspace :history :selected] (:id history)) - (update-in [:workspace :history :current] (fnil identity packed))))))) + (assoc-in [:workspace :history :selected] (:id history))))))) (defn select-page-history [id history] diff --git a/src/uxbox/repo/pages.cljs b/src/uxbox/repo/pages.cljs index 954c846ef..facc59d15 100644 --- a/src/uxbox/repo/pages.cljs +++ b/src/uxbox/repo/pages.cljs @@ -26,7 +26,7 @@ (defmethod -do :fetch/page-history [type {:keys [page] :as params}] (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 }))) (defmethod -do :delete/page diff --git a/src/uxbox/state/project.cljs b/src/uxbox/state/project.cljs index 725d67f36..a5da4c371 100644 --- a/src/uxbox/state/project.cljs +++ b/src/uxbox/state/project.cljs @@ -23,10 +23,19 @@ acc)) 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 "Return a packed version of page object ready for send to remore storage service." [state id] + (time (let [page (get-in state [:pages-by-id id]) xf (filter #(= (:page (second %)) id)) shapes (into {} xf (:shapes-by-id state))] @@ -34,7 +43,7 @@ (assoc-in [:data :shapes] (into [] (:shapes page))) (assoc-in [:data :shapes-by-id] shapes) (update-in [:data] dissoc :items) - (dissoc :shapes)))) + (dissoc :shapes))))) (defn unpack-page "Unpacks packed page object and assocs it to the diff --git a/src/uxbox/ui/workspace/sidebar/history.cljs b/src/uxbox/ui/workspace/sidebar/history.cljs index 7d8dba810..a3f3729e3 100644 --- a/src/uxbox/ui/workspace/sidebar/history.cljs +++ b/src/uxbox/ui/workspace/sidebar/history.cljs @@ -39,7 +39,8 @@ (defn- history-toolbox-will-mount [own] (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] (when (and (> (:version nv) (:version ov)) (not (:history nv))) @@ -54,7 +55,8 @@ (defn history-list-render [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 [:ul.history-content [:li {:class (when-not (:selected history) "current") @@ -68,9 +70,9 @@ [:div.pin-icon i/pin] [:span (str "Version " (:version item) " (" (dt/timeago (:created-at item)) ")")]]) - - [:li - [:a.btn-primary.btn-small "view more"]]]))) + (if show-more? + [:li + [:a.btn-primary.btn-small "view more"]])]))) (def history-list (mx/component