mirror of
https://github.com/penpot/penpot.git
synced 2025-02-24 15:56:11 -05:00
Improve page data structure and adapt it to the backend representation.
This commit is contained in:
parent
4fde0469c0
commit
f05d6924a3
6 changed files with 126 additions and 130 deletions
|
@ -104,23 +104,23 @@
|
||||||
|
|
||||||
;; --- Create Page
|
;; --- Create Page
|
||||||
|
|
||||||
(defrecord CreatePage [name width height project layout]
|
(defrecord CreatePage [name project metadata]
|
||||||
rs/WatchEvent
|
rs/WatchEvent
|
||||||
(-apply-watch [this state s]
|
(-apply-watch [this state s]
|
||||||
(letfn [(on-created [{page :payload}]
|
(letfn [(on-created [{page :payload}]
|
||||||
(rx/of
|
(rx/of
|
||||||
#(unpack-page % page)
|
#(unpack-page % page)
|
||||||
#(assoc-page % page)))]
|
#(assoc-page % page)))]
|
||||||
(let [params (-> (into {} this)
|
(let [params {:name name
|
||||||
(assoc :data {}))]
|
:project project
|
||||||
|
:data {}
|
||||||
|
:metadata metadata}]
|
||||||
(->> (rp/req :create/page params)
|
(->> (rp/req :create/page params)
|
||||||
(rx/mapcat on-created))))))
|
(rx/mapcat on-created))))))
|
||||||
|
|
||||||
(def ^:private create-page-schema
|
(def ^:private create-page-schema
|
||||||
{:name [sc/required sc/string]
|
{:name [sc/required sc/string]
|
||||||
:layout [sc/required sc/string]
|
:metadata [sc/required]
|
||||||
:width [sc/required sc/integer]
|
|
||||||
:height [sc/required sc/integer]
|
|
||||||
:project [sc/required sc/uuid]})
|
:project [sc/required sc/uuid]})
|
||||||
|
|
||||||
(defn create-page
|
(defn create-page
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
[uxbox.util.transit :as t]))
|
[uxbox.util.transit :as t]))
|
||||||
|
|
||||||
(defn decode-page
|
(defn decode-page
|
||||||
[{:keys [data options] :as page}]
|
[{:keys [data metadata] :as page}]
|
||||||
(merge page
|
(merge page
|
||||||
(when data {:data (t/decode data)})
|
(when data {:data (t/decode data)})
|
||||||
(when options {:options (t/decode options)})))
|
(when metadata {:metadata (t/decode metadata)})))
|
||||||
|
|
||||||
(defn decode-payload
|
(defn decode-payload
|
||||||
[{:keys [payload] :as rsp}]
|
[{:keys [payload] :as rsp}]
|
||||||
|
@ -51,10 +51,10 @@
|
||||||
:method :delete})))
|
:method :delete})))
|
||||||
|
|
||||||
(defmethod request :create/page
|
(defmethod request :create/page
|
||||||
[type {:keys [data options] :as body}]
|
[type {:keys [data metadata] :as body}]
|
||||||
(let [body (assoc body
|
(let [body (assoc body
|
||||||
:data (t/encode data)
|
:data (t/encode data)
|
||||||
:options (t/encode options))
|
:metadata (t/encode metadata))
|
||||||
params {:url (str url "/pages")
|
params {:url (str url "/pages")
|
||||||
:method :post
|
:method :post
|
||||||
:body body}]
|
:body body}]
|
||||||
|
@ -62,10 +62,10 @@
|
||||||
(rx/map decode-payload))))
|
(rx/map decode-payload))))
|
||||||
|
|
||||||
(defmethod request :update/page
|
(defmethod request :update/page
|
||||||
[type {:keys [id data options] :as body}]
|
[type {:keys [id data metadata] :as body}]
|
||||||
(let [body (assoc body
|
(let [body (assoc body
|
||||||
:data (t/encode data)
|
:data (t/encode data)
|
||||||
:options (t/encode options))
|
:metadata (t/encode metadata))
|
||||||
params {:url (str url "/pages/" id)
|
params {:url (str url "/pages/" id)
|
||||||
:method :put
|
:method :put
|
||||||
:body body}]
|
:body body}]
|
||||||
|
@ -81,9 +81,9 @@
|
||||||
(rx/map decode-payload))))
|
(rx/map decode-payload))))
|
||||||
|
|
||||||
(defmethod request :update/page-metadata
|
(defmethod request :update/page-metadata
|
||||||
[type {:keys [id options] :as body}]
|
[type {:keys [id metadata] :as body}]
|
||||||
(let [body (dissoc body :data)
|
(let [body (dissoc body :data)
|
||||||
body (assoc body :options (t/encode options))
|
body (assoc body :metadata (t/encode metadata))
|
||||||
params {:url (str url "/pages/" id "/metadata")
|
params {:url (str url "/pages/" id "/metadata")
|
||||||
:method :put
|
:method :put
|
||||||
:body body}]
|
:body body}]
|
||||||
|
|
|
@ -43,16 +43,18 @@
|
||||||
|
|
||||||
(mx/defc canvas
|
(mx/defc canvas
|
||||||
{:mixins [mx/reactive]}
|
{:mixins [mx/reactive]}
|
||||||
[{:keys [width height id] :as page}]
|
[{:keys [metadata id] :as page}]
|
||||||
(let [workspace (mx/react wb/workspace-ref)
|
(let [workspace (mx/react wb/workspace-ref)
|
||||||
flags (:flags workspace)]
|
flags (:flags workspace)
|
||||||
|
width (:width metadata)
|
||||||
|
height (:height metadata)]
|
||||||
[:svg.page-canvas {:x c/canvas-start-x
|
[:svg.page-canvas {:x c/canvas-start-x
|
||||||
:y c/canvas-start-y
|
:y c/canvas-start-y
|
||||||
:ref (str "canvas" id)
|
:ref (str "canvas" id)
|
||||||
:width width
|
:width width
|
||||||
:height height}
|
:height height}
|
||||||
(background)
|
(background)
|
||||||
[:svg.page-layout {}
|
[:svg.page-layout
|
||||||
[:g.main {}
|
[:g.main {}
|
||||||
(for [item (reverse (:shapes page))]
|
(for [item (reverse (:shapes page))]
|
||||||
(-> (uus/shape item)
|
(-> (uus/shape item)
|
||||||
|
|
|
@ -6,9 +6,7 @@
|
||||||
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||||
|
|
||||||
(ns uxbox.main.ui.workspace.sidebar.sitemap
|
(ns uxbox.main.ui.workspace.sidebar.sitemap
|
||||||
(:require [sablono.core :as html :refer-macros [html]]
|
(:require [lentes.core :as l]
|
||||||
[rum.core :as rum]
|
|
||||||
[lentes.core :as l]
|
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[uxbox.util.i18n :refer (tr)]
|
[uxbox.util.i18n :refer (tr)]
|
||||||
[uxbox.util.router :as r]
|
[uxbox.util.router :as r]
|
||||||
|
@ -24,10 +22,10 @@
|
||||||
[uxbox.main.ui.icons :as i]
|
[uxbox.main.ui.icons :as i]
|
||||||
[uxbox.util.mixins :as mx :include-macros true]
|
[uxbox.util.mixins :as mx :include-macros true]
|
||||||
[uxbox.main.ui.lightbox :as lbx]
|
[uxbox.main.ui.lightbox :as lbx]
|
||||||
[uxbox.util.data :refer (read-string parse-int)]
|
[uxbox.util.data :refer (deep-merge parse-int)]
|
||||||
[uxbox.util.dom :as dom]))
|
[uxbox.util.dom :as dom]))
|
||||||
|
|
||||||
;; --- Lenses
|
;; --- Refs
|
||||||
|
|
||||||
(defn- resolve-pages
|
(defn- resolve-pages
|
||||||
[state]
|
[state]
|
||||||
|
@ -42,8 +40,9 @@
|
||||||
|
|
||||||
;; --- Component
|
;; --- Component
|
||||||
|
|
||||||
(defn page-item-render
|
(mx/defc page-item
|
||||||
[own page total active?]
|
{:mixins [(mx/local) mx/static mx/reactive]}
|
||||||
|
[page total active?]
|
||||||
(letfn [(on-edit [event]
|
(letfn [(on-edit [event]
|
||||||
(udl/open! :page-form {:page page}))
|
(udl/open! :page-form {:page page}))
|
||||||
|
|
||||||
|
@ -58,50 +57,37 @@
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(udl/open! :confirm {:on-accept delete}))]
|
(udl/open! :confirm {:on-accept delete}))]
|
||||||
(html
|
[:li {:class (when active? "selected")
|
||||||
[:li {:class (when active? "selected")
|
:on-click on-navigate}
|
||||||
:on-click on-navigate}
|
[:div.page-icon i/page]
|
||||||
[:div.page-icon i/page]
|
[:span (:name page)]
|
||||||
[:span (:name page)]
|
[:div.page-actions
|
||||||
[:div.page-actions
|
[:a {:on-click on-edit} i/pencil]
|
||||||
[:a {:on-click on-edit} i/pencil]
|
(if (> total 1)
|
||||||
(if (> total 1)
|
[:a {:on-click on-delete} i/trash])]]))
|
||||||
[:a {:on-click on-delete} i/trash])]])))
|
|
||||||
|
|
||||||
(def page-item
|
(mx/defc sitemap-toolbox
|
||||||
(mx/component
|
{:mixins [mx/static mx/reactive]}
|
||||||
{:render page-item-render
|
[]
|
||||||
:name "page-item"
|
|
||||||
:mixins [(mx/local) mx/static mx/reactive]}))
|
|
||||||
|
|
||||||
(defn sitemap-toolbox-render
|
|
||||||
[own]
|
|
||||||
(let [project (mx/react wb/project-ref)
|
(let [project (mx/react wb/project-ref)
|
||||||
pages (mx/react pages-ref)
|
pages (mx/react pages-ref)
|
||||||
current (mx/react wb/page-ref)
|
current (mx/react wb/page-ref)
|
||||||
create #(udl/open! :page-form {:page {:project (:id project)}})
|
create #(udl/open! :page-form {:page {:project (:id project)}})
|
||||||
close #(rs/emit! (dw/toggle-flag :sitemap))]
|
close #(rs/emit! (dw/toggle-flag :sitemap))]
|
||||||
(html
|
[:div.sitemap.tool-window
|
||||||
[:div.sitemap.tool-window
|
[:div.tool-window-bar
|
||||||
[:div.tool-window-bar
|
[:div.tool-window-icon i/project-tree]
|
||||||
[:div.tool-window-icon i/project-tree]
|
[:span (tr "ds.sitemap")]
|
||||||
[:span (tr "ds.sitemap")]
|
[:div.tool-window-close {:on-click close} i/close]]
|
||||||
[:div.tool-window-close {:on-click close} i/close]]
|
[:div.tool-window-content
|
||||||
[:div.tool-window-content
|
[:div.project-title
|
||||||
[:div.project-title
|
[:span (:name project)]
|
||||||
[:span (:name project)]
|
[:div.add-page {:on-click create} i/close]]
|
||||||
[:div.add-page {:on-click create} i/close]]
|
[:ul.element-list
|
||||||
[:ul.element-list
|
(for [page pages
|
||||||
(for [page pages
|
:let [active? (= (:id page) (:id current))]]
|
||||||
:let [active? (= (:id page) (:id current))]]
|
(-> (page-item page (count pages) active?)
|
||||||
(-> (page-item page (count pages) active?)
|
(mx/with-key (:id page))))]]]))
|
||||||
(rum/with-key (:id page))))]]])))
|
|
||||||
|
|
||||||
(def sitemap-toolbox
|
|
||||||
(mx/component
|
|
||||||
{:render sitemap-toolbox-render
|
|
||||||
:name "sitemap-toolbox"
|
|
||||||
:mixins [mx/static mx/reactive]}))
|
|
||||||
|
|
||||||
;; --- Lightbox
|
;; --- Lightbox
|
||||||
|
|
||||||
|
@ -110,39 +96,43 @@
|
||||||
:height 1080
|
:height 1080
|
||||||
:layout :desktop})
|
:layout :desktop})
|
||||||
|
|
||||||
(defn- layout-input
|
(mx/defc layout-input
|
||||||
[local page id]
|
[local page id]
|
||||||
(let [layout (get +layouts+ id)
|
(let [layout (get +layouts+ id)
|
||||||
|
metadata (:metadata page)
|
||||||
size (select-keys layout [:width :height])
|
size (select-keys layout [:width :height])
|
||||||
change #(swap! local merge {:layout id} size)]
|
change #(swap! local update :metadata merge {:layout id} size)]
|
||||||
(html
|
[:div
|
||||||
[:div
|
[:input {:type "radio"
|
||||||
[:input {:type "radio"
|
:key id :id id
|
||||||
:key id :id id
|
:name "project-layout"
|
||||||
:name "project-layout"
|
:value (:id layout)
|
||||||
:value (:id layout)
|
:checked (= id (:layout metadata))
|
||||||
:checked (= id (:layout page))
|
:on-change change}]
|
||||||
:on-change change}]
|
[:label {:value (:id layout) :for id} (:name layout)]]))
|
||||||
[:label {:value (:id layout) :for id} (:name layout)]])))
|
|
||||||
|
|
||||||
(defn- page-form-lightbox-render
|
(mx/defcs page-form-lightbox
|
||||||
[own local page]
|
{:mixins [(mx/local)]}
|
||||||
(let [edition? (:id page)
|
[own page]
|
||||||
page (merge page @local {:data nil})
|
(let [local (:rum/local own)
|
||||||
|
page (deep-merge page @local {:data nil})
|
||||||
|
metadata (:metadata page)
|
||||||
|
edition? (:id page)
|
||||||
valid? (and (not (str/empty? (str/trim (:name page ""))))
|
valid? (and (not (str/empty? (str/trim (:name page ""))))
|
||||||
(pos? (:width page))
|
(pos? (:width metadata))
|
||||||
(pos? (:height page)))]
|
(pos? (:height metadata)))]
|
||||||
(letfn [(update-size [field e]
|
(letfn [(update-size [field e]
|
||||||
(let [value (dom/event->value e)
|
(let [value (dom/event->value e)
|
||||||
value (parse-int value)]
|
value (parse-int value)]
|
||||||
(swap! local assoc field value)))
|
(swap! local assoc-in [:metadata field] value)))
|
||||||
(update-name [e]
|
(update-name [e]
|
||||||
(let [value (dom/event->value e)]
|
(let [value (dom/event->value e)]
|
||||||
(swap! local assoc :name value)))
|
(swap! local assoc :name value)))
|
||||||
(toggle-sizes []
|
(toggle-sizes []
|
||||||
(swap! local assoc
|
(let [width (get-in page [:metadata :width])
|
||||||
:width (:height page)
|
height (get-in page [:metadata :height])]
|
||||||
:height (:width page)))
|
(swap! local update :metadata merge {:width height
|
||||||
|
:height width})))
|
||||||
(cancel [e]
|
(cancel [e]
|
||||||
(dom/prevent-default e)
|
(dom/prevent-default e)
|
||||||
(udl/close!))
|
(udl/close!))
|
||||||
|
@ -152,53 +142,46 @@
|
||||||
(if edition?
|
(if edition?
|
||||||
(rs/emit! (udp/update-page-metadata page))
|
(rs/emit! (udp/update-page-metadata page))
|
||||||
(rs/emit! (udp/create-page page))))]
|
(rs/emit! (udp/create-page page))))]
|
||||||
(html
|
[:div.lightbox-body
|
||||||
[:div.lightbox-body
|
(if edition?
|
||||||
(if edition?
|
[:h3 "Edit page"]
|
||||||
[:h3 "Edit page"]
|
[:h3 "New page"])
|
||||||
[:h3 "New page"])
|
[:form
|
||||||
[:form
|
[:input#project-name.input-text
|
||||||
[:input#project-name.input-text
|
{:placeholder "Page name"
|
||||||
{:placeholder "Page name"
|
:type "text"
|
||||||
:type "text"
|
:value (:name page "")
|
||||||
:value (:name page "")
|
:auto-focus true
|
||||||
:auto-focus true
|
:on-change update-name}]
|
||||||
:on-change update-name}]
|
[:div.project-size
|
||||||
[:div.project-size
|
[:input#project-witdh.input-text
|
||||||
[:input#project-witdh.input-text
|
{:placeholder "Width"
|
||||||
{:placeholder "Width"
|
:type "number"
|
||||||
:type "number"
|
:min 0
|
||||||
:min 0
|
:max 4000
|
||||||
:max 4000
|
:value (:width metadata)
|
||||||
:value (:width page)
|
:on-change #(update-size :width %)}]
|
||||||
:on-change #(update-size :width %)}]
|
[:a.toggle-layout {:on-click toggle-sizes} i/toggle]
|
||||||
[:a.toggle-layout {:on-click toggle-sizes} i/toggle]
|
[:input#project-height.input-text
|
||||||
[:input#project-height.input-text
|
{:placeholder "Height"
|
||||||
{:placeholder "Height"
|
:type "number"
|
||||||
:type "number"
|
:min 0
|
||||||
:min 0
|
:max 4000
|
||||||
:max 4000
|
:value (:height metadata)
|
||||||
:value (:height page)
|
:on-change #(update-size :height %)}]]
|
||||||
:on-change #(update-size :height %)}]]
|
|
||||||
|
|
||||||
[:div.input-radio.radio-primary
|
[:div.input-radio.radio-primary
|
||||||
(layout-input local page "mobile")
|
(layout-input local page "mobile")
|
||||||
(layout-input local page "tablet")
|
(layout-input local page "tablet")
|
||||||
(layout-input local page "notebook")
|
(layout-input local page "notebook")
|
||||||
(layout-input local page "desktop")]
|
(layout-input local page "desktop")]
|
||||||
|
|
||||||
(when valid?
|
(when valid?
|
||||||
[:input#project-btn.btn-primary
|
[:input#project-btn.btn-primary
|
||||||
{:value "Go go go!"
|
{:value "Go go go!"
|
||||||
:on-click persist
|
:on-click persist
|
||||||
:type "button"}])]
|
:type "button"}])]
|
||||||
[:a.close {:on-click cancel} i/close]]))))
|
[:a.close {:on-click cancel} i/close]])))
|
||||||
|
|
||||||
(def page-form-lightbox
|
|
||||||
(mx/component
|
|
||||||
{:render #(page-form-lightbox-render %1 (:rum/local %1) %2)
|
|
||||||
:name "page-form-lightbox"
|
|
||||||
:mixins [(mx/local)]}))
|
|
||||||
|
|
||||||
(defmethod lbx/render-lightbox :page-form
|
(defmethod lbx/render-lightbox :page-form
|
||||||
[{:keys [page]}]
|
[{:keys [page]}]
|
||||||
|
|
|
@ -90,6 +90,16 @@
|
||||||
(and (string? v)
|
(and (string? v)
|
||||||
(re-seq +uuid-re+ v)))
|
(re-seq +uuid-re+ v)))
|
||||||
|
|
||||||
|
;; --- Interop
|
||||||
|
|
||||||
|
(defn jscoll->vec
|
||||||
|
"Convert array like js object into vector."
|
||||||
|
[v]
|
||||||
|
(-> (clj->js [])
|
||||||
|
(.-slice)
|
||||||
|
(.call v)
|
||||||
|
(js->clj)))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Numbers Parsing
|
;; Numbers Parsing
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
|
@ -46,8 +46,9 @@
|
||||||
{:mixins [mx/static mx/reactive]}
|
{:mixins [mx/static mx/reactive]}
|
||||||
[]
|
[]
|
||||||
(let [page (rum/react page-ref)
|
(let [page (rum/react page-ref)
|
||||||
width (:width page)
|
metadata (:metadata page)
|
||||||
height (:height page)]
|
width (:width metadata)
|
||||||
|
height (:height metadata)]
|
||||||
[:div.view-canvas
|
[:div.view-canvas
|
||||||
[:svg.page-layout {:width width :height height}
|
[:svg.page-layout {:width width :height height}
|
||||||
(background)
|
(background)
|
||||||
|
|
Loading…
Add table
Reference in a new issue