mirror of
https://github.com/penpot/penpot.git
synced 2026-08-01 10:56:20 +00:00
✨ Enable history sidebar and dialog.
This commit is contained in:
parent
006fcaa511
commit
7598637efc
@ -2,127 +2,155 @@
|
|||||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) 2016-2017 Andrey Antukh <niwi@niwi.nz>
|
;; Copyright (c) 2016-2019 Andrey Antukh <niwi@niwi.nz>
|
||||||
|
|
||||||
(ns uxbox.main.data.history
|
(ns uxbox.main.data.history
|
||||||
(:require [beicon.core :as rx]
|
(:require
|
||||||
[potok.core :as ptk]
|
[beicon.core :as rx]
|
||||||
[uxbox.main.data.pages :as udp]
|
[cljs.spec.alpha :as s]
|
||||||
[uxbox.main.repo :as rp]
|
[potok.core :as ptk]
|
||||||
[uxbox.util.data :refer [replace-by-id
|
[uxbox.main.data.pages :as udp]
|
||||||
index-by]]))
|
[uxbox.main.repo :as rp]
|
||||||
|
[uxbox.util.data :refer [replace-by-id index-by]]
|
||||||
|
[uxbox.util.spec :as us]))
|
||||||
|
|
||||||
;; TODO: this need refactor (completely broken)
|
;; --- Schema
|
||||||
|
|
||||||
|
(s/def ::pinned ::us/bool)
|
||||||
|
(s/def ::id ::us/uuid)
|
||||||
|
(s/def ::label ::us/string)
|
||||||
|
(s/def ::project ::us/uuid)
|
||||||
|
(s/def ::created-at ::us/inst)
|
||||||
|
(s/def ::modified-at ::us/inst)
|
||||||
|
(s/def ::version ::us/number)
|
||||||
|
(s/def ::user ::us/uuid)
|
||||||
|
|
||||||
|
(s/def ::shapes
|
||||||
|
(s/every ::udp/minimal-shape :kind vector?))
|
||||||
|
|
||||||
|
(s/def ::data
|
||||||
|
(s/keys :req-un [::shapes]))
|
||||||
|
|
||||||
|
(s/def ::history-entry
|
||||||
|
(s/keys :req-un [::id
|
||||||
|
::pinned
|
||||||
|
::label
|
||||||
|
::project
|
||||||
|
::created-at
|
||||||
|
::modified-at
|
||||||
|
::version
|
||||||
|
::user
|
||||||
|
::data]))
|
||||||
|
|
||||||
|
(s/def ::history-entries
|
||||||
|
(s/every ::history-entry))
|
||||||
|
|
||||||
;; --- Initialize History State
|
;; --- Initialize History State
|
||||||
|
|
||||||
(declare fetch-history)
|
(declare fetch-history)
|
||||||
(declare fetch-pinned-history)
|
(declare fetch-pinned-history)
|
||||||
|
|
||||||
(deftype Initialize [page-id]
|
|
||||||
ptk/UpdateEvent
|
|
||||||
(update [_ state]
|
|
||||||
(let [data {:section :main
|
|
||||||
:selected nil
|
|
||||||
:pinned #{}
|
|
||||||
:items #{}
|
|
||||||
:byver {}}]
|
|
||||||
(assoc-in state [:workspace :history] data)))
|
|
||||||
|
|
||||||
ptk/WatchEvent
|
|
||||||
(watch [_ state stream]
|
|
||||||
(let [page-id (get-in state [:workspace :page])
|
|
||||||
stopper (->> stream
|
|
||||||
(rx/filter #(= % ::stop-changes-watcher))
|
|
||||||
(rx/take 1))]
|
|
||||||
(rx/merge
|
|
||||||
(->> stream
|
|
||||||
(rx/take-until stopper)
|
|
||||||
(rx/filter udp/page-persisted?)
|
|
||||||
(rx/flat-map #(rx/of (fetch-history page-id)
|
|
||||||
(fetch-pinned-history page-id))))
|
|
||||||
(rx/of (fetch-history page-id)
|
|
||||||
(fetch-pinned-history page-id))))))
|
|
||||||
|
|
||||||
(defn initialize
|
(defn initialize
|
||||||
[page-id]
|
[id]
|
||||||
{:pre [(uuid? page-id)]}
|
(s/assert ::us/uuid id)
|
||||||
(Initialize. page-id))
|
(ptk/reify ::initialize
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(update-in state [:workspace id]
|
||||||
|
assoc :history {:selected nil
|
||||||
|
:pinned #{}
|
||||||
|
:items #{}
|
||||||
|
:byver {}}))
|
||||||
|
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state stream]
|
||||||
|
(rx/of (fetch-history id)
|
||||||
|
(fetch-pinned-history id)))))
|
||||||
|
|
||||||
|
;; --- Watch Page Changes
|
||||||
|
|
||||||
|
(defn watch-page-changes
|
||||||
|
[id]
|
||||||
|
(s/assert ::us/uuid id)
|
||||||
|
(reify
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state stream]
|
||||||
|
(let [stopper (rx/filter #(= % ::stop-page-watcher) stream)]
|
||||||
|
(->> stream
|
||||||
|
(rx/filter udp/page-persisted?)
|
||||||
|
(rx/debounce 1000)
|
||||||
|
(rx/flat-map #(rx/of (fetch-history id)
|
||||||
|
(fetch-pinned-history id)))
|
||||||
|
(rx/take-until stopper))))))
|
||||||
|
|
||||||
;; --- Pinned Page History Fetched
|
;; --- Pinned Page History Fetched
|
||||||
|
|
||||||
(deftype PinnedPageHistoryFetched [items]
|
(defn pinned-history-fetched
|
||||||
ptk/UpdateEvent
|
|
||||||
(update [_ state]
|
|
||||||
(let [items-map (index-by :version items)
|
|
||||||
items-set (into #{} items)]
|
|
||||||
(update-in state [:workspace :history]
|
|
||||||
(fn [history]
|
|
||||||
(-> history
|
|
||||||
(assoc :pinned items-set)
|
|
||||||
(update :byver merge items-map)))))))
|
|
||||||
|
|
||||||
(defn pinned-page-history-fetched
|
|
||||||
[items]
|
[items]
|
||||||
(PinnedPageHistoryFetched. items))
|
(s/assert ::history-entries items)
|
||||||
|
(ptk/reify ::pinned-history-fetched
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(let [pid (get-in state [:workspace :current])
|
||||||
|
items-map (index-by :version items)
|
||||||
|
items-set (into #{} items)]
|
||||||
|
(update-in state [:workspace pid :history]
|
||||||
|
(fn [history]
|
||||||
|
(-> history
|
||||||
|
(assoc :pinned items-set)
|
||||||
|
(update :byver merge items-map))))))))
|
||||||
|
|
||||||
;; --- Fetch Pinned Page History
|
;; --- Fetch Pinned Page History
|
||||||
|
|
||||||
(deftype FetchPinnedPageHistory [id]
|
|
||||||
ptk/WatchEvent
|
|
||||||
(watch [_ state s]
|
|
||||||
(let [params {:page id :pinned true}]
|
|
||||||
(->> (rp/req :fetch/page-history params)
|
|
||||||
(rx/map :payload)
|
|
||||||
(rx/map pinned-page-history-fetched)))))
|
|
||||||
|
|
||||||
(defn fetch-pinned-history
|
(defn fetch-pinned-history
|
||||||
[id]
|
[id]
|
||||||
{:pre [(uuid? id)]}
|
(s/assert ::us/uuid id)
|
||||||
(FetchPinnedPageHistory. id))
|
(ptk/reify ::fetch-pinned-history
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state s]
|
||||||
|
(let [params {:page id :pinned true}]
|
||||||
|
(->> (rp/req :fetch/page-history params)
|
||||||
|
(rx/map :payload)
|
||||||
|
(rx/map pinned-history-fetched))))))
|
||||||
|
|
||||||
;; --- Page History Fetched
|
;; --- Page History Fetched
|
||||||
|
|
||||||
(deftype PageHistoryFetched [items]
|
(defn history-fetched
|
||||||
ptk/UpdateEvent
|
|
||||||
(update [_ state]
|
|
||||||
(let [versions (into #{} (map :version) items)
|
|
||||||
items-map (index-by items :version)
|
|
||||||
min-version (apply min versions)
|
|
||||||
max-version (apply max versions)]
|
|
||||||
(update-in state [:workspace :history]
|
|
||||||
(fn [history]
|
|
||||||
(-> history
|
|
||||||
(assoc :min-version min-version)
|
|
||||||
(assoc :max-version max-version)
|
|
||||||
(update :byver merge items-map)
|
|
||||||
(update :items #(reduce conj % items))))))))
|
|
||||||
|
|
||||||
;; TODO: add spec to history items
|
|
||||||
|
|
||||||
(defn page-history-fetched
|
|
||||||
[items]
|
[items]
|
||||||
(PageHistoryFetched. items))
|
(s/assert ::history-entries items)
|
||||||
|
(ptk/reify ::history-fetched
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(let [pid (get-in state [:workspace :current])
|
||||||
|
versions (into #{} (map :version) items)
|
||||||
|
items-map (index-by :version items)
|
||||||
|
min-version (apply min versions)
|
||||||
|
max-version (apply max versions)]
|
||||||
|
(update-in state [:workspace pid :history]
|
||||||
|
(fn [history]
|
||||||
|
(-> history
|
||||||
|
(assoc :min-version min-version)
|
||||||
|
(assoc :max-version max-version)
|
||||||
|
(update :byver merge items-map)
|
||||||
|
(update :items #(reduce conj % items)))))))))
|
||||||
|
|
||||||
;; --- Fetch Page History
|
;; --- Fetch Page History
|
||||||
|
|
||||||
(deftype FetchPageHistory [page-id since max]
|
|
||||||
ptk/WatchEvent
|
|
||||||
(watch [_ state s]
|
|
||||||
(let [params (merge {:page page-id
|
|
||||||
:max (or max 15)}
|
|
||||||
(when since
|
|
||||||
{:since since}))]
|
|
||||||
(->> (rp/req :fetch/page-history params)
|
|
||||||
(rx/map :payload)
|
|
||||||
(rx/map page-history-fetched)))))
|
|
||||||
|
|
||||||
(defn fetch-history
|
(defn fetch-history
|
||||||
([id]
|
([id]
|
||||||
(fetch-history id nil))
|
(fetch-history id nil))
|
||||||
([id {:keys [since max]}]
|
([id {:keys [since max]}]
|
||||||
{:pre [(uuid? id)]}
|
(s/assert ::us/uuid id)
|
||||||
(FetchPageHistory. id since max)))
|
(ptk/reify ::fetch-history
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state s]
|
||||||
|
(let [params (merge {:page id
|
||||||
|
:max (or max 5)}
|
||||||
|
(when since
|
||||||
|
{:since since}))]
|
||||||
|
(->> (rp/req :fetch/page-history params)
|
||||||
|
(rx/map :payload)
|
||||||
|
(rx/map history-fetched)))))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Context Aware Events
|
;; Context Aware Events
|
||||||
@ -142,186 +170,101 @@
|
|||||||
|
|
||||||
;; --- Load More
|
;; --- Load More
|
||||||
|
|
||||||
(deftype LoadMore []
|
(def load-more
|
||||||
ptk/WatchEvent
|
(ptk/reify ::load-more
|
||||||
(watch [_ state stream]
|
ptk/WatchEvent
|
||||||
(let [page-id (get-in state [:workspace :page])
|
(watch [_ state stream]
|
||||||
since (get-in state [:workspace :history :min-version])]
|
(let [pid (get-in state [:workspace :current])
|
||||||
(rx/of (fetch-history page-id {:since since})))))
|
since (get-in state [:workspace pid :history :min-version])]
|
||||||
|
(rx/of (fetch-history pid {:since since}))))))
|
||||||
(defn load-more
|
|
||||||
[]
|
|
||||||
(LoadMore.))
|
|
||||||
|
|
||||||
;; --- Select Page History
|
;; --- Select Page History
|
||||||
|
|
||||||
(deftype SelectPageHistory [version]
|
(defn select
|
||||||
ptk/UpdateEvent
|
|
||||||
(update [_ state]
|
|
||||||
(let [history (get-in state [:workspace :history])
|
|
||||||
item (get-in history [:byver version])
|
|
||||||
page (get-in state [:pages (:page item)])
|
|
||||||
|
|
||||||
page (-> (get-in state [:pages (:page item)])
|
|
||||||
(assoc :history true
|
|
||||||
:data (:data item)))]
|
|
||||||
(-> state
|
|
||||||
(udp/unpack-page page)
|
|
||||||
(assoc-in [:workspace :history :selected] version)))))
|
|
||||||
|
|
||||||
(defn select-page-history
|
|
||||||
[version]
|
[version]
|
||||||
{:pre [(integer? version)]}
|
(s/assert int? version)
|
||||||
(SelectPageHistory. version))
|
(ptk/reify ::select
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(let [pid (get-in state [:workspace :current])
|
||||||
|
item (get-in state [:workspace pid :history :byver version])
|
||||||
|
page (-> (get-in state [:pages pid])
|
||||||
|
(assoc :history true
|
||||||
|
:data (:data item)))]
|
||||||
|
(-> state
|
||||||
|
(udp/unpack-page page)
|
||||||
|
(assoc-in [:workspace pid :history :selected] version))))))
|
||||||
|
|
||||||
;; --- Apply Selected History
|
;; --- Apply Selected History
|
||||||
|
|
||||||
(deftype ApplySelectedHistory []
|
(def apply-selected
|
||||||
ptk/UpdateEvent
|
(ptk/reify ::apply-selected
|
||||||
(update [_ state]
|
ptk/UpdateEvent
|
||||||
(let [page-id (get-in state [:workspace :page])]
|
(update [_ state]
|
||||||
(-> state
|
(let [pid (get-in state [:workspace :current])]
|
||||||
(update-in [:pages page-id] dissoc :history)
|
(-> state
|
||||||
(assoc-in [:workspace :history :selected] nil))))
|
(update-in [:pages pid] dissoc :history)
|
||||||
|
(assoc-in [:workspace pid :history :selected] nil))))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state s]
|
(watch [_ state s]
|
||||||
(let [page-id (get-in state [:workspace :page])]
|
(let [pid (get-in state [:workspace :current])]
|
||||||
(rx/of (udp/persist-page page-id)))))
|
(rx/of (udp/persist-page pid))))))
|
||||||
|
|
||||||
(defn apply-selected-history
|
|
||||||
[]
|
|
||||||
(ApplySelectedHistory.))
|
|
||||||
|
|
||||||
;; --- Deselect Page History
|
;; --- Deselect Page History
|
||||||
|
|
||||||
(deftype DeselectPageHistory [^:mutable noop]
|
(def deselect
|
||||||
ptk/UpdateEvent
|
(ptk/reify ::deselect
|
||||||
(update [_ state]
|
ptk/UpdateEvent
|
||||||
(let [page-id (get-in state [:workspace :page])
|
(update [_ state]
|
||||||
selected (get-in state [:workspace :history :selected])]
|
(let [pid (get-in state [:workspace :current])
|
||||||
(if (nil? selected)
|
packed (get-in state [:packed-pages pid])]
|
||||||
(do
|
(-> (udp/unpack-page state packed)
|
||||||
(set! noop true)
|
(assoc-in [:workspace pid :history :selected] nil))))))
|
||||||
state)
|
|
||||||
(let [packed (get-in state [:packed-pages page-id])]
|
|
||||||
(-> (udp/unpack-page state packed)
|
|
||||||
(assoc-in [:workspace :history :deselecting] true)
|
|
||||||
(assoc-in [:workspace :history :selected] nil))))))
|
|
||||||
|
|
||||||
ptk/WatchEvent
|
|
||||||
(watch [_ state s]
|
|
||||||
(if noop
|
|
||||||
(rx/empty)
|
|
||||||
(->> (rx/of #(assoc-in % [:workspace :history :deselecting] false))
|
|
||||||
(rx/delay 500)))))
|
|
||||||
|
|
||||||
(defn deselect-page-history
|
|
||||||
[]
|
|
||||||
(DeselectPageHistory. false))
|
|
||||||
|
|
||||||
;; --- Refresh Page History
|
;; --- Refresh Page History
|
||||||
|
|
||||||
(deftype RefreshHistory []
|
(def refres-history
|
||||||
ptk/WatchEvent
|
(ptk/reify ::refresh-history
|
||||||
(watch [_ state stream]
|
ptk/WatchEvent
|
||||||
(let [page-id (get-in state [:workspace :page])
|
(watch [_ state stream]
|
||||||
history (get-in state [:workspace :history])
|
(let [pid (get-in state [:workspace :current])
|
||||||
maxitems (count (:items history))]
|
history (get-in state [:workspace pid :history])
|
||||||
(rx/of (fetch-history page-id {:max maxitems})
|
maxitems (count (:items history))]
|
||||||
(fetch-pinned-history page-id)))))
|
(rx/of (fetch-history pid {:max maxitems})
|
||||||
|
(fetch-pinned-history pid))))))
|
||||||
(defn refres-history
|
|
||||||
[]
|
|
||||||
(RefreshHistory.))
|
|
||||||
|
|
||||||
;; --- History Item Updated
|
;; --- History Item Updated
|
||||||
|
|
||||||
(deftype HistoryItemUpdated [item]
|
|
||||||
ptk/UpdateEvent
|
|
||||||
(update [_ state]
|
|
||||||
(update-in state [:workspace :history]
|
|
||||||
(fn [history]
|
|
||||||
(-> history
|
|
||||||
(update :items #(into #{} (replace-by-id item) %))
|
|
||||||
(update :pinned #(into #{} (replace-by-id item) %))
|
|
||||||
(assoc-in [:byver (:id item)] item))))))
|
|
||||||
|
|
||||||
(defn history-updated?
|
|
||||||
[item]
|
|
||||||
(instance? HistoryItemUpdated item))
|
|
||||||
|
|
||||||
(defn history-updated
|
(defn history-updated
|
||||||
[item]
|
[item]
|
||||||
(HistoryItemUpdated. item))
|
(s/assert ::history-entry item)
|
||||||
|
(ptk/reify ::history-item-updated
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(let [pid (get-in state [:workspace :current])]
|
||||||
|
(update-in state [:workspace pid :history]
|
||||||
|
(fn [history]
|
||||||
|
(-> history
|
||||||
|
(update :items #(into #{} (replace-by-id item) %))
|
||||||
|
(update :pinned #(into #{} (replace-by-id item) %))
|
||||||
|
(assoc-in [:byver (:version item)] item))))))))
|
||||||
|
|
||||||
|
(defn history-updated?
|
||||||
|
[v]
|
||||||
|
(= ::history-item-updated (ptk/type v)))
|
||||||
|
|
||||||
;; --- Update History Item
|
;; --- Update History Item
|
||||||
|
|
||||||
(deftype UpdateHistoryItem [item]
|
|
||||||
ptk/WatchEvent
|
|
||||||
(watch [_ state stream]
|
|
||||||
(rx/concat
|
|
||||||
(->> (rp/req :update/page-history item)
|
|
||||||
(rx/map :payload)
|
|
||||||
(rx/map history-updated))
|
|
||||||
(->> (rx/filter history-updated? stream)
|
|
||||||
(rx/take 1)
|
|
||||||
(rx/map refres-history)))))
|
|
||||||
|
|
||||||
(defn update-history-item
|
(defn update-history-item
|
||||||
[item]
|
[item]
|
||||||
(UpdateHistoryItem. item))
|
(ptk/reify ::update-history-item
|
||||||
|
ptk/WatchEvent
|
||||||
;; --- Forward to Next Version
|
(watch [_ state stream]
|
||||||
|
(rx/concat
|
||||||
(deftype ForwardToNextVersion []
|
(->> (rp/req :update/page-history item)
|
||||||
ptk/WatchEvent
|
(rx/map :payload)
|
||||||
(watch [_ state s]
|
(rx/map history-updated))
|
||||||
(let [workspace (:workspace state)
|
(->> (rx/filter history-updated? stream)
|
||||||
history (:history workspace)
|
(rx/take 1)
|
||||||
version (:selected history)]
|
(rx/map (constantly refres-history)))))))
|
||||||
(cond
|
|
||||||
(nil? version)
|
|
||||||
(rx/empty)
|
|
||||||
|
|
||||||
(>= (:max-version history) (inc version))
|
|
||||||
(rx/of (select-page-history (inc version)))
|
|
||||||
|
|
||||||
(> (inc version) (:max-version history))
|
|
||||||
(rx/of (deselect-page-history))
|
|
||||||
|
|
||||||
:else
|
|
||||||
(rx/empty)))))
|
|
||||||
|
|
||||||
(defn forward-to-next-version
|
|
||||||
[]
|
|
||||||
(ForwardToNextVersion.))
|
|
||||||
|
|
||||||
;; --- Backwards to Previous Version
|
|
||||||
|
|
||||||
(deftype BackwardsToPreviousVersion []
|
|
||||||
ptk/WatchEvent
|
|
||||||
(watch [_ state s]
|
|
||||||
(let [workspace (:workspace state)
|
|
||||||
history (:history workspace)
|
|
||||||
version (:selected history)]
|
|
||||||
(cond
|
|
||||||
(nil? version)
|
|
||||||
(let [maxv (:max-version history)]
|
|
||||||
(rx/of (select-page-history maxv)))
|
|
||||||
|
|
||||||
(pos? (dec version))
|
|
||||||
(if (contains? (:by-version history) (dec version))
|
|
||||||
(rx/of (select-page-history (dec version)))
|
|
||||||
(let [since (:min-version history)
|
|
||||||
page (:page workspace)
|
|
||||||
params {:since since}]
|
|
||||||
(rx/of (fetch-history page params)
|
|
||||||
(select-page-history (dec version)))))
|
|
||||||
|
|
||||||
:else
|
|
||||||
(rx/empty)))))
|
|
||||||
|
|
||||||
(defn backwards-to-previous-version
|
|
||||||
[]
|
|
||||||
(BackwardsToPreviousVersion.))
|
|
||||||
|
|||||||
@ -57,6 +57,7 @@
|
|||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [default-flags #{:sitemap :drawtools :layers :element-options :rules}
|
(let [default-flags #{:sitemap :drawtools :layers :element-options :rules}
|
||||||
initial-workspace {:project-id project-id
|
initial-workspace {:project-id project-id
|
||||||
|
:initialized true
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:zoom 1
|
:zoom 1
|
||||||
:flags default-flags
|
:flags default-flags
|
||||||
@ -65,7 +66,11 @@
|
|||||||
:drawing-tool nil
|
:drawing-tool nil
|
||||||
:tooltip nil}]
|
:tooltip nil}]
|
||||||
(-> state
|
(-> state
|
||||||
(update-in [:workspace page-id] #(if (nil? %) initial-workspace %))
|
(update-in [:workspace page-id]
|
||||||
|
(fn [wsp]
|
||||||
|
(if (:initialized wsp)
|
||||||
|
wsp
|
||||||
|
(merge wsp initial-workspace))))
|
||||||
(assoc-in [:workspace :current] page-id))))
|
(assoc-in [:workspace :current] page-id))))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
[uxbox.main.ui.workspace.scroll :as scroll]
|
[uxbox.main.ui.workspace.scroll :as scroll]
|
||||||
[uxbox.main.ui.workspace.shortcuts :as shortcuts]
|
[uxbox.main.ui.workspace.shortcuts :as shortcuts]
|
||||||
[uxbox.main.ui.workspace.sidebar :refer [left-sidebar right-sidebar]]
|
[uxbox.main.ui.workspace.sidebar :refer [left-sidebar right-sidebar]]
|
||||||
;; [uxbox.main.ui.workspace.sidebar.history :refer [history-dialog]]
|
[uxbox.main.ui.workspace.sidebar.history :refer [history-dialog]]
|
||||||
[uxbox.main.ui.workspace.streams :as uws]
|
[uxbox.main.ui.workspace.streams :as uws]
|
||||||
[uxbox.util.data :refer [classnames]]
|
[uxbox.util.data :refer [classnames]]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
@ -61,12 +61,14 @@
|
|||||||
|
|
||||||
(defn- subscribe
|
(defn- subscribe
|
||||||
[canvas page]
|
[canvas page]
|
||||||
;; (scroll/scroll-to-page-center (mf/ref-node canvas) page)
|
|
||||||
(st/emit! (udp/watch-page-changes (:id page))
|
(st/emit! (udp/watch-page-changes (:id page))
|
||||||
(udu/watch-page-changes (:id page))
|
(udu/watch-page-changes (:id page))
|
||||||
|
(udh/initialize (:id page))
|
||||||
|
(udh/watch-page-changes (:id page))
|
||||||
(dw/start-shapes-watcher (:id page)))
|
(dw/start-shapes-watcher (:id page)))
|
||||||
(let [sub (shortcuts/init)]
|
(let [sub (shortcuts/init)]
|
||||||
#(do (st/emit! ::udp/stop-page-watcher
|
#(do (st/emit! ::udp/stop-page-watcher
|
||||||
|
::udh/stop-page-watcher
|
||||||
::dw/stop-shapes-watcher)
|
::dw/stop-shapes-watcher)
|
||||||
(rx/cancel! sub))))
|
(rx/cancel! sub))))
|
||||||
|
|
||||||
@ -74,7 +76,6 @@
|
|||||||
[{:keys [page] :as props}]
|
[{:keys [page] :as props}]
|
||||||
(let [flags (or (mf/deref refs/flags) #{})
|
(let [flags (or (mf/deref refs/flags) #{})
|
||||||
canvas (mf/use-ref nil)
|
canvas (mf/use-ref nil)
|
||||||
|
|
||||||
left-sidebar? (not (empty? (keep flags [:layers :sitemap
|
left-sidebar? (not (empty? (keep flags [:layers :sitemap
|
||||||
:document-history])))
|
:document-history])))
|
||||||
right-sidebar? (not (empty? (keep flags [:icons :drawtools
|
right-sidebar? (not (empty? (keep flags [:icons :drawtools
|
||||||
@ -101,7 +102,7 @@
|
|||||||
:on-scroll on-scroll
|
:on-scroll on-scroll
|
||||||
:on-wheel #(on-wheel % canvas)}
|
:on-wheel #(on-wheel % canvas)}
|
||||||
|
|
||||||
;; (history-dialog)
|
[:& history-dialog]
|
||||||
|
|
||||||
;; Rules
|
;; Rules
|
||||||
(when (contains? flags :rules)
|
(when (contains? flags :rules)
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
(:require
|
(:require
|
||||||
[rumext.alpha :as mf]
|
[rumext.alpha :as mf]
|
||||||
[uxbox.main.ui.workspace.sidebar.drawtools :refer [draw-toolbox]]
|
[uxbox.main.ui.workspace.sidebar.drawtools :refer [draw-toolbox]]
|
||||||
;; [uxbox.main.ui.workspace.sidebar.history :refer [history-toolbox]]
|
[uxbox.main.ui.workspace.sidebar.history :refer [history-toolbox]]
|
||||||
[uxbox.main.ui.workspace.sidebar.icons :refer [icons-toolbox]]
|
[uxbox.main.ui.workspace.sidebar.icons :refer [icons-toolbox]]
|
||||||
[uxbox.main.ui.workspace.sidebar.layers :refer [layers-toolbox]]
|
[uxbox.main.ui.workspace.sidebar.layers :refer [layers-toolbox]]
|
||||||
[uxbox.main.ui.workspace.sidebar.options :refer [options-toolbox]]
|
[uxbox.main.ui.workspace.sidebar.options :refer [options-toolbox]]
|
||||||
@ -27,8 +27,8 @@
|
|||||||
[:& sitemap-toolbox {:project-id (:project page)
|
[:& sitemap-toolbox {:project-id (:project page)
|
||||||
:current-page-id (:id page)
|
:current-page-id (:id page)
|
||||||
:page page}])
|
:page page}])
|
||||||
#_(when (contains? flags :document-history)
|
(when (contains? flags :document-history)
|
||||||
(history-toolbox page-id))
|
[:& history-toolbox])
|
||||||
(when (contains? flags :layers)
|
(when (contains? flags :layers)
|
||||||
[:& layers-toolbox {:page page}])]])
|
[:& layers-toolbox {:page page}])]])
|
||||||
|
|
||||||
|
|||||||
@ -2,134 +2,115 @@
|
|||||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) 2015-2017 Andrey Antukh <niwi@niwi.nz>
|
;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz>
|
||||||
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||||
|
|
||||||
(ns uxbox.main.ui.workspace.sidebar.history
|
(ns uxbox.main.ui.workspace.sidebar.history
|
||||||
(:require [uxbox.builtins.icons :as i]
|
(:require
|
||||||
[uxbox.main.refs :as refs]
|
[rumext.alpha :as mf]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.builtins.icons :as i]
|
||||||
[uxbox.main.data.history :as udh]
|
[uxbox.main.data.history :as udh]
|
||||||
[uxbox.main.data.pages :as udp]
|
[uxbox.main.data.pages :as udp]
|
||||||
[uxbox.main.data.workspace :as dw]
|
[uxbox.main.data.workspace :as dw]
|
||||||
[uxbox.util.data :refer [read-string]]
|
[uxbox.main.refs :as refs]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.util.i18n :refer (tr)]
|
[uxbox.util.data :refer [read-string]]
|
||||||
[rumext.alpha :as mf]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.util.router :as r]
|
[uxbox.util.i18n :refer (tr)]
|
||||||
[uxbox.util.time :as dt]))
|
[uxbox.util.router :as r]
|
||||||
|
[uxbox.util.time :as dt]))
|
||||||
|
|
||||||
;; --- History Item (Component)
|
;; --- History Item (Component)
|
||||||
|
|
||||||
;; (mf/def history-item
|
(mf/defc history-item
|
||||||
;; :mixins [mf/memo]
|
[{:keys [item selected?] :as props}]
|
||||||
;; :key-fn :id
|
(letfn [(on-select [event]
|
||||||
;; :render
|
(dom/prevent-default event)
|
||||||
;; (fn [own {:keys [::selected] :as item}]
|
(st/emit! (udh/select (:version item))))
|
||||||
;; (letfn [(on-select [event]
|
(on-pinned [event]
|
||||||
;; (dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
;; (st/emit! (udh/select-page-history (:version item))))
|
(dom/stop-propagation event)
|
||||||
;; (on-pinned [event]
|
(let [item (assoc item
|
||||||
;; (dom/prevent-default event)
|
:label "no label"
|
||||||
;; (dom/stop-propagation event)
|
:pinned (not (:pinned item)))]
|
||||||
;; (let [item (assoc item
|
(st/emit! (udh/update-history-item item))))]
|
||||||
;; :label "no label"
|
[:li {:class (when selected? "current")
|
||||||
;; :pinned (not (:pinned item)))]
|
:on-click on-select}
|
||||||
;; (st/emit! (udh/update-history-item item))))]
|
[:div.pin-icon {:on-click on-pinned
|
||||||
;; [:li {:class (when (= selected (:version item)) "current")
|
:class (when (:pinned item) "selected")}
|
||||||
;; :on-click on-select}
|
i/pin]
|
||||||
;; [:div.pin-icon {:on-click on-pinned
|
[:span (str "Version " (:version item)
|
||||||
;; :class (when (:pinned item) "selected")}
|
" (" (dt/timeago (:created-at item)) ")")]]))
|
||||||
;; i/pin]
|
|
||||||
;; [:span (str "Version " (:version item)
|
|
||||||
;; " (" (dt/timeago (:created-at item)) ")")]])))
|
|
||||||
|
|
||||||
;; ;; --- History List (Component)
|
;; --- History List (Component)
|
||||||
|
|
||||||
;; (mf/def history-list
|
(mf/defc history-list
|
||||||
;; :mixins [mf/memo mf/reactive]
|
[{:keys [history] :as props}]
|
||||||
;; :render
|
(let [items (reverse (sort-by :version (:items history)))
|
||||||
;; (fn [own {:keys [selected items min-version] :as history}]
|
show-more? (pos? (:min-version history))
|
||||||
;; (let [items (reverse (sort-by :version items))
|
load-more #(st/emit! udh/load-more)]
|
||||||
;; page (mf/react refs/selected-page)
|
[:ul.history-content
|
||||||
;; show-more? (pos? min-version)
|
(for [item items]
|
||||||
;; load-more #(st/emit! (udh/load-more))]
|
[:& history-item {:item item
|
||||||
;; [:ul.history-content
|
:key (:id item)
|
||||||
;; (for [item items]
|
:selected? (= (:selected history)
|
||||||
;; (history-item (assoc item ::selectd selected)))
|
(:version item))}])
|
||||||
;; (when show-more?
|
(when show-more?
|
||||||
;; [:li {:on-click load-more}
|
[:li {:on-click load-more}
|
||||||
;; [:a.btn-primary.btn-small
|
[:a.btn-primary.btn-small "view more"]])]))
|
||||||
;; "view more"]])])))
|
|
||||||
|
|
||||||
;; ;; --- History Pinned List (Component)
|
;; --- History Pinned List (Component)
|
||||||
|
|
||||||
;; (mf/def history-pinned-list
|
(mf/defc history-pinned-list
|
||||||
;; :mixins [mf/memo]
|
[{:keys [history] :as props}]
|
||||||
;; :render
|
[:ul.history-content
|
||||||
;; (fn [own {:keys [pinned selected] :as history}]
|
(for [item (reverse (sort-by :version (:pinned history)))]
|
||||||
;; [:ul.history-content
|
[:& history-item {:item item
|
||||||
;; (for [item (reverse (sort-by :version pinned))]
|
:key (:id item)
|
||||||
;; (let [selected (= (:version item) selected)]
|
:selected? (= (:selected history)
|
||||||
;; (history-item (assoc item ::selected selected))))]))
|
(:version item))}])])
|
||||||
|
|
||||||
;; ;; --- History Toolbox (Component)
|
;; --- History Toolbox (Component)
|
||||||
|
|
||||||
;; (mf/def history-toolbox
|
(mf/defc history-toolbox
|
||||||
;; :mixins [mf/memo mf/reactive]
|
[props]
|
||||||
|
(let [history (mf/deref refs/history)
|
||||||
|
section (mf/use-state :main)
|
||||||
|
close #(st/emit! (dw/toggle-flag :history))
|
||||||
|
main? (= @section :main)
|
||||||
|
pinned? (= @section :pinned)
|
||||||
|
show-main #(st/emit! (udh/select-section :main))
|
||||||
|
show-pinned #(st/emit! (udh/select-section :pinned))]
|
||||||
|
[:div.document-history.tool-window
|
||||||
|
[:div.tool-window-bar
|
||||||
|
[:div.tool-window-icon i/undo-history]
|
||||||
|
[:span (tr "ds.settings.document-history")]
|
||||||
|
[:div.tool-window-close {:on-click close} i/close]]
|
||||||
|
[:div.tool-window-content
|
||||||
|
[:ul.history-tabs
|
||||||
|
[:li {:on-click #(reset! section :main)
|
||||||
|
:class (when main? "selected")}
|
||||||
|
(tr "ds.history.versions")]
|
||||||
|
[:li {:on-click #(reset! section :pinned)
|
||||||
|
:class (when pinned? "selected")}
|
||||||
|
(tr "ds.history.pinned")]]
|
||||||
|
(if (= @section :pinned)
|
||||||
|
[:& history-pinned-list {:history history}]
|
||||||
|
[:& history-list {:history history}])]]))
|
||||||
|
|
||||||
;; :init
|
;; --- History Dialog
|
||||||
;; (fn [own page-id]
|
|
||||||
;; (st/emit! (udh/initialize page-id))
|
|
||||||
;; own)
|
|
||||||
|
|
||||||
;; :will-unmount
|
(mf/defc history-dialog
|
||||||
;; (fn [own]
|
[props]
|
||||||
;; (st/emit! ::udh/stop-changes-watcher)
|
(let [history (mf/deref refs/history)
|
||||||
;; own)
|
version (:selected history)
|
||||||
|
on-accept #(st/emit! udh/apply-selected)
|
||||||
|
on-cancel #(st/emit! udh/deselect)]
|
||||||
|
(when (or version (:deselecting history))
|
||||||
|
[:div.message-version
|
||||||
|
{:class (when (:deselecting history) "hide-message")}
|
||||||
|
[:span (tr "history.alert-message" (or version "00"))
|
||||||
|
[:div.message-action
|
||||||
|
[:a.btn-transparent {:on-click on-accept} (tr "ds.accept")]
|
||||||
|
[:a.btn-transparent {:on-click on-cancel} (tr "ds.cancel")]]]])))
|
||||||
|
|
||||||
;; :render
|
|
||||||
;; (fn [own page-id]
|
|
||||||
;; (let [history (mf/react refs/history)
|
|
||||||
;; section (:section history :main)
|
|
||||||
|
|
||||||
;; close #(st/emit! (dw/toggle-flag :document-history))
|
|
||||||
;; main? (= section :main)
|
|
||||||
;; pinned? (= section :pinned)
|
|
||||||
|
|
||||||
;; show-main #(st/emit! (udh/select-section :main))
|
|
||||||
;; show-pinned #(st/emit! (udh/select-section :pinned))]
|
|
||||||
;; [:div.document-history.tool-window {}
|
|
||||||
;; [:div.tool-window-bar {}
|
|
||||||
;; [:div.tool-window-icon {} i/undo-history]
|
|
||||||
;; [:span {} (tr "ds.settings.document-history")]
|
|
||||||
;; [:div.tool-window-close {:on-click close} i/close]]
|
|
||||||
;; [:div.tool-window-content {}
|
|
||||||
;; [:ul.history-tabs {}
|
|
||||||
;; [:li {:on-click show-main
|
|
||||||
;; :class (when main? "selected")}
|
|
||||||
;; (tr "ds.history.versions")]
|
|
||||||
;; [:li {:on-click show-pinned
|
|
||||||
;; :class (when pinned? "selected")}
|
|
||||||
;; (tr "ds.history.pinned")]]
|
|
||||||
;; (if (= section :pinned)
|
|
||||||
;; (history-pinned-list history)
|
|
||||||
;; (history-list history))]])))
|
|
||||||
|
|
||||||
;; ;; --- History Dialog
|
|
||||||
|
|
||||||
;; (mf/def history-dialog
|
|
||||||
;; :mixins [mf/memo mf/reactive]
|
|
||||||
;; :render
|
|
||||||
;; (fn [own]
|
|
||||||
;; (let [history (mf/react refs/history)
|
|
||||||
;; version (:selected history)
|
|
||||||
;; on-accept #(st/emit! (udh/apply-selected-history))
|
|
||||||
;; on-cancel #(st/emit! (udh/deselect-page-history))]
|
|
||||||
;; (when (or version (:deselecting history))
|
|
||||||
;; [:div.message-version
|
|
||||||
;; {:class (when (:deselecting history) "hide-message")}
|
|
||||||
;; [:span {} (tr "history.alert-message" (or version "00"))
|
|
||||||
;; [:div.message-action {}
|
|
||||||
;; [:a.btn-transparent {:on-click on-accept} (tr "ds.accept")]
|
|
||||||
;; [:a.btn-transparent {:on-click on-cancel} (tr "ds.cancel")]]]]))))
|
|
||||||
|
|||||||
@ -45,6 +45,7 @@
|
|||||||
|
|
||||||
;; --- Default Specs
|
;; --- Default Specs
|
||||||
|
|
||||||
|
(s/def ::bool boolean?)
|
||||||
(s/def ::uuid uuid?)
|
(s/def ::uuid uuid?)
|
||||||
(s/def ::email email?)
|
(s/def ::email email?)
|
||||||
(s/def ::color color?)
|
(s/def ::color color?)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user