diff --git a/backend/resources/migrations/0003.projects.sql b/backend/resources/migrations/0003.projects.sql index 10f950eab..5826f1345 100644 --- a/backend/resources/migrations/0003.projects.sql +++ b/backend/resources/migrations/0003.projects.sql @@ -81,7 +81,7 @@ CREATE TABLE IF NOT EXISTS project_page_snapshots ( label text NOT NULL DEFAULT '', data bytea NOT NULL, - operations bytea NULL DEFAULT NULL + changes bytea NULL DEFAULT NULL ); -- Indexes diff --git a/backend/src/uxbox/services/mutations/project_pages.clj b/backend/src/uxbox/services/mutations/project_pages.clj index 2ca5443a2..c277634fd 100644 --- a/backend/src/uxbox/services/mutations/project_pages.clj +++ b/backend/src/uxbox/services/mutations/project_pages.clj @@ -28,7 +28,6 @@ (s/def ::data ::cp/data) (s/def ::user ::us/uuid) (s/def ::project-id ::us/uuid) -(s/def ::metadata ::cp/metadata) (s/def ::ordering ::us/number) ;; --- Mutation: Create Page @@ -36,7 +35,7 @@ (declare create-page) (s/def ::create-project-page - (s/keys :req-un [::user ::file-id ::name ::ordering ::metadata ::data] + (s/keys :req-un [::user ::file-id ::name ::ordering ::data] :opt-un [::id])) (sm/defmutation ::create-project-page @@ -46,15 +45,14 @@ (create-page conn params))) (defn create-page - [conn {:keys [id user file-id name ordering data metadata] :as params}] + [conn {:keys [id user file-id name ordering data] :as params}] (let [sql "insert into project_pages (id, user_id, file_id, name, - ordering, data, metadata, version) - values ($1, $2, $3, $4, $5, $6, $7, 0) + ordering, data, version) + values ($1, $2, $3, $4, $5, $6, 0) returning *" id (or id (uuid/next)) - data (blob/encode data) - mdata (blob/encode metadata)] - (-> (db/query-one conn [sql id user file-id name ordering data mdata]) + data (blob/encode data)] + (-> (db/query-one conn [sql id user file-id name ordering data]) (p/then' decode-row)))) ;; --- Mutation: Update Page Data @@ -98,11 +96,11 @@ (p/then' su/constantly-nil)))) (defn- insert-page-snapshot - [conn {:keys [user-id id version data operations]}] - (let [sql "insert into project_page_snapshots (user_id, page_id, version, data, operations) + [conn {:keys [user-id id version data changes]}] + (let [sql "insert into project_page_snapshots (user_id, page_id, version, data, changes) values ($1, $2, $3, $4, $5) - returning id, page_id, user_id, version, operations"] - (db/query-one conn [sql user-id id version data operations]))) + returning id, page_id, user_id, version, changes"] + (db/query-one conn [sql user-id id version data changes]))) ;; --- Mutation: Rename Page @@ -129,16 +127,16 @@ ;; --- Mutation: Update Page -;; A generic, Ops based (granular) page update method. +;; A generic, Changes based (granular) page update method. -(s/def ::operations +(s/def ::changes (s/coll-of vector? :kind vector?)) (s/def ::update-project-page - (s/keys :opt-un [::id ::user ::version ::operations])) + (s/keys :opt-un [::id ::user ::version ::changes])) (declare update-project-page) -(declare retrieve-lagged-operations) +(declare retrieve-lagged-changes) (sm/defmutation ::update-project-page [{:keys [id user] :as params}] @@ -156,17 +154,17 @@ :hint "The incoming version is greater that stored version." :context {:incoming-version (:version params) :stored-version (:version page)})) - (let [ops (:operations params) + (let [changes (:changes params) data (-> (:data page) (blob/decode) - (cp/process-ops ops) + (cp/process-changes changes) (blob/encode)) page (assoc page :user-id (:user params) :data data :version (inc (:version page)) - :operations (blob/encode ops))] + :changes (blob/encode changes))] (-> (update-page-data conn page) (p/then (fn [_] (insert-page-snapshot conn page))) @@ -176,26 +174,26 @@ :user-id (:user-id s) :page-id (:page-id s) :version (:version s) - :operations ops}) - (retrieve-lagged-operations conn s params)))))))) + :changes changes}) + (retrieve-lagged-changes conn s params)))))))) (su/defstr sql:lagged-snapshots - "select s.id, s.operations + "select s.id, s.changes from project_page_snapshots as s where s.page_id = $1 and s.version > $2") -(defn- retrieve-lagged-operations +(defn- retrieve-lagged-changes [conn snapshot params] (let [sql sql:lagged-snapshots] (-> (db/query conn [sql (:id params) (:version params) #_(:id snapshot)]) (p/then (fn [rows] {:page-id (:id params) :version (:version snapshot) - :operations (into [] (comp (map decode-row) - (map :operations) - (mapcat identity)) - rows)}))))) + :changes (into [] (comp (map decode-row) + (map :changes) + (mapcat identity)) + rows)}))))) ;; --- Mutation: Delete Page diff --git a/backend/src/uxbox/services/queries/project_pages.clj b/backend/src/uxbox/services/queries/project_pages.clj index 9d4310ee6..e19530f95 100644 --- a/backend/src/uxbox/services/queries/project_pages.clj +++ b/backend/src/uxbox/services/queries/project_pages.clj @@ -120,9 +120,9 @@ ;; --- Helpers (defn decode-row - [{:keys [data metadata operations] :as row}] + [{:keys [data metadata changes] :as row}] (when row (cond-> row data (assoc :data (blob/decode data)) metadata (assoc :metadata (blob/decode metadata)) - operations (assoc :operations (blob/decode operations))))) + changes (assoc :changes (blob/decode changes))))) diff --git a/common/uxbox/common/pages.cljc b/common/uxbox/common/pages.cljc index 0e942be37..b996b63eb 100644 --- a/common/uxbox/common/pages.cljc +++ b/common/uxbox/common/pages.cljc @@ -10,25 +10,83 @@ (s/def ::name string?) (s/def ::type keyword?) -;; Metadata related -(s/def ::grid-x-axis number?) -(s/def ::grid-y-axis number?) +;; Page Options +(s/def ::grid-x number?) +(s/def ::grid-y number?) (s/def ::grid-color string?) -(s/def ::background string?) -(s/def ::background-opacity number?) -(s/def ::metadata - (s/keys :opt-un [::grid-y-axis - ::grid-x-axis - ::grid-color - ::background - ::background-opacity])) +(s/def ::options + (s/keys :opt-un [::grid-y + ::grid-x + ::grid-color])) ;; Page Data related -(s/def ::shape +(s/def ::blocked boolean?) +(s/def ::collapsed boolean?) +(s/def ::content string?) +(s/def ::fill-color string?) +(s/def ::fill-opacity number?) +(s/def ::font-family string?) +(s/def ::font-size number?) +(s/def ::font-style string?) +(s/def ::font-weight string?) +(s/def ::hidden boolean?) +(s/def ::letter-spacing number?) +(s/def ::line-height number?) +(s/def ::locked boolean?) +(s/def ::page-id uuid?) +(s/def ::proportion number?) +(s/def ::proportion-lock boolean?) +(s/def ::rx number?) +(s/def ::ry number?) +(s/def ::stroke-color string?) +(s/def ::stroke-opacity number?) +(s/def ::stroke-style #{:none :solid :dotted :dashed :mixed}) +(s/def ::stroke-width number?) +(s/def ::text-align #{"left" "right" "center" "justify"}) +(s/def ::type #{:rect :path :circle :image :text :canvas}) +(s/def ::x number?) +(s/def ::y number?) +(s/def ::cx number?) +(s/def ::cy number?) +(s/def ::width number?) +(s/def ::height number?) + +(s/def ::shape-attrs + (s/keys :opt-un [::blocked + ::collapsed + ::content + ::fill-color + ::fill-opacity + ::font-family + ::font-size + ::font-style + ::font-weight + ::hidden + ;; ::page-id ?? + ::letter-spacing + ::line-height + ::locked + ::proportion + ::proportion-lock + ::rx ::ry + ::cx ::cy + ::x ::y + ::stroke-color + ::stroke-opacity + ::stroke-style + ::stroke-width + ::text-align + ::width ::height])) + +(s/def ::minimal-shape (s/keys :req-un [::type ::name] :opt-un [::id])) +(s/def ::shape + (s/and ::minimal-shape ::shape-attrs + (s/keys :opt-un [::id]))) + (s/def ::shapes (s/coll-of uuid? :kind vector?)) (s/def ::canvas (s/coll-of uuid? :kind vector?)) @@ -36,12 +94,16 @@ (s/map-of uuid? ::shape)) (s/def ::data - (s/keys :req-un [::shapes ::canvas ::shapes-by-id])) + (s/keys :req-un [::shapes + ::canvas + ::options + ::shapes-by-id])) +;; Changes related (s/def ::attr-change (s/tuple #{:set} keyword? any?)) -(s/def ::operation +(s/def ::change (s/or :mod-shape (s/cat :name #(= % :mod-shape) :id uuid? :changes (s/* ::attr-change)) @@ -64,12 +126,12 @@ :del-canvas (s/cat :name #(= % :del-canvas) :id uuid?))) -(s/def ::operations - (s/coll-of ::operation :kind vector?)) +(s/def ::changes + (s/coll-of ::change :kind vector?)) -;; --- Operations Processing Impl +;; --- Changes Processing Impl -(declare process-operation) +(declare process-change) (declare process-mod-shape) (declare process-mod-opts) (declare process-mov-shape) @@ -78,12 +140,12 @@ (declare process-del-shape) (declare process-del-canvas) -(defn process-ops - [data operations] - (->> (s/assert ::operations operations) - (reduce process-operation data))) +(defn process-changes + [data items] + (->> (s/assert ::changes items) + (reduce process-change data))) -(defn- process-operation +(defn- process-change [data [op & rest]] (case op :mod-shape (process-mod-shape data rest) diff --git a/frontend/src/uxbox/main/data/projects.cljs b/frontend/src/uxbox/main/data/projects.cljs index 906c65c8a..2c50fff33 100644 --- a/frontend/src/uxbox/main/data/projects.cljs +++ b/frontend/src/uxbox/main/data/projects.cljs @@ -471,26 +471,3 @@ (assoc :workspace-page page) (update :pages assoc id page) (update :pages-data assoc id data)))))) - -;; --- Update Page - -;; TODO: deprecated, need refactor (this is used on page options) -(defn update-page-attrs - [{:keys [id] :as data}] - (s/assert ::page data) - (ptk/reify ::update-page-attrs - ptk/UpdateEvent - (update [_ state] - (update state :workspace-page merge (dissoc data :id :version))))) - -;; --- Update Page Metadata - -;; TODO: deprecated, need refactor (this is used on page options) -(defn update-metadata - [id metadata] - (s/assert ::id id) - (s/assert ::metadata metadata) - (reify - ptk/UpdateEvent - (update [this state] - (assoc-in state [:pages id :metadata] metadata)))) diff --git a/frontend/src/uxbox/main/data/workspace.cljs b/frontend/src/uxbox/main/data/workspace.cljs index 6cb22f666..b881a4039 100644 --- a/frontend/src/uxbox/main/data/workspace.cljs +++ b/frontend/src/uxbox/main/data/workspace.cljs @@ -34,89 +34,24 @@ [uxbox.util.uuid :as uuid] [vendor.randomcolor])) - ;; TODO: temporal workaround (def clear-ruler nil) (def start-ruler nil) ;; --- Specs -(s/def ::id ::us/uuid) -(s/def ::blocked boolean?) -(s/def ::collapsed boolean?) -(s/def ::content string?) -(s/def ::fill-color string?) -(s/def ::fill-opacity number?) -(s/def ::font-family string?) -(s/def ::font-size number?) -(s/def ::font-style string?) -(s/def ::font-weight string?) -(s/def ::hidden boolean?) -(s/def ::id uuid?) -(s/def ::letter-spacing number?) -(s/def ::line-height number?) -(s/def ::locked boolean?) -(s/def ::name string?) -(s/def ::page uuid?) -(s/def ::proportion number?) -(s/def ::proportion-lock boolean?) -(s/def ::rx number?) -(s/def ::ry number?) -(s/def ::stroke-color string?) -(s/def ::stroke-opacity number?) -(s/def ::stroke-style #{:none :solid :dotted :dashed :mixed}) -(s/def ::stroke-width number?) -(s/def ::text-align #{"left" "right" "center" "justify"}) -(s/def ::type #{:rect :path :circle :image :text :canvas}) -(s/def ::x number?) -(s/def ::y number?) -(s/def ::cx number?) -(s/def ::cy number?) -(s/def ::width number?) -(s/def ::height number?) - -(s/def ::attributes - (s/keys :opt-un [::blocked - ::collapsed - ::content - ::fill-color - ::fill-opacity - ::font-family - ::font-size - ::font-style - ::font-weight - ::hidden - ::letter-spacing - ::line-height - ::locked - ::proportion - ::proportion-lock - ::rx ::ry - ::cx ::cy - ::x ::y - ::stroke-color - ::stroke-opacity - ::stroke-style - ::stroke-width - ::text-align - ::width ::height])) - -(s/def ::minimal-shape - (s/keys :req-un [::id ::page ::type ::name])) - -(s/def ::shape - (s/and ::minimal-shape ::attributes)) - -(s/def ::rect-like-shape - (s/keys :req-un [::x1 ::y1 ::x2 ::y2 ::type])) - +(s/def ::shape-attrs ::cp/shape-attrs) (s/def ::set-of-uuid - (s/every ::us/uuid :kind set?)) + (s/every uuid? :kind set?)) ;; --- Expose inner functions (defn interrupt? [e] (= e :interrupt)) +;; --- Protocols + +(defprotocol IAsyncChange) + ;; --- Declarations (declare fetch-users) @@ -125,8 +60,8 @@ (declare handle-pointer-send) (declare handle-page-snapshot) (declare shapes-changes-commited) -(declare commit-shapes-changes) -(declare async-commit-shapes-changes) +(declare commit-changes) +(declare commit-async-changes) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Websockets Events @@ -320,19 +255,14 @@ (watch [_ state stream] (let [stoper (rx/filter #(or (ptk/type? ::finalize %) (ptk/type? ::initialize-page %)) - stream) - notifier (->> stream - (rx/filter (ptk/type? ::async-commit-shapes-changes)) - (rx/debounce 500))] + stream)] (->> stream - (rx/filter (ptk/type? ::async-commit-shapes-changes)) - (rx/map deref) - (rx/mapcat identity) - (rx/buffer-until notifier) - (rx/map vec) - (rx/map commit-shapes-changes) - (rx/take-until stoper) - (rx/finalize #(prn "FINALIZE" %))))))) + (rx/filter #(satisfies? IAsyncChange %)) + (rx/debounce 500) + (rx/map (constantly commit-async-changes)) + (rx/finalize #(prn "FINALIZE" %)) + (rx/take-until stoper)))))) + ;; --- Fetch Workspace Users @@ -612,7 +542,7 @@ (defn add-shape [data] - (s/assert ::attributes data) + (s/assert ::shape-attrs data) (let [id (uuid/random)] (ptk/reify ::add-shape ptk/UpdateEvent @@ -626,7 +556,7 @@ ptk/WatchEvent (watch [_ state stream] (let [shape (get-in state [:workspace-data :shapes-by-id id])] - (rx/of (commit-shapes-changes [[:add-shape id shape]]) + (rx/of (commit-changes [[:add-shape id shape]]) (select-shape id))))))) (def canvas-default-attrs @@ -637,7 +567,7 @@ (defn add-canvas [data] - (s/assert ::attributes data) + (s/assert ::shape-attrs data) (let [id (uuid/random)] (ptk/reify ::add-canvas ptk/UpdateEvent @@ -651,7 +581,7 @@ ptk/WatchEvent (watch [_ state stream] (let [shape (get-in state [:workspace-data :shapes-by-id id])] - (rx/of (commit-shapes-changes [[:add-canvas id shape]]) + (rx/of (commit-changes [[:add-canvas id shape]]) (select-shape id))))))) @@ -671,7 +601,7 @@ shapes (map duplicate selected)] (rx/merge (rx/from (map (fn [s] #(impl-assoc-shape % s)) shapes)) - (rx/of (commit-shapes-changes (mapv #(vector :add-shape (:id %) %) shapes)))))))) + (rx/of (commit-changes (mapv #(vector :add-shape (:id %) %) shapes)))))))) ;; --- Toggle shape's selection status (selected or deselected) @@ -740,8 +670,9 @@ (defn update-shape [id attrs] (s/assert ::us/uuid id) - (s/assert ::attributes attrs) + (s/assert ::shape-attrs attrs) (ptk/reify ::update-shape + IAsyncChange ptk/UpdateEvent (update [_ state] (let [shape-old (get-in state [:workspace-data :shapes-by-id id]) @@ -749,13 +680,23 @@ diff (d/diff-maps shape-old shape-new)] (-> state (assoc-in [:workspace-data :shapes-by-id id] shape-new) - (assoc ::tmp-change (into [:mod-shape id] diff))))) + (update ::async-changes (fnil conj []) (into [:mod-shape id] diff))))))) - ptk/WatchEvent - (watch [_ state stream] - (let [change (::tmp-change state)] - (rx/of (async-commit-shapes-changes [change]) - #(dissoc state ::tmp-change)))))) +;; --- Update Page Options + +(defn update-options + [opts] + (s/assert ::cp/options opts) + (ptk/reify ::update-options + IAsyncChange + ptk/UpdateEvent + (update [_ state] + (let [opts-old (get-in state [:workspace-data :options]) + opts-new (merge opts-old opts) + diff (d/diff-maps opts-old opts-new)] + (-> state + (assoc-in [:workspace-data :options] opts-new) + (update ::async-changes (fnil conj []) (into [:mod-opts] diff))))))) ;; --- Update Selected Shapes attrs @@ -844,7 +785,7 @@ ptk/WatchEvent (watch [_ state stream] (let [selected (get-in state [:workspace-local :selected])] - (rx/of (commit-shapes-changes (mapv #(vector :del-shape %) selected))))))) + (rx/of (commit-changes (mapv #(vector :del-shape %) selected))))))) ;; --- Rename Shape @@ -858,7 +799,7 @@ ptk/WatchEvent (watch [_ state stream] - (rx/of (commit-shapes-changes [[:mod-shape id [:mod :name name]]]))))) + (rx/of (commit-changes [[:mod-shape id [:mod :name name]]]))))) ;; --- Shape Vertical Ordering @@ -897,7 +838,6 @@ [id index] (s/assert ::us/uuid id) (s/assert number? index) - {:pre [(uuid? id) (number? index)]} (ptk/reify ::change-shape-order ptk/UpdateEvent (update [_ state] @@ -905,18 +845,18 @@ shapes (into [] (remove #(= % id)) shapes) [before after] (split-at index shapes) shapes (d/concat [] before [id] after) - operation [:mov-shape id :after (last before)]] + change [:mov-shape id :after (last before)]] (-> state (assoc-in [:workspace-data :shapes] shapes) - (assoc ::tmp-changes [operation])))))) + (assoc ::tmp-shape-order-change change)))))) (def commit-shape-order-change (ptk/reify ::commit-shape-order-change ptk/WatchEvent (watch [_ state stream] - (let [changes (::tmp-changes state)] - (rx/of (commit-shapes-changes changes) - #(dissoc state ::tmp-changes)))))) + (let [change (::tmp-shape-order-change state)] + (rx/of #(dissoc state ::tmp-changes) + (commit-changes [change])))))) ;; --- Change Canvas Order (D&D Ordering) @@ -1001,50 +941,46 @@ diff (d/diff-maps shape-old shape-new)] (-> state (assoc-in [:workspace-data :shapes-by-id id] shape-new) - (update ::tmp-changes (fnil conj []) (into [:mod-shape id] diff)))))] + (update ::async-changes (fnil conj []) (into [:mod-shape id] diff)))))] (ptk/reify ::materialize-temporal-modifier-in-bulk + IAsyncChange ptk/UpdateEvent (update [_ state] - (reduce process-shape state ids)) + (reduce process-shape state ids))))) - ptk/WatchEvent - (watch [_ state stream] - (let [changes (::tmp-changes state)] - (rx/of (commit-shapes-changes changes) - #(dissoc state ::tmp-changes))))))) - -(defn commit-shapes-changes - [operations] - (s/assert ::cp/operations operations) - (ptk/reify ::commit-shapes-changes +(defn commit-changes + [changes] + (s/assert ::cp/changes changes) + (ptk/reify ::commit-changes ptk/UpdateEvent (update [_ state] (let [pid (get-in state [:workspace-local :page-id]) data (get-in state [:pages-data pid])] - (update-in state [:pages-data pid] cp/process-ops operations))) + (update-in state [:pages-data pid] cp/process-changes changes))) ptk/WatchEvent (watch [_ state stream] (let [page (:workspace-page state) params {:id (:id page) :version (:version page) - :operations operations}] + :changes changes}] (->> (rp/mutation :update-project-page params) (rx/map shapes-changes-commited)))))) -(defn async-commit-shapes-changes - [operations] - (s/assert ::cp/operations operations) - (ptk/reify ::async-commit-shapes-changes - cljs.core/IDeref - (-deref [_] operations))) +(def commit-async-changes + (ptk/reify ::commit-async-changes + ptk/WatchEvent + (watch [_ state stream] + (let [changes (::async-changes state)] + (rx/of #(dissoc % ::async-changes) + (commit-changes changes)))))) (s/def ::shapes-changes-commited - (s/keys :req-un [::page-id ::version ::cp/operations])) + (s/keys :req-un [::page-id ::version ::cp/changes])) (defn shapes-changes-commited - [{:keys [page-id version operations] :as params}] + [{:keys [page-id version changes] :as params}] (s/assert ::shapes-changes-commited params) (ptk/reify ::shapes-changes-commited ptk/UpdateEvent @@ -1052,8 +988,8 @@ (-> state (assoc-in [:workspace-page :version] version) (assoc-in [:pages page-id :version] version) - (update-in [:pages-data page-id] cp/process-ops operations) - (update :workspace-data cp/process-ops operations))))) + (update-in [:pages-data page-id] cp/process-changes changes) + (update :workspace-data cp/process-changes changes))))) ;; --- Start shape "edition mode" diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/page.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/page.cljs index 1883a540b..bc383ecda 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/page.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/page.cljs @@ -10,6 +10,8 @@ (:require [cuerdas.core :as str] [rumext.alpha :as mf] + [lentes.core :as l] + [uxbox.common.data :as d] [uxbox.builtins.icons :as i] [uxbox.main.constants :as c] [uxbox.main.data.workspace :as udw] @@ -22,16 +24,79 @@ [uxbox.util.i18n :refer [tr]] [uxbox.util.spec :refer [color?]])) -(mf/defc metadata-options - [{:keys [page] :as props}] - (let [metadata (:metadata page) +;; (mf/defc metadata-options +;; [{:keys [page] :as props}] +;; (let [metadata (:metadata page) +;; change-color +;; (fn [color] +;; #_(st/emit! (->> (assoc metadata :background color) +;; (udp/update-metadata (:id page))))) +;; on-color-change +;; (fn [event] +;; (let [value (dom/event->value event)] +;; (change-color value))) + +;; show-color-picker +;; (fn [event] +;; (let [x (.-clientX event) +;; y (.-clientY event) +;; props {:x x :y y +;; :default "#ffffff" +;; :value (:background metadata) +;; :transparent? true +;; :on-change change-color}] +;; (modal/show! colorpicker-modal props)))] + +;; [:div.element-set +;; [:div.element-set-title (tr "workspace.options.page-measures")] +;; [:div.element-set-content +;; [:span (tr "workspace.options.background-color")] +;; [:div.row-flex.color-data +;; [:span.color-th +;; {:style {:background-color (:background metadata "#ffffff")} +;; :on-click show-color-picker}] +;; [:div.color-info +;; [:input +;; {:on-change on-color-change +;; :value (:background metadata "#ffffff")}]]]]])) + +(def default-options + "Default data for page metadata." + {:grid-x 10 + :grid-y 10 + :grid-color "#cccccc"}) + +(def options-iref + (-> (l/key :options) + (l/derive refs/workspace-data))) + +(mf/defc grid-options + {:wrap [mf/wrap-memo]} + [props] + (let [options (->> (mf/deref options-iref) + (merge default-options)) + on-x-change + (fn [event] + (let [value (-> (dom/get-target event) + (dom/get-value) + (d/parse-integer 0))] + (st/emit! (udw/update-options {:grid-x value})))) + + on-y-change + (fn [event] + (let [value (-> (dom/get-target event) + (dom/get-value) + (d/parse-integer 0))] + (st/emit! (udw/update-options {:grid-y value})))) + change-color (fn [color] - #_(st/emit! (->> (assoc metadata :background color) - (udp/update-metadata (:id page))))) + (st/emit! (udw/update-options {:grid-color color}))) + on-color-change (fn [event] - (let [value (dom/event->value event)] + (let [value (-> (dom/get-target event) + (dom/get-value))] (change-color value))) show-color-picker @@ -39,86 +104,34 @@ (let [x (.-clientX event) y (.-clientY event) props {:x x :y y - :default "#ffffff" - :value (:background metadata) :transparent? true + :default "#cccccc" + :attr :grid-color :on-change change-color}] (modal/show! colorpicker-modal props)))] - [:div.element-set - [:div.element-set-title (tr "workspace.options.page-measures")] + [:div.element-set-title (tr "element.page-grid-options")] [:div.element-set-content - [:span (tr "workspace.options.background-color")] + [:span (tr "workspace.options.size")] + [:div.row-flex + [:div.input-element.pixels + [:input.input-text {:type "number" + :value (:grid-x options) + :on-change on-x-change}]] + [:div.input-element.pixels + [:input.input-text {:type "number" + :value (:grid-y options) + :on-change on-y-change}]]] + [:span (tr "workspace.options.color")] [:div.row-flex.color-data - [:span.color-th - {:style {:background-color (:background metadata "#ffffff")} - :on-click show-color-picker}] + [:span.color-th {:style {:background-color (:grid-color options)} + :on-click show-color-picker}] [:div.color-info - [:input - {:on-change on-color-change - :value (:background metadata "#ffffff")}]]]]])) - -(mf/defc grid-options - [{:keys [page] :as props}] - (let [metadata (:metadata page) - metadata (merge c/page-metadata metadata)] - (letfn [(on-x-change [event] - #_(let [value (-> (dom/event->value event) - (parse-int nil))] - (st/emit! (->> (assoc metadata :grid-x-axis value) - (udp/update-metadata (:id page)))))) - (on-y-change [event] - #_(let [value (-> (dom/event->value event) - (parse-int nil))] - (st/emit! (->> (assoc metadata :grid-y-axis value) - (udp/update-metadata (:id page)))))) - - (change-color [color] - #_(st/emit! (->> (assoc metadata :grid-color color) - (udp/update-metadata (:id page))))) - (on-color-change [event] - (let [value (dom/event->value event)] - (change-color value))) - - (show-color-picker [event] - (let [x (.-clientX event) - y (.-clientY event) - props {:x x :y y - :transparent? true - :default "#cccccc" - :attr :grid-color - :on-change change-color}] - (modal/show! colorpicker-modal props)))] - [:div.element-set - [:div.element-set-title (tr "element.page-grid-options")] - [:div.element-set-content - [:span (tr "workspace.options.size")] - [:div.row-flex - [:div.input-element.pixels - [:input.input-text - {:type "number" - :value (:grid-x-axis metadata) - :on-change on-x-change - :placeholder "x"}]] - [:div.input-element.pixels - [:input.input-text - {:type "number" - :value (:grid-y-axis metadata) - :on-change on-y-change - :placeholder "y"}]]] - [:span (tr "workspace.options.color")] - [:div.row-flex.color-data - [:span.color-th - {:style {:background-color (:grid-color metadata)} - :on-click show-color-picker}] - [:div.color-info - [:input - {:on-change on-color-change - :value (:grid-color metadata "#cccccc")}]]]]]))) + [:input {:on-change on-color-change + :value (:grid-color options)}]]]]])) (mf/defc options [{:keys [page] :as props}] [:div - #_[:& metadata-options {:page page}] [:& grid-options {:page page}]]) diff --git a/frontend/src/uxbox/main/ui/workspace/viewport.cljs b/frontend/src/uxbox/main/ui/workspace/viewport.cljs index 22c52387a..fb033876e 100644 --- a/frontend/src/uxbox/main/ui/workspace/viewport.cljs +++ b/frontend/src/uxbox/main/ui/workspace/viewport.cljs @@ -150,7 +150,7 @@ shapes-by-id (:shapes-by-id data) shapes (map #(get shapes-by-id %) (:shapes data [])) canvas (map #(get shapes-by-id %) (:canvas data []))] - [:* + [:g.shapes (for [item canvas] [:& shape-wrapper {:shape item :key (:id item)}]) (for [item shapes] @@ -285,7 +285,7 @@ :modifiers (:modifiers local)}])] (if (contains? flags :grid) - [:& grid {:page page}])] + [:& grid])] (when (contains? flags :ruler) [:& ruler {:zoom zoom :ruler (:ruler local)}])