mirror of
https://github.com/penpot/penpot.git
synced 2025-04-05 03:21:26 -05:00
feat(frontend): refactor many workspace components (rumext update)
This commit is contained in:
parent
c4d7d545ae
commit
9ddd9f317d
15 changed files with 504 additions and 526 deletions
|
@ -2,78 +2,42 @@
|
|||
;; 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/.
|
||||
;;
|
||||
;; Copyright (c) 2015-2017 Andrey Antukh <niwi@niwi.nz>
|
||||
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||
;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.main.ui.workspace
|
||||
(:require [beicon.core :as rx]
|
||||
[lentes.core :as l]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.constants :as c]
|
||||
[uxbox.main.refs :as refs]
|
||||
[uxbox.main.streams :as streams]
|
||||
[uxbox.main.data.workspace :as dw]
|
||||
[uxbox.main.data.pages :as udp]
|
||||
[uxbox.main.data.history :as udh]
|
||||
[uxbox.main.data.undo :as udu]
|
||||
[uxbox.main.user-events :as uev]
|
||||
[uxbox.main.ui.messages :refer [messages-widget]]
|
||||
[uxbox.main.ui.confirm]
|
||||
[uxbox.main.ui.workspace.images]
|
||||
[uxbox.main.ui.keyboard :as kbd]
|
||||
[uxbox.main.ui.workspace.scroll :as scroll]
|
||||
[uxbox.main.ui.workspace.download]
|
||||
[uxbox.main.ui.workspace.shortcuts :refer [shortcuts-mixin]]
|
||||
[uxbox.main.ui.workspace.header :refer [header]]
|
||||
[uxbox.main.ui.workspace.rules :refer [horizontal-rule vertical-rule]]
|
||||
[uxbox.main.ui.workspace.sidebar.history :refer [history-dialog]]
|
||||
[uxbox.main.ui.workspace.sidebar :refer [left-sidebar right-sidebar]]
|
||||
[uxbox.main.ui.workspace.colorpalette :refer [colorpalette]]
|
||||
[uxbox.main.ui.workspace.canvas :refer [viewport]]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.geom.point :as gpt]
|
||||
[uxbox.util.data :refer [classnames]]
|
||||
[rumext.core :as mx :include-macros true]))
|
||||
(:require
|
||||
[beicon.core :as rx]
|
||||
[lentes.core :as l]
|
||||
[rumext.core :as mx :include-macros true]
|
||||
[uxbox.main.constants :as c]
|
||||
[uxbox.main.data.history :as udh]
|
||||
[uxbox.main.data.pages :as udp]
|
||||
[uxbox.main.data.undo :as udu]
|
||||
[uxbox.main.data.workspace :as dw]
|
||||
[uxbox.main.refs :as refs]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.streams :as streams]
|
||||
[uxbox.main.ui.confirm]
|
||||
[uxbox.main.ui.keyboard :as kbd]
|
||||
[uxbox.main.ui.messages :refer [messages-widget]]
|
||||
[uxbox.main.ui.workspace.canvas :refer [viewport]]
|
||||
[uxbox.main.ui.workspace.colorpalette :refer [colorpalette]]
|
||||
[uxbox.main.ui.workspace.download]
|
||||
[uxbox.main.ui.workspace.header :refer [header]]
|
||||
[uxbox.main.ui.workspace.images]
|
||||
[uxbox.main.ui.workspace.rules :refer [horizontal-rule vertical-rule]]
|
||||
[uxbox.main.ui.workspace.scroll :as scroll]
|
||||
[uxbox.main.ui.workspace.shortcuts :refer [shortcuts-mixin]]
|
||||
[uxbox.main.ui.workspace.sidebar :refer [left-sidebar right-sidebar]]
|
||||
[uxbox.main.ui.workspace.sidebar.history :refer [history-dialog]]
|
||||
[uxbox.main.user-events :as uev]
|
||||
[uxbox.util.data :refer [classnames]]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.geom.point :as gpt]))
|
||||
|
||||
;; --- Workspace
|
||||
|
||||
(defn- workspace-will-mount
|
||||
[own]
|
||||
(let [[projectid pageid] (:rum/args own)]
|
||||
(st/emit! (dw/initialize projectid pageid))
|
||||
own))
|
||||
|
||||
(defn- workspace-did-mount
|
||||
[own]
|
||||
(let [[projectid pageid] (:rum/args own)
|
||||
dom (mx/ref-node own "workspace-canvas")
|
||||
scroll-to-page-center #(scroll/scroll-to-page-center dom @refs/selected-page)
|
||||
sub (rx/subscribe streams/page-id-ref-s scroll-to-page-center)]
|
||||
|
||||
(scroll-to-page-center)
|
||||
|
||||
(st/emit! (udp/watch-page-changes pageid)
|
||||
(udu/watch-page-changes pageid))
|
||||
|
||||
(assoc own ::sub sub)))
|
||||
|
||||
(defn- workspace-will-unmount
|
||||
[own]
|
||||
(st/emit! ::udp/stop-page-watcher)
|
||||
(rx/cancel! (::sub own))
|
||||
(dissoc own ::sub))
|
||||
|
||||
(defn- workspace-did-remount
|
||||
[old-state state]
|
||||
(let [[projectid pageid] (:rum/args state)
|
||||
[oldprojectid oldpageid] (:rum/args old-state)]
|
||||
(when (not= pageid oldpageid)
|
||||
(st/emit! (dw/initialize projectid pageid)
|
||||
::udp/stop-page-watcher
|
||||
(udp/watch-page-changes pageid)
|
||||
(udu/watch-page-changes pageid)))
|
||||
state))
|
||||
|
||||
(defn- on-scroll
|
||||
[event]
|
||||
(let [target (.-target event)
|
||||
|
@ -99,52 +63,76 @@
|
|||
(-> (l/key :page)
|
||||
(l/derive refs/workspace)))
|
||||
|
||||
(mx/defcs workspace
|
||||
{:did-remount workspace-did-remount
|
||||
:will-mount workspace-will-mount
|
||||
:will-unmount workspace-will-unmount
|
||||
:did-mount workspace-did-mount
|
||||
:mixins [mx/static
|
||||
(mx/def workspace
|
||||
:key-fn vector
|
||||
:mixins #{mx/static
|
||||
mx/reactive
|
||||
shortcuts-mixin]}
|
||||
[own project-id page-id]
|
||||
(let [flags (mx/react refs/flags)
|
||||
left-sidebar? (not (empty? (keep flags [:layers :sitemap
|
||||
:document-history])))
|
||||
right-sidebar? (not (empty? (keep flags [:icons :drawtools
|
||||
:element-options])))
|
||||
classes (classnames
|
||||
:no-tool-bar-right (not right-sidebar?)
|
||||
:no-tool-bar-left (not left-sidebar?)
|
||||
:scrolling (:viewport-positionig workspace))]
|
||||
[:div {}
|
||||
(messages-widget)
|
||||
(header)
|
||||
(colorpalette)
|
||||
shortcuts-mixin}
|
||||
|
||||
[:main.main-content {}
|
||||
[:section.workspace-content
|
||||
{:class classes
|
||||
:on-scroll on-scroll
|
||||
:on-wheel (partial on-wheel own)}
|
||||
:init
|
||||
(fn [own {:keys [project page] :as props}]
|
||||
(st/emit! (dw/initialize project page))
|
||||
(assoc own ::canvas (mx/create-ref)))
|
||||
|
||||
(history-dialog)
|
||||
:did-mount
|
||||
(fn [own]
|
||||
(let [{:keys [project page]} (::mx/props own)
|
||||
;; dom (mx/ref-node own "workspace-canvas")
|
||||
dom (mx/ref-node (::canvas own))
|
||||
scroll-to-page-center #(scroll/scroll-to-page-center dom @refs/selected-page)
|
||||
sub (rx/subscribe streams/page-id-ref-s scroll-to-page-center)]
|
||||
(scroll-to-page-center)
|
||||
(st/emit! (udp/watch-page-changes page)
|
||||
(udu/watch-page-changes page))
|
||||
(assoc own ::sub sub)))
|
||||
|
||||
;; Rules
|
||||
(when (contains? flags :rules)
|
||||
(horizontal-rule))
|
||||
:will-unmount
|
||||
(fn [own]
|
||||
(st/emit! ::udp/stop-page-watcher)
|
||||
(rx/cancel! (::sub own))
|
||||
(dissoc own ::sub))
|
||||
|
||||
(when (contains? flags :rules)
|
||||
(vertical-rule))
|
||||
:render
|
||||
(fn [own props]
|
||||
;; [own project-id page-id]
|
||||
(let [flags (mx/react refs/flags)
|
||||
project-id (get-in own [::mx/props :project])
|
||||
page-id (get-in own [::mx/props :page])
|
||||
left-sidebar? (not (empty? (keep flags [:layers :sitemap
|
||||
:document-history])))
|
||||
right-sidebar? (not (empty? (keep flags [:icons :drawtools
|
||||
:element-options])))
|
||||
classes (classnames
|
||||
:no-tool-bar-right (not right-sidebar?)
|
||||
:no-tool-bar-left (not left-sidebar?)
|
||||
:scrolling (:viewport-positionig workspace))]
|
||||
[:*
|
||||
(messages-widget)
|
||||
(header)
|
||||
(colorpalette)
|
||||
|
||||
;; Canvas
|
||||
[:section.workspace-canvas
|
||||
{:id "workspace-canvas"
|
||||
:ref "workspace-canvas"}
|
||||
(viewport)]]
|
||||
[:main.main-content
|
||||
[:section.workspace-content
|
||||
{:class classes
|
||||
:on-scroll on-scroll
|
||||
:on-wheel (partial on-wheel own)}
|
||||
|
||||
;; Aside
|
||||
(when left-sidebar?
|
||||
(left-sidebar flags page-id))
|
||||
(when right-sidebar?
|
||||
(right-sidebar flags page-id))]]))
|
||||
(history-dialog)
|
||||
|
||||
;; Rules
|
||||
(when (contains? flags :rules)
|
||||
(horizontal-rule))
|
||||
|
||||
(when (contains? flags :rules)
|
||||
(vertical-rule))
|
||||
|
||||
;; Canvas
|
||||
[:section.workspace-canvas {:id "workspace-canvas"
|
||||
:ref (::canvas own)}
|
||||
(viewport)]]
|
||||
|
||||
;; Aside
|
||||
(when left-sidebar?
|
||||
(left-sidebar {:flags flags :page-id page-id}))
|
||||
(when right-sidebar?
|
||||
(right-sidebar {:flags flags :page-id page-id}))]])))
|
||||
|
|
|
@ -244,7 +244,7 @@
|
|||
opts {:shift? shift?
|
||||
:ctrl? ctrl?}]
|
||||
(st/emit! (uev/mouse-event :double-click ctrl? shift?))))]
|
||||
[:div {}
|
||||
[:*
|
||||
(coordinates)
|
||||
[:div.tooltip-container {}
|
||||
(when tooltip
|
||||
|
|
|
@ -30,13 +30,13 @@
|
|||
(on-close [event]
|
||||
(dom/prevent-default event)
|
||||
(udl/close!))]
|
||||
[:div.lightbox-body.clipboard {}
|
||||
[:div.clipboard-list {}
|
||||
[:div.lightbox-body.clipboard
|
||||
[:div.clipboard-list
|
||||
(for [item (mx/react clipboard-ref)]
|
||||
[:div.clipboard-item
|
||||
{:key (str (:id item))
|
||||
:on-click (partial on-paste item)}
|
||||
[:span.clipboard-icon {} i/box]
|
||||
[:span.clipboard-icon i/box]
|
||||
[:span {} (str "Copied (" (dt/timeago (:created-at item)) ")")]])]
|
||||
[:a.close {:href "#" :on-click on-close} i/close]]))
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
[:span.color-text {} rgb-color]])))
|
||||
|
||||
(defn- palette-after-render
|
||||
[{:keys [rum/local] :as own}]
|
||||
[{:keys [::mx/local] :as own}]
|
||||
(let [dom (mx/ref-node own "container")
|
||||
width (.-clientWidth dom)]
|
||||
(when (not= (:width @local) width)
|
||||
|
@ -60,7 +60,7 @@
|
|||
(mx/defcs palette
|
||||
{:mixins [mx/static mx/reactive (mx/local)]
|
||||
:after-render palette-after-render}
|
||||
[{:keys [rum/local] :as own}]
|
||||
[{:keys [::mx/local] :as own}]
|
||||
(let [collections (->> (mx/react collections-ref)
|
||||
(vals)
|
||||
(filter :id)
|
||||
|
@ -112,14 +112,14 @@
|
|||
[:span.close-palette {:on-click close}
|
||||
i/close]])))
|
||||
|
||||
(defn- colorpalette-will-mount
|
||||
(defn- colorpalette-init
|
||||
[own]
|
||||
(st/emit! (dc/fetch-collections))
|
||||
own)
|
||||
|
||||
(mx/defc colorpalette
|
||||
{:mixins [mx/static mx/reactive]
|
||||
:will-mount colorpalette-will-mount}
|
||||
:init colorpalette-init}
|
||||
[]
|
||||
(let [flags (mx/react refs/flags)]
|
||||
(when (contains? flags :colorpalette)
|
||||
|
|
|
@ -2,24 +2,25 @@
|
|||
;; 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/.
|
||||
;;
|
||||
;; Copyright (c) 2015-2017 Andrey Antukh <niwi@niwi.nz>
|
||||
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||
;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.main.ui.workspace.images
|
||||
(:require [lentes.core :as l]
|
||||
[rumext.core :as mx :include-macros true]
|
||||
[potok.core :as ptk]
|
||||
[uxbox.builtins.icons :as i]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.data.lightbox :as udl]
|
||||
[uxbox.main.data.images :as udi]
|
||||
[uxbox.main.data.workspace :as udw]
|
||||
[uxbox.main.data.shapes :as uds]
|
||||
[uxbox.main.ui.lightbox :as lbx]
|
||||
[uxbox.util.i18n :as t :refer [tr]]
|
||||
[uxbox.util.data :refer [read-string jscoll->vec]]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.uuid :as uuid]))
|
||||
(:require
|
||||
[lentes.core :as l]
|
||||
[potok.core :as ptk]
|
||||
[rumext.core :as mx :include-macros true]
|
||||
[uxbox.builtins.icons :as i]
|
||||
[uxbox.main.data.images :as udi]
|
||||
[uxbox.main.data.lightbox :as udl]
|
||||
[uxbox.main.data.shapes :as uds]
|
||||
[uxbox.main.data.workspace :as udw]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.ui.lightbox :as lbx]
|
||||
[uxbox.util.data :refer [read-string jscoll->vec]]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.i18n :as t :refer [tr]]
|
||||
[uxbox.util.uuid :as uuid]))
|
||||
|
||||
;; --- Refs
|
||||
|
||||
|
@ -113,9 +114,9 @@
|
|||
(-> (image-item image)
|
||||
(mx/with-key (str (:id image)))))])
|
||||
|
||||
(defn will-mount
|
||||
(defn init
|
||||
[own]
|
||||
(let [local (:rum/local own)]
|
||||
(let [local (::mx/local own)]
|
||||
(st/emit! (udi/fetch-collections))
|
||||
(st/emit! (udi/fetch-images nil))
|
||||
(add-watch local ::key (fn [_ _ _ v]
|
||||
|
@ -124,16 +125,16 @@
|
|||
|
||||
(defn will-unmount
|
||||
[own]
|
||||
(let [local (:rum/local own)]
|
||||
(let [local (::mx/local own)]
|
||||
(remove-watch local ::key)
|
||||
own))
|
||||
|
||||
(mx/defcs image-collections-lightbox
|
||||
{:mixins [mx/reactive (mx/local)]
|
||||
:will-mount will-mount
|
||||
:init init
|
||||
:will-unmount will-unmount}
|
||||
[own]
|
||||
(let [local (:rum/local own)
|
||||
(let [local (::mx/local own)
|
||||
id (:id @local)
|
||||
type (:type @local :own)
|
||||
own? (= type :own)
|
||||
|
|
|
@ -6,13 +6,14 @@
|
|||
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||
|
||||
(ns uxbox.main.ui.workspace.rules
|
||||
(:require [cuerdas.core :as str]
|
||||
[beicon.core :as rx]
|
||||
[uxbox.main.store :as s]
|
||||
[uxbox.main.constants :as c]
|
||||
[uxbox.main.refs :as refs]
|
||||
[uxbox.util.dom :as dom]
|
||||
[rumext.core :as mx :include-macros true]))
|
||||
(:require
|
||||
[beicon.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.core :as mx]
|
||||
[uxbox.main.constants :as c]
|
||||
[uxbox.main.refs :as refs]
|
||||
[uxbox.main.store :as s]
|
||||
[uxbox.util.dom :as dom]))
|
||||
|
||||
;; --- Constants & Helpers
|
||||
|
||||
|
@ -65,102 +66,103 @@
|
|||
|
||||
;; --- Horizontal Text Label
|
||||
|
||||
(mx/defc horizontal-text-label
|
||||
[zoom value]
|
||||
(let [big-ticks-mod (big-ticks-mod zoom)
|
||||
pos (+ (* value zoom)
|
||||
rule-padding
|
||||
(* c/canvas-start-x zoom)
|
||||
c/canvas-scroll-padding)]
|
||||
(when (< (mod value big-ticks-mod) step-size)
|
||||
[:text {:x (+ pos 2)
|
||||
:y 13
|
||||
:key (str pos)
|
||||
:fill "#9da2a6"
|
||||
:style {:font-size "12px"}}
|
||||
value])))
|
||||
(mx/def horizontal-text-label
|
||||
:key-fn second
|
||||
:render
|
||||
(fn [own [zoom value]]
|
||||
(let [big-ticks-mod (big-ticks-mod zoom)
|
||||
pos (+ (* value zoom)
|
||||
rule-padding
|
||||
(* c/canvas-start-x zoom)
|
||||
c/canvas-scroll-padding)]
|
||||
(when (< (mod value big-ticks-mod) step-size)
|
||||
[:text {:x (+ pos 2)
|
||||
:y 13
|
||||
:key (str pos)
|
||||
:fill "#9da2a6"
|
||||
:style {:font-size "12px"}}
|
||||
value]))))
|
||||
|
||||
;; --- Horizontal Text Label
|
||||
|
||||
(mx/defc vertical-text-label
|
||||
[zoom value]
|
||||
(let [big-ticks-mod (big-ticks-mod zoom)
|
||||
pos (+ (* value zoom)
|
||||
(* c/canvas-start-x zoom)
|
||||
;; c/canvas-start-x
|
||||
c/canvas-scroll-padding)]
|
||||
(when (< (mod value big-ticks-mod) step-size)
|
||||
[:text {:y (- pos 3)
|
||||
:x 5
|
||||
:key (str pos)
|
||||
:fill "#9da2a6"
|
||||
:transform (str/format "rotate(90 0 %s)" pos)
|
||||
:style {:font-size "12px"}}
|
||||
value])))
|
||||
(mx/def vertical-text-label
|
||||
:key-fn second
|
||||
:render
|
||||
(fn [own [zoom value]]
|
||||
(let [big-ticks-mod (big-ticks-mod zoom)
|
||||
pos (+ (* value zoom)
|
||||
(* c/canvas-start-x zoom)
|
||||
c/canvas-scroll-padding)]
|
||||
(when (< (mod value big-ticks-mod) step-size)
|
||||
[:text {:y (- pos 3)
|
||||
:x 5
|
||||
:key (str pos)
|
||||
:fill "#9da2a6"
|
||||
:transform (str/format "rotate(90 0 %s)" pos)
|
||||
:style {:font-size "12px"}}
|
||||
value]))))
|
||||
|
||||
;; --- Horizontal Rule Ticks (Component)
|
||||
|
||||
(mx/defc horizontal-rule-ticks
|
||||
{:mixins [mx/static]}
|
||||
[zoom]
|
||||
(let [zoom (or zoom 1)
|
||||
path (reduce (partial make-vertical-tick zoom) [] +ticks+)
|
||||
labels (->> (map (partial horizontal-text-label zoom) +ticks+)
|
||||
(filterv identity))]
|
||||
[:g {}
|
||||
[:path {:d (str/join " " path)}]
|
||||
(for [tick +ticks+]
|
||||
(-> (horizontal-text-label zoom tick)
|
||||
(mx/with-key (str tick))))]))
|
||||
(mx/def horizontal-rule-ticks
|
||||
:mixins #{mx/static}
|
||||
:render
|
||||
(fn [own zoom]
|
||||
(let [zoom (or zoom 1)
|
||||
path (reduce (partial make-vertical-tick zoom) [] +ticks+)]
|
||||
[:g
|
||||
[:path {:d (str/join " " path)}]
|
||||
(for [tick +ticks+]
|
||||
(horizontal-text-label [zoom tick]))])))
|
||||
|
||||
;; --- Vertical Rule Ticks (Component)
|
||||
|
||||
(mx/defc vertical-rule-ticks
|
||||
{:mixins [mx/static]}
|
||||
[zoom]
|
||||
(let [zoom (or zoom 1)
|
||||
path (reduce (partial make-horizontal-tick zoom) [] +ticks+)
|
||||
labels (->> (map (partial vertical-text-label zoom) +ticks+)
|
||||
(filterv identity))]
|
||||
[:g {}
|
||||
[:path {:d (str/join " " path)}]
|
||||
(for [tick +ticks+]
|
||||
(-> (vertical-text-label zoom tick)
|
||||
(mx/with-key (str tick))))]))
|
||||
(mx/def vertical-rule-ticks
|
||||
:mixins #{mx/static}
|
||||
:render
|
||||
(fn [own zoom]
|
||||
(let [zoom (or zoom 1)
|
||||
path (reduce (partial make-horizontal-tick zoom) [] +ticks+)]
|
||||
[:g
|
||||
[:path {:d (str/join " " path)}]
|
||||
(for [tick +ticks+]
|
||||
(vertical-text-label [zoom tick]))])))
|
||||
|
||||
;; --- Horizontal Rule (Component)
|
||||
|
||||
(mx/defc horizontal-rule
|
||||
{:mixins [mx/static mx/reactive]}
|
||||
[]
|
||||
(let [scroll (mx/react refs/workspace-scroll)
|
||||
zoom (mx/react refs/selected-zoom)
|
||||
scroll-x (:x scroll)
|
||||
translate-x (- (- c/canvas-scroll-padding) (:x scroll))]
|
||||
[:svg.horizontal-rule
|
||||
{:width c/viewport-width
|
||||
:height 20}
|
||||
[:rect {:height 20
|
||||
:width c/viewport-width}]
|
||||
[:g {:transform (str "translate(" translate-x ", 0)")}
|
||||
(horizontal-rule-ticks zoom)]]))
|
||||
(mx/def horizontal-rule
|
||||
:mixins #{mx/static mx/reactive}
|
||||
:render
|
||||
(fn [own props]
|
||||
(let [scroll (mx/react refs/workspace-scroll)
|
||||
zoom (mx/react refs/selected-zoom)
|
||||
scroll-x (:x scroll)
|
||||
translate-x (- (- c/canvas-scroll-padding) (:x scroll))]
|
||||
[:svg.horizontal-rule
|
||||
{:width c/viewport-width
|
||||
:height 20}
|
||||
[:rect {:height 20
|
||||
:width c/viewport-width}]
|
||||
[:g {:transform (str "translate(" translate-x ", 0)")}
|
||||
(horizontal-rule-ticks zoom)]])))
|
||||
|
||||
;; --- Vertical Rule (Component)
|
||||
|
||||
(mx/defc vertical-rule
|
||||
{:mixins [mx/static mx/reactive]}
|
||||
[]
|
||||
(let [scroll (mx/react refs/workspace-scroll)
|
||||
zoom (mx/react refs/selected-zoom)
|
||||
scroll-y (:y scroll)
|
||||
translate-y (- (- c/canvas-scroll-padding) (:y scroll))]
|
||||
[:svg.vertical-rule
|
||||
{:width 20
|
||||
:height c/viewport-height}
|
||||
(mx/def vertical-rule
|
||||
:mixins #{mx/static mx/reactive}
|
||||
:render
|
||||
(fn [own props]
|
||||
(let [scroll (mx/react refs/workspace-scroll)
|
||||
zoom (mx/react refs/selected-zoom)
|
||||
scroll-y (:y scroll)
|
||||
translate-y (- (- c/canvas-scroll-padding) (:y scroll))]
|
||||
[:svg.vertical-rule
|
||||
{:width 20
|
||||
:height c/viewport-height}
|
||||
|
||||
[:g {:transform (str "translate(0, " translate-y ")")}
|
||||
(vertical-rule-ticks zoom)]
|
||||
[:rect {:x 0
|
||||
:y 0
|
||||
:height 20
|
||||
:width 20}]]))
|
||||
[:g {:transform (str "translate(0, " translate-y ")")}
|
||||
(vertical-rule-ticks zoom)]
|
||||
[:rect {:x 0
|
||||
:y 0
|
||||
:height 20
|
||||
:width 20}]])))
|
||||
|
|
|
@ -98,7 +98,7 @@
|
|||
|
||||
;; --- Mixin
|
||||
|
||||
(defn- will-mount
|
||||
(defn- init
|
||||
[own]
|
||||
(assoc own ::sub (initialize)))
|
||||
|
||||
|
@ -108,5 +108,5 @@
|
|||
(dissoc own ::sub))
|
||||
|
||||
(def shortcuts-mixin
|
||||
{:will-mount will-mount
|
||||
{:init init
|
||||
:will-unmount will-unmount})
|
||||
|
|
|
@ -18,10 +18,9 @@
|
|||
;; --- Left Sidebar (Component)
|
||||
|
||||
(mx/defc left-sidebar
|
||||
{:mixins [mx/static]}
|
||||
[flags page-id]
|
||||
[:aside#settings-bar.settings-bar.settings-bar-left {}
|
||||
[:div.settings-bar-inside {}
|
||||
[{:keys [flags page-id] :as props}]
|
||||
[:aside#settings-bar.settings-bar.settings-bar-left
|
||||
[:div.settings-bar-inside
|
||||
(when (contains? flags :sitemap)
|
||||
(sitemap-toolbox page-id))
|
||||
(when (contains? flags :document-history)
|
||||
|
@ -32,10 +31,9 @@
|
|||
;; --- Right Sidebar (Component)
|
||||
|
||||
(mx/defc right-sidebar
|
||||
{:mixins [mx/static]}
|
||||
[flags page-id]
|
||||
[:aside#settings-bar.settings-bar {}
|
||||
[:div.settings-bar-inside {}
|
||||
[{:keys [flags page-id] :as props}]
|
||||
[:aside#settings-bar.settings-bar
|
||||
[:div.settings-bar-inside
|
||||
(when (contains? flags :drawtools)
|
||||
(draw-toolbox flags))
|
||||
(when (contains? flags :element-options)
|
||||
|
|
|
@ -21,125 +21,115 @@
|
|||
|
||||
;; --- History Item (Component)
|
||||
|
||||
(mx/defc history-item
|
||||
{:mixins [mx/static]}
|
||||
[item selected]
|
||||
(letfn [(on-select [event]
|
||||
(dom/prevent-default event)
|
||||
(st/emit! (udh/select-page-history (:version item))))
|
||||
(on-pinned [event]
|
||||
(dom/prevent-default event)
|
||||
(dom/stop-propagation event)
|
||||
(let [item (assoc item
|
||||
:label "no label"
|
||||
:pinned (not (:pinned item)))]
|
||||
(st/emit! (udh/update-history-item item))))]
|
||||
[:li {:class (when (= selected (:version item)) "current")
|
||||
:on-click on-select}
|
||||
[:div.pin-icon {:on-click on-pinned
|
||||
:class (when (:pinned item) "selected")}
|
||||
i/pin]
|
||||
[:span {} (str "Version " (:version item)
|
||||
" (" (dt/timeago (:created-at item)) ")")]]))
|
||||
(mx/def history-item
|
||||
:mixins [mx/static]
|
||||
:key-fn :id
|
||||
:render
|
||||
(fn [own {:keys [::selected] :as item}]
|
||||
(letfn [(on-select [event]
|
||||
(dom/prevent-default event)
|
||||
(st/emit! (udh/select-page-history (:version item))))
|
||||
(on-pinned [event]
|
||||
(dom/prevent-default event)
|
||||
(dom/stop-propagation event)
|
||||
(let [item (assoc item
|
||||
:label "no label"
|
||||
:pinned (not (:pinned item)))]
|
||||
(st/emit! (udh/update-history-item item))))]
|
||||
[:li {:class (when (= selected (:version item)) "current")
|
||||
:on-click on-select}
|
||||
[:div.pin-icon {:on-click on-pinned
|
||||
:class (when (:pinned item) "selected")}
|
||||
i/pin]
|
||||
[:span (str "Version " (:version item)
|
||||
" (" (dt/timeago (:created-at item)) ")")]])))
|
||||
|
||||
;; --- History List (Component)
|
||||
|
||||
(mx/defc history-list
|
||||
{:mixins [mx/static mx/reactive]}
|
||||
[{:keys [selected items min-version] :as history}]
|
||||
(let [items (reverse (sort-by :version items))
|
||||
page (mx/react refs/selected-page)
|
||||
show-more? (pos? min-version)
|
||||
load-more #(st/emit! (udh/load-more))]
|
||||
[:ul.history-content {}
|
||||
(for [item items]
|
||||
(let [current? (= (:version item) (:version page))]
|
||||
(-> (history-item item selected current?)
|
||||
(mx/with-key (str (:id item))))))
|
||||
(when show-more?
|
||||
[:li {:on-click load-more}
|
||||
[:a.btn-primary.btn-small {}
|
||||
"view more"]])]))
|
||||
(mx/def history-list
|
||||
:mixins [mx/static mx/reactive]
|
||||
:render
|
||||
(fn [own {:keys [selected items min-version] :as history}]
|
||||
(let [items (reverse (sort-by :version items))
|
||||
page (mx/react refs/selected-page)
|
||||
show-more? (pos? min-version)
|
||||
load-more #(st/emit! (udh/load-more))]
|
||||
[:ul.history-content
|
||||
(for [item items]
|
||||
(history-item (assoc item ::selectd selected)))
|
||||
(when show-more?
|
||||
[:li {:on-click load-more}
|
||||
[:a.btn-primary.btn-small
|
||||
"view more"]])])))
|
||||
|
||||
;; --- History Pinned List (Component)
|
||||
|
||||
(mx/defc history-pinned-list
|
||||
{:mixins [mx/static]}
|
||||
[{:keys [pinned selected] :as history}]
|
||||
[:ul.history-content {}
|
||||
(for [item (reverse (sort-by :version pinned))]
|
||||
(let [selected? (= (:version item) selected)]
|
||||
(-> (history-item item selected?)
|
||||
(mx/with-key (str (:id item))))))])
|
||||
(mx/def history-pinned-list
|
||||
:mixins [mx/static]
|
||||
:render
|
||||
(fn [own {:keys [pinned selected] :as history}]
|
||||
[:ul.history-content
|
||||
(for [item (reverse (sort-by :version pinned))]
|
||||
(let [selected (= (:version item) selected)]
|
||||
(history-item (assoc item ::selected selected))))]))
|
||||
|
||||
;; --- History Toolbox (Component)
|
||||
|
||||
(mx/def history-toolbox
|
||||
:mixins [mx/static mx/reactive]
|
||||
|
||||
(defn- history-toolbox-will-mount
|
||||
[own]
|
||||
(let [[page-id] (:rum/args own)]
|
||||
:init
|
||||
(fn [own page-id]
|
||||
(st/emit! (udh/initialize page-id))
|
||||
own))
|
||||
own)
|
||||
|
||||
(defn- history-toolbox-did-remount
|
||||
[oldown own]
|
||||
(let [[old-page-id] (:rum/args oldown)
|
||||
[new-page-id] (:rum/args own)]
|
||||
(when-not (= old-page-id new-page-id)
|
||||
(st/emit! ::udh/stop-changes-watcher
|
||||
(udh/initialize new-page-id)))
|
||||
own))
|
||||
:will-unmount
|
||||
(fn [own]
|
||||
(st/emit! ::udh/stop-changes-watcher)
|
||||
own)
|
||||
|
||||
(defn- history-toolbox-will-unmount
|
||||
[own]
|
||||
(st/emit! ::udh/stop-changes-watcher)
|
||||
own)
|
||||
:render
|
||||
(fn [own page-id]
|
||||
(let [history (mx/react refs/history)
|
||||
section (:section history :main)
|
||||
|
||||
(mx/defc history-toolbox
|
||||
{:mixins [mx/static mx/reactive]
|
||||
:will-mount history-toolbox-will-mount
|
||||
:will-unmount history-toolbox-will-unmount
|
||||
:did-remount history-toolbox-did-remount}
|
||||
[_]
|
||||
(let [history (mx/react refs/history)
|
||||
section (:section history :main)
|
||||
close #(st/emit! (dw/toggle-flag :document-history))
|
||||
main? (= section :main)
|
||||
pinned? (= section :pinned)
|
||||
|
||||
close #(st/emit! (dw/toggle-flag :document-history))
|
||||
main? (= section :main)
|
||||
pinned? (= section :pinned)
|
||||
|
||||
show-main #(st/emit! (udh/select-section :main))
|
||||
show-pinned #(st/emit! (udh/select-section :pinned))]
|
||||
[:div.document-history.tool-window {}
|
||||
[:div.tool-window-bar {}
|
||||
[:div.tool-window-icon {} i/undo-history]
|
||||
[:span {} (tr "ds.document-history")]
|
||||
[:div.tool-window-close {:on-click close} i/close]]
|
||||
[:div.tool-window-content {}
|
||||
[:ul.history-tabs {}
|
||||
[:li {:on-click show-main
|
||||
:class (when main? "selected")}
|
||||
"History"]
|
||||
[:li {:on-click show-pinned
|
||||
:class (when pinned? "selected")}
|
||||
"Pinned"]]
|
||||
(if (= section :pinned)
|
||||
(history-pinned-list history)
|
||||
(history-list history))]]))
|
||||
show-main #(st/emit! (udh/select-section :main))
|
||||
show-pinned #(st/emit! (udh/select-section :pinned))]
|
||||
[:div.document-history.tool-window {}
|
||||
[:div.tool-window-bar {}
|
||||
[:div.tool-window-icon {} i/undo-history]
|
||||
[:span {} (tr "ds.document-history")]
|
||||
[:div.tool-window-close {:on-click close} i/close]]
|
||||
[:div.tool-window-content {}
|
||||
[:ul.history-tabs {}
|
||||
[:li {:on-click show-main
|
||||
:class (when main? "selected")}
|
||||
"History"]
|
||||
[:li {:on-click show-pinned
|
||||
:class (when pinned? "selected")}
|
||||
"Pinned"]]
|
||||
(if (= section :pinned)
|
||||
(history-pinned-list history)
|
||||
(history-list history))]])))
|
||||
|
||||
;; --- History Dialog
|
||||
|
||||
(mx/defc history-dialog
|
||||
{:mixins [mx/static mx/reactive]}
|
||||
[]
|
||||
(let [history (mx/react refs/history)
|
||||
version (:selected history)
|
||||
on-accept #(st/emit! (udh/apply-selected-history))
|
||||
on-cancel #(st/emit! (udh/deselect-page-history))]
|
||||
(when (or version (:deselecting history))
|
||||
[:div.message-version
|
||||
{:class (when (:deselecting history) "hide-message")}
|
||||
[:span {} (tr "history.alert-message" (or version "00"))
|
||||
[:div.message-action {}
|
||||
[:a.btn-transparent {:on-click on-accept} "Accept"]
|
||||
[:a.btn-transparent {:on-click on-cancel} "Cancel"]]]])))
|
||||
(mx/def history-dialog
|
||||
:mixins [mx/static mx/reactive]
|
||||
:render
|
||||
(fn [own]
|
||||
(let [history (mx/react refs/history)
|
||||
version (:selected history)
|
||||
on-accept #(st/emit! (udh/apply-selected-history))
|
||||
on-cancel #(st/emit! (udh/deselect-page-history))]
|
||||
(when (or version (:deselecting history))
|
||||
[:div.message-version
|
||||
{:class (when (:deselecting history) "hide-message")}
|
||||
[:span {} (tr "history.alert-message" (or version "00"))
|
||||
[:div.message-action {}
|
||||
[:a.btn-transparent {:on-click on-accept} "Accept"]
|
||||
[:a.btn-transparent {:on-click on-cancel} "Cancel"]]]]))))
|
||||
|
|
|
@ -40,14 +40,14 @@
|
|||
[icon]
|
||||
(icon/icon-svg icon))
|
||||
|
||||
(defn- icons-toolbox-will-mount
|
||||
(defn- icons-toolbox-init
|
||||
[own]
|
||||
(st/emit! (udw/initialize-icons-toolbox))
|
||||
own)
|
||||
|
||||
(mx/defc icons-toolbox
|
||||
{:mixins [mx/static mx/reactive]
|
||||
:will-mount icons-toolbox-will-mount}
|
||||
:init icons-toolbox-init}
|
||||
[]
|
||||
(let [drawing (mx/react drawing-shape-ref)
|
||||
selected (mx/react icons-toolbox-ref)
|
||||
|
|
|
@ -89,43 +89,42 @@
|
|||
|
||||
;; --- Shape Name (Component)
|
||||
|
||||
(mx/defcs shape-name
|
||||
"A generic component that displays the shape name
|
||||
if it is available and allows inline edition of it."
|
||||
{:mixins [mx/static (mx/local)]}
|
||||
[{:keys [rum/local]} {:keys [id] :as shape}]
|
||||
(letfn [(on-blur [event]
|
||||
(let [target (dom/event->target event)
|
||||
parent (.-parentNode target)
|
||||
name (dom/get-value target)]
|
||||
(set! (.-draggable parent) true)
|
||||
(st/emit! (uds/rename-shape id name))
|
||||
(swap! local assoc :edition false)))
|
||||
(on-key-down [event]
|
||||
(js/console.log event)
|
||||
(when (kbd/enter? event)
|
||||
(on-blur event)))
|
||||
(on-click [event]
|
||||
(dom/prevent-default event)
|
||||
(let [parent (.-parentNode (.-target event))]
|
||||
(set! (.-draggable parent) false))
|
||||
(swap! local assoc :edition true))]
|
||||
(if (:edition @local)
|
||||
[:input.element-name
|
||||
{:type "text"
|
||||
:on-blur on-blur
|
||||
:on-key-down on-key-down
|
||||
:auto-focus true
|
||||
:default-value (:name shape "")}]
|
||||
[:span.element-name
|
||||
{:on-double-click on-click}
|
||||
(:name shape "")])))
|
||||
(mx/def shape-name
|
||||
:mixins [mx/static (mx/local)]
|
||||
:render
|
||||
(fn [{:keys [::mx/local] :as own} {:keys [id] :as shape}]
|
||||
(letfn [(on-blur [event]
|
||||
(let [target (dom/event->target event)
|
||||
parent (.-parentNode target)
|
||||
name (dom/get-value target)]
|
||||
(set! (.-draggable parent) true)
|
||||
(st/emit! (uds/rename-shape id name))
|
||||
(swap! local assoc :edition false)))
|
||||
(on-key-down [event]
|
||||
(js/console.log event)
|
||||
(when (kbd/enter? event)
|
||||
(on-blur event)))
|
||||
(on-click [event]
|
||||
(dom/prevent-default event)
|
||||
(let [parent (.-parentNode (.-target event))]
|
||||
(set! (.-draggable parent) false))
|
||||
(swap! local assoc :edition true))]
|
||||
(if (:edition @local)
|
||||
[:input.element-name
|
||||
{:type "text"
|
||||
:on-blur on-blur
|
||||
:on-key-down on-key-down
|
||||
:auto-focus true
|
||||
:default-value (:name shape "")}]
|
||||
[:span.element-name
|
||||
{:on-double-click on-click}
|
||||
(:name shape "")]))))
|
||||
|
||||
;; --- Layer Simple (Component)
|
||||
|
||||
(mx/defcs layer-simple
|
||||
{:mixins [mx/static (mx/local)]}
|
||||
[{:keys [rum/local]} item selected]
|
||||
[{:keys [::mx/local]} item selected]
|
||||
(let [selected? (contains? selected (:id item))
|
||||
select #(select-shape selected item %)
|
||||
toggle-visibility #(toggle-visibility selected item %)
|
||||
|
@ -189,14 +188,14 @@
|
|||
{:class (when (:blocked item) "selected")
|
||||
:on-click toggle-blocking}
|
||||
i/lock]]
|
||||
[:div.element-icon {} (element-icon item)]
|
||||
[:div.element-icon (element-icon item)]
|
||||
(shape-name item)]])))
|
||||
|
||||
;; --- Layer Group (Component)
|
||||
|
||||
(mx/defcs layer-group
|
||||
{:mixins [mx/static mx/reactive (mx/local)]}
|
||||
[{:keys [rum/local]} {:keys [id] :as item} selected]
|
||||
[{:keys [::mx/local]} {:keys [id] :as item} selected]
|
||||
(let [selected? (contains? selected (:id item))
|
||||
collapsed? (:collapsed item true)
|
||||
shapes-map (mx/react refs/shapes-by-id)
|
||||
|
|
|
@ -8,27 +8,27 @@
|
|||
(ns uxbox.main.ui.workspace.sidebar.options
|
||||
(:require
|
||||
[lentes.core :as l]
|
||||
[uxbox.util.i18n :refer [tr]]
|
||||
[uxbox.util.router :as r]
|
||||
[potok.core :as ptk]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.data.workspace :as udw]
|
||||
[uxbox.main.data.shapes :as uds]
|
||||
[rumext.core :as mx :include-macros true]
|
||||
[uxbox.builtins.icons :as i]
|
||||
[uxbox.main.data.shapes :as uds]
|
||||
[uxbox.main.data.workspace :as udw]
|
||||
[uxbox.main.geom :as geom]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.ui.shapes.attrs :refer [shape-default-attrs]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.circle-measures :as options-circlem]
|
||||
[uxbox.main.ui.workspace.sidebar.options.fill :as options-fill]
|
||||
[uxbox.main.ui.workspace.sidebar.options.icon-measures :as options-iconm]
|
||||
[uxbox.main.ui.workspace.sidebar.options.image-measures :as options-imagem]
|
||||
[uxbox.main.ui.workspace.sidebar.options.circle-measures :as options-circlem]
|
||||
[uxbox.main.ui.workspace.sidebar.options.rect-measures :as options-rectm]
|
||||
[uxbox.main.ui.workspace.sidebar.options.fill :as options-fill]
|
||||
[uxbox.main.ui.workspace.sidebar.options.text :as options-text]
|
||||
[uxbox.main.ui.workspace.sidebar.options.stroke :as options-stroke]
|
||||
[uxbox.main.ui.workspace.sidebar.options.page :as options-page]
|
||||
[uxbox.main.ui.workspace.sidebar.options.interactions :as options-interactions]
|
||||
[uxbox.main.geom :as geom]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.main.ui.workspace.sidebar.options.page :as options-page]
|
||||
[uxbox.main.ui.workspace.sidebar.options.rect-measures :as options-rectm]
|
||||
[uxbox.main.ui.workspace.sidebar.options.stroke :as options-stroke]
|
||||
[uxbox.main.ui.workspace.sidebar.options.text :as options-text]
|
||||
[uxbox.util.data :as data]
|
||||
[rumext.core :as mx :include-macros true]))
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.i18n :refer [tr]]
|
||||
[uxbox.util.router :as r]))
|
||||
|
||||
;; --- Constants
|
||||
|
||||
|
@ -89,18 +89,10 @@
|
|||
|
||||
;; --- Options
|
||||
|
||||
(defn- options-did-remount
|
||||
[old-own own]
|
||||
(let [[prev-shape] (:rum/args old-own)
|
||||
[curr-shape] (:rum/args own)]
|
||||
(when-not (= (:id prev-shape) (:id curr-shape))
|
||||
(reset! (:rum/local own) {}))
|
||||
own))
|
||||
|
||||
(mx/defcs options
|
||||
{:mixins [mx/static (mx/local)]
|
||||
:did-remount options-did-remount}
|
||||
[{:keys [rum/local] :as own} shape]
|
||||
:key-fn #(pr-str (:id %1))}
|
||||
[{:keys [::mx/local] :as own} shape]
|
||||
(let [menus (get +menus-map+ (:type shape ::page))
|
||||
contained-in? (into #{} menus)
|
||||
active (:menu @local (first menus))]
|
||||
|
|
|
@ -2,24 +2,25 @@
|
|||
;; 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/.
|
||||
;;
|
||||
;; Copyright (c) 2015-2016 Andrey Antukh <niwi@niwi.nz>
|
||||
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||
;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.main.ui.workspace.sidebar.options.interactions
|
||||
(:require [lentes.core :as l]
|
||||
[uxbox.builtins.icons :as i]
|
||||
[uxbox.util.i18n :refer [tr]]
|
||||
[uxbox.util.router :as r]
|
||||
[uxbox.main.refs :as refs]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.data.shapes :as uds]
|
||||
[uxbox.main.data.lightbox :as udl]
|
||||
[uxbox.main.ui.lightbox :as lbx]
|
||||
[uxbox.main.ui.colorpicker :as cp]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.data :refer [read-string]]
|
||||
[uxbox.util.spec :refer [color?]]
|
||||
[rumext.core :as mx :include-macros true]))
|
||||
(:require
|
||||
[lentes.core :as l]
|
||||
[rumext.core :as mx :include-macros true]
|
||||
[uxbox.builtins.icons :as i]
|
||||
[uxbox.main.data.lightbox :as udl]
|
||||
[uxbox.main.data.shapes :as uds]
|
||||
[uxbox.main.refs :as refs]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.ui.colorpicker :as cp]
|
||||
[uxbox.main.ui.lightbox :as lbx]
|
||||
[uxbox.util.data :refer [read-string]]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.i18n :refer [tr]]
|
||||
[uxbox.util.router :as r]
|
||||
[uxbox.util.spec :refer [color?]]))
|
||||
|
||||
;; --- Helpers
|
||||
|
||||
|
@ -473,7 +474,7 @@
|
|||
(mx/defcs interactions-menu
|
||||
{:mixins [mx/static (mx/local)]}
|
||||
[own menu shape]
|
||||
(let [local (:rum/local own)
|
||||
(let [local (::mx/local own)
|
||||
form-ref (l/derive (l/key :form) local)
|
||||
interactions (:interactions shape)
|
||||
create-interaction #(reset! form-ref {})]
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
(mx/defcs stroke-menu
|
||||
{:mixins [mx/static (mx/local)]}
|
||||
[{:keys [rum/local]} menu {:keys [id] :as shape}]
|
||||
[{:keys [::mx/local]} menu {:keys [id] :as shape}]
|
||||
(letfn [(on-width-change [event]
|
||||
(let [value (-> (dom/event->value event)
|
||||
(parse-float 1))]
|
||||
|
|
|
@ -6,119 +6,126 @@
|
|||
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||
|
||||
(ns uxbox.main.ui.workspace.sidebar.sitemap
|
||||
(:require [lentes.core :as l]
|
||||
[cuerdas.core :as str]
|
||||
[uxbox.builtins.icons :as i]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.refs :as refs]
|
||||
[uxbox.main.data.projects :as dp]
|
||||
[uxbox.main.data.pages :as udp]
|
||||
[uxbox.main.data.workspace :as dw]
|
||||
[uxbox.main.data.lightbox :as udl]
|
||||
[uxbox.main.ui.workspace.sidebar.sitemap-pageform]
|
||||
[uxbox.main.ui.lightbox :as lbx]
|
||||
[uxbox.util.i18n :refer (tr)]
|
||||
[uxbox.util.router :as r]
|
||||
[uxbox.util.data :refer [classnames]]
|
||||
[uxbox.util.dom.dnd :as dnd]
|
||||
[uxbox.util.dom :as dom]
|
||||
[rumext.core :as mx :include-macros true]))
|
||||
(:require
|
||||
[cuerdas.core :as str]
|
||||
[lentes.core :as l]
|
||||
[rumext.core :as mx :include-macros true]
|
||||
[uxbox.builtins.icons :as i]
|
||||
[uxbox.main.data.lightbox :as udl]
|
||||
[uxbox.main.data.pages :as udp]
|
||||
[uxbox.main.data.projects :as dp]
|
||||
[uxbox.main.data.workspace :as dw]
|
||||
[uxbox.main.refs :as refs]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.ui.lightbox :as lbx]
|
||||
[uxbox.main.ui.workspace.sidebar.sitemap-pageform]
|
||||
[uxbox.util.data :refer [classnames]]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.dom.dnd :as dnd]
|
||||
[uxbox.util.i18n :refer (tr)]
|
||||
[uxbox.util.router :as r]))
|
||||
|
||||
(mx/defcs page-item
|
||||
{:mixins [(mx/local) mx/static mx/reactive]}
|
||||
[{:keys [rum/local] :as own} page total active?]
|
||||
(let [body-classes (classnames
|
||||
:selected active?
|
||||
:drag-active (:dragging @local)
|
||||
:drag-top (= :top (:over @local))
|
||||
:drag-bottom (= :bottom (:over @local))
|
||||
:drag-inside (= :middle (:over @local)))
|
||||
li-classes (classnames
|
||||
:selected active?
|
||||
:hide (:dragging @local))]
|
||||
(letfn [(on-edit [event]
|
||||
(udl/open! :page-form {:page page}))
|
||||
(mx/def page-item
|
||||
:mixins [(mx/local) mx/static mx/reactive]
|
||||
:key-fn :id
|
||||
|
||||
(on-navigate [event]
|
||||
(st/emit! (dp/go-to (:project page) (:id page))))
|
||||
:render
|
||||
(fn [{:keys [::mx/local] :as own}
|
||||
{:keys [::deletable? ::selected?] :as page}]
|
||||
(let [body-classes (classnames
|
||||
:selected selected?
|
||||
:drag-active (:dragging @local)
|
||||
:drag-top (= :top (:over @local))
|
||||
:drag-bottom (= :bottom (:over @local))
|
||||
:drag-inside (= :middle (:over @local)))
|
||||
li-classes (classnames
|
||||
:selected selected?
|
||||
:hide (:dragging @local))]
|
||||
(letfn [(on-edit [event]
|
||||
(udl/open! :page-form {:page page}))
|
||||
|
||||
(delete []
|
||||
(let [next #(st/emit! (dp/go-to (:project page)))]
|
||||
(st/emit! (udp/delete-page (:id page) next))))
|
||||
(on-navigate [event]
|
||||
(st/emit! (dp/go-to (:project page) (:id page))))
|
||||
|
||||
(on-delete [event]
|
||||
(dom/prevent-default event)
|
||||
(dom/stop-propagation event)
|
||||
(udl/open! :confirm {:on-accept delete}))
|
||||
(delete []
|
||||
(let [next #(st/emit! (dp/go-to (:project page)))]
|
||||
(st/emit! (udp/delete-page (:id page) next))))
|
||||
|
||||
(on-drag-start [event]
|
||||
(let [target (dom/event->target event)]
|
||||
(dnd/set-allowed-effect! event "move")
|
||||
(dnd/set-data! event (:id page))
|
||||
(dnd/set-image! event target 50 10)
|
||||
(swap! local assoc :dragging true)))
|
||||
(on-drag-end [event]
|
||||
(swap! local assoc :dragging false :over nil))
|
||||
(on-drop [event]
|
||||
(dom/stop-propagation event)
|
||||
(let [id (dnd/get-data event)
|
||||
over (:over @local)]
|
||||
(case (:over @local)
|
||||
:top (let [new-order (dec (get-in page [:metadata :order]))]
|
||||
(st/emit! (udp/update-order id new-order)))
|
||||
:bottom (let [new-order (inc (get-in page [:metadata :order]))]
|
||||
(st/emit! (udp/update-order id new-order))))
|
||||
(swap! local assoc :dragging false :over nil)))
|
||||
(on-drag-over [event]
|
||||
(dom/prevent-default event)
|
||||
(dnd/set-drop-effect! event "move")
|
||||
(let [over (dnd/get-hover-position event false)]
|
||||
(swap! local assoc :over over)))
|
||||
(on-drag-enter [event]
|
||||
(swap! local assoc :over true))
|
||||
(on-drag-leave [event]
|
||||
(swap! local assoc :over false))]
|
||||
[:li {:class li-classes}
|
||||
[:div.element-list-body
|
||||
{:class body-classes
|
||||
:style {:opacity (if (:dragging @local)
|
||||
"0.5"
|
||||
"1")}
|
||||
:on-click on-navigate
|
||||
:on-double-click #(dom/stop-propagation %)
|
||||
:on-drag-start on-drag-start
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over on-drag-over
|
||||
:on-drag-end on-drag-end
|
||||
:on-drop on-drop
|
||||
:draggable true}
|
||||
(on-delete [event]
|
||||
(dom/prevent-default event)
|
||||
(dom/stop-propagation event)
|
||||
(udl/open! :confirm {:on-accept delete}))
|
||||
|
||||
[:div.page-icon {} i/page]
|
||||
[:span {} (:name page)]
|
||||
[:div.page-actions {}
|
||||
[:a {:on-click on-edit} i/pencil]
|
||||
(when (> total 1)
|
||||
[:a {:on-click on-delete} i/trash])]]])))
|
||||
(on-drag-start [event]
|
||||
(let [target (dom/event->target event)]
|
||||
(dnd/set-allowed-effect! event "move")
|
||||
(dnd/set-data! event (:id page))
|
||||
(dnd/set-image! event target 50 10)
|
||||
(swap! local assoc :dragging true)))
|
||||
(on-drag-end [event]
|
||||
(swap! local assoc :dragging false :over nil))
|
||||
(on-drop [event]
|
||||
(dom/stop-propagation event)
|
||||
(let [id (dnd/get-data event)
|
||||
over (:over @local)]
|
||||
(case (:over @local)
|
||||
:top (let [new-order (dec (get-in page [:metadata :order]))]
|
||||
(st/emit! (udp/update-order id new-order)))
|
||||
:bottom (let [new-order (inc (get-in page [:metadata :order]))]
|
||||
(st/emit! (udp/update-order id new-order))))
|
||||
(swap! local assoc :dragging false :over nil)))
|
||||
(on-drag-over [event]
|
||||
(dom/prevent-default event)
|
||||
(dnd/set-drop-effect! event "move")
|
||||
(let [over (dnd/get-hover-position event false)]
|
||||
(swap! local assoc :over over)))
|
||||
(on-drag-enter [event]
|
||||
(swap! local assoc :over true))
|
||||
(on-drag-leave [event]
|
||||
(swap! local assoc :over false))]
|
||||
[:li {:class li-classes}
|
||||
[:div.element-list-body
|
||||
{:class body-classes
|
||||
:style {:opacity (if (:dragging @local)
|
||||
"0.5"
|
||||
"1")}
|
||||
:on-click on-navigate
|
||||
:on-double-click #(dom/stop-propagation %)
|
||||
:on-drag-start on-drag-start
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over on-drag-over
|
||||
:on-drag-end on-drag-end
|
||||
:on-drop on-drop
|
||||
:draggable true}
|
||||
|
||||
(mx/defc sitemap-toolbox
|
||||
{:mixins [mx/static mx/reactive]}
|
||||
[current]
|
||||
(let [project (mx/react refs/selected-project)
|
||||
pages (mx/react refs/selected-project-pages)
|
||||
create #(udl/open! :page-form {:page {:project (:id project)}})
|
||||
close #(st/emit! (dw/toggle-flag :sitemap))]
|
||||
[:div.sitemap.tool-window {}
|
||||
[:div.tool-window-bar {}
|
||||
[:div.tool-window-icon {} i/project-tree]
|
||||
[:span {} (tr "ds.sitemap")]
|
||||
[:div.tool-window-close {:on-click close} i/close]]
|
||||
[:div.tool-window-content {}
|
||||
[:div.project-title {}
|
||||
[:span {} (:name project)]
|
||||
[:div.add-page {:on-click create} i/close]]
|
||||
[:ul.element-list {}
|
||||
(for [page pages]
|
||||
(let [active? (= (:id page) current)]
|
||||
(-> (page-item page (count pages) active?)
|
||||
(mx/with-key (:id page)))))]]]))
|
||||
[:div.page-icon {} i/page]
|
||||
[:span {} (:name page)]
|
||||
[:div.page-actions {}
|
||||
[:a {:on-click on-edit} i/pencil]
|
||||
(when deletable?
|
||||
[:a {:on-click on-delete} i/trash])]]]))))
|
||||
|
||||
(mx/def sitemap-toolbox
|
||||
:mixins [mx/static mx/reactive]
|
||||
|
||||
:render
|
||||
(fn [own current-page-id]
|
||||
(let [project (mx/react refs/selected-project)
|
||||
pages (mx/react refs/selected-project-pages)
|
||||
create #(udl/open! :page-form {:page {:project (:id project)}})
|
||||
close #(st/emit! (dw/toggle-flag :sitemap))
|
||||
deletable? (> (count pages) 1)]
|
||||
[:div.sitemap.tool-window
|
||||
[:div.tool-window-bar
|
||||
[:div.tool-window-icon i/project-tree]
|
||||
[:span (tr "ds.sitemap")]
|
||||
[:div.tool-window-close {:on-click close} i/close]]
|
||||
[:div.tool-window-content
|
||||
[:div.project-title
|
||||
[:span (:name project)]
|
||||
[:div.add-page {:on-click create} i/close]]
|
||||
[:ul.element-list
|
||||
(for [page pages]
|
||||
(let [selected? (= (:id page) current-page-id)]
|
||||
(page-item (assoc page ::deletable? deletable? ::selected? selected?))))]]])))
|
||||
|
|
Loading…
Add table
Reference in a new issue