0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-23 15:26:29 -05:00

🐸 integration with backend data

This commit is contained in:
alonso.torres 2020-03-24 14:31:15 +01:00
parent 4102dca55c
commit 57d633b1d2
17 changed files with 301 additions and 116 deletions

View file

@ -50,7 +50,7 @@
(sq/defquery ::color-libraries
[{:keys [profile-id team-id]}]
(db/with-atomic [conn db/pool]
(teams/check-edition-permissions! conn profile-id team-id)
(teams/check-read-permissions! conn profile-id team-id)
(db/query conn [sql:libraries team-id])))
@ -66,7 +66,7 @@
[{:keys [profile-id id]}]
(db/with-atomic [conn db/pool]
(p/let [lib (retrieve-library conn id)]
(teams/check-edition-permissions! conn profile-id (:team-id lib))
(teams/check-read-permissions! conn profile-id (:team-id lib))
lib)))
(def ^:private sql:single-library
@ -94,7 +94,7 @@
[{:keys [profile-id library-id] :as params}]
(db/with-atomic [conn db/pool]
(p/let [lib (retrieve-library conn library-id)]
(teams/check-edition-permissions! conn profile-id (:team-id lib))
(teams/check-read-permissions! conn profile-id (:team-id lib))
(retrieve-colors conn library-id))))
(def ^:private sql:colors
@ -123,7 +123,7 @@
[{:keys [profile-id id] :as params}]
(db/with-atomic [conn db/pool]
(p/let [color (retrieve-color conn id)]
(teams/check-edition-permissions! conn profile-id (:team-id color))
(teams/check-read-permissions! conn profile-id (:team-id color))
color)))
(def ^:private sql:single-color

View file

@ -56,8 +56,10 @@
(sq/defquery ::icon-libraries
[{:keys [profile-id team-id]}]
(println profile-id)
(println team-id)
(db/with-atomic [conn db/pool]
(teams/check-edition-permissions! conn profile-id team-id)
(teams/check-read-permissions! conn profile-id team-id)
(db/query conn [sql:libraries team-id])))
@ -73,7 +75,7 @@
[{:keys [profile-id id]}]
(db/with-atomic [conn db/pool]
(p/let [lib (retrieve-library conn id)]
(teams/check-edition-permissions! conn profile-id (:team-id lib))
(teams/check-read-permissions! conn profile-id (:team-id lib))
lib)))
(def ^:private sql:single-library
@ -101,7 +103,7 @@
[{:keys [profile-id library-id] :as params}]
(db/with-atomic [conn db/pool]
(p/let [lib (retrieve-library conn library-id)]
(teams/check-edition-permissions! conn profile-id (:team-id lib))
(teams/check-read-permissions! conn profile-id (:team-id lib))
(-> (retrieve-icons conn library-id)
(p/then' (fn [rows] (mapv decode-row rows)))))))
@ -131,7 +133,7 @@
[{:keys [profile-id id] :as params}]
(db/with-atomic [conn db/pool]
(p/let [icon (retrieve-icon conn id)]
(teams/check-edition-permissions! conn profile-id (:team-id icon))
(teams/check-read-permissions! conn profile-id (:team-id icon))
(decode-row icon))))
(def ^:private sql:single-icon

View file

@ -40,7 +40,7 @@
(sq/defquery ::image-libraries
[{:keys [profile-id team-id]}]
(db/with-atomic [conn db/pool]
(teams/check-edition-permissions! conn profile-id team-id)
(teams/check-read-permissions! conn profile-id team-id)
(db/query conn [sql:libraries team-id])))
@ -55,7 +55,7 @@
[{:keys [profile-id id]}]
(db/with-atomic [conn db/pool]
(p/let [lib (retrieve-library conn id)]
(teams/check-edition-permissions! conn profile-id (:team-id lib))
(teams/check-read-permissions! conn profile-id (:team-id lib))
lib)))
(def ^:private sql:single-library
@ -86,7 +86,7 @@
[{:keys [profile-id library-id] :as params}]
(db/with-atomic [conn db/pool]
(p/let [lib (retrieve-library conn library-id)]
(teams/check-edition-permissions! conn profile-id (:team-id lib))
(teams/check-read-permissions! conn profile-id (:team-id lib))
(-> (retrieve-images conn library-id)
(p/then' (fn [rows]
(->> rows
@ -120,7 +120,7 @@
[{:keys [profile-id id] :as params}]
(db/with-atomic [conn db/pool]
(p/let [img (retrieve-image conn id)]
(teams/check-edition-permissions! conn profile-id (:team-id img))
(teams/check-read-permissions! conn profile-id (:team-id img))
(-> img
(images/resolve-urls :path :uri)
(images/resolve-urls :thumb-path :thumb-uri)))))

View file

@ -47,16 +47,37 @@
where team_id = $2
order by modified_at desc")
(def ^:private sql:project-by-id
"select p.*
from project as p
inner join project_profile_rel as ppr on (ppr.project_id = p.id)
where ppr.profile_id = $1
and p.id = $2
and p.deleted_at is null
and (ppr.is_admin = true or
ppr.is_owner = true or
ppr.can_edit = true)")
(s/def ::team-id ::us/uuid)
(s/def ::profile-id ::us/uuid)
(s/def ::project-id ::us/uuid)
(s/def ::projects-by-team
(s/keys :req-un [::profile-id ::team-id]))
(s/def ::project-by-id
(s/keys :req-un [::profile-id ::project-id]))
(defn projects-by-team [profile-id team-id]
(db/query db/pool [sql:projects profile-id team-id]))
(defn project-by-id [profile-id project-id]
(db/query-one db/pool [sql:project-by-id profile-id project-id]))
(sq/defquery ::projects-by-team
[{:keys [profile-id team-id]}]
(projects-by-team profile-id team-id))
(sq/defquery ::project-by-id
[{:keys [profile-id project-id]}]
(project-by-id profile-id project-id))

View file

@ -40,5 +40,14 @@
(ex/raise :type :validation
:code :not-authorized))))))
(defn check-read-permissions!
[conn profile-id team-id]
(-> (db/query-one conn [sql:team-permissions profile-id team-id])
(p/then' (fn [row]
(when-not (or (:can-edit row)
(:is-admin row)
(:is-owner row)
;; We can read global-project owned items
(= team-id #uuid "00000000-0000-0000-0000-000000000000"))
(ex/raise :type :validation
:code :not-authorized))))))

View file

@ -24,7 +24,7 @@
#"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$")
(def uuid-rx
#"^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$")
#"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$")
;; --- Conformers

View file

@ -11,21 +11,23 @@
background-color: $color-gray-50;
border-top: 1px solid $color-gray-60;
display: flex;
padding: 1rem;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
z-index: 11;
.right-arrow,
.left-arrow {
cursor: pointer;
& .right-arrow,
& .left-arrow {
cursor: pointer;
svg {
fill: $color-gray-light;
height: 30px;
height: 1rem;
margin: 0 .5rem;
width: 30px;
width: 1rem;
}
&:hover {
svg {
fill: $color-gray-darker;
@ -35,12 +37,21 @@
display: none;
}
}
.left-arrow {
transform: rotate(180deg);
transform: rotate(180deg);
padding-top: 10px;
}
&.fade-out-down {
@include animation(0,.5s,fadeOutDown);
}
&.left-sidebar-open {
left: 280px;
width: calc(100% - 280px);
}
}
.color-palette-actions {
@ -48,7 +59,12 @@
flex-direction: column;
flex-shrink: 0;
margin-right: .5rem;
width: 200px;
border: 1px solid #1F1F1F;
align-self: stretch;
padding: 0.5rem;
justify-content: center;
.color-palette-buttons {
align-items: center;
display: flex;
@ -56,6 +72,15 @@
}
}
.color-palette-actions-button {
cursor: pointer;
& svg {
width: 1rem;
height: 1rem;
fill: #AFB2BF;
}
}
.btn-palette {
align-items: center;
border: 2px solid $color-gray-lighter;
@ -90,6 +115,7 @@
display: flex;
overflow: hidden;
width: 100%;
padding: 0.25rem;
}
.color-palette-inside {
@ -106,15 +132,14 @@
display: flex;
flex-direction: column;
flex-shrink: 0;
margin: 0 10px;
position: relative;
flex-basis: 66px;
.color {
background-color: $color-gray-lighter;
border: 2px solid $color-gray-60;
border-radius: 50%;
flex-shrink: 0;
margin-bottom: .4rem;
padding: 1.5rem;
}
.color-text {

View file

@ -1,3 +1,35 @@
.libraries-window-bar {
display: grid;
grid-template-columns: repeat(2, 50%);
padding: 0.5rem;
align-items: center;
}
.libraries-window-bar-title {
color: #F0F0F0;
}
.libraries-window-bar-options {
font-size: 12px;
display: flex;
justify-content: space-between;
padding: 0 0.5rem;
button {
border: none;
padding: 0;
margin: 0;
background: transparent;
cursor: pointer;
}
& svg {
width: 0.5rem;
height: 0.5rem;
fill: #F0F0F0;
transform: rotate(90deg);
}
}
.library-tab {
display: flex;
flex-direction: column;
@ -10,7 +42,6 @@
flex-direction: row;
flex-wrap: wrap;
padding: 0.25rem;
height: 100%;
overflow-y: scroll;
.icons-tab & {
@ -80,8 +111,9 @@
width: 90%;
padding: 0.5rem;
box-sizing: border-box;
color: white;
color: #AFB2BF;
font-size: 12px;
border: 1px solid #7c7c7c;
}
.library-tab-libraries-item {

View file

@ -14,30 +14,33 @@
[uxbox.util.router :as r]
[uxbox.util.uuid :as uuid]))
(defn initialize-workspace-libraries []
())
;; Retrieve libraries
(declare retrieve-libraries-result)
(defn retrieve-libraries
[type team-id]
(s/assert ::us/uuid team-id)
(let [method (case type
:icons :icon-libraries
:images :image-libraries
:palettes :color-libraries)]
(ptk/reify ::retrieve-libraries
ptk/WatchEvent
(watch [_ state stream]
(->> (rp/query! method {:team-id team-id})
(rx/map (partial retrieve-libraries-result type)))))))
([type] (retrieve-libraries type uuid/zero))
([type team-id]
(s/assert ::us/uuid team-id)
(let [method (case type
:icons :icon-libraries
:images :image-libraries
:palettes :color-libraries)]
(ptk/reify ::retrieve-libraries
ptk/WatchEvent
(watch [_ state stream]
(->> (rp/query! method {:team-id team-id})
(rx/map (partial retrieve-libraries-result type team-id))))))))
(defn retrieve-libraries-result [type result]
(defn retrieve-libraries-result [type team-id result]
(ptk/reify ::retrieve-libraries-result
ptk/UpdateEvent
(update [_ state]
(-> state
(assoc-in [:library type] result)))))
(assoc-in [:library type team-id] result)))))
;; Retrieve library data
@ -78,23 +81,23 @@
:images :create-image-library
:palettes :create-color-library)]
(->> (rp/mutation! method {:team-id team-id
:name name})
(rx/map (partial create-library-result type)))))))
:name name})
(rx/map (partial create-library-result type team-id)))))))
(defn create-library-result
[type result]
[type team-id result]
(ptk/reify ::create-library-result
ptk/UpdateEvent
(update [_ state]
(-> state
(update-in [:library type] #(into [result] %))))))
(update-in [:library type team-id] #(into [result] %))))))
;; Rename library
(declare rename-library-result)
(defn rename-library
[type library-id name]
[type team-id library-id name]
(ptk/reify ::rename-library
ptk/WatchEvent
(watch [_ state stream]
@ -104,10 +107,10 @@
:palettes :rename-color-library)]
(->> (rp/mutation! method {:id library-id
:name name})
(rx/map #(rename-library-result type library-id name)))))))
(rx/map #(rename-library-result type team-id library-id name)))))))
(defn rename-library-result
[type library-id name]
[type team-id library-id name]
(ptk/reify ::rename-library-result
ptk/UpdateEvent
(update [_ state]
@ -118,14 +121,14 @@
(update-fn [libraries] (map change-name libraries))]
(-> state
(update-in [:library type] update-fn))))))
(update-in [:library type team-id] update-fn))))))
;; Delete library
(declare delete-library-result)
(defn delete-library
[type library-id]
[type team-id library-id]
(ptk/reify ::delete-library
ptk/UpdateEvent
(update [_ state]
@ -139,17 +142,17 @@
:images :delete-image-library
:palettes :delete-color-library)]
(->> (rp/mutation! method {:id library-id})
(rx/map #(delete-library-result type library-id)))))))
(rx/map #(delete-library-result type team-id library-id)))))))
(defn delete-library-result
[type library-id]
[type team-id library-id]
(ptk/reify ::create-library-result
ptk/UpdateEvent
(update [_ state]
(let [update-fn (fn [libraries]
(filterv #(not= library-id (:id %)) libraries))]
(-> state
(update-in [:library type] update-fn))))))
(update-in [:library type team-id] update-fn))))))
;; Delete library item

View file

@ -66,6 +66,7 @@
(declare fetch-users)
(declare fetch-images)
(declare fetch-project)
(declare handle-who)
(declare handle-pointer-update)
(declare handle-pointer-send)
@ -270,7 +271,7 @@
(declare initialize-alignment)
#_(def default-layout #{:sitemap :layers :element-options :rules})
(def default-layout #{:libraries :rules})
(def default-layout #{:libraries :rules :colorpalette})
(def workspace-default
@ -296,7 +297,8 @@
(defn initialize
"Initialize the workspace state."
[file-id page-id]
[project-id file-id page-id]
(us/verify ::us/uuid project-id)
(us/verify ::us/uuid file-id)
(us/verify ::us/uuid page-id)
(ptk/reify ::initialize
@ -307,9 +309,11 @@
(rx/merge
(rx/of (fetch-file-with-users file-id)
(fetch-pages file-id)
(fetch-images file-id))
(fetch-images file-id)
(fetch-project project-id))
(->> (rx/zip (rx/filter (ptk/type? ::pages-fetched) stream)
(rx/filter (ptk/type? ::file-fetched) stream))
(rx/filter (ptk/type? ::file-fetched) stream)
(rx/filter (ptk/type? ::project-fetched) stream))
(rx/take 1)
(rx/do (fn [_]
(uxbox.util.timers/schedule 500 #(reset! st/loader false))))
@ -357,7 +361,8 @@
(rx/of (initialize-page-persistence page-id)))))
(defn finalize
[file-id page-id]
[project-id file-id page-id]
(us/verify ::us/uuid project-id)
(us/verify ::us/uuid file-id)
(us/verify ::us/uuid page-id)
(ptk/reify ::finalize
@ -495,6 +500,7 @@
(s/def ::data ::cp/data)
(s/def ::file ::dd/file)
(s/def ::project ::dd/project)
(s/def ::page
(s/keys :req-un [::id
::name
@ -548,6 +554,25 @@
state
users))))
;; --- Fetch Project data
(declare project-fetched)
(defn fetch-project
[id]
(us/verify ::us/uuid id)
(ptk/reify ::fetch-project
ptk/WatchEvent
(watch [_ state stream]
(->> (rp/query :project-by-id {:project-id id})
(rx/map project-fetched)))))
(defn project-fetched
[project]
(us/verify ::project project)
(ptk/reify ::project-fetched
ptk/UpdateEvent
(update [_ state]
(assoc state :workspace-project project))))
;; --- Fetch Pages
@ -1931,7 +1956,8 @@
(ptk/reify ::go-to-page
ptk/WatchEvent
(watch [_ state stream]
(let [file-id (get-in state [:workspace-page :file-id])
(let [project-id (get-in state [:workspace-project :id])
file-id (get-in state [:workspace-page :file-id])
path-params {:file-id file-id}
query-params {:page-id page-id}]
(rx/of (rt/nav :workspace path-params query-params))))))
@ -1942,8 +1968,9 @@
(ptk/reify ::go-to-file
ptk/WatchEvent
(watch [_ state stream]
(let [page-ids (get-in state [:files file-id :pages])
path-params {:file-id file-id}
(let [project-id (get-in state [:workspace-project :id])
page-ids (get-in state [:files file-id :pages])
path-params {:project-id project-id :file-id file-id}
query-params {:page-id (first page-ids)}]
(rx/of (rt/nav :workspace path-params query-params))))))

View file

@ -73,7 +73,7 @@
]]]
["/workspace/:file-id" :workspace]])
["/workspace/:project-id/:file-id" :workspace]])
(mf/defc app-error
[{:keys [error] :as props}]
@ -119,9 +119,11 @@
(mf/element dashboard #js {:route route})
:workspace
(let [file-id (uuid (get-in route [:params :path :file-id]))
(let [project-id (uuid (get-in route [:params :path :project-id]))
file-id (uuid (get-in route [:params :path :file-id]))
page-id (uuid (get-in route [:params :query :page-id]))]
[:& workspace/workspace {:file-id file-id
[:& workspace/workspace {:project-id project-id
:file-id file-id
:page-id page-id
:key file-id}])
nil)))

View file

@ -15,7 +15,7 @@
handle-select (fn [tab]
(let [id (-> tab .-props .-id)]
(swap! state assoc :selected id)
(on-change-tab id)))]
(when on-change-tab (on-change-tab id))))]
[:div.tab-container
[:div.tab-container-tabs
(for [tab children]

View file

@ -41,8 +41,9 @@
:edition false})
locale (i18n/use-locale)
on-navigate #(st/emit! (rt/nav :workspace
{:file-id (:id file)}
{:page-id (first (:pages file))}))
{:project-id (:project-id file)
:file-id (:id file)}
{:page-id (first (:pages file))}))
delete-fn #(st/emit! nil (dsh/delete-file (:id file)))
on-delete #(do
(dom/stop-propagation %)
@ -75,7 +76,7 @@
[:h3 (:name file)])
[:& grid-item-metadata {:modified-at (:modified-at file)}]]
[:div.project-th-actions {:class (classnames
:force-display (:menu-open @local))}
:force-display (:menu-open @local))}
;; [:div.project-th-icon.pages
;; i/page
;; #_[:span (:total-pages project)]]

View file

@ -122,7 +122,7 @@
(dlib/retrieve-libraries :icons (:id item))
(st/emit! (rt/nav path {:team-id team-id :library-id (:id item)}))))}
[:& editable-label {:value (:name item)
:on-change #(st/emit! (dlib/rename-library section library-id %))}]
:on-change #(st/emit! (dlib/rename-library section team-id library-id %))}]
])]]))
(mf/defc library-top-menu
@ -136,7 +136,7 @@
[:& editable-label {:edit (:editing-name @state)
:on-change #(do
(stop-editing)
(st/emit! (dlib/rename-library section library-id %)))
(st/emit! (dlib/rename-library section team-id library-id %)))
:on-cancel #(swap! state assoc :editing-name false)
:class-name "library-top-menu-current-element-name"
:value (:name selected)}]
@ -155,7 +155,7 @@
(modal/show!
confirm-dialog
{:on-accept #(do
(st/emit! (dlib/delete-library section library-id))
(st/emit! (dlib/delete-library section team-id library-id))
(st/emit! (rt/nav path {:team-id team-id})))
:message "Are you sure you want to delete this library?"
:accept-text "Delete"})))]]}]]
@ -301,8 +301,8 @@
:message "Are you sure you want to delete this color?"
:accept-text "Delete"}))]]}]]])))
(defn libraries-ref [section]
(-> (comp (l/key :library) (l/key section))
(defn libraries-ref [section team-id]
(-> (comp (l/key :library) (l/key section) (l/key team-id))
(l/derive st/state)))
(defn selected-items-ref [library-id]
@ -316,7 +316,7 @@
(mf/defc library-page
[{:keys [team-id library-id section]}]
(let [state (mf/use-state {:selected #{}})
libraries (mf/deref (libraries-ref section))
libraries (mf/deref (libraries-ref section team-id))
items (mf/deref (selected-items-ref library-id))
last-deleted-library (mf/deref last-deleted-library-ref)
selected-library (first (filter #(= (:id %) library-id) libraries))]

View file

@ -67,7 +67,7 @@
:no-tool-bar-left (not left-sidebar?))]
[:*
(when (:colorpalette layout)
[:& colorpalette])
[:& colorpalette {:left-sidebar? left-sidebar?}])
[:main.main-content
[:& context-menu {}]
@ -99,13 +99,13 @@
(mf/defc workspace
[{:keys [file-id page-id] :as props}]
[{:keys [project-id file-id page-id] :as props}]
(-> (mf/deps file-id page-id)
(mf/use-effect
(fn []
(st/emit! (dw/initialize file-id page-id))
#(st/emit! (dw/finalize file-id page-id)))))
(st/emit! (dw/initialize project-id file-id page-id))
#(st/emit! (dw/finalize project-id file-id page-id)))))
(-> (mf/deps file-id)
(mf/use-effect

View file

@ -42,10 +42,10 @@
:on-click select-color}
[:span.color {:style {:background color}}]
[:span.color-text color]
[:span.color-text rgb-color]]))
#_[:span.color-text rgb-color]]))
(mf/defc palette
[{:keys [colls] :as props}]
[{:keys [colls left-sidebar?] :as props}]
(let [local (mf/use-state {})
colls (->> colls
(filter :id)
@ -97,9 +97,10 @@
(mf/use-effect nil after-render)
[:div.color-palette
[:div.color-palette {:class (when left-sidebar? "left-sidebar-open")}
[:div.color-palette-actions
[:select.input-select {:on-change select-coll
[:div.color-palette-actions-button i/actions]
#_[:select.input-select {:on-change select-coll
:default-value (pr-str (:id coll))}
(for [item colls]
[:option {:key (:id item) :value (pr-str (:id item))}
@ -116,14 +117,17 @@
:style {:position "relative"
:width (str (* 86 (count (:colors coll))) "px")
:right (str (* 86 offset) "px")}}
(for [color (:colors coll)]
[:& palette-item {:color color :key color}])]]
#_(for [color (:colors coll)]
[:& palette-item {:color color :key color}])
(for [color (range 0 20)]
[:& palette-item {:color "#FFFF00" :key color}])]]
[:span.right-arrow {:on-click on-right-arrow-click} i/arrow-slide]
[:span.close-palette {:on-click close} i/close]]))
#_[:span.close-palette {:on-click close} i/close]]))
(mf/defc colorpalette
[props]
[{:keys [left-sidebar?]}]
(let [colls (mf/deref collections-iref)]
#_(mf/use-effect #(st/emit! (udc/fetch-collections)))
[:& palette {:colls (vals colls)}]))
[:& palette {:left-sidebar? left-sidebar?
:colls (vals colls)}]))

View file

@ -10,6 +10,7 @@
(ns uxbox.main.ui.workspace.sidebar.libraries
(:require
[lentes.core :as l]
[cuerdas.core :as str]
[rumext.alpha :as mf]
[uxbox.common.data :as d]
[uxbox.builtins.icons :as i]
@ -22,40 +23,98 @@
[uxbox.util.dom :as dom]
[uxbox.util.uuid :as uuid]
[uxbox.util.i18n :as i18n :refer [t]]
[uxbox.main.ui.components.tab-container :refer [tab-container tab-element]]))
[uxbox.main.ui.components.tab-container :refer [tab-container tab-element]]
[uxbox.main.data.library :as dlib]))
(mf/defc library-tab []
[:div.library-tab.icons-tab
[:select.library-tab-libraries
[:option.library-tab-libraries-item "Material design"]
[:option.library-tab-libraries-item "Icon library 1"]
[:option.library-tab-libraries-item "Icon library 2"]]
[:div.library-tab-content
(for [_ (range 0 200)]
[:div.library-tab-element
i/trash
[:span.library-tab-element-name "my-icon.svg"]])]])
(def project-ref
(-> (l/key :workspace-project)
(l/derive st/state)))
(mf/defc images-tab []
[:div.library-tab.images-tab
[:select.library-tab-libraries
[:option.library-tab-libraries-item "Material design"]
[:option.library-tab-libraries-item "Icon library 1"]
[:option.library-tab-libraries-item "Icon library 2"]]
[:div.library-tab-content
(for [_ (range 0 200)]
[:div.library-tab-element
[:img {:src "https://www.placecage.com/c/200/300"}]
[:span.library-tab-element-name "my-icon.svg"]])]])
(defn libraries-ref [section]
(-> (comp (l/key :library) (l/key section))
(l/derive st/state)))
(defn selected-items-ref [library-id]
(-> (comp (l/key :library) (l/key :selected-items) (l/key library-id))
(l/derive st/state)))
(mf/defc icons-tab [{:keys [libraries]}]
(when (and libraries (-> libraries count (> 0)))
(let [state (mf/use-state {:selected-library (-> libraries first :id)})]
(mf/use-effect {:fn (fn []
(st/emit! (dlib/retrieve-library-data :icons (:selected-library @state))))
:deps (mf/deps (:selected-library @state))})
[:div.library-tab.icons-tab
[:select.input-select.library-tab-libraries
{:on-change #(swap! state assoc :selected-library (-> % dom/get-target dom/get-value))}
(for [library libraries]
[:option.library-tab-libraries-item
{:key (:id library)
:value (:id library)}
(:name library)])]
[:div.library-tab-content
(let [items (mf/deref (selected-items-ref (:selected-library @state)))]
(for [item items]
[:div.library-tab-element
{:key (:id item)}
[:svg {:view-box (->> item :metadata :view-box (str/join " "))
:width (-> item :metadata :width)
:height (-> item :metadat :height)
:dangerouslySetInnerHTML {:__html (:content item)}}]
[:span.library-tab-element-name (:name item)]]))]])))
(mf/defc images-tab [{:keys [libraries]}]
(when (and libraries (-> libraries count (> 0)))
(let [state (mf/use-state {:selected-library (-> libraries first :id)})]
(mf/use-effect {:fn (fn []
(st/emit! (dlib/retrieve-library-data :images (:selected-library @state))))
:deps (mf/deps (:selected-library @state))})
[:div.library-tab.images-tab
[:select.input-select.library-tab-libraries
{:on-change #(swap! state assoc :selected-library (-> % dom/get-target dom/get-value))}
(for [library libraries]
[:option.library-tab-libraries-item
{:key (:id library)
:value (:id library)}
(:name library)])]
[:div.library-tab-content
(let [items (mf/deref (selected-items-ref (:selected-library @state)))]
(for [item items]
[:div.library-tab-element
{:key (:id item)}
[:img {:src (:thumb-uri item)}]
[:span.library-tab-element-name (:name item)]]))]])))
(mf/defc libraries-toolbox
[]
(let [locale (i18n/use-locale)]
[{:keys [key]}]
(let [team-id (-> project-ref mf/deref :team-id)
locale (i18n/use-locale)]
(mf/use-effect {:fn (fn []
(st/emit! (dlib/retrieve-libraries :icons))
(st/emit! (dlib/retrieve-libraries :images)))
:deps (mf/deps key)})
(mf/use-effect {:fn (fn []
(when team-id
(do
(st/emit! (dlib/retrieve-libraries :icons team-id))
(st/emit! (dlib/retrieve-libraries :images team-id)))))
:deps (mf/deps team-id)})
[:div#libraries.tool-window
[:div.tool-window-bar
[:div "Libraries"]
[:div "All libraries"]]
[:div.libraries-window-bar
[:div.libraries-window-bar-title "Libraries"]
[:div.libraries-window-bar-options
"All libraries"
[:button {:type "button"}
i/arrow-slide]]]
[:div.tool-window-content
[:& tab-container {}
[:& tab-element {:id :icons :title "Icons"} [:& library-tab]]
[:& tab-element {:id :images :title "Images"} [:& images-tab]]]]]))
[:& tab-element
{:id :icons :title "Icons"}
[:& icons-tab {:libraries (-> (libraries-ref :icons) mf/deref vals flatten) }]]
[:& tab-element
{:id :images :title "Images"}
[:& images-tab {:libraries (-> (libraries-ref :images) mf/deref vals flatten)}]]]]]))