mirror of
https://github.com/penpot/penpot.git
synced 2025-05-25 06:06:13 +02:00
♻️ Big refactor of the default data model.
Introduce teams.
This commit is contained in:
parent
6379c62e37
commit
7a5145fa37
65 changed files with 4529 additions and 3005 deletions
|
@ -58,7 +58,7 @@
|
|||
(st/emit! #(assoc % :router router))
|
||||
(add-watch html-history/path ::main #(on-navigate router %4))
|
||||
|
||||
(when (:auth storage)
|
||||
(when (:profile storage)
|
||||
(st/emit! udu/fetch-profile))
|
||||
|
||||
(mf/mount (mf/element ui/app) (dom/get-element "app"))
|
||||
|
|
|
@ -30,14 +30,9 @@
|
|||
(defn logged-in
|
||||
[data]
|
||||
(ptk/reify ::logged-in
|
||||
ptk/UpdateEvent
|
||||
(update [this state]
|
||||
(assoc state :auth data))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [this state s]
|
||||
(swap! storage assoc :auth data)
|
||||
(rx/of du/fetch-profile
|
||||
(watch [this state stream]
|
||||
(rx/of (du/profile-fetched data)
|
||||
(rt/navigate :dashboard-projects)))))
|
||||
|
||||
;; --- Login
|
||||
|
|
|
@ -5,49 +5,222 @@
|
|||
;; Copyright (c) 2015-2016 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.main.data.dashboard
|
||||
(:require [beicon.core :as rx]
|
||||
[uxbox.util.uuid :as uuid]
|
||||
[potok.core :as ptk]
|
||||
[uxbox.util.router :as r]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.repo :as rp]
|
||||
[uxbox.main.data.projects :as dp]
|
||||
[uxbox.main.data.colors :as dc]
|
||||
[uxbox.main.data.images :as di]
|
||||
[uxbox.util.data :refer (deep-merge)]))
|
||||
(:require
|
||||
[beicon.core :as rx]
|
||||
[cljs.spec.alpha :as s]
|
||||
[cuerdas.core :as str]
|
||||
[potok.core :as ptk]
|
||||
[uxbox.common.data :as d]
|
||||
[uxbox.common.pages :as cp]
|
||||
[uxbox.common.spec :as us]
|
||||
[uxbox.main.repo :as rp]
|
||||
[uxbox.util.router :as rt]
|
||||
[uxbox.util.time :as dt]
|
||||
[uxbox.util.timers :as ts]
|
||||
[uxbox.util.uuid :as uuid]))
|
||||
|
||||
;; --- Events
|
||||
;; --- Specs
|
||||
|
||||
(defrecord InitializeDashboard [section]
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :dashboard assoc
|
||||
:section section
|
||||
:collection-type :builtin
|
||||
:collection-id 1)))
|
||||
(s/def ::id ::us/uuid)
|
||||
(s/def ::name string?)
|
||||
(s/def ::team-id ::us/uuid)
|
||||
(s/def ::profile-id ::us/uuid)
|
||||
(s/def ::project-id ::us/uuid)
|
||||
(s/def ::created-at ::us/inst)
|
||||
(s/def ::modified-at ::us/inst)
|
||||
|
||||
(defn initialize
|
||||
[section]
|
||||
(InitializeDashboard. section))
|
||||
(s/def ::team
|
||||
(s/keys :req-un [::id
|
||||
::name
|
||||
::created-at
|
||||
::modified-at]))
|
||||
|
||||
(defn set-collection-type
|
||||
[type]
|
||||
{:pre [(contains? #{:builtin :own} type)]}
|
||||
(letfn [(select-first [state]
|
||||
(if (= type :builtin)
|
||||
(assoc-in state [:dashboard :collection-id] 1)
|
||||
(let [colls (sort-by :id (vals (:colors-by-id state)))]
|
||||
(assoc-in state [:dashboard :collection-id] (:id (first colls))))))]
|
||||
(reify
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(as-> state $
|
||||
(assoc-in $ [:dashboard :collection-type] type)
|
||||
(select-first $))))))
|
||||
(s/def ::project
|
||||
(s/keys ::req-un [::id
|
||||
::name
|
||||
::team-id
|
||||
::version
|
||||
::profile-id
|
||||
::created-at
|
||||
::modified-at]))
|
||||
|
||||
(defn set-collection
|
||||
[id]
|
||||
(reify
|
||||
(s/def ::file
|
||||
(s/keys :req-un [::id
|
||||
::name
|
||||
::created-at
|
||||
::modified-at
|
||||
::project-id]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Initialization
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(declare fetch-files)
|
||||
|
||||
(def initialize-drafts
|
||||
(ptk/reify ::initialize
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc-in state [:dashboard :collection-id] id))))
|
||||
(let [profile (:profile state)]
|
||||
(update state :dashboard-local assoc
|
||||
:team-id (:default-team-id profile)
|
||||
:project-id (:default-project-id profile))))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [local (:dashboard-local state)]
|
||||
(rx/of (fetch-files (:project-id local)))))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Data Fetching
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; --- Fetch Projects
|
||||
|
||||
(declare projects-fetched)
|
||||
|
||||
(def fetch-projects
|
||||
(ptk/reify ::fetch-projects
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(->> (rp/query :projects)
|
||||
(rx/map projects-fetched)))))
|
||||
|
||||
(defn projects-fetched
|
||||
[projects]
|
||||
(us/verify (s/every ::project) projects)
|
||||
(ptk/reify ::projects-fetched
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [assoc-project #(update-in %1 [:projects (:id %2)] merge %2)]
|
||||
(reduce assoc-project state projects)))))
|
||||
|
||||
;; --- Fetch Files
|
||||
|
||||
(declare files-fetched)
|
||||
|
||||
(defn fetch-files
|
||||
[project-id]
|
||||
(ptk/reify ::fetch-files
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [params {:project-id project-id}]
|
||||
(->> (rp/query :files params)
|
||||
(rx/map files-fetched))))))
|
||||
|
||||
(defn files-fetched
|
||||
[files]
|
||||
(us/verify (s/every ::file) files)
|
||||
(ptk/reify ::files-fetched
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [state (dissoc state :files)
|
||||
files (d/index-by :id files)]
|
||||
(assoc state :files files)))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Data Modification
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; --- Rename Project
|
||||
|
||||
(defn rename-project
|
||||
[id name]
|
||||
{:pre [(uuid? id) (string? name)]}
|
||||
(ptk/reify ::rename-project
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc-in state [:projects id :name] name))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [params {:id id :name name}]
|
||||
(->> (rp/mutation :rename-project params)
|
||||
(rx/ignore))))))
|
||||
|
||||
;; --- Delete Project (by id)
|
||||
|
||||
(defn delete-project
|
||||
[id]
|
||||
(us/verify ::us/uuid id)
|
||||
(ptk/reify ::delete-project
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :projects dissoc id))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state s]
|
||||
(->> (rp/mutation :delete-project {:id id})
|
||||
(rx/ignore)))))
|
||||
|
||||
;; --- Delete File (by id)
|
||||
|
||||
(defn delete-file
|
||||
[id]
|
||||
(us/verify ::us/uuid id)
|
||||
(ptk/reify ::delete-file
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :files dissoc id))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state s]
|
||||
(->> (rp/mutation :delete-file {:id id})
|
||||
(rx/ignore)))))
|
||||
|
||||
;; --- Rename Project
|
||||
|
||||
(defn rename-file
|
||||
[id name]
|
||||
{:pre [(uuid? id) (string? name)]}
|
||||
(ptk/reify ::rename-file
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc-in state [:files id :name] name))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [params {:id id :name name}]
|
||||
(->> (rp/mutation :rename-file params)
|
||||
(rx/ignore))))))
|
||||
|
||||
|
||||
;; --- Create File
|
||||
|
||||
(declare file-created)
|
||||
|
||||
(def create-file
|
||||
(ptk/reify ::create-draft-file
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [name (str "New File " (gensym "p"))
|
||||
project-id (get-in state [:dashboard-local :project-id])
|
||||
params {:name name :project-id project-id}]
|
||||
(->> (rp/mutation! :create-file params)
|
||||
(rx/map file-created))))))
|
||||
|
||||
(defn file-created
|
||||
[data]
|
||||
(us/verify ::file data)
|
||||
(ptk/reify ::create-draft-file
|
||||
ptk/UpdateEvent
|
||||
(update [this state]
|
||||
(update state :files assoc (:id data) data))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; UI State Handling
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; --- Update Opts (Filtering & Ordering)
|
||||
|
||||
(defn update-opts
|
||||
[& {:keys [order filter] :as opts}]
|
||||
(ptk/reify ::update-opts
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :dashboard-local merge
|
||||
(when order {:order order})
|
||||
(when filter {:filter filter})))))
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
(ptk/reify ::fetch-collections
|
||||
ptk/WatchEvent
|
||||
(watch [_ state s]
|
||||
(->> (rp/query! :images-collections)
|
||||
(->> (rp/query! :image-collections)
|
||||
(rx/map collections-fetched)))))
|
||||
|
||||
|
||||
|
@ -108,7 +108,7 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ state s]
|
||||
(let [data {:name (tr "ds.default-library-title" (gensym "c"))}]
|
||||
(->> (rp/mutation! :create-images-collection data)
|
||||
(->> (rp/mutation! :create-image-collection data)
|
||||
(rx/map collection-created))))))
|
||||
|
||||
;; --- Collection Created
|
||||
|
@ -134,7 +134,7 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ state s]
|
||||
(let [params {:id id :name name}]
|
||||
(->> (rp/mutation! :rename-images-collection params)
|
||||
(->> (rp/mutation! :rename-image-collection params)
|
||||
(rx/ignore))))))
|
||||
|
||||
;; --- Delete Collection
|
||||
|
@ -148,7 +148,7 @@
|
|||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state s]
|
||||
(->> (rp/mutation! :delete-images-collection {:id id})
|
||||
(->> (rp/mutation! :delete-image-collection {:id id})
|
||||
(rx/tap on-success)
|
||||
(rx/ignore)))))
|
||||
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
;;
|
||||
;; Copyright (c) 2015-2017 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
;; NOTE: this namespace is deprecated and will be removed when new
|
||||
;; dashboard is implemented. Is just maintained as a temporal solution
|
||||
;; for have the old dashboard code "working".
|
||||
|
||||
|
||||
(ns uxbox.main.data.projects
|
||||
(:require
|
||||
[beicon.core :as rx]
|
||||
|
@ -22,22 +27,16 @@
|
|||
|
||||
(s/def ::id ::us/uuid)
|
||||
(s/def ::name string?)
|
||||
(s/def ::user ::us/uuid)
|
||||
(s/def ::type keyword?)
|
||||
(s/def ::file-id ::us/uuid)
|
||||
(s/def ::project-id ::us/uuid)
|
||||
(s/def ::profile-id ::us/uuid)
|
||||
(s/def ::project-id (s/nilable ::us/uuid))
|
||||
(s/def ::created-at ::us/inst)
|
||||
(s/def ::modified-at ::us/inst)
|
||||
(s/def ::version ::us/number)
|
||||
(s/def ::ordering ::us/number)
|
||||
(s/def ::metadata (s/nilable ::cp/metadata))
|
||||
(s/def ::data ::cp/data)
|
||||
|
||||
(s/def ::project
|
||||
(s/keys ::req-un [::id
|
||||
::name
|
||||
::version
|
||||
::user-id
|
||||
::profile-id
|
||||
::created-at
|
||||
::modified-at]))
|
||||
|
||||
|
@ -48,43 +47,17 @@
|
|||
::modified-at
|
||||
::project-id]))
|
||||
|
||||
(s/def ::page
|
||||
(s/keys :req-un [::id
|
||||
::name
|
||||
::file-id
|
||||
::version
|
||||
::created-at
|
||||
::modified-at
|
||||
::user-id
|
||||
::ordering
|
||||
::data]))
|
||||
|
||||
;; --- Helpers
|
||||
|
||||
(defn unpack-page
|
||||
[state {:keys [id data] :as page}]
|
||||
(-> state
|
||||
(update :pages assoc id (dissoc page :data))
|
||||
(update :pages-data assoc id data)))
|
||||
|
||||
(defn purge-page
|
||||
"Remove page and all related stuff from the state."
|
||||
[state id]
|
||||
(if-let [file-id (get-in state [:pages id :file-id])]
|
||||
(-> state
|
||||
(update-in [:files file-id :pages] #(filterv (partial not= id) %))
|
||||
(update-in [:workspace-file :pages] #(filterv (partial not= id) %))
|
||||
(update :pages dissoc id)
|
||||
(update :pages-data dissoc id))
|
||||
state))
|
||||
|
||||
;; --- Initialize Dashboard
|
||||
|
||||
(declare fetch-projects)
|
||||
|
||||
(declare fetch-files)
|
||||
(declare fetch-draft-files)
|
||||
(declare initialized)
|
||||
|
||||
;; NOTE/WARN: this need to be refactored completly when new UI is
|
||||
;; prototyped.
|
||||
|
||||
(defn initialize
|
||||
[id]
|
||||
(ptk/reify ::initialize
|
||||
|
@ -95,7 +68,9 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(rx/merge
|
||||
(rx/of (fetch-files id))
|
||||
(if (nil? id)
|
||||
(rx/of fetch-draft-files)
|
||||
(rx/of (fetch-files id)))
|
||||
(->> stream
|
||||
(rx/filter (ptk/type? ::files-fetched))
|
||||
(rx/take 1)
|
||||
|
@ -121,6 +96,7 @@
|
|||
(when filter {:filter filter})))))
|
||||
|
||||
;; --- Fetch Projects
|
||||
|
||||
(declare projects-fetched)
|
||||
|
||||
(def fetch-projects
|
||||
|
@ -151,9 +127,16 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [params (if (nil? project-id) {} {:project-id project-id})]
|
||||
(->> (rp/query :project-files params)
|
||||
(->> (rp/query :files params)
|
||||
(rx/map files-fetched))))))
|
||||
|
||||
(def fetch-draft-files
|
||||
(ptk/reify ::fetch-draft-files
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(->> (rp/query :draft-files {})
|
||||
(rx/map files-fetched)))))
|
||||
|
||||
;; --- Fetch File (by ID)
|
||||
|
||||
(defn fetch-file
|
||||
|
@ -162,23 +145,11 @@
|
|||
(ptk/reify ::fetch-file
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(->> (rp/query :project-file {:id id})
|
||||
(->> (rp/query :file {:id id})
|
||||
(rx/map #(files-fetched [%]))))))
|
||||
|
||||
;; --- Files Fetched
|
||||
|
||||
(defn files-fetched
|
||||
[files]
|
||||
(us/verify (s/every ::file) files)
|
||||
(ptk/reify ::files-fetched
|
||||
cljs.core/IDeref
|
||||
(-deref [_] files)
|
||||
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [assoc-file #(assoc-in %1 [:files (:id %2)] %2)]
|
||||
(reduce assoc-file state files)))))
|
||||
|
||||
;; --- Create Project
|
||||
|
||||
(declare project-created)
|
||||
|
@ -201,12 +172,31 @@
|
|||
(watch [this state stream]
|
||||
(let [name (str "New File " (gensym "p"))
|
||||
params {:name name :project-id project-id}]
|
||||
(->> (rp/mutation! :create-project-file params)
|
||||
(->> (rp/mutation! :create-file params)
|
||||
(rx/mapcat
|
||||
(fn [data]
|
||||
(rx/of (files-fetched [data])
|
||||
#(update-in % [:dashboard-projects :files project-id] conj (:id data))))))))))
|
||||
|
||||
(declare file-created)
|
||||
|
||||
(def create-draft-file
|
||||
(ptk/reify ::create-draft-file
|
||||
ptk/WatchEvent
|
||||
(watch [this state stream]
|
||||
(let [name (str "New File " (gensym "p"))
|
||||
params {:name name}]
|
||||
(->> (rp/mutation! :create-draft-file params)
|
||||
(rx/map file-created))))))
|
||||
|
||||
(defn file-created
|
||||
[data]
|
||||
(us/verify ::file data)
|
||||
(ptk/reify ::create-draft-file
|
||||
ptk/UpdateEvent
|
||||
(update [this state]
|
||||
(update state :files assoc (:id data) data))))
|
||||
|
||||
;; --- Rename Project
|
||||
|
||||
(defn rename-project
|
||||
|
@ -250,7 +240,7 @@
|
|||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state s]
|
||||
(->> (rp/mutation :delete-project-file {:id id})
|
||||
(->> (rp/mutation :delete-file {:id id})
|
||||
(rx/ignore)))))
|
||||
|
||||
;; --- Rename Project
|
||||
|
@ -266,7 +256,7 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [params {:id id :name name}]
|
||||
(->> (rp/mutation :rename-project-file params)
|
||||
(->> (rp/mutation :rename-file params)
|
||||
(rx/ignore))))))
|
||||
|
||||
;; --- Go To Project
|
||||
|
@ -291,178 +281,3 @@
|
|||
(if (nil? id)
|
||||
(rx/of (rt/nav :dashboard-projects {} {}))
|
||||
(rx/of (rt/nav :dashboard-projects {} {:project-id (str id)}))))))
|
||||
|
||||
|
||||
;; --- Fetch Pages (by File ID)
|
||||
|
||||
(declare pages-fetched)
|
||||
|
||||
(defn fetch-pages
|
||||
[file-id]
|
||||
(us/verify ::us/uuid file-id)
|
||||
(reify
|
||||
ptk/WatchEvent
|
||||
(watch [_ state s]
|
||||
(->> (rp/query :project-pages {:file-id file-id})
|
||||
(rx/map pages-fetched)))))
|
||||
|
||||
;; --- Pages Fetched
|
||||
|
||||
(defn pages-fetched
|
||||
[pages]
|
||||
(us/verify (s/every ::page) pages)
|
||||
(ptk/reify ::pages-fetched
|
||||
IDeref
|
||||
(-deref [_] pages)
|
||||
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(reduce unpack-page state pages))))
|
||||
|
||||
;; --- Fetch Page (By ID)
|
||||
|
||||
(declare page-fetched)
|
||||
|
||||
(defn fetch-page
|
||||
"Fetch page by id."
|
||||
[id]
|
||||
(us/verify ::us/uuid id)
|
||||
(reify
|
||||
ptk/WatchEvent
|
||||
(watch [_ state s]
|
||||
(->> (rp/query :project-page {:id id})
|
||||
(rx/map page-fetched)))))
|
||||
|
||||
;; --- Page Fetched
|
||||
|
||||
(defn page-fetched
|
||||
[data]
|
||||
(us/verify ::page data)
|
||||
(ptk/reify ::page-fetched
|
||||
IDeref
|
||||
(-deref [_] data)
|
||||
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(unpack-page state data))))
|
||||
|
||||
;; --- Create Page
|
||||
|
||||
(declare page-created)
|
||||
|
||||
(def create-empty-page
|
||||
(ptk/reify ::create-empty-page
|
||||
ptk/WatchEvent
|
||||
(watch [this state stream]
|
||||
(let [file-id (get-in state [:workspace-page :file-id])
|
||||
name (str "Page " (gensym "p"))
|
||||
ordering (count (get-in state [:files file-id :pages]))
|
||||
params {:name name
|
||||
:file-id file-id
|
||||
:ordering ordering
|
||||
:data cp/default-page-data}]
|
||||
(->> (rp/mutation :create-project-page params)
|
||||
(rx/map page-created))))))
|
||||
|
||||
;; --- Page Created
|
||||
|
||||
(defn page-created
|
||||
[{:keys [id file-id] :as page}]
|
||||
(us/verify ::page page)
|
||||
(ptk/reify ::page-created
|
||||
cljs.core/IDeref
|
||||
(-deref [_] page)
|
||||
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [data (:data page)
|
||||
page (dissoc page :data)]
|
||||
(-> state
|
||||
(update-in [:workspace-file :pages] (fnil conj []) id)
|
||||
(update :pages assoc id page)
|
||||
(update :pages-data assoc id data))))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(rx/of (fetch-file file-id)))))
|
||||
|
||||
;; --- Rename Page
|
||||
|
||||
(s/def ::rename-page
|
||||
(s/keys :req-un [::id ::name]))
|
||||
|
||||
(defn rename-page
|
||||
[id name]
|
||||
(us/verify ::us/uuid id)
|
||||
(us/verify string? name)
|
||||
(ptk/reify ::rename-page
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [pid (get-in state [:workspace-page :id])
|
||||
state (assoc-in state [:pages id :name] name)]
|
||||
(cond-> state
|
||||
(= pid id) (assoc-in [:workspace-page :name] name))))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [params {:id id :name name}]
|
||||
(->> (rp/mutation :rename-project-page params)
|
||||
(rx/map #(ptk/data-event ::page-renamed params)))))))
|
||||
|
||||
;; --- Delete Page (by ID)
|
||||
|
||||
(defn delete-page
|
||||
[id]
|
||||
{:pre [(uuid? id)]}
|
||||
(reify
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(purge-page state id))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state s]
|
||||
(let [page (:workspace-page state)]
|
||||
(rx/merge
|
||||
(->> (rp/mutation :delete-project-page {:id id})
|
||||
(rx/flat-map (fn [_]
|
||||
(if (= id (:id page))
|
||||
(rx/of (go-to (:file-id page)))
|
||||
(rx/empty))))))))))
|
||||
|
||||
;; --- Persist Page
|
||||
|
||||
(declare page-persisted)
|
||||
|
||||
(def persist-current-page
|
||||
(ptk/reify ::persist-page
|
||||
ptk/WatchEvent
|
||||
(watch [this state s]
|
||||
(let [local (:workspace-local state)
|
||||
page (:workspace-page state)
|
||||
data (:workspace-data state)]
|
||||
(if (:history local)
|
||||
(rx/empty)
|
||||
(let [page (assoc page :data data)]
|
||||
(->> (rp/mutation :update-project-page-data page)
|
||||
(rx/map (fn [res] (merge page res)))
|
||||
(rx/map page-persisted)
|
||||
(rx/catch (fn [err] (rx/of ::page-persist-error))))))))))
|
||||
|
||||
;; --- Page Persisted
|
||||
|
||||
(defn page-persisted
|
||||
[{:keys [id] :as page}]
|
||||
(us/verify ::page page)
|
||||
(ptk/reify ::page-persisted
|
||||
cljs.core/IDeref
|
||||
(-deref [_] page)
|
||||
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [data (:data page)
|
||||
page (dissoc page :data)]
|
||||
(-> state
|
||||
(assoc :workspace-data data)
|
||||
(assoc :workspace-page page)
|
||||
(update :pages assoc id page)
|
||||
(update :pages-data assoc id data))))))
|
||||
|
|
|
@ -58,12 +58,12 @@
|
|||
(declare handle-who)
|
||||
(declare handle-pointer-update)
|
||||
(declare handle-pointer-send)
|
||||
(declare handle-page-snapshot)
|
||||
(declare handle-page-change)
|
||||
(declare shapes-changes-commited)
|
||||
(declare commit-changes)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Websockets Events
|
||||
;; Workspace WebSocket
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; --- Initialize WebSocket
|
||||
|
@ -93,7 +93,7 @@
|
|||
(case type
|
||||
:who (handle-who msg)
|
||||
:pointer-update (handle-pointer-update msg)
|
||||
:page-snapshot (handle-page-snapshot msg)
|
||||
:page-change (handle-page-change msg)
|
||||
::unknown))))
|
||||
|
||||
(->> stream
|
||||
|
@ -160,11 +160,12 @@
|
|||
:y (:y point)}]
|
||||
(ws/-send ws (t/encode msg))))))
|
||||
|
||||
(defn handle-page-snapshot
|
||||
[{:keys [user-id page-id version operations] :as msg}]
|
||||
(ptk/reify ::handle-page-snapshot
|
||||
(defn handle-page-change
|
||||
[{:keys [profile-id page-id revn operations] :as msg}]
|
||||
(ptk/reify ::handle-page-change
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(prn "handle-page-change")
|
||||
(let [page-id' (get-in state [:workspace-page :id])]
|
||||
(when (= page-id page-id')
|
||||
(rx/of (shapes-changes-commited msg)))))))
|
||||
|
@ -254,9 +255,9 @@
|
|||
;; (update [_ state]
|
||||
;; (update :workspace-local dissoc :undo-index))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; General workspace events
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Workspace Initialization
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; --- Initialize Workspace
|
||||
|
||||
|
@ -275,6 +276,9 @@
|
|||
(declare initialize-layout)
|
||||
(declare initialize-page)
|
||||
(declare initialize-file)
|
||||
(declare fetch-file-with-users)
|
||||
(declare fetch-pages)
|
||||
(declare fetch-page)
|
||||
|
||||
(defn initialize
|
||||
"Initialize the workspace state."
|
||||
|
@ -286,21 +290,31 @@
|
|||
(watch [_ state stream]
|
||||
(let [file (:workspace-file state)]
|
||||
(if (not= (:id file) file-id)
|
||||
(do
|
||||
;; (reset! st/loader true)
|
||||
(rx/merge
|
||||
(rx/of (fetch-file-with-users file-id)
|
||||
(fetch-pages file-id)
|
||||
(initialize-layout file-id)
|
||||
(fetch-images file-id))
|
||||
(->> (rx/zip (rx/filter (ptk/type? ::pages-fetched) stream)
|
||||
(rx/filter (ptk/type? ::file-fetched) stream))
|
||||
(rx/take 1)
|
||||
(rx/do (fn [_]
|
||||
(uxbox.util.timers/schedule 500 #(reset! st/loader false))))
|
||||
(rx/mapcat (fn [_]
|
||||
(rx/of (initialize-file file-id)
|
||||
(initialize-page page-id)
|
||||
#_(initialize-alignment page-id)))))))
|
||||
|
||||
(rx/merge
|
||||
(rx/of (dp/fetch-file file-id)
|
||||
(dp/fetch-pages file-id)
|
||||
(initialize-layout file-id)
|
||||
(fetch-users file-id)
|
||||
(fetch-images file-id))
|
||||
(->> (rx/zip (rx/filter (ptk/type? ::dp/pages-fetched) stream)
|
||||
(rx/filter (ptk/type? ::dp/files-fetched) stream))
|
||||
(rx/of (fetch-page page-id))
|
||||
(->> stream
|
||||
(rx/filter (ptk/type? ::pages-fetched))
|
||||
(rx/take 1)
|
||||
(rx/do #(reset! st/loader false))
|
||||
(rx/mapcat #(rx/of (initialize-file file-id)
|
||||
(initialize-page page-id)
|
||||
#_(initialize-alignment page-id)))))
|
||||
(rx/of (initialize-file file-id)
|
||||
(initialize-page page-id)))))))
|
||||
(rx/merge-map (fn [_]
|
||||
(rx/of (initialize-file file-id)
|
||||
(initialize-page page-id)))))))))))
|
||||
|
||||
(defn- initialize-layout
|
||||
[file-id]
|
||||
|
@ -351,9 +365,10 @@
|
|||
(ptk/reify ::finalize
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(dissoc state
|
||||
:workspace-page
|
||||
:workspace-data))))
|
||||
state
|
||||
#_(dissoc state
|
||||
:workspace-page
|
||||
:workspace-data))))
|
||||
|
||||
(def diff-and-commit-changes
|
||||
(ptk/reify ::diff-and-commit-changes
|
||||
|
@ -379,17 +394,69 @@
|
|||
(when-not (empty? changes)
|
||||
(rx/of (commit-changes changes)))))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Data Fetching & Uploading
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; --- Specs
|
||||
|
||||
(s/def ::id ::us/uuid)
|
||||
(s/def ::profile-id ::us/uuid)
|
||||
(s/def ::name string?)
|
||||
(s/def ::type keyword?)
|
||||
(s/def ::file-id ::us/uuid)
|
||||
(s/def ::created-at ::us/inst)
|
||||
(s/def ::modified-at ::us/inst)
|
||||
(s/def ::version ::us/integer)
|
||||
(s/def ::revn ::us/integer)
|
||||
(s/def ::ordering ::us/integer)
|
||||
(s/def ::metadata (s/nilable ::cp/metadata))
|
||||
(s/def ::data ::cp/data)
|
||||
|
||||
(s/def ::file ::dp/file)
|
||||
(s/def ::page
|
||||
(s/keys :req-un [::id
|
||||
::name
|
||||
::file-id
|
||||
::version
|
||||
::revn
|
||||
::created-at
|
||||
::modified-at
|
||||
::ordering
|
||||
::data]))
|
||||
|
||||
;; --- Fetch Workspace Users
|
||||
|
||||
(declare users-fetched)
|
||||
(declare file-fetched)
|
||||
|
||||
(defn fetch-users
|
||||
[file-id]
|
||||
(ptk/reify ::fetch-users
|
||||
(defn fetch-file-with-users
|
||||
[id]
|
||||
(us/verify ::us/uuid id)
|
||||
(ptk/reify ::fetch-file-with-users
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(->> (rp/query :project-file-users {:file-id file-id})
|
||||
(rx/map users-fetched)))))
|
||||
(->> (rp/query :file-with-users {:id id})
|
||||
(rx/merge-map (fn [result]
|
||||
(rx/of (file-fetched (dissoc result :users))
|
||||
(users-fetched (:users result)))))))))
|
||||
(defn fetch-file
|
||||
[id]
|
||||
(us/verify ::us/uuid id)
|
||||
(ptk/reify ::fetch-file
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(->> (rp/query :file {:id id})
|
||||
(rx/map file-fetched)))))
|
||||
|
||||
(defn file-fetched
|
||||
[{:keys [id] :as file}]
|
||||
(us/verify ::file file)
|
||||
(ptk/reify ::file-fetched
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :files assoc id file))))
|
||||
|
||||
(defn users-fetched
|
||||
[users]
|
||||
|
@ -402,6 +469,226 @@
|
|||
users))))
|
||||
|
||||
|
||||
;; --- Fetch Pages
|
||||
|
||||
(declare pages-fetched)
|
||||
(declare unpack-page)
|
||||
|
||||
(defn fetch-pages
|
||||
[file-id]
|
||||
(us/verify ::us/uuid file-id)
|
||||
(ptk/reify ::fetch-pages
|
||||
ptk/WatchEvent
|
||||
(watch [_ state s]
|
||||
(->> (rp/query :pages {:file-id file-id})
|
||||
(rx/map pages-fetched)))))
|
||||
|
||||
(defn fetch-page
|
||||
[page-id]
|
||||
(us/verify ::us/uuid page-id)
|
||||
(ptk/reify ::fetch-pages
|
||||
ptk/WatchEvent
|
||||
(watch [_ state s]
|
||||
(->> (rp/query :page {:id page-id})
|
||||
(rx/map #(pages-fetched [%]))))))
|
||||
|
||||
(defn pages-fetched
|
||||
[pages]
|
||||
(us/verify (s/every ::page) pages)
|
||||
(ptk/reify ::pages-fetched
|
||||
IDeref
|
||||
(-deref [_] pages)
|
||||
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(reduce unpack-page state pages))))
|
||||
|
||||
;; --- Page Crud
|
||||
|
||||
(declare page-created)
|
||||
|
||||
(def create-empty-page
|
||||
(ptk/reify ::create-empty-page
|
||||
ptk/WatchEvent
|
||||
(watch [this state stream]
|
||||
(let [file-id (get-in state [:workspace-page :file-id])
|
||||
name (str "Page " (gensym "p"))
|
||||
ordering (count (get-in state [:files file-id :pages]))
|
||||
params {:name name
|
||||
:file-id file-id
|
||||
:ordering ordering
|
||||
:data cp/default-page-data}]
|
||||
(->> (rp/mutation :create-page params)
|
||||
(rx/map page-created))))))
|
||||
|
||||
(defn page-created
|
||||
[{:keys [id file-id] :as page}]
|
||||
(us/verify ::page page)
|
||||
(ptk/reify ::page-created
|
||||
cljs.core/IDeref
|
||||
(-deref [_] page)
|
||||
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(update-in [:workspace-file :pages] (fnil conj []) id)
|
||||
(unpack-page page)))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(rx/of (fetch-file file-id)))))
|
||||
|
||||
(s/def ::rename-page
|
||||
(s/keys :req-un [::id ::name]))
|
||||
|
||||
(defn rename-page
|
||||
[id name]
|
||||
(us/verify ::us/uuid id)
|
||||
(us/verify string? name)
|
||||
(ptk/reify ::rename-page
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [pid (get-in state [:workspac-page :id])
|
||||
state (assoc-in state [:pages id :name] name)]
|
||||
(cond-> state
|
||||
(= pid id) (assoc-in [:workspace-page :name] name))))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [params {:id id :name name}]
|
||||
(->> (rp/mutation :rename-page params)
|
||||
(rx/map #(ptk/data-event ::page-renamed params)))))))
|
||||
|
||||
(declare purge-page)
|
||||
(declare go-to-file)
|
||||
|
||||
(defn delete-page
|
||||
[id]
|
||||
{:pre [(uuid? id)]}
|
||||
(reify
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(purge-page state id))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state s]
|
||||
(let [page (:workspace-page state)]
|
||||
(rx/merge
|
||||
(->> (rp/mutation :delete-page {:id id})
|
||||
(rx/flat-map (fn [_]
|
||||
(if (= id (:id page))
|
||||
(rx/of (go-to-file (:file-id page)))
|
||||
(rx/empty))))))))))
|
||||
|
||||
|
||||
;; --- Fetch Workspace Images
|
||||
|
||||
(declare images-fetched)
|
||||
|
||||
(defn fetch-images
|
||||
[file-id]
|
||||
(ptk/reify ::fetch-images
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(->> (rp/query :file-images {:file-id file-id})
|
||||
(rx/map images-fetched)))))
|
||||
|
||||
(defn images-fetched
|
||||
[images]
|
||||
(ptk/reify ::images-fetched
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [images (d/index-by :id images)]
|
||||
(assoc state :workspace-images images)))))
|
||||
|
||||
|
||||
;; --- Upload Image
|
||||
|
||||
(declare image-uploaded)
|
||||
(def allowed-file-types #{"image/jpeg" "image/png"})
|
||||
|
||||
(defn upload-image
|
||||
([file] (upload-image file identity))
|
||||
([file on-uploaded]
|
||||
(us/verify fn? on-uploaded)
|
||||
(ptk/reify ::upload-image
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc-in state [:workspace-local :uploading] true))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [allowed-file? #(contains? allowed-file-types (.-type %))
|
||||
finalize-upload #(assoc-in % [:workspace-local :uploading] false)
|
||||
file-id (get-in state [:workspace-page :file-id])
|
||||
|
||||
on-success #(do (st/emit! finalize-upload)
|
||||
(on-uploaded %))
|
||||
on-error #(do (st/emit! finalize-upload)
|
||||
(rx/throw %))
|
||||
|
||||
prepare
|
||||
(fn [file]
|
||||
{:name (.-name file)
|
||||
:file-id file-id
|
||||
:content file})]
|
||||
(->> (rx/of file)
|
||||
(rx/filter allowed-file?)
|
||||
(rx/map prepare)
|
||||
(rx/mapcat #(rp/mutation! :upload-file-image %))
|
||||
(rx/do on-success)
|
||||
(rx/map image-uploaded)
|
||||
(rx/catch on-error)))))))
|
||||
|
||||
|
||||
(s/def ::id ::us/uuid)
|
||||
(s/def ::name ::us/string)
|
||||
(s/def ::width ::us/number)
|
||||
(s/def ::height ::us/number)
|
||||
(s/def ::mtype ::us/string)
|
||||
(s/def ::uri ::us/string)
|
||||
(s/def ::thumb-uri ::us/string)
|
||||
|
||||
(s/def ::image
|
||||
(s/keys :req-un [::id
|
||||
::name
|
||||
::width
|
||||
::height
|
||||
::uri
|
||||
::thumb-uri]))
|
||||
|
||||
(defn image-uploaded
|
||||
[item]
|
||||
(us/verify ::image item)
|
||||
(ptk/reify ::image-created
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :workspace-images assoc (:id item) item))))
|
||||
|
||||
|
||||
;; --- Helpers
|
||||
|
||||
(defn unpack-page
|
||||
[state {:keys [id data] :as page}]
|
||||
(-> state
|
||||
(update :pages assoc id (dissoc page :data))
|
||||
(update :pages-data assoc id data)))
|
||||
|
||||
(defn purge-page
|
||||
"Remove page and all related stuff from the state."
|
||||
[state id]
|
||||
(if-let [file-id (get-in state [:pages id :file-id])]
|
||||
(-> state
|
||||
(update-in [:files file-id :pages] #(filterv (partial not= id) %))
|
||||
(update-in [:workspace-file :pages] #(filterv (partial not= id) %))
|
||||
(update :pages dissoc id)
|
||||
(update :pages-data dissoc id))
|
||||
state))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Workspace State Manipulation
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; --- Toggle layout flag
|
||||
|
||||
(defn toggle-layout-flag
|
||||
|
@ -1052,23 +1339,23 @@
|
|||
(watch [_ state stream]
|
||||
(let [page (:workspace-page state)
|
||||
params {:id (:id page)
|
||||
:version (:version page)
|
||||
:revn (:revn page)
|
||||
:changes (vec changes)}]
|
||||
(->> (rp/mutation :update-project-page params)
|
||||
(->> (rp/mutation :update-page params)
|
||||
(rx/map shapes-changes-commited))))))
|
||||
|
||||
(s/def ::shapes-changes-commited
|
||||
(s/keys :req-un [::page-id ::version ::cp/changes]))
|
||||
(s/keys :req-un [::page-id ::revn ::cp/changes]))
|
||||
|
||||
(defn shapes-changes-commited
|
||||
[{:keys [page-id version changes] :as params}]
|
||||
[{:keys [page-id revn changes] :as params}]
|
||||
(us/verify ::shapes-changes-commited params)
|
||||
(ptk/reify ::shapes-changes-commited
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(assoc-in [:workspace-page :version] version)
|
||||
(assoc-in [:pages page-id :version] version)
|
||||
(assoc-in [:workspace-page :revn] revn)
|
||||
(assoc-in [:pages page-id :revn] revn)
|
||||
(update-in [:pages-data page-id] cp/process-changes changes)
|
||||
(update :workspace-data cp/process-changes changes)))))
|
||||
|
||||
|
@ -1298,7 +1585,7 @@
|
|||
(defn go-to-page
|
||||
[page-id]
|
||||
(us/verify ::us/uuid page-id)
|
||||
(ptk/reify ::go-to
|
||||
(ptk/reify ::go-to-page
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [file-id (get-in state [:workspace-page :file-id])
|
||||
|
@ -1306,93 +1593,16 @@
|
|||
query-params {:page-id page-id}]
|
||||
(rx/of (rt/nav :workspace path-params query-params))))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Workspace Images
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; --- Fetch Workspace Images
|
||||
|
||||
(declare images-fetched)
|
||||
|
||||
(defn fetch-images
|
||||
(defn go-to-file
|
||||
[file-id]
|
||||
(ptk/reify ::fetch-images
|
||||
(us/verify ::us/uuid file-id)
|
||||
(ptk/reify ::go-to-file
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(->> (rp/query :project-file-images {:file-id file-id})
|
||||
(rx/map images-fetched)))))
|
||||
|
||||
(defn images-fetched
|
||||
[images]
|
||||
(ptk/reify ::images-fetched
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [images (d/index-by :id images)]
|
||||
(assoc state :workspace-images images)))))
|
||||
|
||||
|
||||
;; --- Upload Image
|
||||
|
||||
(declare image-uploaded)
|
||||
(def allowed-file-types #{"image/jpeg" "image/png"})
|
||||
|
||||
(defn upload-image
|
||||
([file] (upload-image file identity))
|
||||
([file on-uploaded]
|
||||
(us/verify fn? on-uploaded)
|
||||
(ptk/reify ::upload-image
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc-in state [:workspace-local :uploading] true))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [allowed-file? #(contains? allowed-file-types (.-type %))
|
||||
finalize-upload #(assoc-in % [:workspace-local :uploading] false)
|
||||
file-id (get-in state [:workspace-page :file-id])
|
||||
|
||||
on-success #(do (st/emit! finalize-upload)
|
||||
(on-uploaded %))
|
||||
on-error #(do (st/emit! finalize-upload)
|
||||
(rx/throw %))
|
||||
|
||||
prepare
|
||||
(fn [file]
|
||||
{:name (.-name file)
|
||||
:file-id file-id
|
||||
:content file})]
|
||||
(->> (rx/of file)
|
||||
(rx/filter allowed-file?)
|
||||
(rx/map prepare)
|
||||
(rx/mapcat #(rp/mutation! :upload-project-file-image %))
|
||||
(rx/do on-success)
|
||||
(rx/map image-uploaded)
|
||||
(rx/catch on-error)))))))
|
||||
|
||||
(s/def ::id ::us/uuid)
|
||||
(s/def ::name ::us/string)
|
||||
(s/def ::width ::us/number)
|
||||
(s/def ::height ::us/number)
|
||||
(s/def ::mtype ::us/string)
|
||||
(s/def ::uri ::us/string)
|
||||
(s/def ::thumb-uri ::us/string)
|
||||
|
||||
(s/def ::image
|
||||
(s/keys :req-un [::id
|
||||
::name
|
||||
::width
|
||||
::height
|
||||
::uri
|
||||
::thumb-uri]))
|
||||
|
||||
(defn image-uploaded
|
||||
[item]
|
||||
(us/verify ::image item)
|
||||
(ptk/reify ::image-created
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :workspace-images assoc (:id item) item))))
|
||||
(let [page-ids (get-in state [:files file-id :pages])
|
||||
path-params {:file-id file-id}
|
||||
query-params {:page-id (first page-ids)}]
|
||||
(rx/of (rt/nav :workspace path-params query-params))))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Page Changes Reactions
|
||||
|
|
|
@ -120,7 +120,7 @@
|
|||
(seq params))
|
||||
(send-mutation! id form)))
|
||||
|
||||
(defmethod mutation :upload-project-file-image
|
||||
(defmethod mutation :upload-file-image
|
||||
[id params]
|
||||
(let [form (js/FormData.)]
|
||||
(run! (fn [[key val]]
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
[uxbox.util.data :refer [parse-int uuid-str?]]
|
||||
[uxbox.main.ui.dashboard.header :refer [header]]
|
||||
[uxbox.main.ui.dashboard.projects :as projects]
|
||||
;; [uxbox.main.ui.dashboard.elements :as elements]
|
||||
[uxbox.main.ui.dashboard.icons :as icons]
|
||||
[uxbox.main.ui.dashboard.images :as images]
|
||||
[uxbox.main.ui.dashboard.colors :as colors]
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
;; 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/.
|
||||
;;
|
||||
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
;; defined by the Mozilla Public License, v. 2.0.
|
||||
;;
|
||||
;; Copyright (c) 2015-2017 Andrey Antukh <niwi@niwi.nz>
|
||||
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||
|
||||
|
@ -14,6 +17,7 @@
|
|||
[uxbox.builtins.icons :as i]
|
||||
[uxbox.main.constants :as c]
|
||||
[uxbox.main.data.projects :as udp]
|
||||
[uxbox.main.data.dashboard :as dsh]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.exports :as exports]
|
||||
[uxbox.main.ui.modal :as modal]
|
||||
|
@ -137,13 +141,12 @@
|
|||
(sort-by order))
|
||||
on-click #(do
|
||||
(dom/prevent-default %)
|
||||
(st/emit! (udp/create-file {:project-id id})))]
|
||||
(st/emit! dsh/create-file))]
|
||||
[:section.dashboard-grid
|
||||
[:div.dashboard-grid-content
|
||||
[:div.dashboard-grid-row
|
||||
(when id
|
||||
[:div.grid-item.add-project {:on-click on-click}
|
||||
[:span (tr "ds.new-file")]])
|
||||
[:div.grid-item.add-project {:on-click on-click}
|
||||
[:span (tr "ds.new-file")]]
|
||||
(for [item files]
|
||||
[:& grid-item {:file item :key (:id item)}])]]]))
|
||||
|
||||
|
@ -195,16 +198,20 @@
|
|||
:placeholder (tr "ds.search.placeholder")}]
|
||||
[:div.clear-search i/close]]
|
||||
[:ul.library-elements
|
||||
[:li.recent-projects {:on-click #(st/emit! (udp/go-to-project nil))
|
||||
:class-name (when (nil? id) "current")}
|
||||
[:li.recent-projects #_{:on-click #(st/emit! (udp/go-to-project nil))
|
||||
:class-name (when (nil? id) "current")}
|
||||
[:span.element-title "Recent"]]
|
||||
|
||||
[:li.recent-projects {:on-click #(st/emit! (udp/go-to-project nil))
|
||||
:class-name (when (nil? id) "current")}
|
||||
[:span.element-title "Drafts"]]
|
||||
|
||||
[:div.projects-row
|
||||
[:span "PROJECTS"]
|
||||
[:a.add-project {:on-click #(st/emit! udp/create-project)}
|
||||
[:span "PROJECTS/TEAMS TODO"]
|
||||
#_[:a.add-project {:on-click #(st/emit! udp/create-project)}
|
||||
i/close]]
|
||||
|
||||
(for [item projects]
|
||||
#_(for [item projects]
|
||||
[:& nav-item {:id (:id item)
|
||||
:key (:id item)
|
||||
:name (:name item)
|
||||
|
@ -213,14 +220,9 @@
|
|||
;; --- Component: Content
|
||||
|
||||
(def files-ref
|
||||
(letfn [(selector [state]
|
||||
(let [id (get-in state [:dashboard-projects :id])
|
||||
ids (get-in state [:dashboard-projects :files id])
|
||||
xf (comp (map #(get-in state [:files %]))
|
||||
(remove nil?))]
|
||||
(into [] xf ids)))]
|
||||
(-> (l/lens selector)
|
||||
(l/derive st/state))))
|
||||
(-> (comp (l/key :files)
|
||||
(l/lens vals))
|
||||
(l/derive st/state)))
|
||||
|
||||
(mf/defc content
|
||||
[{:keys [id] :as props}]
|
||||
|
@ -233,8 +235,7 @@
|
|||
|
||||
(mf/defc projects-page
|
||||
[{:keys [id] :as props}]
|
||||
(mf/use-effect #(st/emit! udp/fetch-projects))
|
||||
(mf/use-effect {:fn #(st/emit! (udp/initialize id))
|
||||
(mf/use-effect {:fn #(st/emit! dsh/initialize-drafts)
|
||||
:deps #js [id]})
|
||||
[:section.dashboard-content
|
||||
[:& nav {:id id}]
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
{:alt (tr "header.sitemap")
|
||||
:class (when (contains? layout :sitemap) "selected")
|
||||
:on-click #(st/emit! (dw/toggle-layout-flag :sitemap))}
|
||||
[:span (:project-name file) " / " (:name file)]]
|
||||
[:span (:name file)]]
|
||||
|
||||
[:& active-users]
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
[lentes.core :as l]
|
||||
[rumext.alpha :as mf]
|
||||
[uxbox.builtins.icons :as i]
|
||||
[uxbox.main.data.projects :as dp]
|
||||
[uxbox.main.data.workspace :as dw]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.refs :as refs]
|
||||
|
@ -45,7 +44,7 @@
|
|||
;; parent (.-parentNode parent)
|
||||
name (dom/get-value target)]
|
||||
;; (set! (.-draggable parent) true)
|
||||
(st/emit! (dp/rename-page (:id page) name))
|
||||
(st/emit! (dw/rename-page (:id page) name))
|
||||
(swap! local assoc :edition false)))
|
||||
|
||||
on-key-down (fn [event]
|
||||
|
@ -56,7 +55,7 @@
|
|||
(kbd/esc? event)
|
||||
(swap! local assoc :edition false)))
|
||||
|
||||
delete-fn #(st/emit! (dp/delete-page (:id page)))
|
||||
delete-fn #(st/emit! (dw/delete-page (:id page)))
|
||||
on-delete #(do
|
||||
(dom/prevent-default %)
|
||||
(dom/stop-propagation %)
|
||||
|
@ -128,7 +127,7 @@
|
|||
|
||||
(mf/defc sitemap-toolbox
|
||||
[{:keys [file page] :as props}]
|
||||
(let [on-create-click #(st/emit! dp/create-empty-page)
|
||||
(let [on-create-click #(st/emit! dw/create-empty-page)
|
||||
locale (i18n/use-locale)]
|
||||
[:div.sitemap.tool-window
|
||||
[:div.tool-window-bar
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue