mirror of
https://github.com/penpot/penpot.git
synced 2025-01-23 23:18:48 -05:00
Add code optimizations to colors and images ns.
This commit is contained in:
parent
34adb68372
commit
43f3c43eab
2 changed files with 321 additions and 344 deletions
|
@ -2,28 +2,27 @@
|
|||
;; 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-2017 Andrey Antukh <niwi@niwi.nz>
|
||||
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||
|
||||
(ns uxbox.main.ui.dashboard.colors
|
||||
(:require [cuerdas.core :as str]
|
||||
[lentes.core :as l]
|
||||
[potok.core :as ptk]
|
||||
[rumext.core :as mx :include-macros true]
|
||||
[uxbox.main.data.colors :as dc]
|
||||
[uxbox.main.data.dashboard :as dd]
|
||||
[uxbox.main.data.lightbox :as udl]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.ui.messages :refer [messages-widget]]
|
||||
[uxbox.main.ui.colorpicker :refer (colorpicker)]
|
||||
[uxbox.main.ui.dashboard.header :refer (header)]
|
||||
[uxbox.main.ui.colorpicker :refer [colorpicker]]
|
||||
[uxbox.main.ui.dashboard.header :refer [header]]
|
||||
[uxbox.builtins.icons :as i]
|
||||
[uxbox.main.ui.keyboard :as k]
|
||||
[uxbox.main.ui.lightbox :as lbx]
|
||||
[uxbox.util.color :refer (hex->rgb)]
|
||||
[uxbox.util.color :refer [hex->rgb]]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.i18n :as t :refer (tr)]
|
||||
[uxbox.util.lens :as ul]
|
||||
[rumext.core :as mx :include-macros true]))
|
||||
[uxbox.util.i18n :as t :refer [tr]]
|
||||
[uxbox.util.lens :as ul]))
|
||||
|
||||
;; --- Refs
|
||||
|
||||
|
@ -38,10 +37,9 @@
|
|||
;; --- Page Title
|
||||
|
||||
(mx/defcs page-title
|
||||
{:mixins [(mx/local {}) mx/static mx/reactive]}
|
||||
[own {:keys [id] :as coll}]
|
||||
(let [local (:rum/local own)
|
||||
dashboard (mx/react dashboard-ref)
|
||||
{:mixins [(mx/local) mx/static mx/reactive]}
|
||||
[{:keys [rum/local] :as own} {:keys [id] :as coll}]
|
||||
(let [dashboard (mx/react dashboard-ref)
|
||||
own? (= :own (:type coll))
|
||||
edit? (:edit @local)]
|
||||
(letfn [(save []
|
||||
|
@ -65,37 +63,34 @@
|
|||
(st/emit! (dc/delete-collection id)))
|
||||
(on-delete []
|
||||
(udl/open! :confirm {:on-accept delete}))]
|
||||
[:div.dashboard-title
|
||||
[:h2
|
||||
[:div.dashboard-title {}
|
||||
[:h2 {}
|
||||
(if edit?
|
||||
[:div.dashboard-title-field
|
||||
[:span.edit
|
||||
{:content-editable true
|
||||
:ref "input"
|
||||
:on-key-down on-input-keydown}
|
||||
[:div.dashboard-title-field {}
|
||||
[:span.edit {:content-editable true
|
||||
:ref "input"
|
||||
:on-key-down on-input-keydown}
|
||||
(:name coll)]
|
||||
[:span.close {:on-click cancel} i/close]]
|
||||
(if own?
|
||||
[:span.dashboard-title-field
|
||||
{:on-double-click edit}
|
||||
[:span.dashboard-title-field {:on-double-click edit}
|
||||
(:name coll)]
|
||||
[:span.dashboard-title-field
|
||||
[:span.dashboard-title-field {}
|
||||
(:name coll)]))]
|
||||
(when (and own? coll)
|
||||
[:div.edition
|
||||
[:div.edition {}
|
||||
(if edit?
|
||||
[:span {:on-click save} i/save]
|
||||
[:span {:on-click edit} i/pencil])
|
||||
[:span {:on-click on-delete} i/trash]])])))
|
||||
[:span {:on-click save} ^:inline i/save]
|
||||
[:span {:on-click edit} ^:inline i/pencil])
|
||||
[:span {:on-click on-delete} ^:inline i/trash]])])))
|
||||
|
||||
;; --- Nav
|
||||
|
||||
(mx/defcs nav-item
|
||||
{:mixins [(mx/local) mx/static]}
|
||||
[own {:keys [id type name] :as coll} selected?]
|
||||
[{:keys [rum/local]} {:keys [id type name] :as coll} selected?]
|
||||
(let [colors (count (:colors coll))
|
||||
editable? (= type :own)
|
||||
local (:rum/local own)]
|
||||
editable? (= type :own)]
|
||||
(letfn [(on-click [event]
|
||||
(let [type (or type :own)]
|
||||
(st/emit! (dc/select-collection type id))))
|
||||
|
@ -119,14 +114,14 @@
|
|||
:on-double-click on-double-click
|
||||
:class-name (when selected? "current")}
|
||||
(if (:edit @local)
|
||||
[:div
|
||||
[:div {}
|
||||
[:input.element-title
|
||||
{:value (if (:name @local) (:name @local) name)
|
||||
:on-change on-input-change
|
||||
:on-key-down on-input-keyup}]
|
||||
{:value (if (:name @local) (:name @local) name)
|
||||
:on-change on-input-change
|
||||
:on-key-down on-input-keyup}]
|
||||
[:span.close {:on-click on-cancel} i/close]]
|
||||
[:span.element-title name])
|
||||
[:span.element-subtitle
|
||||
[:span.element-title {} name])
|
||||
[:span.element-subtitle {}
|
||||
(tr "ds.num-elements" (t/c colors))]])))
|
||||
|
||||
(mx/defc nav-section
|
||||
|
@ -139,51 +134,45 @@
|
|||
builtin? (filter #(= :builtin (:type %)))
|
||||
own? (sort-by :created-at)
|
||||
builtin? (sort-by :created-at))]
|
||||
[:ul.library-elements
|
||||
[:ul.library-elements {}
|
||||
(when own?
|
||||
[:li
|
||||
[:a.btn-primary
|
||||
{:on-click #(st/emit! (dc/create-collection))}
|
||||
"+ New library"]])
|
||||
(for [coll colls
|
||||
:let [selected? (= (:id coll) selected)
|
||||
key (str (:id coll))]]
|
||||
(-> (nav-item coll selected?)
|
||||
(mx/with-key key)))]))
|
||||
[:li {}
|
||||
[:a.btn-primary {:on-click #(st/emit! (dc/create-collection))} "+ New library"]])
|
||||
(mx/doseq [{:keys [id] :as coll} colls]
|
||||
(let [selected? (= (:id coll) selected)]
|
||||
(-> (nav-item coll selected?)
|
||||
(mx/with-key id))))]))
|
||||
|
||||
(mx/defc nav
|
||||
{:mixins [mx/static mx/reactive]}
|
||||
{:mixins [mx/static]}
|
||||
[{:keys [id type] :as state} colls]
|
||||
(let [own? (= type :own)
|
||||
builtin? (= type :builtin)]
|
||||
(letfn [(select-tab [type]
|
||||
(if (= type :own)
|
||||
(st/emit! (dc/select-collection type))
|
||||
(let [coll (->> (map second colls)
|
||||
(filter #(= type (:type %)))
|
||||
(sort-by :created-at)
|
||||
(first))]
|
||||
(if coll
|
||||
(st/emit! (dc/select-collection type (:id coll)))
|
||||
(st/emit! (dc/select-collection type))))))]
|
||||
[:div.library-bar
|
||||
[:div.library-bar-inside
|
||||
[:ul.library-tabs
|
||||
[:li {:class-name (when own? "current")
|
||||
:on-click (partial select-tab :own)}
|
||||
"YOUR COLORS"]
|
||||
[:li {:class-name (when builtin? "current")
|
||||
:on-click (partial select-tab :builtin)}
|
||||
"COLORS STORE"]]
|
||||
(nav-section type id colls)]])))
|
||||
(letfn [(select-tab [type]
|
||||
(if (= type :own)
|
||||
(st/emit! (dc/select-collection type))
|
||||
(let [coll (->> (map second colls)
|
||||
(filter #(= type (:type %)))
|
||||
(sort-by :created-at)
|
||||
(first))]
|
||||
(if coll
|
||||
(st/emit! (dc/select-collection type (:id coll)))
|
||||
(st/emit! (dc/select-collection type))))))]
|
||||
[:div.library-bar {}
|
||||
[:div.library-bar-inside {}
|
||||
[:ul.library-tabs {}
|
||||
[:li {:class-name (when (= type :own) "current")
|
||||
:on-click (partial select-tab :own)}
|
||||
"YOUR COLORS"]
|
||||
[:li {:class-name (when (= type :builtin) "current")
|
||||
:on-click (partial select-tab :builtin)}
|
||||
"COLORS STORE"]]
|
||||
(nav-section type id colls)]]))
|
||||
|
||||
;; --- Grid
|
||||
|
||||
(mx/defc grid-form
|
||||
[coll-id]
|
||||
[:div.grid-item.small-item.add-project
|
||||
{:on-click #(udl/open! :color-form {:coll coll-id})}
|
||||
[:span "+ New color"]])
|
||||
[:div.grid-item.small-item.add-project {:on-click #(udl/open! :color-form {:coll coll-id})}
|
||||
[:span {} "+ New color"]])
|
||||
|
||||
(mx/defc grid-options-tooltip
|
||||
{:mixins [mx/reactive mx/static]}
|
||||
|
@ -200,88 +189,86 @@
|
|||
(dom/prevent-default event)
|
||||
(dom/stop-propagation event)
|
||||
(on-select id))]
|
||||
[:ul.move-list
|
||||
[:li.title title]
|
||||
(for [coll colls
|
||||
:let [id (:id coll)
|
||||
name (:name coll)]]
|
||||
[:ul.move-list {}
|
||||
[:li.title {} title]
|
||||
(mx/doseq [{:keys [id name] :as coll} colls]
|
||||
[:li {:key (str id)}
|
||||
[:a {:on-click #(on-select % id)} name]])]))
|
||||
|
||||
(mx/defcs grid-options
|
||||
{:mixins [mx/static (mx/local)]}
|
||||
[own {:keys [type id] :as coll}]
|
||||
(let [editable? (or (= type :own) (nil? id))
|
||||
local (:rum/local own)]
|
||||
(letfn [(delete [event]
|
||||
(st/emit! (dc/delete-selected-colors)))
|
||||
(on-delete [event]
|
||||
(udl/open! :confirm {:on-accept delete}))
|
||||
(on-toggle-copy [event]
|
||||
(swap! local update :show-copy-tooltip not)
|
||||
(swap! local assoc :show-move-tooltip false))
|
||||
(on-toggle-move [event]
|
||||
(swap! local update :show-move-tooltip not)
|
||||
(swap! local assoc :show-copy-tooltip false))
|
||||
(on-copy [selected]
|
||||
(swap! local assoc
|
||||
:show-move-tooltip false
|
||||
:show-copy-tooltip false)
|
||||
(st/emit! (dc/copy-selected selected)))
|
||||
(on-move [selected]
|
||||
(swap! local assoc
|
||||
:show-move-tooltip false
|
||||
:show-copy-tooltip false)
|
||||
(st/emit! (dc/move-selected id selected)))]
|
||||
[{:keys [rum/local]} {:keys [type id] :as coll}]
|
||||
(letfn [(delete [event]
|
||||
(st/emit! (dc/delete-selected-colors)))
|
||||
(on-delete [event]
|
||||
(udl/open! :confirm {:on-accept delete}))
|
||||
(on-toggle-copy [event]
|
||||
(swap! local update :show-copy-tooltip not)
|
||||
(swap! local assoc :show-move-tooltip false))
|
||||
(on-toggle-move [event]
|
||||
(swap! local update :show-move-tooltip not)
|
||||
(swap! local assoc :show-copy-tooltip false))
|
||||
(on-copy [selected]
|
||||
(swap! local assoc
|
||||
:show-move-tooltip false
|
||||
:show-copy-tooltip false)
|
||||
(st/emit! (dc/copy-selected selected)))
|
||||
(on-move [selected]
|
||||
(swap! local assoc
|
||||
:show-move-tooltip false
|
||||
:show-copy-tooltip false)
|
||||
(st/emit! (dc/move-selected id selected)))]
|
||||
|
||||
;; MULTISELECT OPTIONS BAR
|
||||
[:div.multiselect-bar
|
||||
(if editable?
|
||||
[:div.multiselect-nav
|
||||
[:span.move-item.tooltip.tooltip-top
|
||||
{:on-click on-toggle-copy :alt "Copy"}
|
||||
(when (:show-copy-tooltip @local)
|
||||
(grid-options-tooltip :selected id
|
||||
:title "Copy to library"
|
||||
:on-select on-copy))
|
||||
;; MULTISELECT OPTIONS BAR
|
||||
[:div.multiselect-bar
|
||||
(if (or (= type :own) (nil? id))
|
||||
;; if editable
|
||||
[:div.multiselect-nav {}
|
||||
[:span.move-item.tooltip.tooltip-top
|
||||
{:on-click on-toggle-copy :alt "Copy"}
|
||||
(when (:show-copy-tooltip @local)
|
||||
(grid-options-tooltip :selected id
|
||||
:title "Copy to library"
|
||||
:on-select on-copy))
|
||||
|
||||
i/copy]
|
||||
[:span.move-item.tooltip.tooltip-top
|
||||
{:on-click on-toggle-move :alt "Move"}
|
||||
(when (:show-move-tooltip @local)
|
||||
(grid-options-tooltip :selected id
|
||||
:title "Move to library"
|
||||
:on-select on-move))
|
||||
i/move]
|
||||
[:span.delete.tooltip.tooltip-top
|
||||
{:alt "Delete"
|
||||
:on-click on-delete}
|
||||
i/trash]]
|
||||
[:div.multiselect-nav
|
||||
[:span.move-item.tooltip.tooltip-top
|
||||
{:on-click on-toggle-copy}
|
||||
(when (:show-copy-tooltip @local)
|
||||
(grid-options-tooltip :selected id
|
||||
:title "Copy to library"
|
||||
:on-select on-copy))
|
||||
i/organize]])])))
|
||||
i/copy]
|
||||
[:span.move-item.tooltip.tooltip-top
|
||||
{:on-click on-toggle-move :alt "Move"}
|
||||
(when (:show-move-tooltip @local)
|
||||
(grid-options-tooltip :selected id
|
||||
:title "Move to library"
|
||||
:on-select on-move))
|
||||
i/move]
|
||||
[:span.delete.tooltip.tooltip-top
|
||||
{:alt "Delete"
|
||||
:on-click on-delete}
|
||||
i/trash]]
|
||||
|
||||
;; if not editable
|
||||
[:div.multiselect-nav {}
|
||||
[:span.move-item.tooltip.tooltip-top
|
||||
{:on-click on-toggle-copy}
|
||||
(when (:show-copy-tooltip @local)
|
||||
(grid-options-tooltip :selected id
|
||||
:title "Copy to library"
|
||||
:on-select on-copy))
|
||||
i/organize]])]))
|
||||
|
||||
(mx/defc grid-item
|
||||
{:mixins [mx/static]}
|
||||
[color selected?]
|
||||
(let [color-rgb (hex->rgb color)]
|
||||
(letfn [(toggle-selection [event]
|
||||
(st/emit! (dc/toggle-color-selection color)))]
|
||||
[:div.grid-item.small-item.project-th
|
||||
{:on-click toggle-selection}
|
||||
[:span.color-swatch {:style {:background-color color}}]
|
||||
[:div.input-checkbox.check-primary
|
||||
[:input {:type "checkbox"
|
||||
:id color
|
||||
:on-click toggle-selection
|
||||
:checked selected?}]
|
||||
[:label {:for color}]]
|
||||
[:span.color-data color]
|
||||
[:span.color-data (apply str "RGB " (interpose ", " color-rgb))]])))
|
||||
(letfn [(toggle-selection [event]
|
||||
(st/emit! (dc/toggle-color-selection color)))]
|
||||
[:div.grid-item.small-item.project-th {:on-click toggle-selection}
|
||||
[:span.color-swatch {:style {:background-color color}}]
|
||||
[:div.input-checkbox.check-primary {}
|
||||
[:input {:type "checkbox"
|
||||
:id color
|
||||
:on-click toggle-selection
|
||||
:checked selected?}]
|
||||
[:label {:for color}]]
|
||||
[:span.color-data {} color]
|
||||
[:span.color-data {} (apply str "RGB " (interpose ", " (hex->rgb color)))]]))
|
||||
|
||||
(mx/defc grid
|
||||
{:mixins [mx/static]}
|
||||
|
@ -289,18 +276,18 @@
|
|||
(let [editable? (or (= :own type) (nil? id))
|
||||
colors (->> (remove nil? colors)
|
||||
(sort-by identity))]
|
||||
[:div.dashboard-grid-content
|
||||
[:div.dashboard-grid-row
|
||||
[:div.dashboard-grid-content {}
|
||||
[:div.dashboard-grid-row {}
|
||||
(when editable? (grid-form id))
|
||||
(for [color colors
|
||||
:let [selected? (contains? selected color)]]
|
||||
(-> (grid-item color selected?)
|
||||
(mx/with-key (str color))))]]))
|
||||
(mx/doseq [color colors]
|
||||
(let [selected? (contains? selected color)]
|
||||
(-> (grid-item color selected?)
|
||||
(mx/with-key (str color)))))]]))
|
||||
|
||||
(mx/defc content
|
||||
{:mixins [mx/static]}
|
||||
[{:keys [selected] :as state} coll]
|
||||
[:section.dashboard-grid.library
|
||||
[:section.dashboard-grid.library {}
|
||||
(page-title coll)
|
||||
(grid coll selected)
|
||||
(when (and (seq selected))
|
||||
|
@ -331,10 +318,10 @@
|
|||
(let [state (mx/react dashboard-ref)
|
||||
colls (mx/react collections-ref)
|
||||
coll (get colls (:id state))]
|
||||
[:main.dashboard-main
|
||||
[:main.dashboard-main {}
|
||||
(messages-widget)
|
||||
(header)
|
||||
[:section.dashboard-content
|
||||
[:section.dashboard-content {}
|
||||
(nav state colls)
|
||||
(content state coll)]]))
|
||||
|
||||
|
@ -342,32 +329,30 @@
|
|||
|
||||
(mx/defcs color-lightbox
|
||||
{:mixins [(mx/local {}) mx/static]}
|
||||
[own {:keys [coll color] :as params}]
|
||||
(let [local (:rum/local own)]
|
||||
(letfn [(on-submit [event]
|
||||
(let [params {:id coll
|
||||
:from color
|
||||
:to (:hex @local)}]
|
||||
(st/emit! (dc/replace-color params))
|
||||
(udl/close!)))
|
||||
(on-change [event]
|
||||
(let [value (str/trim (dom/event->value event))]
|
||||
(swap! local assoc :hex value)))
|
||||
(on-close [event]
|
||||
(udl/close!))]
|
||||
[:div.lightbox-body
|
||||
[:h3 "New color"]
|
||||
[:form
|
||||
[:div.row-flex.center
|
||||
(colorpicker
|
||||
:value (or (:hex @local) color "#00ccff")
|
||||
:on-change #(swap! local assoc :hex %))]
|
||||
[{:keys [rum/local]} {:keys [coll color] :as params}]
|
||||
(letfn [(on-submit [event]
|
||||
(let [params {:id coll
|
||||
:from color
|
||||
:to (:hex @local)}]
|
||||
(st/emit! (dc/replace-color params))
|
||||
(udl/close!)))
|
||||
(on-change [event]
|
||||
(let [value (str/trim (dom/event->value event))]
|
||||
(swap! local assoc :hex value)))
|
||||
(on-close [event]
|
||||
(udl/close!))]
|
||||
[:div.lightbox-body {}
|
||||
[:h3 {} "New color"]
|
||||
[:form {}
|
||||
[:div.row-flex.center {}
|
||||
(colorpicker
|
||||
:value (or (:hex @local) color "#00ccff")
|
||||
:on-change #(swap! local assoc :hex %))]
|
||||
|
||||
[:input#project-btn.btn-primary
|
||||
{:value "+ Add color"
|
||||
:on-click on-submit
|
||||
:type "button"}]]
|
||||
[:a.close {:on-click on-close} i/close]])))
|
||||
[:input#project-btn.btn-primary {:value "+ Add color"
|
||||
:on-click on-submit
|
||||
:type "button"}]]
|
||||
[:a.close {:on-click on-close} i/close]]))
|
||||
|
||||
(defmethod lbx/render-lightbox :color-form
|
||||
[params]
|
||||
|
|
|
@ -8,13 +8,12 @@
|
|||
(ns uxbox.main.ui.dashboard.images
|
||||
(:require [cuerdas.core :as str]
|
||||
[lentes.core :as l]
|
||||
[rumext.core :as mx :include-macros true]
|
||||
[uxbox.util.i18n :as t :refer [tr]]
|
||||
[uxbox.main.store :as st]
|
||||
[potok.core :as ptk]
|
||||
[uxbox.main.data.lightbox :as udl]
|
||||
[uxbox.main.data.images :as di]
|
||||
[uxbox.builtins.icons :as i]
|
||||
[rumext.core :as mx :include-macros true]
|
||||
[uxbox.main.ui.lightbox :as lbx]
|
||||
[uxbox.main.ui.keyboard :as kbd]
|
||||
[uxbox.main.ui.dashboard.header :refer [header]]
|
||||
|
@ -94,10 +93,10 @@
|
|||
(st/emit! (di/delete-collection id)))
|
||||
(on-delete []
|
||||
(udl/open! :confirm {:on-accept delete}))]
|
||||
[:div.dashboard-title
|
||||
[:h2
|
||||
[:div.dashboard-title {}
|
||||
[:h2 {}
|
||||
(if edit?
|
||||
[:div.dashboard-title-field
|
||||
[:div.dashboard-title-field {}
|
||||
[:span.edit
|
||||
{:content-editable true
|
||||
:ref "input"
|
||||
|
@ -111,11 +110,11 @@
|
|||
[:span.dashboard-title-field
|
||||
(:name coll "Storage")]))]
|
||||
(when (and own? coll)
|
||||
[:div.edition
|
||||
[:div.edition {}
|
||||
(if edit?
|
||||
[:span {:on-click on-save} i/save]
|
||||
[:span {:on-click on-edit} i/pencil])
|
||||
[:span {:on-click on-delete} i/trash]])])))
|
||||
[:span {:on-click on-save} ^:inline i/save]
|
||||
[:span {:on-click on-edit} ^:inline i/pencil])
|
||||
[:span {:on-click on-delete} ^:inline i/trash]])])))
|
||||
|
||||
;; --- Nav
|
||||
|
||||
|
@ -128,42 +127,40 @@
|
|||
|
||||
(mx/defcs nav-item
|
||||
{:mixins [(mx/local) mx/static mx/reactive]}
|
||||
[own {:keys [id type name num-images] :as coll} selected?]
|
||||
(let [editable? (= type :own)
|
||||
local (:rum/local own)]
|
||||
(letfn [(on-click [event]
|
||||
(let [type (or type :own)]
|
||||
(st/emit! (di/select-collection type id))))
|
||||
(on-input-change [event]
|
||||
[{:keys [rum/local] :as own} {:keys [id type name num-images] :as coll} selected?]
|
||||
(letfn [(on-click [event]
|
||||
(let [type (or type :own)]
|
||||
(st/emit! (di/select-collection type id))))
|
||||
(on-input-change [event]
|
||||
(let [value (dom/get-target event)
|
||||
value (dom/get-value value)]
|
||||
(swap! local assoc :name value)))
|
||||
(on-cancel [event]
|
||||
(swap! local dissoc :name)
|
||||
(swap! local dissoc :edit))
|
||||
(on-double-click [event]
|
||||
(when (= type :own)
|
||||
(swap! local assoc :edit true)))
|
||||
(on-input-keyup [event]
|
||||
(when (kbd/enter? event)
|
||||
(let [value (dom/get-target event)
|
||||
value (dom/get-value value)]
|
||||
(swap! local assoc :name value)))
|
||||
(on-cancel [event]
|
||||
(swap! local dissoc :name)
|
||||
(swap! local dissoc :edit))
|
||||
(on-double-click [event]
|
||||
(when editable?
|
||||
(swap! local assoc :edit true)))
|
||||
(on-input-keyup [event]
|
||||
(when (kbd/enter? event)
|
||||
(let [value (dom/get-target event)
|
||||
value (dom/get-value value)]
|
||||
(st/emit! (di/rename-collection id (str/trim (:name @local))))
|
||||
(swap! local assoc :edit false))))]
|
||||
[:li {:on-click on-click
|
||||
:on-double-click on-double-click
|
||||
:class-name (when selected? "current")}
|
||||
(if (:edit @local)
|
||||
[:div
|
||||
[:input.element-title
|
||||
{:value (if (:name @local) (:name @local) (if coll name "Storage"))
|
||||
:on-change on-input-change
|
||||
:on-key-down on-input-keyup}]
|
||||
[:span.close {:on-click on-cancel} i/close]]
|
||||
[:span.element-title
|
||||
(if coll name "Storage")])
|
||||
[:span.element-subtitle
|
||||
(tr "ds.num-elements" (t/c (or num-images (react-count-images id))))]])))
|
||||
(st/emit! (di/rename-collection id (str/trim (:name @local))))
|
||||
(swap! local assoc :edit false))))]
|
||||
[:li {:on-click on-click
|
||||
:on-double-click on-double-click
|
||||
:class-name (when selected? "current")}
|
||||
(if (:edit @local)
|
||||
[:div {}
|
||||
[:input.element-title
|
||||
{:value (if (:name @local) (:name @local) (if coll name "Storage"))
|
||||
:on-change on-input-change
|
||||
:on-key-down on-input-keyup}]
|
||||
[:span.close {:on-click on-cancel} ^:inline i/close]]
|
||||
[:span.element-title {}
|
||||
(if coll name "Storage")])
|
||||
[:span.element-subtitle
|
||||
(tr "ds.num-elements" (t/c (or num-images (react-count-images id))))]]))
|
||||
|
||||
(mx/defc nav-section
|
||||
{:mixins [mx/static]}
|
||||
|
@ -174,19 +171,19 @@
|
|||
own? (filter #(= :own (:type %)))
|
||||
builtin? (filter #(= :builtin (:type %)))
|
||||
own? (sort-by :name))]
|
||||
[:ul.library-elements
|
||||
[:ul.library-elements {}
|
||||
(when own?
|
||||
[:li
|
||||
[:li {}
|
||||
[:a.btn-primary
|
||||
{:on-click #(st/emit! (di/create-collection))}
|
||||
"+ New library"]])
|
||||
(when own?
|
||||
(nav-item nil (nil? selected)))
|
||||
(for [coll collections
|
||||
:let [selected? (= (:id coll) selected)
|
||||
key (str (:id coll))]]
|
||||
(-> (nav-item coll selected?)
|
||||
(mx/with-key key)))]))
|
||||
(mx/doseq [coll collections]
|
||||
(let [selected? (= (:id coll) selected)
|
||||
key (str (:id coll))]
|
||||
(-> (nav-item coll selected?)
|
||||
(mx/with-key key))))]))
|
||||
|
||||
(mx/defc nav
|
||||
{:mixins [mx/static]}
|
||||
|
@ -203,9 +200,9 @@
|
|||
(if coll
|
||||
(st/emit! (di/select-collection type (:id coll)))
|
||||
(st/emit! (di/select-collection type))))))]
|
||||
[:div.library-bar
|
||||
[:div.library-bar-inside
|
||||
[:ul.library-tabs
|
||||
[:div.library-bar {}
|
||||
[:div.library-bar-inside {}
|
||||
[:ul.library-tabs {}
|
||||
[:li {:class-name (when own? "current")
|
||||
:on-click (partial select-tab :own)}
|
||||
"YOUR IMAGES"]
|
||||
|
@ -229,8 +226,8 @@
|
|||
(let [uploading? (mx/react uploading?-ref)]
|
||||
[:div.grid-item.add-project {:on-click forward-click}
|
||||
(if uploading?
|
||||
[:div i/loader-pencil]
|
||||
[:span "+ New image"])
|
||||
[:div {} ^:inline i/loader-pencil]
|
||||
[:span {} "+ New image"])
|
||||
[:input.upload-image-input
|
||||
{:style {:display "none"}
|
||||
:multiple true
|
||||
|
@ -255,76 +252,76 @@
|
|||
(dom/prevent-default event)
|
||||
(dom/stop-propagation event)
|
||||
(on-select id))]
|
||||
[:ul.move-list
|
||||
[:li.title title]
|
||||
[:li [:a {:href "#" :on-click #(on-select % nil)} "Storage"]]
|
||||
(for [coll colls
|
||||
:let [id (:id coll)
|
||||
name (:name coll)]]
|
||||
[:ul.move-list {}
|
||||
[:li.title {} title]
|
||||
[:li {}
|
||||
[:a {:href "#" :on-click #(on-select % nil)} "Storage"]]
|
||||
(mx/doseq [{:keys [id name] :as coll} colls]
|
||||
[:li {:key (str id)}
|
||||
[:a {:on-click #(on-select % id)} name]])]))
|
||||
|
||||
(mx/defcs grid-options
|
||||
{:mixins [(mx/local) mx/static]}
|
||||
[own {:keys [type id] :as coll} selected]
|
||||
(let [editable? (or (= type :own) (nil? coll))
|
||||
local (:rum/local own)]
|
||||
(letfn [(delete []
|
||||
(st/emit! (di/delete-selected)))
|
||||
(on-delete [event]
|
||||
(udl/open! :confirm {:on-accept delete}))
|
||||
(on-toggle-copy [event]
|
||||
(swap! local update :show-copy-tooltip not))
|
||||
(on-toggle-move [event]
|
||||
(swap! local update :show-move-tooltip not))
|
||||
(on-copy [selected]
|
||||
(swap! local assoc
|
||||
:show-move-tooltip false
|
||||
:show-copy-tooltip false)
|
||||
(st/emit! (di/copy-selected selected)))
|
||||
(on-move [selected]
|
||||
(swap! local assoc
|
||||
:show-move-tooltip false
|
||||
:show-copy-tooltip false)
|
||||
(st/emit! (di/move-selected selected)))
|
||||
(on-rename [event]
|
||||
(let [selected (first selected)]
|
||||
(st/emit! (di/update-opts :edition selected))))]
|
||||
;; MULTISELECT OPTIONS BAR
|
||||
[:div.multiselect-bar
|
||||
(if editable?
|
||||
[:div.multiselect-nav
|
||||
[{:keys [rum/local] :as own} {:keys [type id] :as coll} selected]
|
||||
(letfn [(delete []
|
||||
(st/emit! (di/delete-selected)))
|
||||
(on-delete [event]
|
||||
(udl/open! :confirm {:on-accept delete}))
|
||||
(on-toggle-copy [event]
|
||||
(swap! local update :show-copy-tooltip not))
|
||||
(on-toggle-move [event]
|
||||
(swap! local update :show-move-tooltip not))
|
||||
(on-copy [selected]
|
||||
(swap! local assoc
|
||||
:show-move-tooltip false
|
||||
:show-copy-tooltip false)
|
||||
(st/emit! (di/copy-selected selected)))
|
||||
(on-move [selected]
|
||||
(swap! local assoc
|
||||
:show-move-tooltip false
|
||||
:show-copy-tooltip false)
|
||||
(st/emit! (di/move-selected selected)))
|
||||
(on-rename [event]
|
||||
(let [selected (first selected)]
|
||||
(st/emit! (di/update-opts :edition selected))))]
|
||||
;; MULTISELECT OPTIONS BAR
|
||||
[:div.multiselect-bar {}
|
||||
(if (or (= type :own) (nil? coll))
|
||||
;; If editable
|
||||
[:div.multiselect-nav {}
|
||||
[:span.move-item.tooltip.tooltip-top
|
||||
{:on-click on-toggle-copy :alt "Copy"}
|
||||
(when (:show-copy-tooltip @local)
|
||||
(grid-options-tooltip :selected id
|
||||
:title "Copy to library"
|
||||
:on-select on-copy))
|
||||
^:inline i/copy]
|
||||
[:span.move-item.tooltip.tooltip-top
|
||||
{:on-click on-toggle-move :alt "Move"}
|
||||
(when (:show-move-tooltip @local)
|
||||
(grid-options-tooltip :selected id
|
||||
:title "Move to library"
|
||||
:on-select on-move))
|
||||
^:inline i/move]
|
||||
(when (= 1 (count selected))
|
||||
[:span.move-item.tooltip.tooltip-top
|
||||
{:on-click on-toggle-copy :alt "Copy"}
|
||||
(when (:show-copy-tooltip @local)
|
||||
(grid-options-tooltip :selected id
|
||||
:title "Copy to library"
|
||||
:on-select on-copy))
|
||||
i/copy]
|
||||
[:span.move-item.tooltip.tooltip-top
|
||||
{:on-click on-toggle-move :alt "Move"}
|
||||
(when (:show-move-tooltip @local)
|
||||
(grid-options-tooltip :selected id
|
||||
:title "Move to library"
|
||||
:on-select on-move))
|
||||
i/move]
|
||||
(when (= 1 (count selected))
|
||||
[:span.move-item.tooltip.tooltip-top
|
||||
{:alt "Rename"
|
||||
:on-click on-rename}
|
||||
i/pencil])
|
||||
[:span.delete.tooltip.tooltip-top
|
||||
{:alt "Delete"
|
||||
:on-click on-delete}
|
||||
i/trash]]
|
||||
[:div.multiselect-nav
|
||||
[:span.move-item.tooltip.tooltip-top
|
||||
{:on-click on-toggle-copy}
|
||||
(when (:show-copy-tooltip @local)
|
||||
(grid-options-tooltip :selected id
|
||||
:title "Copy to library"
|
||||
:on-select on-copy))
|
||||
i/organize]])])))
|
||||
{:alt "Rename"
|
||||
:on-click on-rename}
|
||||
^:inline i/pencil])
|
||||
[:span.delete.tooltip.tooltip-top
|
||||
{:alt "Delete"
|
||||
:on-click on-delete}
|
||||
^:inline i/trash]]
|
||||
|
||||
;; If not editable
|
||||
[:div.multiselect-nav {}
|
||||
[:span.move-item.tooltip.tooltip-top
|
||||
{:on-click on-toggle-copy}
|
||||
(when (:show-copy-tooltip @local)
|
||||
(grid-options-tooltip :selected id
|
||||
:title "Copy to library"
|
||||
:on-select on-copy))
|
||||
^:inline i/organize]])]))
|
||||
|
||||
(mx/defc grid-item
|
||||
{:mixins [mx/static]}
|
||||
|
@ -343,28 +340,25 @@
|
|||
(dom/stop-propagation event)
|
||||
(dom/prevent-default event)
|
||||
(st/emit! (di/update-opts :edition id)))]
|
||||
[:div.grid-item.images-th
|
||||
[:div.grid-item-th
|
||||
{:on-click toggle-selection
|
||||
:style {:background-image (str "url('" (:thumbnail image) "')")}}
|
||||
[:div.input-checkbox.check-primary
|
||||
[:div.grid-item.images-th {}
|
||||
[:div.grid-item-th {:on-click toggle-selection
|
||||
:style {:background-image (str "url('" (:thumbnail image) "')")}}
|
||||
[:div.input-checkbox.check-primary {}
|
||||
[:input {:type "checkbox"
|
||||
:id (:id image)
|
||||
:on-click toggle-selection
|
||||
:checked selected?}]
|
||||
[:label {:for (:id image)}]]]
|
||||
[:div.item-info
|
||||
[:div.item-info {}
|
||||
(if edition?
|
||||
[:input.element-name {:type "text"
|
||||
:auto-focus true
|
||||
:on-key-down on-key-down
|
||||
:on-blur on-blur
|
||||
:on-click on-edit
|
||||
:default-value (:name image)}]
|
||||
[:h3 {:on-double-click on-edit}
|
||||
(:name image)])
|
||||
[:span.date
|
||||
(str "Uploaded at " (dt/format created-at "L"))]]]))
|
||||
:auto-focus true
|
||||
:on-key-down on-key-down
|
||||
:on-blur on-blur
|
||||
:on-click on-edit
|
||||
:default-value (:name image)}]
|
||||
[:h3 {:on-double-click on-edit} (:name image)])
|
||||
[:span.date {} (str "Uploaded at " (dt/format created-at "L"))]]]))
|
||||
|
||||
(mx/defc grid
|
||||
{:mixins [mx/static mx/reactive]}
|
||||
|
@ -377,20 +371,20 @@
|
|||
(filter #(= id (:collection %)))
|
||||
(filter-images-by filtering)
|
||||
(sort-images-by ordering))]
|
||||
[:div.dashboard-grid-content
|
||||
[:div.dashboard-grid-row
|
||||
(when editable? (grid-form id))
|
||||
(for [image images
|
||||
:let [id (:id image)
|
||||
edition? (= edition id)
|
||||
selected? (contains? selected id)]]
|
||||
(-> (grid-item image selected? edition?)
|
||||
(mx/with-key (str id))))]]))
|
||||
[:div.dashboard-grid-content {}
|
||||
[:div.dashboard-grid-row {}
|
||||
(when editable?
|
||||
(grid-form id))
|
||||
(mx/doseq [{:keys [id] :as image} images]
|
||||
(let [edition? (= edition id)
|
||||
selected? (contains? selected id)]
|
||||
(-> (grid-item image selected? edition?)
|
||||
(mx/with-key (str id)))))]]))
|
||||
|
||||
(mx/defc content
|
||||
{:mixins [mx/static]}
|
||||
[{:keys [selected] :as state} coll]
|
||||
[:section.dashboard-grid.library
|
||||
[:section.dashboard-grid.library {}
|
||||
(page-title coll)
|
||||
(grid state)
|
||||
(when (seq selected)
|
||||
|
@ -415,31 +409,29 @@
|
|||
(st/emit! (di/update-opts :order value))))
|
||||
(on-clear [event]
|
||||
(st/emit! (di/update-opts :filter "")))]
|
||||
[:section.dashboard-bar.library-gap
|
||||
[:div.dashboard-info
|
||||
[:section.dashboard-bar.library-gap {}
|
||||
[:div.dashboard-info {}
|
||||
|
||||
;; Counter
|
||||
[:span.dashboard-images (tr "ds.num-images" (t/c icount))]
|
||||
[:span.dashboard-images {} (tr "ds.num-images" (t/c icount))]
|
||||
|
||||
;; Sorting
|
||||
[:div
|
||||
[:span (tr "ds.project-ordering")]
|
||||
[:select.input-select
|
||||
{:on-change on-ordering-change
|
||||
:value (pr-str ordering)}
|
||||
(for [[key value] (seq +ordering-options+)
|
||||
:let [ovalue (pr-str key)
|
||||
olabel (tr value)]]
|
||||
[:option {:key ovalue :value ovalue} olabel])]]
|
||||
[:div {}
|
||||
[:span {} (tr "ds.project-ordering")]
|
||||
[:select.input-select {:on-change on-ordering-change
|
||||
:value (pr-str ordering)}
|
||||
(mx/doseq [[key value] (seq +ordering-options+)]
|
||||
(let [key (pr-str key)
|
||||
label (tr value)]
|
||||
[:option {:key key :value key} label]))]]
|
||||
;; Search
|
||||
[:form.dashboard-search
|
||||
[:input.input-text
|
||||
{:key :images-search-box
|
||||
:type "text"
|
||||
:on-change on-term-change
|
||||
:auto-focus true
|
||||
:placeholder (tr "ds.project-search.placeholder")
|
||||
:value (or filtering "")}]
|
||||
[:form.dashboard-search {}
|
||||
[:input.input-text {:key :images-search-box
|
||||
:type "text"
|
||||
:on-change on-term-change
|
||||
:auto-focus true
|
||||
:placeholder (tr "ds.project-search.placeholder")
|
||||
:value (or filtering "")}]
|
||||
[:div.clear-search {:on-click on-clear} i/close]]]])))
|
||||
|
||||
;; --- Images Page
|
||||
|
@ -467,9 +459,9 @@
|
|||
(let [state (mx/react dashboard-ref)
|
||||
colls (mx/react collections-ref)
|
||||
coll (get colls (:id state))]
|
||||
[:main.dashboard-main
|
||||
[:main.dashboard-main {}
|
||||
(header)
|
||||
[:section.dashboard-content
|
||||
[:section.dashboard-content {}
|
||||
(nav state colls)
|
||||
(menu coll)
|
||||
(content state coll)]]))
|
||||
|
|
Loading…
Add table
Reference in a new issue