diff --git a/frontend/uxbox/data/projects.cljs b/frontend/uxbox/data/projects.cljs index bdaeb720b..7879b8000 100644 --- a/frontend/uxbox/data/projects.cljs +++ b/frontend/uxbox/data/projects.cljs @@ -3,6 +3,7 @@ [uxbox.router :as r] [uxbox.state :as st] [uxbox.schema :as sc] + [uxbox.time :as time] [bouncer.validators :as v])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -39,14 +40,14 @@ (let [uuid (:id page)] (update-in state [:pages-by-id] assoc uuid page))) -;; (defn project-pages -;; "Get a ordered list of pages that -;; belongs to a specified project." -;; [state projectid] -;; (let [xf (comp -;; (filter #(= projectid (:project %))) -;; (map #(get-in state [:pages-by-id %])))] -;; (into [] xf (:pages state)))) +(defn project-pages + "Get a ordered list of pages that + belongs to a specified project." + [state projectid] + (->> (vals (:pages-by-id state)) + (filter #(= projectid (:project %))) + (sort-by :created) + (into []))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Events @@ -60,6 +61,7 @@ (-apply-update [_ state] (let [page {:id (random-uuid) :project project + :created (time/now :unix) :name name :width width :height height}] @@ -79,6 +81,7 @@ (let [proj {:id uuid :name name :width width + :created (time/now :unix) :height height :layout layout}] (assoc-project state proj))) @@ -99,7 +102,9 @@ (reify rs/UpdateEvent (-apply-update [_ state] - (assoc state :workspace {:project projectid :page pageid})) + (assoc state :workspace {:project projectid + :page pageid + :toolboxes {}})) IPrintWithWriter (-pr-writer [mv writer _] @@ -117,9 +122,10 @@ (if pageid (rs/emit! (r/navigate :main/page {:project-uuid projectid :page-uuid pageid})) - (let [pages (get-in state [:projects-by-id projectid :pages])] + (let [pages (project-pages state projectid) + pageid (:id (first pages))] (rs/emit! (r/navigate :main/page {:project-uuid projectid - :page-uuid (first pages)}))))) + :page-uuid pageid}))))) IPrintWithWriter (-pr-writer [mv writer _] (-write writer "#" innerHTML "") -;; data (js/Blob. #js [html] #js {:type "application/octet-stream"}) -;; url (.createObjectURL (.-URL js/window) data)] -;; (set! (.-href (.-currentTarget e)) url)))} -;; icons/export]] -;; [:li.tooltip.tooltip-bottom -;; {:alt "Image (Ctrl + I)"} -;; icons/image]] -;; [:ul.options-btn -;; [:li.tooltip.tooltip-bottom -;; {:alt "Ruler (Ctrl + R)"} -;; icons/ruler] -;; [:li.tooltip.tooltip-bottom -;; {:alt "Grid (Ctrl + G)" -;; :class (when (rum/react ws/grid?) "selected") -;; :on-click ws/toggle-grid!} -;; icons/grid] -;; [:li.tooltip.tooltip-bottom -;; {:alt "Align (Ctrl + A)"} -;; icons/alignment] -;; [:li.tooltip.tooltip-bottom -;; {:alt "Organize (Ctrl + O)"} -;; icons/organize]]] -;; (user conn)])) - -;; (def header -;; (util/component -;; {:render header-render -;; :name "header"})) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Header -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(def project-state +(def ^:static project-state (as-> (util/dep-in [:projects-by-id] [:workspace :project]) $ (l/focus-atom $ s/state))) -(def page-state +(def ^:static page-state (as-> (util/dep-in [:pages-by-id] [:workspace :page]) $ (l/focus-atom $ s/state))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Header +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defn on-download-clicked + [event page] + (let [content (.-innerHTML (.getElementById js/document "page-layout")) + width (:width page) + height (:height page) + html (str "" content "") + data (js/Blob. #js [html] #js {:type "application/octet-stream"}) + url (.createObjectURL (.-URL js/window) data)] + (set! (.-href (.-currentTarget event)) url))) + +(defn header-render + [own] + (let [page (rum/react page-state)] + (html + [:header#workspace-bar.workspace-bar + [:div.main-icon + (nav/link (r/route-for :dashboard) i/logo-icon)] + [:div.project-tree-btn + {:on-click (constantly nil)} + i/project-tree + [:span (:name page)]] + [:div.workspace-options + [:ul.options-btn + [:li.tooltip.tooltip-bottom {:alt "Undo (Ctrl + Z)"} + i/undo] + [:li.tooltip.tooltip-bottom {:alt "Redo (Ctrl + Shift + Z)"} + i/redo]] + [:ul.options-btn + ;; TODO: refactor + [:li.tooltip.tooltip-bottom + {:alt "Export (Ctrl + E)"} + ;; page-title + [:a {:download (str (:name page) ".svg") + :href "#" :on-click on-download-clicked} + i/export]] + [:li.tooltip.tooltip-bottom + {:alt "Image (Ctrl + I)"} + i/image]] + [:ul.options-btn + [:li.tooltip.tooltip-bottom + {:alt "Ruler (Ctrl + R)"} + i/ruler] + [:li.tooltip.tooltip-bottom + {:alt "Grid (Ctrl + G)" + :class (when false "selected") + :on-click (constantly nil)} + i/grid] + [:li.tooltip.tooltip-bottom + {:alt "Align (Ctrl + A)"} + i/alignment] + [:li.tooltip.tooltip-bottom + {:alt "Organize (Ctrl + O)"} + i/organize]]] + (ui.u/user)]))) + +(def header + (util/component + {:render header-render + :name "header" + :mixins [rum/reactive]})) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Toolbar +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(def ^:static toolbar-state + (as-> (l/in [:workspace :toolbars]) $ + (l/focus-atom $ s/state))) + +(defn- toggle-toolbox + [state item] + (update state item (fnil not false))) + +(defn toolbar-render + [own] + (let [state (rum/react toolbar-state)] + (html + [:div#tool-bar.tool-bar + [:div.tool-bar-inside + [:ul.main-tools + [:li.tooltip + {:alt "Shapes (Ctrl + Shift + F)" + :class (when (:tools state) "current") + :on-click #(swap! toolbar-state toggle-toolbox :tools)} + i/shapes] + [:li.tooltip + {:alt "Icons (Ctrl + Shift + I)" + :class (when (:icons state) "current") + :on-click #(swap! toolbar-state toggle-toolbox :icons)} + i/icon-set] + [:li.tooltip + {:alt "Elements (Ctrl + Shift + L)" + :class (when (:layers state) + "current") + :on-click #(swap! toolbar-state toggle-toolbox :layers)} + i/layers] + [:li.tooltip + {:alt "Feedback (Ctrl + Shift + M)"} + i/chat]]]]))) + +(def ^:static toolbar + (util/component + {:render toolbar-render + :name "toolbar" + :mixins [rum/reactive]})) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Header +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (defn workspace-render [own projectid] (html - [:div "hello world" - ;; (header conn page ws/grid? project-bar-visible?) - ;; [:main.main-content - ;; [:section.workspace-content - ;; ;; Toolbar - ;; (toolbar open-toolboxes) + [:div + (header) + [:main.main-content + [:section.workspace-content + ;; Toolbar + (toolbar) ;; ;; Project bar ;; (project-bar conn project page pages @project-bar-visible?) ;; ;; Rules @@ -106,11 +157,19 @@ ;; ;; Aside ;; (when-not (empty? @open-toolboxes) ;; (aside conn open-toolboxes page shapes)) - ])) + ]]])) + +(defn workspace-will-mount + [own] + (let [[projectid pageid] (:rum/props own)] + (println "workspace-will-mount" projectid pageid) + (rs/emit! (dp/initialize-workspace projectid pageid)) + own)) (def ^:static workspace (util/component {:render workspace-render + :will-mount workspace-will-mount :name "workspace" :mixins [rum/static]}))