mirror of
https://github.com/penpot/penpot.git
synced 2025-05-17 06:06:10 +02: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 {
|
h2 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 100%;
|
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 {
|
.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.schema :as sc]
|
||||||
[uxbox.repo :as rp]
|
[uxbox.repo :as rp]
|
||||||
[uxbox.data.projects :as dp]
|
[uxbox.data.projects :as dp]
|
||||||
|
[uxbox.data.colors :as dc]
|
||||||
[uxbox.util.data :refer (deep-merge)]))
|
[uxbox.util.data :refer (deep-merge)]))
|
||||||
|
|
||||||
;; --- Events
|
;; --- Events
|
||||||
|
@ -35,13 +36,16 @@
|
||||||
|
|
||||||
rs/WatchEvent
|
rs/WatchEvent
|
||||||
(-apply-watch [_ state s]
|
(-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
|
(rx/merge
|
||||||
;; Load projects if needed
|
;; Load projects if needed
|
||||||
(if projects
|
(if projects
|
||||||
(rx/empty)
|
(rx/empty)
|
||||||
(rx/of (dp/fetch-projects)))
|
(rx/of (dp/fetch-projects)))
|
||||||
|
|
||||||
|
(rx/of (dc/fetch-collections))
|
||||||
|
|
||||||
(when (:loader state)
|
(when (:loader state)
|
||||||
(if projects
|
(if projects
|
||||||
(rx/of #(assoc % :loader false))
|
(rx/of #(assoc % :loader false))
|
||||||
|
@ -54,28 +58,6 @@
|
||||||
[section]
|
[section]
|
||||||
(InitializeDashboard. 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
|
(defn set-collection-type
|
||||||
[type]
|
[type]
|
||||||
{:pre [(contains? #{:builtin :own} type)]}
|
{:pre [(contains? #{:builtin :own} type)]}
|
||||||
|
@ -97,58 +79,3 @@
|
||||||
rs/UpdateEvent
|
rs/UpdateEvent
|
||||||
(-apply-update [_ state]
|
(-apply-update [_ state]
|
||||||
(assoc-in state [:dashboard :collection-id] id))))
|
(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
|
projs
|
||||||
(filter #(contains-term? (:name %) term) 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"
|
[{:name "Generic 1"
|
||||||
:id 1
|
:id 1
|
||||||
:builtin true
|
:builtin true
|
||||||
:colors #{"#00f9ff"
|
:data #{"#00f9ff"
|
||||||
"#009fff"
|
"#009fff"
|
||||||
"#0078ff"
|
"#0078ff"
|
||||||
"#005eff"
|
"#005eff"
|
||||||
"#0900ff"
|
"#0900ff"
|
||||||
"#7502f1"
|
"#7502f1"
|
||||||
"#ffe705"
|
"#ffe705"
|
||||||
"#00ffab"
|
"#00ffab"
|
||||||
"#f52105"}}
|
"#f52105"}}
|
||||||
|
|
||||||
{:name "Generic 2"
|
{:name "Generic 2"
|
||||||
:id 2
|
:id 2
|
||||||
:builtin true
|
:builtin true
|
||||||
:colors #{"#20f9ff"
|
:data #{"#20f9ff"
|
||||||
"#209fff"
|
"#209fff"
|
||||||
"#2078ff"
|
"#2078ff"
|
||||||
"#205eff"
|
"#205eff"
|
||||||
"#2900ff"
|
"#2900ff"
|
||||||
"#3502f1"
|
"#3502f1"
|
||||||
"#3fe705"
|
"#3fe705"
|
||||||
"#30ffab"
|
"#30ffab"
|
||||||
"#352105"
|
"#352105"
|
||||||
"#209f20"
|
"#209f20"
|
||||||
"#207820"
|
"#207820"
|
||||||
"#205e20"
|
"#205e20"
|
||||||
"#290020"
|
"#290020"
|
||||||
"#350220"
|
"#350220"
|
||||||
"#3fe720"
|
"#3fe720"
|
||||||
"#30ff20"
|
"#30ff20"
|
||||||
"#352120"
|
"#352120"
|
||||||
"#352140"}}])
|
"#352140"}}])
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
"ds.num-projects" ["No projects"
|
"ds.num-projects" ["No projects"
|
||||||
"%s project"
|
"%s project"
|
||||||
"%s projects"]
|
"%s projects"]
|
||||||
|
"ds.num-colors" ["No colors"
|
||||||
|
"%s color"
|
||||||
|
"%s colors"]
|
||||||
"ds.project-ordering" "Sort by"
|
"ds.project-ordering" "Sort by"
|
||||||
"ds.project-ordering.by-name" "name"
|
"ds.project-ordering.by-name" "name"
|
||||||
"ds.project-ordering.by-last-update" "last update"
|
"ds.project-ordering.by-last-update" "last update"
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
[uxbox.repo.users]
|
[uxbox.repo.users]
|
||||||
[uxbox.repo.projects]
|
[uxbox.repo.projects]
|
||||||
[uxbox.repo.pages]
|
[uxbox.repo.pages]
|
||||||
|
[uxbox.repo.colors]
|
||||||
[httpurr.status :as status]
|
[httpurr.status :as status]
|
||||||
[beicon.core :as rx]))
|
[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.schema :as sc]
|
||||||
[uxbox.library :as library]
|
[uxbox.library :as library]
|
||||||
[uxbox.data.dashboard :as dd]
|
[uxbox.data.dashboard :as dd]
|
||||||
|
[uxbox.data.colors :as dc]
|
||||||
[uxbox.data.lightbox :as udl]
|
[uxbox.data.lightbox :as udl]
|
||||||
[uxbox.ui.icons :as i]
|
[uxbox.ui.icons :as i]
|
||||||
[uxbox.ui.forms :as form]
|
[uxbox.ui.forms :as form]
|
||||||
|
@ -23,17 +24,18 @@
|
||||||
[uxbox.ui.colorpicker :refer (colorpicker)]
|
[uxbox.ui.colorpicker :refer (colorpicker)]
|
||||||
[uxbox.ui.mixins :as mx]
|
[uxbox.ui.mixins :as mx]
|
||||||
[uxbox.ui.dashboard.header :refer (header)]
|
[uxbox.ui.dashboard.header :refer (header)]
|
||||||
|
[uxbox.ui.keyboard :as k]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.util.lens :as ul]
|
[uxbox.util.lens :as ul]
|
||||||
[uxbox.util.color :refer (hex->rgb)]))
|
[uxbox.util.color :refer (hex->rgb)]))
|
||||||
|
|
||||||
;; --- Lenses
|
;; --- Lenses
|
||||||
|
|
||||||
(def ^:const ^:private dashboard-l
|
(def ^:private dashboard-l
|
||||||
(-> (l/key :dashboard)
|
(-> (l/key :dashboard)
|
||||||
(l/focus-atom st/state)))
|
(l/focus-atom st/state)))
|
||||||
|
|
||||||
(def ^:const ^:private collections-by-id-l
|
(def ^:private collections-by-id-l
|
||||||
(-> (comp (l/key :colors-by-id)
|
(-> (comp (l/key :colors-by-id)
|
||||||
(ul/merge library/+color-collections-by-id+))
|
(ul/merge library/+color-collections-by-id+))
|
||||||
(l/focus-atom st/state)))
|
(l/focus-atom st/state)))
|
||||||
|
@ -47,31 +49,48 @@
|
||||||
|
|
||||||
(defn page-title-render
|
(defn page-title-render
|
||||||
[own coll]
|
[own coll]
|
||||||
(letfn [(on-title-edited [e]
|
(let [local (:rum/local own)
|
||||||
(let [content (dom/event->inner-text e)
|
dashboard (rum/react dashboard-l)
|
||||||
collid (:id coll)]
|
own? (:builtin coll false)]
|
||||||
(rs/emit! (dd/rename-color-collection collid content))))
|
(letfn [(on-title-save [e]
|
||||||
(on-delete [e]
|
(rs/emit! (dc/rename-collection (:id coll) (:coll-name @local)))
|
||||||
(rs/emit! (dd/delete-color-collection (:id coll))))]
|
(swap! local assoc :edit false))
|
||||||
(let [dashboard (rum/react dashboard-l)
|
(on-title-edited [e]
|
||||||
own? (:builtin coll false)]
|
(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
|
(html
|
||||||
[:div.dashboard-title {}
|
[:div.dashboard-title {}
|
||||||
[:h2 {}
|
[:h2 {}
|
||||||
[:span (tr "ds.library-title")]
|
(if (:edit @local)
|
||||||
[:span {:content-editable ""
|
[:div.dashboard-title-field
|
||||||
:on-key-up on-title-edited}
|
[:span.edit
|
||||||
(:name coll)]]
|
{: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)
|
(if (and (not own?) coll)
|
||||||
[:div.edition {}
|
[:div.edition
|
||||||
#_[:span i/pencil]
|
(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]])]))))
|
[:span {:on-click on-delete} i/trash]])]))))
|
||||||
|
|
||||||
(def ^:const ^:private page-title
|
(def ^:private page-title
|
||||||
(mx/component
|
(mx/component
|
||||||
{:render page-title-render
|
{:render page-title-render
|
||||||
:name "page-title"
|
:name "page-title"
|
||||||
:mixins [mx/static rum/reactive]}))
|
:mixins [(rum/local {}) mx/static rum/reactive]}))
|
||||||
|
|
||||||
;; --- Nav
|
;; --- Nav
|
||||||
|
|
||||||
|
@ -97,13 +116,13 @@
|
||||||
:on-click #(rs/emit! (dd/set-collection-type :own))}
|
:on-click #(rs/emit! (dd/set-collection-type :own))}
|
||||||
"YOUR LIBRARIES"]]
|
"YOUR LIBRARIES"]]
|
||||||
[:ul.library-elements
|
[:ul.library-elements
|
||||||
(when own?
|
(if own?
|
||||||
[:li
|
[:li
|
||||||
[:a.btn-primary
|
[:a.btn-primary
|
||||||
{:on-click #(rs/emit! (dd/mk-color-collection))}
|
{:on-click #(rs/emit! (dc/create-collection))}
|
||||||
"+ New library"]])
|
"+ New library"]])
|
||||||
(for [props collections
|
(for [props collections
|
||||||
:let [num (count (:colors props))]]
|
:let [num (count (:data props))]]
|
||||||
[:li {:key (str (:id props))
|
[:li {:key (str (:id props))
|
||||||
:on-click #(rs/emit! (dd/set-collection (:id props)))
|
:on-click #(rs/emit! (dd/set-collection (:id props)))
|
||||||
:class-name (when (= (:id props) collid) "current")}
|
:class-name (when (= (:id props) collid) "current")}
|
||||||
|
@ -111,7 +130,7 @@
|
||||||
[:span.element-subtitle
|
[:span.element-subtitle
|
||||||
(tr "ds.num-elements" (t/c num))]])]]])))
|
(tr "ds.num-elements" (t/c num))]])]]])))
|
||||||
|
|
||||||
(def ^:const ^:private nav
|
(def ^:private nav
|
||||||
(mx/component
|
(mx/component
|
||||||
{:render nav-render
|
{:render nav-render
|
||||||
:name "nav"
|
:name "nav"
|
||||||
|
@ -121,42 +140,82 @@
|
||||||
|
|
||||||
(defn grid-render
|
(defn grid-render
|
||||||
[own]
|
[own]
|
||||||
(let [dashboard (rum/react dashboard-l)
|
(let [local (:rum/local own)
|
||||||
|
dashboard (rum/react dashboard-l)
|
||||||
coll-type (:collection-type dashboard)
|
coll-type (:collection-type dashboard)
|
||||||
coll-id (:collection-id dashboard)
|
coll-id (:collection-id dashboard)
|
||||||
own? (= coll-type :own)
|
own? (= coll-type :own)
|
||||||
coll (rum/react (focus-collection coll-id))
|
coll (rum/react (focus-collection coll-id))
|
||||||
edit-cb #(udl/open! :color-form {:coll coll :color %})
|
toggle-color-check (fn [color]
|
||||||
remove-cb #(rs/emit! (dd/remove-color {:id (:id coll) :color %}))]
|
(swap! local update :selected #(if (% color) (disj % color) (conj % color))))
|
||||||
|
delete-selected #(rs/emit! (dc/remove-colors (:id coll) (:selected @local)))]
|
||||||
(when coll
|
(when coll
|
||||||
(html
|
(html
|
||||||
[:section.dashboard-grid.library
|
[:section.dashboard-grid.library
|
||||||
(page-title coll)
|
(page-title coll)
|
||||||
[:div.dashboard-grid-content
|
[:div.dashboard-grid-content
|
||||||
[:div.dashboard-grid-row
|
[:div.dashboard-grid-row
|
||||||
(when own?
|
(if own?
|
||||||
[:div.grid-item.small-item.add-project
|
[:div.grid-item.small-item.add-project
|
||||||
{:on-click #(udl/open! :color-form {:coll coll})}
|
{:on-click #(udl/open! :color-form {:coll coll})}
|
||||||
[:span "+ New color"]])
|
[:span "+ New color"]])
|
||||||
(for [color (remove nil? (:colors coll))
|
(for [color (remove nil? (:data coll))
|
||||||
:let [color-rgb (hex->rgb color)]]
|
: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}}]
|
[: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 color]
|
||||||
[:span.color-data (apply str "RGB " (interpose ", " color-rgb))]
|
[: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]])])]]]))))
|
|
||||||
|
|
||||||
(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
|
(mx/component
|
||||||
{:render grid-render
|
{:render grid-render
|
||||||
:name "grid"
|
: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
|
;; --- Colors Page
|
||||||
|
|
||||||
|
@ -167,6 +226,7 @@
|
||||||
(header)
|
(header)
|
||||||
[:section.dashboard-content
|
[:section.dashboard-content
|
||||||
(nav)
|
(nav)
|
||||||
|
(menu)
|
||||||
(grid)]]))
|
(grid)]]))
|
||||||
|
|
||||||
(defn colors-page-will-mount
|
(defn colors-page-will-mount
|
||||||
|
@ -192,40 +252,36 @@
|
||||||
(defn- color-lightbox-render
|
(defn- color-lightbox-render
|
||||||
[own {:keys [coll color]}]
|
[own {:keys [coll color]}]
|
||||||
(html
|
(html
|
||||||
[:p "TODO"]))
|
(let [local (:rum/local own)]
|
||||||
;; (let [local (:rum/local own)]
|
(letfn [(submit [e]
|
||||||
;; (letfn [(submit [e]
|
(let [params {:id (:id coll) :from color :to (:hex @local)}]
|
||||||
;; (if-let [errors (sc/validate +color-form-schema+ @local)]
|
(rs/emit! (dc/replace-color params))
|
||||||
;; (swap! local assoc :errors errors)
|
(udl/close!)))
|
||||||
;; (let [params {:id (:id coll) :from color
|
(on-change [e]
|
||||||
;; :to (:hex @local)}]
|
(let [value (str/trim (dom/event->value e))]
|
||||||
;; (rs/emit! (dd/replace-color params))
|
(swap! local assoc :hex value)))]
|
||||||
;; (lightbox/close!))))
|
(html
|
||||||
;; (on-change [e]
|
[:div.lightbox-body
|
||||||
;; (let [value (str/trim (dom/event->value e))]
|
[:h3 "New color"]
|
||||||
;; (swap! local assoc :hex value)))]
|
[:form
|
||||||
;; (html
|
[:div.row-flex
|
||||||
;; [:div.lightbox-body
|
[:input#color-hex.input-text
|
||||||
;; [:h3 "New color"]
|
{:placeholder "#"
|
||||||
;; [:form
|
:class (form/error-class local :hex)
|
||||||
;; [:div.row-flex
|
:on-change on-change
|
||||||
;; [:input#color-hex.input-text
|
:value (or (:hex @local) color "")
|
||||||
;; {:placeholder "#"
|
:type "text"}]]
|
||||||
;; :class (form/error-class local :hex)
|
[:div.row-flex.center.color-picker-default
|
||||||
;; :on-change on-change
|
(colorpicker
|
||||||
;; :value (or (:hex @local) color "")
|
:value (or (:hex @local) color "#00ccff")
|
||||||
;; :type "text"}]]
|
:on-change #(swap! local assoc :hex %))]
|
||||||
;; [: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
|
[:input#project-btn.btn-primary
|
||||||
;; {:value "+ Add color"
|
{:value "+ Add color"
|
||||||
;; :on-click submit
|
:on-click submit
|
||||||
;; :type "button"}]]
|
:type "button"}]]
|
||||||
;; [:a.close {:on-click #(lightbox/close!)}
|
[:a.close {:on-click #(udl/close!)}
|
||||||
;; i/close]]))))
|
i/close]])))))
|
||||||
|
|
||||||
(def color-lightbox
|
(def color-lightbox
|
||||||
(mx/component
|
(mx/component
|
||||||
|
|
|
@ -79,7 +79,7 @@
|
||||||
(defn sort-widget-render
|
(defn sort-widget-render
|
||||||
[]
|
[]
|
||||||
(let [ordering (rum/react project-ordering-l)
|
(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 %)))))]
|
(keyword (.-value (.-target %)))))]
|
||||||
(html
|
(html
|
||||||
[:div
|
[:div
|
||||||
|
@ -109,10 +109,10 @@
|
||||||
(letfn [(on-term-change [event]
|
(letfn [(on-term-change [event]
|
||||||
(-> (dom/get-target event)
|
(-> (dom/get-target event)
|
||||||
(dom/get-value)
|
(dom/get-value)
|
||||||
(dd/set-project-filtering)
|
(dp/set-project-filtering)
|
||||||
(rs/emit!)))
|
(rs/emit!)))
|
||||||
(on-clear [event]
|
(on-clear [event]
|
||||||
(rs/emit! (dd/clear-project-filtering)))]
|
(rs/emit! (dp/clear-project-filtering)))]
|
||||||
(html
|
(html
|
||||||
[:form.dashboard-search
|
[:form.dashboard-search
|
||||||
[:input.input-text
|
[:input.input-text
|
||||||
|
|
|
@ -668,3 +668,15 @@
|
||||||
{:id "loader-line"
|
{:id "loader-line"
|
||||||
:d
|
:d
|
||||||
"M134.482 157.147v25l518.57.008.002-25-518.572-.008z"}]]]))
|
"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.icons :as i]
|
||||||
[uxbox.ui.mixins :as mx]
|
[uxbox.ui.mixins :as mx]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.data.dashboard :as dd]
|
|
||||||
[uxbox.ui.settings.profile :as profile]
|
[uxbox.ui.settings.profile :as profile]
|
||||||
[uxbox.ui.settings.password :as password]
|
[uxbox.ui.settings.password :as password]
|
||||||
[uxbox.ui.settings.notifications :as notifications]
|
[uxbox.ui.settings.notifications :as notifications]
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
[uxbox.ui.icons :as i]
|
[uxbox.ui.icons :as i]
|
||||||
[uxbox.ui.mixins :as mx]
|
[uxbox.ui.mixins :as mx]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.data.dashboard :as dd]
|
|
||||||
[uxbox.ui.settings.header :refer (header)]))
|
[uxbox.ui.settings.header :refer (header)]))
|
||||||
|
|
||||||
(defn notifications-page-render
|
(defn notifications-page-render
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
[:div.btn-palette.create i/close]]]
|
[:div.btn-palette.create i/close]]]
|
||||||
[:span.left-arrow i/arrow-slide]
|
[:span.left-arrow i/arrow-slide]
|
||||||
[:div.color-palette-content
|
[:div.color-palette-content
|
||||||
(for [hex-color (:colors collection)
|
(for [hex-color (:data collection)
|
||||||
:let [rgb-vec (hex->rgb hex-color)
|
:let [rgb-vec (hex->rgb hex-color)
|
||||||
rgb-color (apply str "" (interpose ", " rgb-vec))]]
|
rgb-color (apply str "" (interpose ", " rgb-vec))]]
|
||||||
[:div.color-cell {:key (str hex-color)
|
[:div.color-cell {:key (str hex-color)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue