mirror of
https://github.com/penpot/penpot.git
synced 2025-03-13 16:21:57 -05:00
Merge pull request #151 from uxbox/9/workspace-libraries
Workspace - New libraries panel and color palettes
This commit is contained in:
commit
1e82573675
31 changed files with 886 additions and 266 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)))))
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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))))))
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
3
frontend/resources/images/icons/tick.svg
Normal file
3
frontend/resources/images/icons/tick.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg width="500" height="500" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.99941 1.62266C8.01413 1.36698 7.74905 1.14313 7.49807 1.21294C7.35967 1.27903 7.02149 1.60601 7.02149 1.60601C7.02149 1.60601 3.82775 4.79865 2.80464 5.76808C2.68664 5.81588 2.6167 5.68421 2.54114 5.62249C1.48872 4.57167 1.68802 4.66986 0.628214 3.62654C0.403393 3.46589 0.0441303 3.61642 0.00630665 3.8924C-0.0278168 4.07137 0.0811424 4.23539 0.212762 4.34466C1.2602 5.45375 1.12484 5.34669 2.1814 6.44725C2.31167 6.56977 2.42611 6.71875 2.58163 6.80902C2.77403 6.89051 2.99255 6.79154 3.11096 6.63235C4.317 5.44398 6.72612 3.05828 7.90933 1.84723C7.96218 1.78479 8.00392 1.70675 7.99941 1.62266Z" fill="black"/>
|
||||
</svg>
|
After Width: | Height: | Size: 731 B |
|
@ -1,18 +1,18 @@
|
|||
{
|
||||
"dashboard.grid.delete" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:73", "src/uxbox/main/ui/dashboard/grid.cljs:91" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:72", "src/uxbox/main/ui/dashboard/grid.cljs:92" ],
|
||||
"translations" : {
|
||||
"en" : "Delete"
|
||||
}
|
||||
},
|
||||
"dashboard.grid.edit" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:72", "src/uxbox/main/ui/dashboard/grid.cljs:90" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:71", "src/uxbox/main/ui/dashboard/grid.cljs:91" ],
|
||||
"translations" : {
|
||||
"en" : "Edit"
|
||||
}
|
||||
},
|
||||
"dashboard.grid.empty-files" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/grid.cljs:113" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/grid.cljs:114" ],
|
||||
"translations" : {
|
||||
"en" : "You still have no files here"
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
|||
"unused" : true
|
||||
},
|
||||
"dashboard.header.draft" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:58" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:57" ],
|
||||
"translations" : {
|
||||
"en" : "Draft"
|
||||
}
|
||||
|
@ -45,40 +45,40 @@
|
|||
"unused" : true
|
||||
},
|
||||
"dashboard.header.new-file" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:78" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:77" ],
|
||||
"translations" : {
|
||||
"en" : "+ New file"
|
||||
}
|
||||
},
|
||||
"dashboard.header.new-project" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/recent_files.cljs:54" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/recent_files.cljs:53" ],
|
||||
"translations" : {
|
||||
"en" : "+ New project"
|
||||
}
|
||||
},
|
||||
"dashboard.header.profile-menu.logout" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/profile.cljs:59", "src/uxbox/main/ui/workspace/header.cljs:93" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/profile.cljs:59" ],
|
||||
"translations" : {
|
||||
"en" : "Exit",
|
||||
"fr" : "Quitter"
|
||||
}
|
||||
},
|
||||
"dashboard.header.profile-menu.password" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/profile.cljs:56", "src/uxbox/main/ui/workspace/header.cljs:92" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/profile.cljs:56" ],
|
||||
"translations" : {
|
||||
"en" : "Password",
|
||||
"fr" : "Mot de passe"
|
||||
}
|
||||
},
|
||||
"dashboard.header.profile-menu.profile" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/profile.cljs:53", "src/uxbox/main/ui/workspace/header.cljs:91" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/profile.cljs:53" ],
|
||||
"translations" : {
|
||||
"en" : "Profile",
|
||||
"fr" : "Profil"
|
||||
}
|
||||
},
|
||||
"dashboard.header.project" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:74" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:73" ],
|
||||
"translations" : {
|
||||
"en" : "Project %s"
|
||||
}
|
||||
|
@ -127,25 +127,25 @@
|
|||
"unused" : true
|
||||
},
|
||||
"dashboard.library.menu.icons" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/library.cljs:103" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/library.cljs:96" ],
|
||||
"translations" : {
|
||||
"en" : "Icons"
|
||||
}
|
||||
},
|
||||
"dashboard.library.menu.images" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/library.cljs:107" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/library.cljs:100" ],
|
||||
"translations" : {
|
||||
"en" : "Images"
|
||||
}
|
||||
},
|
||||
"dashboard.library.menu.palettes" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/library.cljs:111" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/library.cljs:104" ],
|
||||
"translations" : {
|
||||
"en" : "Palettes"
|
||||
}
|
||||
},
|
||||
"dashboard.search.no-matches-for" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/search.cljs:47" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/search.cljs:48" ],
|
||||
"translations" : {
|
||||
"en" : "No matches found for \"%s\""
|
||||
}
|
||||
|
@ -157,13 +157,13 @@
|
|||
"unused" : true
|
||||
},
|
||||
"dashboard.search.searching-for" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/search.cljs:43" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/search.cljs:44" ],
|
||||
"translations" : {
|
||||
"en" : "Searching for %s..."
|
||||
}
|
||||
},
|
||||
"dashboard.search.type-something" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/search.cljs:39" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/search.cljs:40" ],
|
||||
"translations" : {
|
||||
"en" : "Type to search results"
|
||||
}
|
||||
|
@ -200,19 +200,19 @@
|
|||
}
|
||||
},
|
||||
"ds.button.delete" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/library.cljs:147", "src/uxbox/main/ui/dashboard/library.cljs:192", "src/uxbox/main/ui/dashboard/library.cljs:216", "src/uxbox/main/ui/dashboard/library.cljs:243" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/library.cljs:152", "src/uxbox/main/ui/dashboard/library.cljs:220", "src/uxbox/main/ui/dashboard/library.cljs:257", "src/uxbox/main/ui/dashboard/library.cljs:296" ],
|
||||
"translations" : {
|
||||
"en" : "Delete"
|
||||
}
|
||||
},
|
||||
"ds.button.rename" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/library.cljs:146" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/library.cljs:149" ],
|
||||
"translations" : {
|
||||
"en" : "Rename"
|
||||
}
|
||||
},
|
||||
"ds.button.save" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/library.cljs:51" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/library.cljs:54" ],
|
||||
"translations" : {
|
||||
"en" : "Save"
|
||||
}
|
||||
|
@ -253,21 +253,21 @@
|
|||
"unused" : true
|
||||
},
|
||||
"ds.confirm-cancel" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/confirm.cljs:38" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/confirm.cljs:19" ],
|
||||
"translations" : {
|
||||
"en" : "Cancel",
|
||||
"fr" : "Annuler"
|
||||
}
|
||||
},
|
||||
"ds.confirm-ok" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/confirm.cljs:34" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/confirm.cljs:20" ],
|
||||
"translations" : {
|
||||
"en" : "Ok",
|
||||
"fr" : "Ok"
|
||||
}
|
||||
},
|
||||
"ds.confirm-title" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/confirm.cljs:28" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/confirm.cljs:18" ],
|
||||
"translations" : {
|
||||
"en" : "Are you sure?",
|
||||
"fr" : "Êtes-vous sûr ?"
|
||||
|
@ -380,7 +380,7 @@
|
|||
"unused" : true
|
||||
},
|
||||
"ds.new-file" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/grid.cljs:109", "src/uxbox/main/ui/dashboard/grid.cljs:115" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/grid.cljs:110", "src/uxbox/main/ui/dashboard/grid.cljs:116" ],
|
||||
"translations" : {
|
||||
"en" : "+ New File",
|
||||
"fr" : null
|
||||
|
@ -450,7 +450,7 @@
|
|||
"unused" : true
|
||||
},
|
||||
"ds.store-images-title" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/images.cljs:181" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/images.cljs:180" ],
|
||||
"translations" : {
|
||||
"en" : "IMAGES STORE",
|
||||
"fr" : "BOUTIQUE"
|
||||
|
@ -499,7 +499,7 @@
|
|||
"unused" : true
|
||||
},
|
||||
"ds.your-images-title" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/images.cljs:178" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/images.cljs:177" ],
|
||||
"translations" : {
|
||||
"en" : "YOUR IMAGES",
|
||||
"fr" : "VOS IMAGES"
|
||||
|
@ -534,21 +534,21 @@
|
|||
}
|
||||
},
|
||||
"errors.generic" : {
|
||||
"used-in" : [ "src/uxbox/main/ui.cljs:160" ],
|
||||
"used-in" : [ "src/uxbox/main/ui.cljs:162" ],
|
||||
"translations" : {
|
||||
"en" : "Something wrong has happened.",
|
||||
"fr" : "Quelque chose c'est mal passé."
|
||||
}
|
||||
},
|
||||
"errors.network" : {
|
||||
"used-in" : [ "src/uxbox/main/ui.cljs:154" ],
|
||||
"used-in" : [ "src/uxbox/main/ui.cljs:156" ],
|
||||
"translations" : {
|
||||
"en" : "Unable to connect to backend server.",
|
||||
"fr" : "Impossible de se connecter au serveur principal."
|
||||
}
|
||||
},
|
||||
"header.sitemap" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:96" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:154" ],
|
||||
"translations" : {
|
||||
"en" : null,
|
||||
"fr" : null
|
||||
|
@ -562,28 +562,28 @@
|
|||
}
|
||||
},
|
||||
"image.import-library" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/images.cljs:170" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/images.cljs:169" ],
|
||||
"translations" : {
|
||||
"en" : "Import image from library",
|
||||
"fr" : "Importer une image depuis une librairie"
|
||||
}
|
||||
},
|
||||
"image.new" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/images.cljs:84" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/images.cljs:83" ],
|
||||
"translations" : {
|
||||
"en" : "New image",
|
||||
"fr" : "Nouvelle image"
|
||||
}
|
||||
},
|
||||
"image.select" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/images.cljs:90", "src/uxbox/main/ui/workspace/images.cljs:95" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/images.cljs:89", "src/uxbox/main/ui/workspace/images.cljs:94" ],
|
||||
"translations" : {
|
||||
"en" : "Select from library",
|
||||
"fr" : "Choisir depuis une librairie"
|
||||
}
|
||||
},
|
||||
"image.upload" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/images.cljs:102" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/images.cljs:101" ],
|
||||
"translations" : {
|
||||
"en" : "Upload file",
|
||||
"fr" : "Envoyer un fichier"
|
||||
|
@ -645,7 +645,7 @@
|
|||
"unused" : true
|
||||
},
|
||||
"modal.create-color.new-color" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/library.cljs:45" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/library.cljs:48" ],
|
||||
"translations" : {
|
||||
"en" : "New Color"
|
||||
}
|
||||
|
@ -658,7 +658,7 @@
|
|||
}
|
||||
},
|
||||
"profile.recovery.go-to-login" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/recovery_request.cljs:65", "src/uxbox/main/ui/profile/recovery.cljs:81" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/recovery.cljs:81", "src/uxbox/main/ui/profile/recovery_request.cljs:65" ],
|
||||
"translations" : {
|
||||
"en" : "Go back!",
|
||||
"fr" : "Retour!"
|
||||
|
@ -798,23 +798,12 @@
|
|||
}
|
||||
},
|
||||
"settings.password" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/header.cljs:37" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/header.cljs:34" ],
|
||||
"translations" : {
|
||||
"en" : "PASSWORD",
|
||||
"fr" : "MOT DE PASSE"
|
||||
}
|
||||
},
|
||||
"workspace.header.menu.hide-rules": "Hide rules",
|
||||
"workspace.header.menu.show-rules": "Show rules",
|
||||
"workspace.header.menu.hide-grid": "Hide grid",
|
||||
"workspace.header.menu.show-grid": "Show grid",
|
||||
"workspace.header.menu.hide-layers": "Hide layers",
|
||||
"workspace.header.menu.show-layers": "Show layers",
|
||||
"workspace.header.menu.hide-palette": "Hide color palette",
|
||||
"workspace.header.menu.show-palette": "Show color palette",
|
||||
"workspace.header.menu.hide-libraries": "Hide libraries",
|
||||
"workspace.header.menu.show-libraries": "Show libraries",
|
||||
|
||||
"settings.password.change-password" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/password.cljs:64" ],
|
||||
"translations" : {
|
||||
|
@ -851,14 +840,14 @@
|
|||
}
|
||||
},
|
||||
"settings.profile" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/header.cljs:34" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/header.cljs:30" ],
|
||||
"translations" : {
|
||||
"en" : "PROFILE",
|
||||
"fr" : "PROFIL"
|
||||
}
|
||||
},
|
||||
"settings.profile.lang" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:91" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:92" ],
|
||||
"translations" : {
|
||||
"en" : "Default language",
|
||||
"fr" : "Langue par défaut"
|
||||
|
@ -872,28 +861,28 @@
|
|||
}
|
||||
},
|
||||
"settings.profile.section-basic-data" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:64" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:66" ],
|
||||
"translations" : {
|
||||
"en" : "Name, username and email",
|
||||
"fr" : "Nom, nom d'utilisateur et adresse email"
|
||||
}
|
||||
},
|
||||
"settings.profile.your-avatar" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:135" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:138" ],
|
||||
"translations" : {
|
||||
"en" : "Your avatar",
|
||||
"fr" : "Votre avatar"
|
||||
}
|
||||
},
|
||||
"settings.profile.your-email" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:85" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:87" ],
|
||||
"translations" : {
|
||||
"en" : null,
|
||||
"fr" : null
|
||||
}
|
||||
},
|
||||
"settings.profile.your-name" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:72" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:75" ],
|
||||
"translations" : {
|
||||
"en" : "Your name",
|
||||
"fr" : "Votre nom complet"
|
||||
|
@ -907,7 +896,7 @@
|
|||
"unused" : true
|
||||
},
|
||||
"settings.update-settings" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/notifications.cljs:42", "src/uxbox/main/ui/settings/password.cljs:102", "src/uxbox/main/ui/settings/profile.cljs:104" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/notifications.cljs:42", "src/uxbox/main/ui/settings/password.cljs:102", "src/uxbox/main/ui/settings/profile.cljs:105" ],
|
||||
"translations" : {
|
||||
"en" : "Update settings",
|
||||
"fr" : "Mettre à jour les paramètres"
|
||||
|
@ -990,6 +979,66 @@
|
|||
},
|
||||
"unused" : true
|
||||
},
|
||||
"workspace.header.menu.hide-grid" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:104" ],
|
||||
"translations" : {
|
||||
"en" : "Hide grid"
|
||||
}
|
||||
},
|
||||
"workspace.header.menu.hide-layers" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:111" ],
|
||||
"translations" : {
|
||||
"en" : "Hide layers"
|
||||
}
|
||||
},
|
||||
"workspace.header.menu.hide-libraries" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:125" ],
|
||||
"translations" : {
|
||||
"en" : "Hide libraries"
|
||||
}
|
||||
},
|
||||
"workspace.header.menu.hide-palette" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:118" ],
|
||||
"translations" : {
|
||||
"en" : "Hide color palette"
|
||||
}
|
||||
},
|
||||
"workspace.header.menu.hide-rules" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:97" ],
|
||||
"translations" : {
|
||||
"en" : "Hide rules"
|
||||
}
|
||||
},
|
||||
"workspace.header.menu.show-grid" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:105" ],
|
||||
"translations" : {
|
||||
"en" : "Show grid"
|
||||
}
|
||||
},
|
||||
"workspace.header.menu.show-layers" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:112" ],
|
||||
"translations" : {
|
||||
"en" : "Show layers"
|
||||
}
|
||||
},
|
||||
"workspace.header.menu.show-libraries" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:126" ],
|
||||
"translations" : {
|
||||
"en" : "Show libraries"
|
||||
}
|
||||
},
|
||||
"workspace.header.menu.show-palette" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:119" ],
|
||||
"translations" : {
|
||||
"en" : "Show color palette"
|
||||
}
|
||||
},
|
||||
"workspace.header.menu.show-rules" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:98" ],
|
||||
"translations" : {
|
||||
"en" : "Show rules"
|
||||
}
|
||||
},
|
||||
"workspace.header.path" : {
|
||||
"translations" : {
|
||||
"en" : "Path",
|
||||
|
@ -1025,29 +1074,65 @@
|
|||
},
|
||||
"unused" : true
|
||||
},
|
||||
"workspace.library.all" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:106" ],
|
||||
"translations" : {
|
||||
"en" : "All libraries"
|
||||
}
|
||||
},
|
||||
"workspace.library.icons" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:156" ],
|
||||
"translations" : {
|
||||
"en" : "Icons"
|
||||
}
|
||||
},
|
||||
"workspace.library.images" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:161" ],
|
||||
"translations" : {
|
||||
"en" : "Images"
|
||||
}
|
||||
},
|
||||
"workspace.library.libraries" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:138" ],
|
||||
"translations" : {
|
||||
"en" : "Libraries"
|
||||
}
|
||||
},
|
||||
"workspace.library.own" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:107" ],
|
||||
"translations" : {
|
||||
"en" : "My libraries"
|
||||
}
|
||||
},
|
||||
"workspace.library.store" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/libraries.cljs:108" ],
|
||||
"translations" : {
|
||||
"en" : "Store libraries"
|
||||
}
|
||||
},
|
||||
"workspace.options.color" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:124", "src/uxbox/main/ui/workspace/sidebar/options/fill.cljs:47", "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:81" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/fill.cljs:47", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:124", "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:81" ],
|
||||
"translations" : {
|
||||
"en" : "Color",
|
||||
"fr" : "Couleur"
|
||||
}
|
||||
},
|
||||
"workspace.options.font-family" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:203" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:202" ],
|
||||
"translations" : {
|
||||
"en" : "Font Family",
|
||||
"fr" : "Police de caractères"
|
||||
}
|
||||
},
|
||||
"workspace.options.font-options" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:201" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:200" ],
|
||||
"translations" : {
|
||||
"en" : "Fonts & Font Size",
|
||||
"fr" : "TODO"
|
||||
}
|
||||
},
|
||||
"workspace.options.font-weight" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:212" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:211" ],
|
||||
"translations" : {
|
||||
"en" : "Font Size & Weight",
|
||||
"fr" : "Taille et graisse"
|
||||
|
@ -1061,14 +1146,14 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.line-height-letter-spacing" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:244" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:243" ],
|
||||
"translations" : {
|
||||
"en" : "Line height and Letter spacing",
|
||||
"fr" : "Hauteur de ligne et Espacement de caractères"
|
||||
}
|
||||
},
|
||||
"workspace.options.measures" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:69", "src/uxbox/main/ui/workspace/sidebar/options/icon.cljs:66", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:62", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:64", "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:55", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:66" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:64", "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:55", "src/uxbox/main/ui/workspace/sidebar/options/icon.cljs:66", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:62", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:66", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:68" ],
|
||||
"translations" : {
|
||||
"en" : "Size, position & rotation",
|
||||
"fr" : "Taille, position et rotation"
|
||||
|
@ -1082,21 +1167,21 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.position" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:98", "src/uxbox/main/ui/workspace/sidebar/options/icon.cljs:95", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:91", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:92", "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:84", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:95" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:92", "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:84", "src/uxbox/main/ui/workspace/sidebar/options/icon.cljs:95", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:91", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:95", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:97" ],
|
||||
"translations" : {
|
||||
"en" : "Position",
|
||||
"fr" : "Position"
|
||||
}
|
||||
},
|
||||
"workspace.options.rotation-radius" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:115", "src/uxbox/main/ui/workspace/sidebar/options/icon.cljs:112", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:108", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:107", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:112" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:107", "src/uxbox/main/ui/workspace/sidebar/options/icon.cljs:112", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:108", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:112", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:114" ],
|
||||
"translations" : {
|
||||
"en" : "Rotation & Radius",
|
||||
"fr" : "TODO"
|
||||
}
|
||||
},
|
||||
"workspace.options.size" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:114", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:71", "src/uxbox/main/ui/workspace/sidebar/options/icon.cljs:68", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:64", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:68", "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:57", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:68" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:68", "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:57", "src/uxbox/main/ui/workspace/sidebar/options/icon.cljs:68", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:64", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:114", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:68", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:70" ],
|
||||
"translations" : {
|
||||
"en" : "Size",
|
||||
"fr" : "Taille"
|
||||
|
@ -1152,7 +1237,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.text-align" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:263" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:262" ],
|
||||
"translations" : {
|
||||
"en" : "Text Alignment",
|
||||
"fr" : "Alignement de texte"
|
||||
|
@ -1180,7 +1265,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.viewport.click-to-close-path" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/drawarea.cljs:334" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/drawarea.cljs:335" ],
|
||||
"translations" : {
|
||||
"en" : "Click to close the path"
|
||||
}
|
||||
|
|
|
@ -42,8 +42,9 @@
|
|||
//#################################################
|
||||
|
||||
@import 'main/partials/main-bar';
|
||||
@import 'main/partials/workspace-bar';
|
||||
@import 'main/partials/workspace';
|
||||
@import 'main/partials/workspace-bar';
|
||||
@import 'main/partials/workspace-libraries';
|
||||
@import 'main/partials/tool-bar';
|
||||
@import 'main/partials/project-bar';
|
||||
@import 'main/partials/sidebar';
|
||||
|
@ -67,6 +68,7 @@
|
|||
@import 'main/partials/context-menu';
|
||||
@import 'main/partials/debug-icons-preview';
|
||||
@import 'main/partials/editable-label';
|
||||
@import 'main/partials/tab-container';
|
||||
|
||||
//#################################################
|
||||
// Resources
|
||||
|
|
|
@ -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,25 +37,54 @@
|
|||
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);
|
||||
}
|
||||
|
||||
& .context-menu-items {
|
||||
bottom: 1.5rem;
|
||||
top: initial;
|
||||
min-width: 10rem;
|
||||
}
|
||||
}
|
||||
|
||||
.color-palette-actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
margin-right: .5rem;
|
||||
width: 200px;
|
||||
.color-palette-buttons {
|
||||
align-items: center;
|
||||
align-self: stretch;
|
||||
border: 1px solid #1F1F1F;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
justify-content: center;
|
||||
margin-right: .5rem;
|
||||
padding: 0.5rem;
|
||||
|
||||
.color-palette-buttons {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
}
|
||||
|
||||
.color-palette-actions-button {
|
||||
cursor: pointer;
|
||||
& svg {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
fill: #AFB2BF;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-palette {
|
||||
|
@ -90,6 +121,8 @@
|
|||
display: flex;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
height: 4.8rem;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.color-palette-inside {
|
||||
|
@ -106,15 +139,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 {
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
border-radius: $br-small;
|
||||
box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25);
|
||||
left: -$size-4;
|
||||
max-height: 30rem;
|
||||
min-width: 7rem;
|
||||
overflow: auto;
|
||||
position: absolute;
|
||||
top: $size-3;
|
||||
}
|
||||
|
@ -27,9 +29,25 @@
|
|||
display: block;
|
||||
font-size: $fs12;
|
||||
padding: $size-2 $size-4;
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover {
|
||||
color: $color-black;
|
||||
background: $color-primary-lighter;
|
||||
background-color: $color-primary-lighter;
|
||||
}
|
||||
}
|
||||
|
||||
.context-menu.is-selectable {
|
||||
& .context-menu-action {
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
& .context-menu-item.is-selected .context-menu-action {
|
||||
background-image: url(/images/icons/tick.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 5% 48%;
|
||||
background-size: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
// Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||
|
||||
.sitemap {
|
||||
max-height: 180px;
|
||||
|
||||
.tool-window-bar {
|
||||
|
||||
.add-page {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
height: 100%;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
width: 230px;
|
||||
width: 15rem;
|
||||
z-index: 10;
|
||||
|
||||
&.settings-bar-left {
|
||||
|
@ -20,10 +20,23 @@
|
|||
|
||||
.settings-bar-inside {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
display: grid;
|
||||
grid-template-columns: 100%;
|
||||
|
||||
&[data-layout*='layers'] {
|
||||
grid-template-rows: 30% 70%;
|
||||
}
|
||||
|
||||
&[data-layout*='libraries'] {
|
||||
grid-template-rows: 100%;
|
||||
}
|
||||
|
||||
&[data-layout*='layers'][data-layout*='libraries'] {
|
||||
grid-template-rows: 15% 25% 60%;
|
||||
}
|
||||
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
overflow: hidden;
|
||||
padding-top: 40px;
|
||||
height: 100%;
|
||||
|
||||
|
@ -33,12 +46,14 @@
|
|||
flex-direction: column;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.tool-window-bar {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
padding: $small;
|
||||
overflow: hidden;
|
||||
|
||||
svg {
|
||||
fill: $color-gray-20;
|
||||
|
@ -78,14 +93,8 @@
|
|||
flex-wrap: wrap;
|
||||
overflow-y: auto;
|
||||
padding-bottom: $medium;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&#layers {
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
43
frontend/resources/styles/main/partials/tab-container.scss
Normal file
43
frontend/resources/styles/main/partials/tab-container.scss
Normal file
|
@ -0,0 +1,43 @@
|
|||
|
||||
.tab-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tab-container-tabs {
|
||||
background: $color-gray-60;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
font-size: 12px;
|
||||
height: 2.5rem;
|
||||
padding: 0 0.25rem;
|
||||
}
|
||||
|
||||
.tab-container-tab-title {
|
||||
align-items: center;
|
||||
background: $color-gray-60;
|
||||
border-radius: 2px 2px 0px 0px;
|
||||
color: $color-white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 0.5rem 0.25rem 0 0.25rem ;
|
||||
width: 100%;
|
||||
|
||||
&.current{
|
||||
background: $color-gray-50;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-container-content {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tab-element, .tab-element-content {
|
||||
height: 100%;
|
||||
}
|
127
frontend/resources/styles/main/partials/workspace-libraries.scss
Normal file
127
frontend/resources/styles/main/partials/workspace-libraries.scss
Normal file
|
@ -0,0 +1,127 @@
|
|||
.libraries-window-bar {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 50%);
|
||||
padding: 0.5rem;
|
||||
align-items: center;
|
||||
|
||||
& .context-menu-items {
|
||||
left: initial;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
height: 100%;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.library-tab-content {
|
||||
display: grid;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
padding: 0.25rem;
|
||||
overflow-y: scroll;
|
||||
|
||||
.icons-tab & {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
.images-tab & {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.library-tab-element {
|
||||
border-radius: 4px;
|
||||
border: 1px solid #1F1F1F;
|
||||
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
margin: 0.25rem;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
|
||||
& svg, & img {
|
||||
height: auto;
|
||||
margin: auto;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: $color-primary;
|
||||
|
||||
& .library-tab-element-name {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
.icons-tab & {
|
||||
background: $color-white;
|
||||
color: $color-black;
|
||||
height: 4rem;
|
||||
width: 4rem;
|
||||
padding: $size-3;
|
||||
}
|
||||
|
||||
.images-tab & {
|
||||
height: 4rem;
|
||||
width: 6.2rem;
|
||||
color: $color-white;
|
||||
padding: $size-2 0;
|
||||
}
|
||||
}
|
||||
|
||||
.library-tab-element-name {
|
||||
display: none;
|
||||
position: absolute;
|
||||
font-size: 9px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.library-tab-libraries {
|
||||
background-color: #303236;
|
||||
margin: 0.5rem;
|
||||
width: 90%;
|
||||
padding: 0.5rem;
|
||||
box-sizing: border-box;
|
||||
color: #AFB2BF;
|
||||
font-size: 12px;
|
||||
border: 1px solid #7c7c7c;
|
||||
}
|
||||
|
||||
.library-tab-libraries-item {
|
||||
padding: 1rem;
|
||||
}
|
|
@ -266,4 +266,4 @@
|
|||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(update-in [:library :selected-items library-id] #(into [item] %) )))))
|
||||
(update-in [:library-items :palettes library-id] #(into [item] %) )))))
|
||||
|
|
|
@ -203,7 +203,7 @@
|
|||
(update [_ state]
|
||||
(let [{:keys [id] :as item} (assoc item :type :icon)]
|
||||
(-> state
|
||||
(update-in [:library :selected-items library-id] #(into [item] %)))))))
|
||||
(update-in [:library-items :icons library-id] #(into [item] %)))))))
|
||||
|
||||
;; ;; --- Icon Persisted
|
||||
;;
|
||||
|
|
|
@ -395,5 +395,5 @@
|
|||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(update-in [:library :selected-items library-id] #(into [item] %))))))
|
||||
(update-in [:library-items :images library-id] #(into [item] %))))))
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -53,15 +56,15 @@
|
|||
:images :images
|
||||
:palettes :colors)]
|
||||
(->> (rp/query! method {:library-id library-id})
|
||||
(rx/map (partial retrieve-library-data-result library-id)))))))
|
||||
(rx/map (partial retrieve-library-data-result type library-id)))))))
|
||||
|
||||
(defn retrieve-library-data-result
|
||||
[library-id data]
|
||||
[type library-id data]
|
||||
(ptk/reify ::retrieve-library-data-result
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(assoc-in [:library :selected-items library-id] data)))))
|
||||
(assoc-in [:library-items type library-id] data)))))
|
||||
|
||||
|
||||
;; Create library
|
||||
|
@ -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
|
||||
|
||||
|
@ -175,7 +178,7 @@
|
|||
(let [update-fn (fn [items]
|
||||
(filterv #(not= item-id (:id %)) items))]
|
||||
(-> state
|
||||
(update-in [:library :selected-items library-id] update-fn))))))
|
||||
(update-in [:library-items type library-id] update-fn))))))
|
||||
|
||||
;; Batch delete
|
||||
|
||||
|
@ -204,4 +207,25 @@
|
|||
update-fn (fn [items]
|
||||
(filterv #(not (item-ids-set (:id %))) items))]
|
||||
(-> state
|
||||
(update-in [:library :selected-items library-id] update-fn))))))
|
||||
(update-in [:library-items type library-id] update-fn))))))
|
||||
|
||||
;; Workspace - select library
|
||||
|
||||
(defn select-library
|
||||
[type library-id]
|
||||
(ptk/reify ::select-library
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(assoc-in [:library-selected type] library-id)))))
|
||||
|
||||
|
||||
;; Workspace - change library filter
|
||||
|
||||
(defn change-library-filter
|
||||
[type filter]
|
||||
(ptk/reify ::change-library-filter
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(assoc-in [:library-filter type] filter)))))
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
|
||||
(declare fetch-users)
|
||||
(declare fetch-images)
|
||||
(declare fetch-project)
|
||||
(declare handle-who)
|
||||
(declare handle-pointer-update)
|
||||
(declare handle-pointer-send)
|
||||
|
@ -294,7 +295,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
|
||||
|
@ -305,9 +307,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))))
|
||||
|
@ -355,7 +359,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
|
||||
|
@ -493,6 +498,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
|
||||
|
@ -546,6 +552,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
|
||||
|
||||
|
@ -770,16 +795,20 @@
|
|||
;; --- Toggle layout flag
|
||||
|
||||
(defn toggle-layout-flag
|
||||
[flag]
|
||||
(us/verify keyword? flag)
|
||||
[& flags]
|
||||
;; Verify all?
|
||||
#_(us/verify keyword? flag)
|
||||
(ptk/reify ::toggle-layout-flag
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :workspace-layout
|
||||
(fn [flags]
|
||||
(if (contains? flags flag)
|
||||
(disj flags flag)
|
||||
(conj flags flag)))))))
|
||||
(let [reduce-fn
|
||||
(fn [state flag]
|
||||
(update state :workspace-layout
|
||||
(fn [flags]
|
||||
(if (contains? flags flag)
|
||||
(disj flags flag)
|
||||
(conj flags flag)))))]
|
||||
(reduce reduce-fn state flags)))))
|
||||
|
||||
;; --- Tooltip
|
||||
|
||||
|
@ -1103,6 +1132,7 @@
|
|||
(rx/empty))))))
|
||||
|
||||
|
||||
|
||||
;; --- Toggle shape's selection status (selected or deselected)
|
||||
|
||||
(defn select-shape
|
||||
|
@ -1924,7 +1954,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))))))
|
||||
|
@ -1935,8 +1966,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))))))
|
||||
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
[rumext.alpha :as mf]
|
||||
[goog.object :as gobj]
|
||||
[uxbox.main.ui.components.dropdown :refer [dropdown-container]]
|
||||
[uxbox.util.uuid :as uuid]))
|
||||
[uxbox.util.uuid :as uuid]
|
||||
[uxbox.util.data :refer [classnames]]))
|
||||
|
||||
(mf/defc context-menu
|
||||
{::mf/wrap-props false}
|
||||
|
@ -13,12 +14,16 @@
|
|||
(assert (vector? (gobj/get props "options")) "missing `options` prop")
|
||||
|
||||
(let [open? (gobj/get props "show")
|
||||
options (gobj/get props "options")]
|
||||
options (gobj/get props "options")
|
||||
is-selectable (gobj/get props "selectable")
|
||||
selected (gobj/get props "selected")]
|
||||
(when open?
|
||||
[:> dropdown-container props
|
||||
[:div.context-menu {:class (when open? "is-open")}
|
||||
[:div.context-menu {:class (classnames :is-open open?
|
||||
:is-selectable is-selectable)}
|
||||
[:ul.context-menu-items
|
||||
(for [[action-name action-handler] options]
|
||||
[:li.context-menu-item {:key action-name}
|
||||
[:li.context-menu-item {:class (classnames :is-selected (and selected (= action-name selected)))
|
||||
:key action-name}
|
||||
[:a.context-menu-action {:on-click action-handler}
|
||||
action-name]])]]])))
|
||||
|
|
27
frontend/src/uxbox/main/ui/components/tab_container.cljs
Normal file
27
frontend/src/uxbox/main/ui/components/tab_container.cljs
Normal file
|
@ -0,0 +1,27 @@
|
|||
(ns uxbox.main.ui.components.tab-container
|
||||
(:require [rumext.alpha :as mf]))
|
||||
|
||||
(mf/defc tab-element
|
||||
[{:keys [children id title]}]
|
||||
[:div.tab-element
|
||||
[:div.tab-element-content children]])
|
||||
|
||||
(mf/defc tab-container
|
||||
[{:keys [children selected on-change-tab]}]
|
||||
(let [first-id (-> children first .-props .-id)
|
||||
state (mf/use-state {:selected first-id})
|
||||
selected (or selected (:selected @state))
|
||||
handle-select (fn [tab]
|
||||
(let [id (-> tab .-props .-id)]
|
||||
(swap! state assoc :selected id)
|
||||
(when on-change-tab (on-change-tab id))))]
|
||||
[:div.tab-container
|
||||
[:div.tab-container-tabs
|
||||
(for [tab children]
|
||||
[:div.tab-container-tab-title
|
||||
{:key (str "tab-" (-> tab .-props .-id))
|
||||
:on-click (partial handle-select tab)
|
||||
:class (when (= selected (-> tab .-props .-id)) "current")}
|
||||
(-> tab .-props .-title)])]
|
||||
[:div.tab-container-content
|
||||
(filter #(= selected (-> % .-props .-id)) children)]]))
|
|
@ -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)]]
|
||||
|
|
|
@ -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,12 +301,12 @@
|
|||
: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]
|
||||
(-> (comp (l/key :library) (l/key :selected-items) (l/key library-id))
|
||||
(defn selected-items-ref [section library-id]
|
||||
(-> (comp (l/key :library-items) (l/key section) (l/key library-id))
|
||||
(l/derive st/state)))
|
||||
|
||||
(def last-deleted-library-ref
|
||||
|
@ -316,8 +316,8 @@
|
|||
(mf/defc library-page
|
||||
[{:keys [team-id library-id section]}]
|
||||
(let [state (mf/use-state {:selected #{}})
|
||||
libraries (mf/deref (libraries-ref section))
|
||||
items (mf/deref (selected-items-ref library-id))
|
||||
libraries (mf/deref (libraries-ref section team-id))
|
||||
items (mf/deref (selected-items-ref section library-id))
|
||||
last-deleted-library (mf/deref last-deleted-library-ref)
|
||||
selected-library (first (filter #(= (:id %) library-id) libraries))]
|
||||
|
||||
|
|
|
@ -60,16 +60,14 @@
|
|||
(mf/defc workspace-content
|
||||
[{:keys [page file layout] :as params}]
|
||||
(let [frame (mf/use-ref nil)
|
||||
left-sidebar? (not (empty? (keep layout [:layers :sitemap
|
||||
:document-history])))
|
||||
right-sidebar? (not (empty? (keep layout [:icons :drawtools
|
||||
:element-options])))
|
||||
left-sidebar? (not (empty? (keep layout [:layers :sitemap :document-history :libraries])))
|
||||
right-sidebar? (not (empty? (keep layout [:icons :drawtools :element-options])))
|
||||
classes (classnames
|
||||
:no-tool-bar-right (not right-sidebar?)
|
||||
:no-tool-bar-left (not left-sidebar?))]
|
||||
[:*
|
||||
(when (:colorpalette layout)
|
||||
[:& colorpalette])
|
||||
[:& colorpalette {:left-sidebar? left-sidebar?}])
|
||||
|
||||
[:main.main-content
|
||||
[:& context-menu {}]
|
||||
|
@ -101,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
|
||||
|
|
|
@ -13,16 +13,30 @@
|
|||
[uxbox.builtins.icons :as i]
|
||||
[uxbox.main.data.colors :as udc]
|
||||
[uxbox.main.data.workspace :as udw]
|
||||
[uxbox.main.data.library :as dlib]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.ui.keyboard :as kbd]
|
||||
[uxbox.util.color :refer [hex->rgb]]
|
||||
[uxbox.util.data :refer [read-string seek]]
|
||||
[uxbox.util.dom :as dom]))
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.main.ui.components.context-menu :refer [context-menu]]))
|
||||
|
||||
;; --- Refs
|
||||
|
||||
(def collections-iref
|
||||
(-> (l/key :colors-collections)
|
||||
(def project-ref
|
||||
(-> (l/key :workspace-project)
|
||||
(l/derive st/state)))
|
||||
|
||||
(def libraries-ref
|
||||
(-> (comp (l/key :library) (l/key :palettes))
|
||||
(l/derive st/state)))
|
||||
|
||||
(defn selected-items-ref [library-id]
|
||||
(-> (comp (l/key :library-items) (l/key :palettes) (l/key library-id))
|
||||
(l/derive st/state)))
|
||||
|
||||
(def selected-library-ref
|
||||
(-> (comp (l/key :library-selected) (l/key :palettes))
|
||||
(l/derive st/state)))
|
||||
|
||||
;; --- Components
|
||||
|
@ -30,8 +44,6 @@
|
|||
(mf/defc palette-item
|
||||
[{:keys [color] :as props}]
|
||||
(let [rgb-vec (hex->rgb color)
|
||||
rgb-color (apply str "" (interpose ", " rgb-vec))
|
||||
|
||||
select-color
|
||||
(fn [event]
|
||||
(if (kbd/shift? event)
|
||||
|
@ -41,89 +53,86 @@
|
|||
[:div.color-cell {:key (str color)
|
||||
:on-click select-color}
|
||||
[:span.color {:style {:background color}}]
|
||||
[:span.color-text color]
|
||||
[:span.color-text rgb-color]]))
|
||||
[:span.color-text color]]))
|
||||
|
||||
(mf/defc palette
|
||||
[{:keys [colls] :as props}]
|
||||
(let [local (mf/use-state {})
|
||||
colls (->> colls
|
||||
(filter :id)
|
||||
(sort-by :name))
|
||||
[{:keys [libraries left-sidebar?] :as props}]
|
||||
|
||||
coll (or (:selected @local)
|
||||
(first colls))
|
||||
(when (and libraries (-> libraries count (> 0)))
|
||||
(let [current-selection (or (mf/deref selected-library-ref) (-> libraries first :id))
|
||||
state (mf/use-state {:show-menu false })]
|
||||
(mf/use-effect
|
||||
(mf/deps current-selection)
|
||||
#(st/emit! (dlib/retrieve-library-data :palettes current-selection)))
|
||||
|
||||
(let [items (-> current-selection selected-items-ref mf/deref)
|
||||
doc-width (.. js/document -documentElement -clientWidth)
|
||||
width (:width @state (* doc-width 0.84))
|
||||
offset (:offset @state 0)
|
||||
visible (/ width 86)
|
||||
invisible (- (count items) visible)
|
||||
close #(st/emit! (udw/toggle-layout-flag :colorpalette))
|
||||
container (mf/use-ref nil)
|
||||
container-child (mf/use-ref nil)
|
||||
|
||||
doc-width (.. js/document -documentElement -clientWidth)
|
||||
width (:width @local (* doc-width 0.84))
|
||||
offset (:offset @local 0)
|
||||
visible (/ width 86)
|
||||
invisible (- (count (:colors coll)) visible)
|
||||
close #(st/emit! (udw/toggle-layout-flag :colorpalette))
|
||||
on-left-arrow-click
|
||||
(fn [event]
|
||||
(when (> offset 0)
|
||||
(let [element (mf/ref-val container-child)]
|
||||
(swap! state update :offset dec))))
|
||||
|
||||
container (mf/use-ref nil)
|
||||
container-child (mf/use-ref nil)
|
||||
on-right-arrow-click
|
||||
(fn [event]
|
||||
(when (< offset invisible)
|
||||
(let [element (mf/ref-val container-child)]
|
||||
(swap! state update :offset inc))))
|
||||
|
||||
select-coll
|
||||
(fn [event]
|
||||
(let [id (read-string (dom/event->value event))
|
||||
selected (seek #(= id (:id %)) colls)]
|
||||
(swap! local assoc :selected selected :position 0)))
|
||||
on-scroll
|
||||
(fn [event]
|
||||
(if (pos? (.. event -nativeEvent -deltaY))
|
||||
(on-right-arrow-click event)
|
||||
(on-left-arrow-click event)))
|
||||
|
||||
on-left-arrow-click
|
||||
(fn [event]
|
||||
(when (> offset 0)
|
||||
(let [element (mf/ref-val container-child)]
|
||||
(swap! local update :offset dec))))
|
||||
after-render
|
||||
(fn []
|
||||
(let [dom (mf/ref-val container)
|
||||
width (.-clientWidth dom)]
|
||||
(when (not= (:width @state) width)
|
||||
(swap! state assoc :width width))))
|
||||
|
||||
on-right-arrow-click
|
||||
(fn [event]
|
||||
(when (< offset invisible)
|
||||
(let [element (mf/ref-val container-child)]
|
||||
(swap! local update :offset inc))))
|
||||
handle-click
|
||||
(fn [library]
|
||||
(st/emit! (dlib/select-library :palettes (:id library))))]
|
||||
|
||||
on-scroll
|
||||
(fn [event]
|
||||
(if (pos? (.. event -nativeEvent -deltaY))
|
||||
(on-right-arrow-click event)
|
||||
(on-left-arrow-click event)))
|
||||
(mf/use-effect nil after-render)
|
||||
|
||||
after-render
|
||||
(fn []
|
||||
(let [dom (mf/ref-val container)
|
||||
width (.-clientWidth dom)]
|
||||
(when (not= (:width @local) width)
|
||||
(swap! local assoc :width width))))]
|
||||
[:div.color-palette {:class (when left-sidebar? "left-sidebar-open")}
|
||||
[:& context-menu {:selectable true
|
||||
:selected (->> libraries (filter #(= (:id %) current-selection)) first :name)
|
||||
:show (:show-menu @state)
|
||||
:on-close #(swap! state assoc :show-menu false)
|
||||
:options (mapv #(vector (:name %) (partial handle-click %)) libraries)} ]
|
||||
[:div.color-palette-actions
|
||||
{:on-click #(swap! state assoc :show-menu true)}
|
||||
[:div.color-palette-actions-button i/actions]]
|
||||
|
||||
(mf/use-effect nil after-render)
|
||||
[:span.left-arrow {:on-click on-left-arrow-click} i/arrow-slide]
|
||||
|
||||
[:div.color-palette
|
||||
[:div.color-palette-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))}
|
||||
(:name item)])]
|
||||
[:div.color-palette-content {:ref container :on-wheel on-scroll}
|
||||
[:div.color-palette-inside {:ref container-child
|
||||
:style {:position "relative"
|
||||
:width (str (* 86 (count items)) "px")
|
||||
:right (str (* 86 offset) "px")}}
|
||||
(for [item items]
|
||||
[:& palette-item {:color (:content item) :key (:id item)}])]]
|
||||
|
||||
#_[:div.color-palette-buttons
|
||||
[:div.btn-palette.edit.current i/pencil]
|
||||
[:div.btn-palette.create i/close]]]
|
||||
|
||||
[:span.left-arrow {:on-click on-left-arrow-click} i/arrow-slide]
|
||||
|
||||
[:div.color-palette-content {:ref container :on-wheel on-scroll}
|
||||
[:div.color-palette-inside {:ref container-child
|
||||
: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}])]]
|
||||
|
||||
[:span.right-arrow {:on-click on-right-arrow-click} i/arrow-slide]
|
||||
[:span.close-palette {:on-click close} i/close]]))
|
||||
[:span.right-arrow {:on-click on-right-arrow-click} i/arrow-slide]]))))
|
||||
|
||||
(mf/defc colorpalette
|
||||
[props]
|
||||
(let [colls (mf/deref collections-iref)]
|
||||
#_(mf/use-effect #(st/emit! (udc/fetch-collections)))
|
||||
[:& palette {:colls (vals colls)}]))
|
||||
[{:keys [left-sidebar?]}]
|
||||
(let [team-id (-> project-ref mf/deref :team-id)
|
||||
libraries (-> libraries-ref mf/deref vals flatten)]
|
||||
(mf/use-effect #(st/emit! (dlib/retrieve-libraries :palettes)
|
||||
(dlib/retrieve-libraries :palettes team-id)))
|
||||
[:& palette {:left-sidebar? left-sidebar?
|
||||
:libraries libraries}]))
|
||||
|
|
|
@ -68,10 +68,12 @@
|
|||
[:li.tooltip.tooltip-right
|
||||
{:alt "Layers"
|
||||
:class (when (contains? layout :layers) "selected")
|
||||
:on-click #(st/emit! (dw/toggle-layout-flag :layers))}
|
||||
:on-click #(st/emit! (dw/toggle-layout-flag :layers :sitemap))}
|
||||
i/layers]
|
||||
[:li.tooltip.tooltip-right
|
||||
{:alt "Libraries"}
|
||||
{:alt "Libraries"
|
||||
:class (when (contains? layout :libraries) "selected")
|
||||
:on-click #(st/emit! (dw/toggle-layout-flag :libraries))}
|
||||
i/icon-set]
|
||||
[:li.tooltip.tooltip-right
|
||||
{:alt "History"}
|
||||
|
|
|
@ -11,11 +11,13 @@
|
|||
(ns uxbox.main.ui.workspace.sidebar
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[cuerdas.core :as str]
|
||||
[uxbox.main.ui.workspace.sidebar.history :refer [history-toolbox]]
|
||||
[uxbox.main.ui.workspace.sidebar.icons :refer [icons-toolbox]]
|
||||
[uxbox.main.ui.workspace.sidebar.layers :refer [layers-toolbox]]
|
||||
[uxbox.main.ui.workspace.sidebar.options :refer [options-toolbox]]
|
||||
[uxbox.main.ui.workspace.sidebar.sitemap :refer [sitemap-toolbox]]))
|
||||
[uxbox.main.ui.workspace.sidebar.sitemap :refer [sitemap-toolbox]]
|
||||
[uxbox.main.ui.workspace.sidebar.libraries :refer [libraries-toolbox]]))
|
||||
|
||||
;; --- Left Sidebar (Component)
|
||||
|
||||
|
@ -24,12 +26,15 @@
|
|||
[{:keys [layout page file] :as props}]
|
||||
[:aside.settings-bar.settings-bar-left
|
||||
[:div.settings-bar-inside
|
||||
{:data-layout (str/join "," layout)}
|
||||
(when (contains? layout :sitemap)
|
||||
[:& sitemap-toolbox {:file file :page page}])
|
||||
(when (contains? layout :document-history)
|
||||
[:& history-toolbox])
|
||||
(when (contains? layout :layers)
|
||||
[:& layers-toolbox {:page page}])]])
|
||||
[:& layers-toolbox {:page page}])
|
||||
(when (contains? layout :libraries)
|
||||
[:& libraries-toolbox])]])
|
||||
|
||||
;; --- Right Sidebar (Component)
|
||||
|
||||
|
|
165
frontend/src/uxbox/main/ui/workspace/sidebar/libraries.cljs
Normal file
165
frontend/src/uxbox/main/ui/workspace/sidebar/libraries.cljs
Normal file
|
@ -0,0 +1,165 @@
|
|||
;; 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/.
|
||||
;;
|
||||
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
;; defined by the Mozilla Public License, v. 2.0.
|
||||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(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]
|
||||
[uxbox.main.data.workspace :as dw]
|
||||
[uxbox.main.refs :as refs]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.ui.keyboard :as kbd]
|
||||
[uxbox.main.ui.shapes.icon :as icon]
|
||||
[uxbox.main.ui.workspace.sortable :refer [use-sortable]]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.uuid :as uuid]
|
||||
[uxbox.util.i18n :as i18n :refer [tr]]
|
||||
[uxbox.util.data :refer [classnames]]
|
||||
[uxbox.main.ui.components.tab-container :refer [tab-container tab-element]]
|
||||
[uxbox.main.data.library :as dlib]
|
||||
[uxbox.main.ui.components.context-menu :refer [context-menu]]))
|
||||
|
||||
;; --- Refs
|
||||
|
||||
(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 [section library-id]
|
||||
(-> (comp (l/key :library-items) (l/key section) (l/key library-id))
|
||||
(l/derive st/state)))
|
||||
|
||||
(defn selected-library-ref [section]
|
||||
(-> (comp (l/key :library-selected) (l/key section))
|
||||
(l/derive st/state)))
|
||||
|
||||
(defn selected-filter-ref [section]
|
||||
(-> (comp (l/key :library-filter) (l/key section))
|
||||
(l/derive st/state)))
|
||||
|
||||
;; --- Components
|
||||
|
||||
(mf/defc library-tab [{:keys [libraries section]}]
|
||||
(when (and libraries (-> libraries count (> 0)))
|
||||
(let [first-id (-> libraries first :id)
|
||||
current-selection (or (mf/deref (selected-library-ref section)) first-id)]
|
||||
|
||||
;; Check if the current selection is in the list of libraries
|
||||
(mf/use-effect
|
||||
(mf/deps libraries)
|
||||
#(when (not (some (fn [it] (= current-selection (-> it :id))) libraries))
|
||||
(st/emit! (dlib/select-library section first-id))))
|
||||
|
||||
;; Retrieve the library data given the current selected library
|
||||
(mf/use-effect
|
||||
(mf/deps current-selection)
|
||||
#(st/emit! (dlib/retrieve-library-data section current-selection)))
|
||||
|
||||
[:div.library-tab
|
||||
{:class (classnames :icons-tab (= section :icons)
|
||||
:images-tab (= section :images))}
|
||||
[:select.input-select.library-tab-libraries
|
||||
{:on-change #(st/emit! (dlib/select-library section (-> % dom/get-target dom/get-value uuid)))}
|
||||
(for [library libraries]
|
||||
[:option.library-tab-libraries-item
|
||||
{:key (:id library)
|
||||
:value (:id library)
|
||||
:selected (= current-selection (:id library))}
|
||||
(:name library)])]
|
||||
[:div.library-tab-content
|
||||
(let [items (mf/deref (selected-items-ref section current-selection))]
|
||||
(for [item items]
|
||||
[:div.library-tab-element
|
||||
{:key (:id item)
|
||||
:on-click #(st/emit! (dw/select-for-drawing :icon item))}
|
||||
(if (= section :icons)
|
||||
[:* ;; ICONS
|
||||
[: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)]]
|
||||
|
||||
[:* ;; IMAGES
|
||||
[:img {:src (:thumb-uri item)}]
|
||||
[:span.library-tab-element-name (:name item)]])]))]])))
|
||||
|
||||
(mf/defc libraries-toolbox
|
||||
[{:keys [key]}]
|
||||
(let [state (mf/use-state {:menu-open false})
|
||||
selected-filter (fn [section] (or (mf/deref (selected-filter-ref section)) :all))
|
||||
team-id (-> project-ref mf/deref :team-id)
|
||||
|
||||
filter-to-str {:all (tr "workspace.library.all")
|
||||
:own (tr "workspace.library.own")
|
||||
:store (tr "workspace.library.store")}
|
||||
|
||||
select-option
|
||||
(fn [option]
|
||||
(st/emit!
|
||||
(dlib/change-library-filter :icons option)
|
||||
(dlib/change-library-filter :images option)))
|
||||
|
||||
filter-libraries
|
||||
(fn [section libraries]
|
||||
(case (selected-filter section)
|
||||
:all (-> libraries vals flatten)
|
||||
:own (libraries team-id)
|
||||
:store (libraries uuid/zero)))
|
||||
|
||||
get-libraries
|
||||
(fn [section] (->> (libraries-ref section)
|
||||
mf/deref
|
||||
(filter-libraries section)))]
|
||||
|
||||
(mf/use-effect
|
||||
(mf/deps team-id)
|
||||
#(when team-id
|
||||
(st/emit! (dlib/retrieve-libraries :icons)
|
||||
(dlib/retrieve-libraries :images)
|
||||
(dlib/retrieve-libraries :icons team-id)
|
||||
(dlib/retrieve-libraries :images team-id))))
|
||||
|
||||
[:div#libraries.tool-window
|
||||
[:div.libraries-window-bar
|
||||
[:div.libraries-window-bar-title (tr "workspace.library.libraries")]
|
||||
[:div.libraries-window-bar-options
|
||||
{:on-click #(swap! state assoc :menu-open true)}
|
||||
(filter-to-str (selected-filter :icons))
|
||||
[:button
|
||||
{
|
||||
:type "button"}
|
||||
i/arrow-slide
|
||||
[:& context-menu
|
||||
{:selectable true
|
||||
:show (:menu-open @state)
|
||||
:selected (filter-to-str (selected-filter :icons))
|
||||
:on-close #(swap! state assoc :menu-open false)
|
||||
:options (mapv (fn [[key val]] [val #(select-option key)]) filter-to-str)}]]]]
|
||||
|
||||
[:div.tool-window-content
|
||||
[:& tab-container {}
|
||||
[:& tab-element
|
||||
{:id :icons :title (tr "workspace.library.icons")}
|
||||
[:& library-tab {:section :icons
|
||||
:libraries (get-libraries :icons) }]]
|
||||
|
||||
[:& tab-element
|
||||
{:id :images :title (tr "workspace.library.images")}
|
||||
[:& library-tab {:section :images
|
||||
:libraries (get-libraries :images)}]]]]]))
|
||||
|
||||
|
|
@ -205,3 +205,4 @@
|
|||
;; (if (::some-interrupt (ex-data e#))
|
||||
;; nil
|
||||
;; (throw e#)))))))
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue