mirror of
https://github.com/penpot/penpot.git
synced 2025-02-10 00:58:26 -05:00
Colors management (#24)
* Colors management * Minor indentation fixes. * Remove redundant naming. * Add missing block comment annotations. * Use consistently defrecord instead of reify. * Remove useless mapcat usage and simplify the related code. * Start using more optimistic updates on collection operations. * Remove println. * Remove ^:const metadata. * Remove neested let. * Replace when with if on sablono templates.
This commit is contained in:
parent
4c193d6026
commit
3f4ed6faa5
15 changed files with 456 additions and 182 deletions
|
@ -23,6 +23,23 @@
|
|||
h2 {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
.edit {
|
||||
padding: 5px 10px;
|
||||
background: $color-white;
|
||||
border: none;
|
||||
height: 100%;
|
||||
}
|
||||
.close {
|
||||
padding: 5px 10px;
|
||||
background: $color-white;
|
||||
cursor: pointer;
|
||||
svg {
|
||||
transform: rotate(45deg);
|
||||
fill: $color-gray;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.edition {
|
||||
|
|
158
src/uxbox/data/colors.cljs
Normal file
158
src/uxbox/data/colors.cljs
Normal file
|
@ -0,0 +1,158 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; 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>
|
||||
|
||||
(ns uxbox.data.colors
|
||||
(:require [clojure.set :as set]
|
||||
[beicon.core :as rx]
|
||||
[uuid.core :as uuid]
|
||||
[uxbox.rstore :as rs]
|
||||
[uxbox.state.colors :as stc]
|
||||
[uxbox.repo :as rp]))
|
||||
|
||||
;; --- Collections Fetched
|
||||
|
||||
(defrecord CollectionFetched [items]
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(reduce stc/assoc-collection state items)))
|
||||
|
||||
(defn collections-fetched
|
||||
[items]
|
||||
(CollectionFetched. items))
|
||||
|
||||
;; --- Fetch Collections
|
||||
|
||||
(defrecord FetchCollections []
|
||||
rs/WatchEvent
|
||||
(-apply-watch [_ state s]
|
||||
(->> (rp/req :fetch/color-collections)
|
||||
(rx/map :payload)
|
||||
(rx/map collections-fetched))))
|
||||
|
||||
(defn fetch-collections
|
||||
[]
|
||||
(FetchCollections.))
|
||||
|
||||
;; --- Collection Created
|
||||
|
||||
(defrecord CollectionCreated [item]
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(-> state
|
||||
(stc/assoc-collection item)
|
||||
(assoc-in [:dashboard :collection-id] (:id item))
|
||||
(assoc-in [:dashboard :collection-type] :own))))
|
||||
|
||||
(defn collection-created
|
||||
[item]
|
||||
(CollectionCreated. item))
|
||||
|
||||
;; --- Create Collection
|
||||
|
||||
(defrecord CreateCollection []
|
||||
rs/WatchEvent
|
||||
(-apply-watch [_ state s]
|
||||
(let [coll {:name "Unnamed collection"
|
||||
:id (uuid/random)}]
|
||||
(->> (rp/req :create/color-collection coll)
|
||||
(rx/map :payload)
|
||||
(rx/map collection-created)))))
|
||||
|
||||
(defn create-collection
|
||||
[]
|
||||
(CreateCollection.))
|
||||
|
||||
;; --- Collection Updated
|
||||
|
||||
(defrecord CollectionUpdated [item]
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(stc/assoc-collection state item)))
|
||||
|
||||
(defn collection-updated
|
||||
[item]
|
||||
(CollectionUpdated. item))
|
||||
|
||||
|
||||
;; --- Update Collection
|
||||
|
||||
(defrecord UpdateCollection [id]
|
||||
rs/WatchEvent
|
||||
(-apply-watch [_ state s]
|
||||
(let [item (get-in state [:colors-by-id id])]
|
||||
(->> (rp/req :update/color-collection item)
|
||||
(rx/map :payload)
|
||||
(rx/map collection-updated)))))
|
||||
|
||||
(defn update-collection
|
||||
[id]
|
||||
(UpdateCollection. id))
|
||||
|
||||
;; --- Rename Collection
|
||||
|
||||
(defrecord RenameCollection [id name]
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(assoc-in state [:colors-by-id id :name] name))
|
||||
|
||||
rs/WatchEvent
|
||||
(-apply-watch [_ state s]
|
||||
(rx/of (update-collection id))))
|
||||
|
||||
(defn rename-collection
|
||||
[item name]
|
||||
(RenameCollection. item name))
|
||||
|
||||
;; --- Delete Collection
|
||||
|
||||
(defrecord DeleteCollection [id]
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(stc/dissoc-collection state id))
|
||||
|
||||
rs/WatchEvent
|
||||
(-apply-watch [_ state s]
|
||||
(->> (rp/req :delete/color-collection id)
|
||||
(rx/ignore))))
|
||||
|
||||
(defn delete-collection
|
||||
[id]
|
||||
(DeleteCollection. id))
|
||||
|
||||
;; --- Replace Color
|
||||
|
||||
(defrecord ReplaceColor [id from to]
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(let [replacer #(-> (disj % from) (conj to))]
|
||||
(update-in state [:colors-by-id id :data] (fnil replacer #{}))))
|
||||
|
||||
rs/WatchEvent
|
||||
(-apply-watch [_ state s]
|
||||
(rx/of (update-collection id))))
|
||||
|
||||
(defn replace-color
|
||||
"Add or replace color in a collection."
|
||||
[{:keys [id from to] :as params}]
|
||||
(ReplaceColor. id from to))
|
||||
|
||||
;; --- Remove Color
|
||||
|
||||
(defrecord RemoveColors [id colors]
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(update-in state [:colors-by-id id :data]
|
||||
#(set/difference % colors)))
|
||||
|
||||
rs/WatchEvent
|
||||
(-apply-watch [_ state s]
|
||||
(rx/of (update-collection id))))
|
||||
|
||||
(defn remove-colors
|
||||
"Remove color in a collection."
|
||||
[id colors]
|
||||
(RemoveColors. id colors))
|
|
@ -14,6 +14,7 @@
|
|||
[uxbox.schema :as sc]
|
||||
[uxbox.repo :as rp]
|
||||
[uxbox.data.projects :as dp]
|
||||
[uxbox.data.colors :as dc]
|
||||
[uxbox.util.data :refer (deep-merge)]))
|
||||
|
||||
;; --- Events
|
||||
|
@ -35,13 +36,16 @@
|
|||
|
||||
rs/WatchEvent
|
||||
(-apply-watch [_ state s]
|
||||
(let [projects (seq (:projects-by-id state))]
|
||||
(let [projects (seq (:projects-by-id state))
|
||||
color-collections (seq (:colors-by-id state))]
|
||||
(rx/merge
|
||||
;; Load projects if needed
|
||||
(if projects
|
||||
(rx/empty)
|
||||
(rx/of (dp/fetch-projects)))
|
||||
|
||||
(rx/of (dc/fetch-collections))
|
||||
|
||||
(when (:loader state)
|
||||
(if projects
|
||||
(rx/of #(assoc % :loader false))
|
||||
|
@ -54,28 +58,6 @@
|
|||
[section]
|
||||
(InitializeDashboard. section))
|
||||
|
||||
|
||||
(defn set-project-ordering
|
||||
[order]
|
||||
(reify
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(assoc-in state [:dashboard :project-order] order))))
|
||||
|
||||
(defn set-project-filtering
|
||||
[term]
|
||||
(reify
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(assoc-in state [:dashboard :project-filter] term))))
|
||||
|
||||
(defn clear-project-filtering
|
||||
[]
|
||||
(reify
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(assoc-in state [:dashboard :project-filter] ""))))
|
||||
|
||||
(defn set-collection-type
|
||||
[type]
|
||||
{:pre [(contains? #{:builtin :own} type)]}
|
||||
|
@ -97,58 +79,3 @@
|
|||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(assoc-in state [:dashboard :collection-id] id))))
|
||||
|
||||
(defn mk-color-collection
|
||||
[]
|
||||
(reify
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(let [id (uuid/random)
|
||||
coll {:name "Unnamed collection"
|
||||
:id id :colors #{}}]
|
||||
(-> state
|
||||
(assoc-in [:colors-by-id id] coll)
|
||||
(assoc-in [:dashboard :collection-id] id)
|
||||
(assoc-in [:dashboard :collection-type] :own))))))
|
||||
|
||||
(defn rename-color-collection
|
||||
[id name]
|
||||
(reify
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(assoc-in state [:colors-by-id id :name] name))))
|
||||
|
||||
(defn delete-color-collection
|
||||
[id]
|
||||
(reify
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(let [state (update state :colors-by-id dissoc id)
|
||||
colls (sort-by :id (vals (:colors-by-id state)))]
|
||||
(assoc-in state [:dashboard :collection-id] (:id (first colls)))))))
|
||||
|
||||
(defn replace-color
|
||||
"Add or replace color in a collection."
|
||||
[{:keys [id from to] :as params}]
|
||||
(reify
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(if-let [colors (get-in state [:colors-by-id id :colors])]
|
||||
(as-> colors $
|
||||
(disj $ from)
|
||||
(conj $ to)
|
||||
(assoc-in state [:colors-by-id id :colors] $))
|
||||
state))))
|
||||
|
||||
(defn remove-color
|
||||
"Remove color in a collection."
|
||||
[{:keys [id color] :as params}]
|
||||
(reify
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(if-let [colors (get-in state [:colors-by-id id :colors])]
|
||||
(as-> colors $
|
||||
(disj $ color)
|
||||
(assoc-in state [:colors-by-id id :colors] $))
|
||||
state))))
|
||||
|
||||
|
|
|
@ -149,3 +149,23 @@
|
|||
projs
|
||||
(filter #(contains-term? (:name %) term) projs)))
|
||||
|
||||
(defn set-project-ordering
|
||||
[order]
|
||||
(reify
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(assoc-in state [:dashboard :project-order] order))))
|
||||
|
||||
(defn set-project-filtering
|
||||
[term]
|
||||
(reify
|
||||
rs/WatchEvent
|
||||
(-apply-watch [_ state s]
|
||||
(assoc-in state [:dashboard :project-filter] term))))
|
||||
|
||||
(defn clear-project-filtering
|
||||
[]
|
||||
(reify
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(assoc-in state [:dashboard :project-filter] ""))))
|
||||
|
|
|
@ -11,34 +11,34 @@
|
|||
[{:name "Generic 1"
|
||||
:id 1
|
||||
:builtin true
|
||||
:colors #{"#00f9ff"
|
||||
"#009fff"
|
||||
"#0078ff"
|
||||
"#005eff"
|
||||
"#0900ff"
|
||||
"#7502f1"
|
||||
"#ffe705"
|
||||
"#00ffab"
|
||||
"#f52105"}}
|
||||
:data #{"#00f9ff"
|
||||
"#009fff"
|
||||
"#0078ff"
|
||||
"#005eff"
|
||||
"#0900ff"
|
||||
"#7502f1"
|
||||
"#ffe705"
|
||||
"#00ffab"
|
||||
"#f52105"}}
|
||||
|
||||
{:name "Generic 2"
|
||||
:id 2
|
||||
:builtin true
|
||||
:colors #{"#20f9ff"
|
||||
"#209fff"
|
||||
"#2078ff"
|
||||
"#205eff"
|
||||
"#2900ff"
|
||||
"#3502f1"
|
||||
"#3fe705"
|
||||
"#30ffab"
|
||||
"#352105"
|
||||
"#209f20"
|
||||
"#207820"
|
||||
"#205e20"
|
||||
"#290020"
|
||||
"#350220"
|
||||
"#3fe720"
|
||||
"#30ff20"
|
||||
"#352120"
|
||||
"#352140"}}])
|
||||
:data #{"#20f9ff"
|
||||
"#209fff"
|
||||
"#2078ff"
|
||||
"#205eff"
|
||||
"#2900ff"
|
||||
"#3502f1"
|
||||
"#3fe705"
|
||||
"#30ffab"
|
||||
"#352105"
|
||||
"#209f20"
|
||||
"#207820"
|
||||
"#205e20"
|
||||
"#290020"
|
||||
"#350220"
|
||||
"#3fe720"
|
||||
"#30ff20"
|
||||
"#352120"
|
||||
"#352140"}}])
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
"ds.num-projects" ["No projects"
|
||||
"%s project"
|
||||
"%s projects"]
|
||||
"ds.num-colors" ["No colors"
|
||||
"%s color"
|
||||
"%s colors"]
|
||||
"ds.project-ordering" "Sort by"
|
||||
"ds.project-ordering.by-name" "name"
|
||||
"ds.project-ordering.by-last-update" "last update"
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
[uxbox.repo.users]
|
||||
[uxbox.repo.projects]
|
||||
[uxbox.repo.pages]
|
||||
[uxbox.repo.colors]
|
||||
[httpurr.status :as status]
|
||||
[beicon.core :as rx]))
|
||||
|
||||
|
|
60
src/uxbox/repo/colors.cljs
Normal file
60
src/uxbox/repo/colors.cljs
Normal file
|
@ -0,0 +1,60 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; 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) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.repo.colors
|
||||
"A main interface for access to remote resources."
|
||||
(:require [beicon.core :as rx]
|
||||
[uxbox.repo.core :refer (request url send!)]
|
||||
[uxbox.state :as ust]
|
||||
[uxbox.util.transit :as t]))
|
||||
|
||||
(defn- decode-color-collection
|
||||
[{:keys [data] :as coll}]
|
||||
(merge coll
|
||||
(when data {:data (t/decode data)})))
|
||||
|
||||
(defn- decode-payload
|
||||
[{:keys [payload] :as rsp}]
|
||||
(if (sequential? payload)
|
||||
(assoc rsp :payload (mapv decode-color-collection payload))
|
||||
(assoc rsp :payload (decode-color-collection payload))))
|
||||
|
||||
(defmethod request :fetch/color-collection
|
||||
[_ id]
|
||||
(let [params {:url (str url "/library/color-collections/" id)
|
||||
:method :get}]
|
||||
(->> (send! params)
|
||||
(rx/map decode-payload))))
|
||||
|
||||
(defmethod request :fetch/color-collections
|
||||
[_]
|
||||
(let [params {:url (str url "/library/color-collections")
|
||||
:method :get}]
|
||||
(->> (send! params)
|
||||
(rx/map decode-payload))))
|
||||
|
||||
(defmethod request :delete/color-collection
|
||||
[_ id]
|
||||
(let [url (str url "/library/color-collections/" id)]
|
||||
(send! {:url url :method :delete})))
|
||||
|
||||
(defmethod request :create/color-collection
|
||||
[_ {:keys [data] :as body}]
|
||||
(let [body (assoc body :data (t/encode data))
|
||||
params {:url (str url "/library/color-collections")
|
||||
:method :post
|
||||
:body body}]
|
||||
(->> (send! params)
|
||||
(rx/map decode-payload))))
|
||||
|
||||
(defmethod request :update/color-collection
|
||||
[_ {:keys [id data] :as body}]
|
||||
(let [body (assoc body :data (t/encode data))
|
||||
params {:url (str url "/library/color-collections/" id)
|
||||
:method :put
|
||||
:body body}]
|
||||
(->> (send! params)
|
||||
(rx/map decode-payload))))
|
22
src/uxbox/state/colors.cljs
Normal file
22
src/uxbox/state/colors.cljs
Normal file
|
@ -0,0 +1,22 @@
|
|||
(ns uxbox.state.colors
|
||||
"A collection of functions for manage dashboard data insinde the state.")
|
||||
|
||||
(defn assoc-collection
|
||||
"A reduce function for assoc the color collection
|
||||
to the state map."
|
||||
[state coll]
|
||||
(let [id (:id coll)]
|
||||
(assoc-in state [:colors-by-id id] coll)))
|
||||
|
||||
(defn dissoc-collection
|
||||
"A reduce function for dissoc the color collection
|
||||
to the state map."
|
||||
[state id]
|
||||
(update state :colors-by-id dissoc id))
|
||||
|
||||
(defn select-first-collection
|
||||
"A reduce function for select the first color collection
|
||||
to the state map."
|
||||
[state]
|
||||
(let [colls (sort-by :id (vals (:colors-by-id state)))]
|
||||
(assoc-in state [:dashboard :collection-id] (:id (first colls)))))
|
|
@ -16,6 +16,7 @@
|
|||
[uxbox.schema :as sc]
|
||||
[uxbox.library :as library]
|
||||
[uxbox.data.dashboard :as dd]
|
||||
[uxbox.data.colors :as dc]
|
||||
[uxbox.data.lightbox :as udl]
|
||||
[uxbox.ui.icons :as i]
|
||||
[uxbox.ui.forms :as form]
|
||||
|
@ -23,17 +24,18 @@
|
|||
[uxbox.ui.colorpicker :refer (colorpicker)]
|
||||
[uxbox.ui.mixins :as mx]
|
||||
[uxbox.ui.dashboard.header :refer (header)]
|
||||
[uxbox.ui.keyboard :as k]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.lens :as ul]
|
||||
[uxbox.util.color :refer (hex->rgb)]))
|
||||
|
||||
;; --- Lenses
|
||||
|
||||
(def ^:const ^:private dashboard-l
|
||||
(def ^:private dashboard-l
|
||||
(-> (l/key :dashboard)
|
||||
(l/focus-atom st/state)))
|
||||
|
||||
(def ^:const ^:private collections-by-id-l
|
||||
(def ^:private collections-by-id-l
|
||||
(-> (comp (l/key :colors-by-id)
|
||||
(ul/merge library/+color-collections-by-id+))
|
||||
(l/focus-atom st/state)))
|
||||
|
@ -47,31 +49,48 @@
|
|||
|
||||
(defn page-title-render
|
||||
[own coll]
|
||||
(letfn [(on-title-edited [e]
|
||||
(let [content (dom/event->inner-text e)
|
||||
collid (:id coll)]
|
||||
(rs/emit! (dd/rename-color-collection collid content))))
|
||||
(on-delete [e]
|
||||
(rs/emit! (dd/delete-color-collection (:id coll))))]
|
||||
(let [dashboard (rum/react dashboard-l)
|
||||
own? (:builtin coll false)]
|
||||
(let [local (:rum/local own)
|
||||
dashboard (rum/react dashboard-l)
|
||||
own? (:builtin coll false)]
|
||||
(letfn [(on-title-save [e]
|
||||
(rs/emit! (dc/rename-collection (:id coll) (:coll-name @local)))
|
||||
(swap! local assoc :edit false))
|
||||
(on-title-edited [e]
|
||||
(cond
|
||||
(k/esc? e) (swap! local assoc :edit false)
|
||||
(k/enter? e) (on-title-save e)
|
||||
:else (let [content (dom/event->inner-text e)]
|
||||
(swap! local assoc :coll-name content))))
|
||||
(on-title-edit [e]
|
||||
(swap! local assoc :edit true :coll-name (:name coll)))
|
||||
(on-delete [e]
|
||||
(rs/emit! (dc/delete-collection (:id coll))))]
|
||||
(html
|
||||
[:div.dashboard-title {}
|
||||
[:h2 {}
|
||||
[:span (tr "ds.library-title")]
|
||||
[:span {:content-editable ""
|
||||
:on-key-up on-title-edited}
|
||||
(:name coll)]]
|
||||
(if (:edit @local)
|
||||
[:div.dashboard-title-field
|
||||
[:span.edit
|
||||
{:content-editable ""
|
||||
:on-key-up on-title-edited}
|
||||
(:name coll)]
|
||||
[:span.close
|
||||
{:on-click #(swap! local assoc :edit false)}
|
||||
i/close]]
|
||||
[:span.dashboard-title-field
|
||||
(:name coll)])]
|
||||
(if (and (not own?) coll)
|
||||
[:div.edition {}
|
||||
#_[:span i/pencil]
|
||||
[:div.edition
|
||||
(if (:edit @local)
|
||||
[:span {:on-click on-title-save} i/save]
|
||||
[:span {:on-click on-title-edit} i/pencil])
|
||||
[:span {:on-click on-delete} i/trash]])]))))
|
||||
|
||||
(def ^:const ^:private page-title
|
||||
(def ^:private page-title
|
||||
(mx/component
|
||||
{:render page-title-render
|
||||
:name "page-title"
|
||||
:mixins [mx/static rum/reactive]}))
|
||||
:mixins [(rum/local {}) mx/static rum/reactive]}))
|
||||
|
||||
;; --- Nav
|
||||
|
||||
|
@ -97,13 +116,13 @@
|
|||
:on-click #(rs/emit! (dd/set-collection-type :own))}
|
||||
"YOUR LIBRARIES"]]
|
||||
[:ul.library-elements
|
||||
(when own?
|
||||
(if own?
|
||||
[:li
|
||||
[:a.btn-primary
|
||||
{:on-click #(rs/emit! (dd/mk-color-collection))}
|
||||
{:on-click #(rs/emit! (dc/create-collection))}
|
||||
"+ New library"]])
|
||||
(for [props collections
|
||||
:let [num (count (:colors props))]]
|
||||
:let [num (count (:data props))]]
|
||||
[:li {:key (str (:id props))
|
||||
:on-click #(rs/emit! (dd/set-collection (:id props)))
|
||||
:class-name (when (= (:id props) collid) "current")}
|
||||
|
@ -111,7 +130,7 @@
|
|||
[:span.element-subtitle
|
||||
(tr "ds.num-elements" (t/c num))]])]]])))
|
||||
|
||||
(def ^:const ^:private nav
|
||||
(def ^:private nav
|
||||
(mx/component
|
||||
{:render nav-render
|
||||
:name "nav"
|
||||
|
@ -121,42 +140,82 @@
|
|||
|
||||
(defn grid-render
|
||||
[own]
|
||||
(let [dashboard (rum/react dashboard-l)
|
||||
(let [local (:rum/local own)
|
||||
dashboard (rum/react dashboard-l)
|
||||
coll-type (:collection-type dashboard)
|
||||
coll-id (:collection-id dashboard)
|
||||
own? (= coll-type :own)
|
||||
coll (rum/react (focus-collection coll-id))
|
||||
edit-cb #(udl/open! :color-form {:coll coll :color %})
|
||||
remove-cb #(rs/emit! (dd/remove-color {:id (:id coll) :color %}))]
|
||||
toggle-color-check (fn [color]
|
||||
(swap! local update :selected #(if (% color) (disj % color) (conj % color))))
|
||||
delete-selected #(rs/emit! (dc/remove-colors (:id coll) (:selected @local)))]
|
||||
(when coll
|
||||
(html
|
||||
[:section.dashboard-grid.library
|
||||
(page-title coll)
|
||||
[:div.dashboard-grid-content
|
||||
[:div.dashboard-grid-row
|
||||
(when own?
|
||||
(if own?
|
||||
[:div.grid-item.small-item.add-project
|
||||
{:on-click #(udl/open! :color-form {:coll coll})}
|
||||
[:span "+ New color"]])
|
||||
(for [color (remove nil? (:colors coll))
|
||||
(for [color (remove nil? (:data coll))
|
||||
:let [color-rgb (hex->rgb color)]]
|
||||
[:div.grid-item.small-item.project-th {:key color}
|
||||
[:div.grid-item.small-item.project-th
|
||||
{:key color :on-click #(when (k/shift? %) (toggle-color-check color))}
|
||||
[:span.color-swatch {:style {:background-color color}}]
|
||||
[:div.input-checkbox.check-primary
|
||||
[:input {:type "checkbox"
|
||||
:id color
|
||||
:on-click #(toggle-color-check color)
|
||||
:checked ((:selected @local) color)}]
|
||||
[:label {:for color}]]
|
||||
[:span.color-data color]
|
||||
[:span.color-data (apply str "RGB " (interpose ", " color-rgb))]
|
||||
(if own?
|
||||
[:div.project-th-actions
|
||||
[:div.project-th-icon.edit
|
||||
{:on-click #(edit-cb color)} i/pencil]
|
||||
[:div.project-th-icon.delete
|
||||
{:on-click #(remove-cb color)}
|
||||
i/trash]])])]]]))))
|
||||
[:span.color-data (apply str "RGB " (interpose ", " color-rgb))]])]]
|
||||
|
||||
(def ^:const ^:private grid
|
||||
(when (not (empty? (:selected @local)))
|
||||
;; MULTISELECT OPTIONS BAR
|
||||
[:div.multiselect-bar
|
||||
(if own?
|
||||
[:div.multiselect-nav
|
||||
[:span.move-item.tooltip.tooltip-top
|
||||
{:alt "Move to"}
|
||||
i/organize]
|
||||
[:span.delete.tooltip.tooltip-top
|
||||
{:alt "Delete" :on-click delete-selected}
|
||||
i/trash]]
|
||||
[:div.multiselect-nav
|
||||
[:span.move-item.tooltip.tooltip-top
|
||||
{:alt "Copy to"}
|
||||
i/organize]])])]))))
|
||||
|
||||
(def ^:private grid
|
||||
(mx/component
|
||||
{:render grid-render
|
||||
:name "grid"
|
||||
:mixins [mx/static rum/reactive]}))
|
||||
:mixins [(rum/local {:selected #{}})
|
||||
mx/static
|
||||
rum/reactive]}))
|
||||
|
||||
;; --- Menu
|
||||
|
||||
(defn menu-render
|
||||
[]
|
||||
(let [dashboard (rum/react dashboard-l)
|
||||
coll-id (:collection-id dashboard)
|
||||
coll (rum/react (focus-collection coll-id))
|
||||
ccount (count (:data coll)) ]
|
||||
(html
|
||||
[:section.dashboard-bar.library-gap
|
||||
[:div.dashboard-info
|
||||
[:span.dashboard-colors (tr "ds.num-colors" (t/c ccount))]]])))
|
||||
|
||||
(def menu
|
||||
(mx/component
|
||||
{:render menu-render
|
||||
:name "menu"
|
||||
:mixins [rum/reactive mx/static]}))
|
||||
|
||||
|
||||
;; --- Colors Page
|
||||
|
||||
|
@ -167,6 +226,7 @@
|
|||
(header)
|
||||
[:section.dashboard-content
|
||||
(nav)
|
||||
(menu)
|
||||
(grid)]]))
|
||||
|
||||
(defn colors-page-will-mount
|
||||
|
@ -192,40 +252,36 @@
|
|||
(defn- color-lightbox-render
|
||||
[own {:keys [coll color]}]
|
||||
(html
|
||||
[:p "TODO"]))
|
||||
;; (let [local (:rum/local own)]
|
||||
;; (letfn [(submit [e]
|
||||
;; (if-let [errors (sc/validate +color-form-schema+ @local)]
|
||||
;; (swap! local assoc :errors errors)
|
||||
;; (let [params {:id (:id coll) :from color
|
||||
;; :to (:hex @local)}]
|
||||
;; (rs/emit! (dd/replace-color params))
|
||||
;; (lightbox/close!))))
|
||||
;; (on-change [e]
|
||||
;; (let [value (str/trim (dom/event->value e))]
|
||||
;; (swap! local assoc :hex value)))]
|
||||
;; (html
|
||||
;; [:div.lightbox-body
|
||||
;; [:h3 "New color"]
|
||||
;; [:form
|
||||
;; [:div.row-flex
|
||||
;; [:input#color-hex.input-text
|
||||
;; {:placeholder "#"
|
||||
;; :class (form/error-class local :hex)
|
||||
;; :on-change on-change
|
||||
;; :value (or (:hex @local) color "")
|
||||
;; :type "text"}]]
|
||||
;; [:div.row-flex.center.color-picker-default
|
||||
;; (colorpicker
|
||||
;; :value (or (:hex @local) color "#00ccff")
|
||||
;; :on-change #(swap! local assoc :hex %))]
|
||||
(let [local (:rum/local own)]
|
||||
(letfn [(submit [e]
|
||||
(let [params {:id (:id coll) :from color :to (:hex @local)}]
|
||||
(rs/emit! (dc/replace-color params))
|
||||
(udl/close!)))
|
||||
(on-change [e]
|
||||
(let [value (str/trim (dom/event->value e))]
|
||||
(swap! local assoc :hex value)))]
|
||||
(html
|
||||
[:div.lightbox-body
|
||||
[:h3 "New color"]
|
||||
[:form
|
||||
[:div.row-flex
|
||||
[:input#color-hex.input-text
|
||||
{:placeholder "#"
|
||||
:class (form/error-class local :hex)
|
||||
:on-change on-change
|
||||
:value (or (:hex @local) color "")
|
||||
:type "text"}]]
|
||||
[:div.row-flex.center.color-picker-default
|
||||
(colorpicker
|
||||
:value (or (:hex @local) color "#00ccff")
|
||||
:on-change #(swap! local assoc :hex %))]
|
||||
|
||||
;; [:input#project-btn.btn-primary
|
||||
;; {:value "+ Add color"
|
||||
;; :on-click submit
|
||||
;; :type "button"}]]
|
||||
;; [:a.close {:on-click #(lightbox/close!)}
|
||||
;; i/close]]))))
|
||||
[:input#project-btn.btn-primary
|
||||
{:value "+ Add color"
|
||||
:on-click submit
|
||||
:type "button"}]]
|
||||
[:a.close {:on-click #(udl/close!)}
|
||||
i/close]])))))
|
||||
|
||||
(def color-lightbox
|
||||
(mx/component
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
(defn sort-widget-render
|
||||
[]
|
||||
(let [ordering (rum/react project-ordering-l)
|
||||
on-change #(rs/emit! (dd/set-project-ordering
|
||||
on-change #(rs/emit! (dp/set-project-ordering
|
||||
(keyword (.-value (.-target %)))))]
|
||||
(html
|
||||
[:div
|
||||
|
@ -109,10 +109,10 @@
|
|||
(letfn [(on-term-change [event]
|
||||
(-> (dom/get-target event)
|
||||
(dom/get-value)
|
||||
(dd/set-project-filtering)
|
||||
(dp/set-project-filtering)
|
||||
(rs/emit!)))
|
||||
(on-clear [event]
|
||||
(rs/emit! (dd/clear-project-filtering)))]
|
||||
(rs/emit! (dp/clear-project-filtering)))]
|
||||
(html
|
||||
[:form.dashboard-search
|
||||
[:input.input-text
|
||||
|
|
|
@ -668,3 +668,15 @@
|
|||
{:id "loader-line"
|
||||
:d
|
||||
"M134.482 157.147v25l518.57.008.002-25-518.572-.008z"}]]]))
|
||||
|
||||
(def save
|
||||
(html
|
||||
[:svg
|
||||
{:viewBox "0 0 48 48"
|
||||
:height "48"
|
||||
:width "48"
|
||||
:id "save"}
|
||||
[:path
|
||||
{:style {:stroke nil}
|
||||
:d
|
||||
"M34 6h-24c-2.21 0-4 1.79-4 4v28c0 2.21 1.79 4 4 4h28c2.21 0 4-1.79 4-4v-24l-8-8zm-10 32c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6zm6-20h-20v-8h20v8z"}]]))
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
[uxbox.ui.icons :as i]
|
||||
[uxbox.ui.mixins :as mx]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.data.dashboard :as dd]
|
||||
[uxbox.ui.settings.profile :as profile]
|
||||
[uxbox.ui.settings.password :as password]
|
||||
[uxbox.ui.settings.notifications :as notifications]
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
[uxbox.ui.icons :as i]
|
||||
[uxbox.ui.mixins :as mx]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.data.dashboard :as dd]
|
||||
[uxbox.ui.settings.header :refer (header)]))
|
||||
|
||||
(defn notifications-page-render
|
||||
|
|
|
@ -77,7 +77,7 @@
|
|||
[:div.btn-palette.create i/close]]]
|
||||
[:span.left-arrow i/arrow-slide]
|
||||
[:div.color-palette-content
|
||||
(for [hex-color (:colors collection)
|
||||
(for [hex-color (:data collection)
|
||||
:let [rgb-vec (hex->rgb hex-color)
|
||||
rgb-color (apply str "" (interpose ", " rgb-vec))]]
|
||||
[:div.color-cell {:key (str hex-color)
|
||||
|
|
Loading…
Add table
Reference in a new issue