🐸 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 (sq/defquery ::color-libraries
[{:keys [profile-id team-id]}] [{:keys [profile-id team-id]}]
(db/with-atomic [conn db/pool] (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]))) (db/query conn [sql:libraries team-id])))
@ -66,7 +66,7 @@
[{:keys [profile-id id]}] [{:keys [profile-id id]}]
(db/with-atomic [conn db/pool] (db/with-atomic [conn db/pool]
(p/let [lib (retrieve-library conn id)] (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))) lib)))
(def ^:private sql:single-library (def ^:private sql:single-library
@ -94,7 +94,7 @@
[{:keys [profile-id library-id] :as params}] [{:keys [profile-id library-id] :as params}]
(db/with-atomic [conn db/pool] (db/with-atomic [conn db/pool]
(p/let [lib (retrieve-library conn library-id)] (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)))) (retrieve-colors conn library-id))))
(def ^:private sql:colors (def ^:private sql:colors
@ -123,7 +123,7 @@
[{:keys [profile-id id] :as params}] [{:keys [profile-id id] :as params}]
(db/with-atomic [conn db/pool] (db/with-atomic [conn db/pool]
(p/let [color (retrieve-color conn id)] (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))) color)))
(def ^:private sql:single-color (def ^:private sql:single-color

View file

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

View file

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

View file

@ -47,16 +47,37 @@
where team_id = $2 where team_id = $2
order by modified_at desc") 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 ::team-id ::us/uuid)
(s/def ::profile-id ::us/uuid) (s/def ::profile-id ::us/uuid)
(s/def ::project-id ::us/uuid)
(s/def ::projects-by-team (s/def ::projects-by-team
(s/keys :req-un [::profile-id ::team-id])) (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] (defn projects-by-team [profile-id team-id]
(db/query db/pool [sql:projects 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 (sq/defquery ::projects-by-team
[{:keys [profile-id team-id]}] [{:keys [profile-id team-id]}]
(projects-by-team 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 (ex/raise :type :validation
:code :not-authorized)))))) :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-.]+$") #"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$")
(def uuid-rx (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 ;; --- Conformers

View file

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

View file

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

View file

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

View file

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

View file

@ -41,7 +41,8 @@
:edition false}) :edition false})
locale (i18n/use-locale) locale (i18n/use-locale)
on-navigate #(st/emit! (rt/nav :workspace on-navigate #(st/emit! (rt/nav :workspace
{:file-id (:id file)} {:project-id (:project-id file)
:file-id (:id file)}
{:page-id (first (:pages file))})) {:page-id (first (:pages file))}))
delete-fn #(st/emit! nil (dsh/delete-file (:id file))) delete-fn #(st/emit! nil (dsh/delete-file (:id file)))
on-delete #(do on-delete #(do

View file

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

View file

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

View file

@ -42,10 +42,10 @@
:on-click select-color} :on-click select-color}
[:span.color {:style {:background color}}] [:span.color {:style {:background color}}]
[:span.color-text color] [:span.color-text color]
[:span.color-text rgb-color]])) #_[:span.color-text rgb-color]]))
(mf/defc palette (mf/defc palette
[{:keys [colls] :as props}] [{:keys [colls left-sidebar?] :as props}]
(let [local (mf/use-state {}) (let [local (mf/use-state {})
colls (->> colls colls (->> colls
(filter :id) (filter :id)
@ -97,9 +97,10 @@
(mf/use-effect nil after-render) (mf/use-effect nil after-render)
[:div.color-palette [:div.color-palette {:class (when left-sidebar? "left-sidebar-open")}
[:div.color-palette-actions [: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))} :default-value (pr-str (:id coll))}
(for [item colls] (for [item colls]
[:option {:key (:id item) :value (pr-str (:id item))} [:option {:key (:id item) :value (pr-str (:id item))}
@ -116,14 +117,17 @@
:style {:position "relative" :style {:position "relative"
:width (str (* 86 (count (:colors coll))) "px") :width (str (* 86 (count (:colors coll))) "px")
:right (str (* 86 offset) "px")}} :right (str (* 86 offset) "px")}}
(for [color (:colors coll)] #_(for [color (:colors coll)]
[:& palette-item {:color color :key color}])]] [:& 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.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 (mf/defc colorpalette
[props] [{:keys [left-sidebar?]}]
(let [colls (mf/deref collections-iref)] (let [colls (mf/deref collections-iref)]
#_(mf/use-effect #(st/emit! (udc/fetch-collections))) #_(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 (ns uxbox.main.ui.workspace.sidebar.libraries
(:require (:require
[lentes.core :as l] [lentes.core :as l]
[cuerdas.core :as str]
[rumext.alpha :as mf] [rumext.alpha :as mf]
[uxbox.common.data :as d] [uxbox.common.data :as d]
[uxbox.builtins.icons :as i] [uxbox.builtins.icons :as i]
@ -22,40 +23,98 @@
[uxbox.util.dom :as dom] [uxbox.util.dom :as dom]
[uxbox.util.uuid :as uuid] [uxbox.util.uuid :as uuid]
[uxbox.util.i18n :as i18n :refer [t]] [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]))
(def project-ref
(-> (l/key :workspace-project)
(l/derive st/state)))
(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))})
(mf/defc library-tab []
[:div.library-tab.icons-tab [:div.library-tab.icons-tab
[:select.library-tab-libraries [:select.input-select.library-tab-libraries
[:option.library-tab-libraries-item "Material design"] {:on-change #(swap! state assoc :selected-library (-> % dom/get-target dom/get-value))}
[:option.library-tab-libraries-item "Icon library 1"] (for [library libraries]
[:option.library-tab-libraries-item "Icon library 2"]] [:option.library-tab-libraries-item
{:key (:id library)
:value (:id library)}
(:name library)])]
[:div.library-tab-content [:div.library-tab-content
(for [_ (range 0 200)] (let [items (mf/deref (selected-items-ref (:selected-library @state)))]
(for [item items]
[:div.library-tab-element [:div.library-tab-element
i/trash {:key (:id item)}
[:span.library-tab-element-name "my-icon.svg"]])]]) [: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))})
(mf/defc images-tab []
[:div.library-tab.images-tab [:div.library-tab.images-tab
[:select.library-tab-libraries [:select.input-select.library-tab-libraries
[:option.library-tab-libraries-item "Material design"] {:on-change #(swap! state assoc :selected-library (-> % dom/get-target dom/get-value))}
[:option.library-tab-libraries-item "Icon library 1"] (for [library libraries]
[:option.library-tab-libraries-item "Icon library 2"]] [:option.library-tab-libraries-item
{:key (:id library)
:value (:id library)}
(:name library)])]
[:div.library-tab-content [:div.library-tab-content
(for [_ (range 0 200)] (let [items (mf/deref (selected-items-ref (:selected-library @state)))]
(for [item items]
[:div.library-tab-element [:div.library-tab-element
[:img {:src "https://www.placecage.com/c/200/300"}] {:key (:id item)}
[:span.library-tab-element-name "my-icon.svg"]])]]) [:img {:src (:thumb-uri item)}]
[:span.library-tab-element-name (:name item)]]))]])))
(mf/defc libraries-toolbox (mf/defc libraries-toolbox
[] [{:keys [key]}]
(let [locale (i18n/use-locale)] (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#libraries.tool-window
[:div.tool-window-bar [:div.libraries-window-bar
[:div "Libraries"] [:div.libraries-window-bar-title "Libraries"]
[:div "All libraries"]] [:div.libraries-window-bar-options
"All libraries"
[:button {:type "button"}
i/arrow-slide]]]
[:div.tool-window-content [:div.tool-window-content
[:& tab-container {} [:& tab-container {}
[:& tab-element {:id :icons :title "Icons"} [:& library-tab]] [:& tab-element
[:& tab-element {:id :images :title "Images"} [:& images-tab]]]]])) {: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)}]]]]]))