mirror of
https://github.com/penpot/penpot.git
synced 2025-01-04 13:50:12 -05:00
🎉 Convert libraries to file libraries
This commit is contained in:
parent
8c8b5887d6
commit
49c57be84a
23 changed files with 605 additions and 295 deletions
|
@ -0,0 +1,29 @@
|
|||
-- ALTER TABLE color_library
|
||||
-- DROP COLUMN team_id,
|
||||
-- DROP COLUMN name,
|
||||
-- ADD COLUMN file_id uuid NOT NULL REFERENCES file(id) ON DELETE CASCADE;
|
||||
--
|
||||
-- CREATE INDEX color_library__file_id__idx
|
||||
-- ON color_library(file_id);
|
||||
|
||||
TRUNCATE TABLE color;
|
||||
TRUNCATE TABLE color_library CASCADE;
|
||||
TRUNCATE TABLE image;
|
||||
TRUNCATE TABLE image_library CASCADE;
|
||||
TRUNCATE TABLE icon;
|
||||
TRUNCATE TABLE icon_library CASCADE;
|
||||
|
||||
ALTER TABLE color
|
||||
DROP COLUMN library_id,
|
||||
ADD COLUMN file_id uuid NOT NULL REFERENCES file(id) ON DELETE CASCADE;
|
||||
|
||||
CREATE INDEX color__file_id__idx
|
||||
ON color(file_id);
|
||||
|
||||
ALTER TABLE image
|
||||
DROP COLUMN library_id,
|
||||
ADD COLUMN file_id uuid NOT NULL REFERENCES file(id) ON DELETE CASCADE;
|
||||
|
||||
CREATE INDEX image__file_id__idx
|
||||
ON image(file_id);
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
(s/def ::width integer?)
|
||||
(s/def ::height integer?)
|
||||
(s/def ::format #{:jpeg :webp :png})
|
||||
(s/def ::format #{:jpeg :webp :png :svg})
|
||||
(s/def ::quality #(< 0 % 101))
|
||||
|
||||
(s/def ::thumbnail-params
|
||||
|
@ -62,21 +62,24 @@
|
|||
(case format
|
||||
:png ".png"
|
||||
:jpeg ".jpg"
|
||||
:webp ".webp"))
|
||||
:webp ".webp"
|
||||
:svg ".svg"))
|
||||
|
||||
(defn format->mtype
|
||||
[format]
|
||||
(case format
|
||||
:png "image/png"
|
||||
:jpeg "image/jpeg"
|
||||
:webp "image/webp"))
|
||||
:webp "image/webp"
|
||||
:svg "image/svg+xml"))
|
||||
|
||||
(defn mtype->format
|
||||
[mtype]
|
||||
(case mtype
|
||||
"image/jpeg" :jpeg
|
||||
"image/webp" :webp
|
||||
"image/png" :png
|
||||
"image/png" :png
|
||||
"image/jpeg" :jpeg
|
||||
"image/webp" :webp
|
||||
"image/svg+xml" :svg
|
||||
nil))
|
||||
|
||||
(defn- generic-process
|
||||
|
@ -127,18 +130,21 @@
|
|||
(defmethod process :info
|
||||
[{:keys [input] :as params}]
|
||||
(us/assert ::input input)
|
||||
(let [{:keys [path mtype]} input
|
||||
instance (Info. (str path))
|
||||
mtype' (.getProperty instance "Mime type")]
|
||||
|
||||
(when (and (string? mtype)
|
||||
(not= mtype mtype'))
|
||||
(ex/raise :type :validation
|
||||
:code :image-type-mismatch
|
||||
:hint "Seems like you are uploading a file whose content does not match the extension."))
|
||||
{:width (.getImageWidth instance)
|
||||
:height (.getImageHeight instance)
|
||||
:mtype mtype'}))
|
||||
(let [{:keys [path mtype]} input]
|
||||
(if (= mtype "image/svg+xml")
|
||||
{:width 100
|
||||
:height 100
|
||||
:mtype mtype}
|
||||
(let [instance (Info. (str path))
|
||||
mtype' (.getProperty instance "Mime type")]
|
||||
(when (and (string? mtype)
|
||||
(not= mtype mtype'))
|
||||
(ex/raise :type :validation
|
||||
:code :image-type-mismatch
|
||||
:hint "Seems like you are uploading a file whose content does not match the extension."))
|
||||
{:width (.getImageWidth instance)
|
||||
:height (.getImageHeight instance)
|
||||
:mtype mtype'}))))
|
||||
|
||||
(defmethod process :default
|
||||
[{:keys [cmd] :as params}]
|
||||
|
@ -164,13 +170,15 @@
|
|||
(defn resolve-urls
|
||||
[row src dst]
|
||||
(s/assert map? row)
|
||||
(let [src (if (vector? src) src [src])
|
||||
dst (if (vector? dst) dst [dst])
|
||||
value (get-in row src)]
|
||||
(if (empty? value)
|
||||
row
|
||||
(let [url (ust/public-uri media/media-storage value)]
|
||||
(assoc-in row dst (str url))))))
|
||||
(if (and src dst)
|
||||
(let [src (if (vector? src) src [src])
|
||||
dst (if (vector? dst) dst [dst])
|
||||
value (get-in row src)]
|
||||
(if (empty? value)
|
||||
row
|
||||
(let [url (ust/public-uri media/media-storage value)]
|
||||
(assoc-in row dst (str url)))))
|
||||
row))
|
||||
|
||||
(defn- resolve-uri
|
||||
[storage row src dst]
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
[uxbox.util.blob :as blob]
|
||||
[uxbox.common.uuid :as uuid]
|
||||
[uxbox.util.data :as data]
|
||||
[uxbox.services.mutations.projects :as projects]
|
||||
[uxbox.services.mutations.files :as files]
|
||||
[uxbox.services.mutations.colors :as colors]
|
||||
[uxbox.services.mutations.icons :as icons]
|
||||
[uxbox.services.mutations.images :as images]
|
||||
|
@ -49,120 +51,243 @@
|
|||
(s/def ::path ::us/string)
|
||||
(s/def ::regex #(instance? java.util.regex.Pattern %))
|
||||
|
||||
(s/def ::colors
|
||||
;; (s/def ::colors
|
||||
;; (s/* (s/cat :name ::us/string :color ::us/color)))
|
||||
;;
|
||||
;; (s/def ::import-item-media
|
||||
;; (s/keys :req-un [::name ::path ::regex]))
|
||||
;;
|
||||
;; (s/def ::import-item-color
|
||||
;; (s/keys :req-un [::name ::id ::colors]))
|
||||
|
||||
(s/def ::import-images
|
||||
(s/keys :req-un [::path ::regex]))
|
||||
|
||||
(s/def ::import-color
|
||||
(s/* (s/cat :name ::us/string :color ::us/color)))
|
||||
|
||||
(s/def ::import-item-media
|
||||
(s/keys :req-un [::name ::path ::regex]))
|
||||
(s/def ::import-colors (s/coll-of ::import-color))
|
||||
|
||||
(s/def ::import-item-color
|
||||
(s/keys :req-un [::name ::id ::colors]))
|
||||
(s/def ::import-library
|
||||
(s/keys :req-un [::name]
|
||||
:opt-un [::import-images ::import-colors]))
|
||||
|
||||
(defn exit!
|
||||
([] (exit! 0))
|
||||
([code]
|
||||
(System/exit code)))
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;; Icons Libraries Importer
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; (defn- icon-library-exists?
|
||||
;; [conn id]
|
||||
;; (s/assert ::us/uuid id)
|
||||
;; (let [row (db/get-by-id conn :icon-library id)]
|
||||
;; (if row true false)))
|
||||
;;
|
||||
;; (defn- create-icons-library
|
||||
;; [conn {:keys [name] :as item}]
|
||||
;; (let [id (uuid/namespaced +icons-uuid-ns+ name)]
|
||||
;; (log/info "Creating icons library:" name)
|
||||
;; (icons/create-library conn {:team-id uuid/zero
|
||||
;; :id id
|
||||
;; :name name})))
|
||||
;;
|
||||
;; (defn- create-icons-library-if-not-exists
|
||||
;; [conn {:keys [name] :as item}]
|
||||
;; (let [id (uuid/namespaced +icons-uuid-ns+ name)]
|
||||
;; (when-not (icon-library-exists? conn id)
|
||||
;; (create-icons-library conn item))
|
||||
;; id))
|
||||
;;
|
||||
;; (defn- create-icon
|
||||
;; [conn library-id icon-id localpath]
|
||||
;; (s/assert fs/path? localpath)
|
||||
;; (s/assert ::us/uuid library-id)
|
||||
;; (s/assert ::us/uuid icon-id)
|
||||
;; (let [filename (fs/name localpath)
|
||||
;; extension (second (fs/split-ext filename))
|
||||
;; data (svg/parse localpath)
|
||||
;; mdata (select-keys data [:width :height :view-box])]
|
||||
;;
|
||||
;; (log/info "Creating or updating icon" filename icon-id)
|
||||
;; (icons/create-icon conn {:id icon-id
|
||||
;; :library-id library-id
|
||||
;; :name (:name data filename)
|
||||
;; :content (:content data)
|
||||
;; :metadata mdata})))
|
||||
;;
|
||||
;; (defn- icon-exists?
|
||||
;; [conn id]
|
||||
;; (s/assert ::us/uuid id)
|
||||
;; (let [row (db/get-by-id conn :icon id)]
|
||||
;; (if row true false)))
|
||||
;;
|
||||
;; (defn- import-icon-if-not-exists
|
||||
;; [conn library-id fpath]
|
||||
;; (s/assert ::us/uuid library-id)
|
||||
;; (s/assert fs/path? fpath)
|
||||
;; (let [icon-id (uuid/namespaced +icons-uuid-ns+ (str library-id (fs/name fpath)))]
|
||||
;; (when-not (icon-exists? conn icon-id)
|
||||
;; (create-icon conn library-id icon-id fpath))
|
||||
;; icon-id))
|
||||
;;
|
||||
;; (defn- import-icons
|
||||
;; [conn library-id {:keys [path regex] :as item}]
|
||||
;; (run! (fn [fpath]
|
||||
;; (when (re-matches regex (str fpath))
|
||||
;; (import-icon-if-not-exists conn library-id fpath)))
|
||||
;; (->> (fs/list-dir path)
|
||||
;; (filter fs/regular-file?))))
|
||||
;;
|
||||
;; (defn- process-icons-library
|
||||
;; [conn basedir {:keys [path regex] :as item}]
|
||||
;; (s/assert ::import-item-media item)
|
||||
;; (let [library-id (create-icons-library-if-not-exists conn item)]
|
||||
;; (->> (assoc item :path (fs/join basedir path))
|
||||
;; (import-icons conn library-id))))
|
||||
;;
|
||||
;;
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;; --- Images Libraries Importer
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; (defn- image-library-exists?
|
||||
;; [conn id]
|
||||
;; (s/assert ::us/uuid id)
|
||||
;; (let [row (db/get-by-id conn :image-library id)]
|
||||
;; (if row true false)))
|
||||
;;
|
||||
;; (defn- create-images-library
|
||||
;; [conn {:keys [name] :as item}]
|
||||
;; (let [id (uuid/namespaced +images-uuid-ns+ name)]
|
||||
;; (log/info "Creating image library:" name)
|
||||
;; (images/create-library conn {:id id
|
||||
;; :team-id uuid/zero
|
||||
;; :name name})))
|
||||
;;
|
||||
;; (defn- create-images-library-if-not-exists
|
||||
;; [conn {:keys [name] :as item}]
|
||||
;; (let [id (uuid/namespaced +images-uuid-ns+ name)]
|
||||
;; (when-not (image-library-exists? conn id)
|
||||
;; (create-images-library conn item)
|
||||
;; id)))
|
||||
;;
|
||||
;; (defn- create-image
|
||||
;; [conn library-id image-id localpath]
|
||||
;; (s/assert fs/path? localpath)
|
||||
;; (s/assert ::us/uuid library-id)
|
||||
;; (s/assert ::us/uuid image-id)
|
||||
;; (let [filename (fs/name localpath)
|
||||
;; extension (second (fs/split-ext filename))
|
||||
;; file (io/as-file localpath)
|
||||
;; mtype (case extension
|
||||
;; ".jpg" "image/jpeg"
|
||||
;; ".png" "image/png"
|
||||
;; ".webp" "image/webp")]
|
||||
;; (log/info "Creating image" filename image-id)
|
||||
;; (images/create-image conn {:content {:tempfile localpath
|
||||
;; :filename filename
|
||||
;; :content-type mtype
|
||||
;; :size (.length file)}
|
||||
;; :id image-id
|
||||
;; :library-id library-id
|
||||
;; :user uuid/zero
|
||||
;; :name filename})))
|
||||
;;
|
||||
;; (defn- image-exists?
|
||||
;; [conn id]
|
||||
;; (s/assert ::us/uuid id)
|
||||
;; (let [row (db/get-by-id conn :image id)]
|
||||
;; (if row true false)))
|
||||
;;
|
||||
;; (defn- import-image-if-not-exists
|
||||
;; [conn library-id fpath]
|
||||
;; (s/assert ::us/uuid library-id)
|
||||
;; (s/assert fs/path? fpath)
|
||||
;; (let [image-id (uuid/namespaced +images-uuid-ns+ (str library-id (fs/name fpath)))]
|
||||
;; (when-not (image-exists? conn image-id)
|
||||
;; (create-image conn library-id image-id fpath))
|
||||
;; image-id))
|
||||
;;
|
||||
;; (defn- import-images
|
||||
;; [conn library-id {:keys [path regex] :as item}]
|
||||
;; (run! (fn [fpath]
|
||||
;; (when (re-matches regex (str fpath))
|
||||
;; (import-image-if-not-exists conn library-id fpath)))
|
||||
;; (->> (fs/list-dir path)
|
||||
;; (filter fs/regular-file?))))
|
||||
;;
|
||||
;; (defn- process-images-library
|
||||
;; [conn basedir {:keys [path regex] :as item}]
|
||||
;; (s/assert ::import-item-media item)
|
||||
;; (let [library-id (create-images-library-if-not-exists conn item)]
|
||||
;; (->> (assoc item :path (fs/join basedir path))
|
||||
;; (import-images conn library-id))))
|
||||
;;
|
||||
;;
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;; Colors Libraries Importer
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; (defn- color-library-exists?
|
||||
;; [conn id]
|
||||
;; (s/assert ::us/uuid id)
|
||||
;; (let [row (db/get-by-id conn :file id)]
|
||||
;; (if row true false)))
|
||||
;;
|
||||
;; (defn- create-colors-library
|
||||
;; [conn {:keys [name] :as item}]
|
||||
;; (let [id (uuid/namespaced +colors-uuid-ns+ name)]
|
||||
;; (log/info "Creating color library:" name)
|
||||
;; (colors/create-library conn {:id id
|
||||
;; :team-id uuid/zero
|
||||
;; :name name})))
|
||||
;;
|
||||
;;
|
||||
;; (defn- create-colors-library-if-not-exists
|
||||
;; [conn {:keys [name] :as item}]
|
||||
;; (let [id (uuid/namespaced +colors-uuid-ns+ name)]
|
||||
;; (when-not (color-library-exists? conn id)
|
||||
;; (create-colors-library conn item))
|
||||
;; id))
|
||||
;;
|
||||
;; (defn- create-color
|
||||
;; [conn library-id name content]
|
||||
;; (s/assert ::us/uuid library-id)
|
||||
;; (s/assert ::us/color content)
|
||||
;; (let [color-id (uuid/namespaced +colors-uuid-ns+ (str library-id content))]
|
||||
;; (log/info "Creating color" color-id "-" name content)
|
||||
;; (colors/create-color conn {:id color-id
|
||||
;; :library-id library-id
|
||||
;; :name name
|
||||
;; :content content})
|
||||
;; color-id))
|
||||
;;
|
||||
;; (defn- import-colors
|
||||
;; [conn library-id {:keys [colors] :as item}]
|
||||
;; (db/delete! conn :color {:library-id library-id})
|
||||
;; (run! (fn [[name content]]
|
||||
;; (create-color conn library-id name content))
|
||||
;; (partition-all 2 colors)))
|
||||
;;
|
||||
;; (defn- process-colors-library
|
||||
;; [conn {:keys [name id colors] :as item}]
|
||||
;; (us/verify ::import-item-color item)
|
||||
;; (let [library-id (create-colors-library-if-not-exists conn item)]
|
||||
;; (import-colors conn library-id item)))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Icons Libraries Importer
|
||||
;; Images Importer
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn- icon-library-exists?
|
||||
[conn id]
|
||||
(s/assert ::us/uuid id)
|
||||
(let [row (db/get-by-id conn :icon-library id)]
|
||||
(if row true false)))
|
||||
|
||||
(defn- create-icons-library
|
||||
[conn {:keys [name] :as item}]
|
||||
(let [id (uuid/namespaced +icons-uuid-ns+ name)]
|
||||
(log/info "Creating icons library:" name)
|
||||
(icons/create-library conn {:team-id uuid/zero
|
||||
:id id
|
||||
:name name})))
|
||||
|
||||
(defn- create-icons-library-if-not-exists
|
||||
[conn {:keys [name] :as item}]
|
||||
(let [id (uuid/namespaced +icons-uuid-ns+ name)]
|
||||
(when-not (icon-library-exists? conn id)
|
||||
(create-icons-library conn item))
|
||||
id))
|
||||
|
||||
(defn- create-icon
|
||||
[conn library-id icon-id localpath]
|
||||
(s/assert fs/path? localpath)
|
||||
(s/assert ::us/uuid library-id)
|
||||
(s/assert ::us/uuid icon-id)
|
||||
(let [filename (fs/name localpath)
|
||||
extension (second (fs/split-ext filename))
|
||||
data (svg/parse localpath)
|
||||
mdata (select-keys data [:width :height :view-box])]
|
||||
|
||||
(log/info "Creating or updating icon" filename icon-id)
|
||||
(icons/create-icon conn {:id icon-id
|
||||
:library-id library-id
|
||||
:name (:name data filename)
|
||||
:content (:content data)
|
||||
:metadata mdata})))
|
||||
|
||||
(defn- icon-exists?
|
||||
[conn id]
|
||||
(s/assert ::us/uuid id)
|
||||
(let [row (db/get-by-id conn :icon id)]
|
||||
(if row true false)))
|
||||
|
||||
(defn- import-icon-if-not-exists
|
||||
[conn library-id fpath]
|
||||
(s/assert ::us/uuid library-id)
|
||||
(s/assert fs/path? fpath)
|
||||
(let [icon-id (uuid/namespaced +icons-uuid-ns+ (str library-id (fs/name fpath)))]
|
||||
(when-not (icon-exists? conn icon-id)
|
||||
(create-icon conn library-id icon-id fpath))
|
||||
icon-id))
|
||||
|
||||
(defn- import-icons
|
||||
[conn library-id {:keys [path regex] :as item}]
|
||||
(run! (fn [fpath]
|
||||
(when (re-matches regex (str fpath))
|
||||
(import-icon-if-not-exists conn library-id fpath)))
|
||||
(->> (fs/list-dir path)
|
||||
(filter fs/regular-file?))))
|
||||
|
||||
(defn- process-icons-library
|
||||
[conn basedir {:keys [path regex] :as item}]
|
||||
(s/assert ::import-item-media item)
|
||||
(let [library-id (create-icons-library-if-not-exists conn item)]
|
||||
(->> (assoc item :path (fs/join basedir path))
|
||||
(import-icons conn library-id))))
|
||||
|
||||
|
||||
;; --- Images Libraries Importer
|
||||
|
||||
(defn- image-library-exists?
|
||||
[conn id]
|
||||
(s/assert ::us/uuid id)
|
||||
(let [row (db/get-by-id conn :image-library id)]
|
||||
(if row true false)))
|
||||
|
||||
(defn- create-images-library
|
||||
[conn {:keys [name] :as item}]
|
||||
(let [id (uuid/namespaced +images-uuid-ns+ name)]
|
||||
(log/info "Creating image library:" name)
|
||||
(images/create-library conn {:id id
|
||||
:team-id uuid/zero
|
||||
:name name})))
|
||||
|
||||
(defn- create-images-library-if-not-exists
|
||||
[conn {:keys [name] :as item}]
|
||||
(let [id (uuid/namespaced +images-uuid-ns+ name)]
|
||||
(when-not (image-library-exists? conn id)
|
||||
(create-images-library conn item)
|
||||
id)))
|
||||
|
||||
(defn- create-image
|
||||
[conn library-id image-id localpath]
|
||||
[conn file-id image-id localpath]
|
||||
(s/assert fs/path? localpath)
|
||||
(s/assert ::us/uuid library-id)
|
||||
(s/assert ::us/uuid file-id)
|
||||
(s/assert ::us/uuid image-id)
|
||||
(let [filename (fs/name localpath)
|
||||
extension (second (fs/split-ext filename))
|
||||
|
@ -170,14 +295,15 @@
|
|||
mtype (case extension
|
||||
".jpg" "image/jpeg"
|
||||
".png" "image/png"
|
||||
".webp" "image/webp")]
|
||||
".webp" "image/webp"
|
||||
".svg" "image/svg+xml")]
|
||||
(log/info "Creating image" filename image-id)
|
||||
(images/create-image conn {:content {:tempfile localpath
|
||||
:filename filename
|
||||
:content-type mtype
|
||||
:size (.length file)}
|
||||
:id image-id
|
||||
:library-id library-id
|
||||
:file-id file-id
|
||||
:user uuid/zero
|
||||
:name filename})))
|
||||
|
||||
|
@ -188,85 +314,100 @@
|
|||
(if row true false)))
|
||||
|
||||
(defn- import-image-if-not-exists
|
||||
[conn library-id fpath]
|
||||
(s/assert ::us/uuid library-id)
|
||||
[conn file-id fpath]
|
||||
(s/assert ::us/uuid file-id)
|
||||
(s/assert fs/path? fpath)
|
||||
(let [image-id (uuid/namespaced +images-uuid-ns+ (str library-id (fs/name fpath)))]
|
||||
(let [image-id (uuid/namespaced +images-uuid-ns+ (str file-id (fs/name fpath)))]
|
||||
(when-not (image-exists? conn image-id)
|
||||
(create-image conn library-id image-id fpath))
|
||||
(create-image conn file-id image-id fpath))
|
||||
image-id))
|
||||
|
||||
(defn- import-images
|
||||
[conn library-id {:keys [path regex] :as item}]
|
||||
[conn file-id {:keys [path regex] :as images}]
|
||||
(run! (fn [fpath]
|
||||
(when (re-matches regex (str fpath))
|
||||
(import-image-if-not-exists conn library-id fpath)))
|
||||
(import-image-if-not-exists conn file-id fpath)))
|
||||
(->> (fs/list-dir path)
|
||||
(filter fs/regular-file?))))
|
||||
|
||||
(defn- process-images-library
|
||||
[conn basedir {:keys [path regex] :as item}]
|
||||
(s/assert ::import-item-media item)
|
||||
(let [library-id (create-images-library-if-not-exists conn item)]
|
||||
(->> (assoc item :path (fs/join basedir path))
|
||||
(import-images conn library-id))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Colors Libraries Importer
|
||||
;; Colors Importer
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn- color-library-exists?
|
||||
[conn id]
|
||||
(s/assert ::us/uuid id)
|
||||
(let [row (db/get-by-id conn :color-library id)]
|
||||
(if row true false)))
|
||||
|
||||
(defn- create-colors-library
|
||||
[conn {:keys [name] :as item}]
|
||||
(let [id (uuid/namespaced +colors-uuid-ns+ name)]
|
||||
(log/info "Creating color library:" name)
|
||||
(colors/create-library conn {:id id
|
||||
:team-id uuid/zero
|
||||
:name name})))
|
||||
|
||||
|
||||
(defn- create-colors-library-if-not-exists
|
||||
[conn {:keys [name] :as item}]
|
||||
(let [id (uuid/namespaced +colors-uuid-ns+ name)]
|
||||
(when-not (color-library-exists? conn id)
|
||||
(create-colors-library conn item))
|
||||
id))
|
||||
|
||||
(defn- create-color
|
||||
[conn library-id name content]
|
||||
(s/assert ::us/uuid library-id)
|
||||
[conn file-id name content]
|
||||
(s/assert ::us/uuid file-id)
|
||||
(s/assert ::us/color content)
|
||||
(let [color-id (uuid/namespaced +colors-uuid-ns+ (str library-id content))]
|
||||
(let [color-id (uuid/namespaced +colors-uuid-ns+ (str file-id content))]
|
||||
(log/info "Creating color" color-id "-" name content)
|
||||
(colors/create-color conn {:id color-id
|
||||
:library-id library-id
|
||||
:file-id file-id
|
||||
:name name
|
||||
:content content})
|
||||
color-id))
|
||||
|
||||
(defn- import-colors
|
||||
[conn library-id {:keys [colors] :as item}]
|
||||
(db/delete! conn :color {:library-id library-id})
|
||||
[conn file-id colors]
|
||||
(db/delete! conn :color {:file-id file-id})
|
||||
(run! (fn [[name content]]
|
||||
(create-color conn library-id name content))
|
||||
(create-color conn file-id name content))
|
||||
(partition-all 2 colors)))
|
||||
|
||||
(defn- process-colors-library
|
||||
[conn {:keys [name id colors] :as item}]
|
||||
(us/verify ::import-item-color item)
|
||||
(let [library-id (create-colors-library-if-not-exists conn item)]
|
||||
(import-colors conn library-id item)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Libraries Importer
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn- library-file-exists?
|
||||
[conn id]
|
||||
(s/assert ::us/uuid id)
|
||||
(let [row (db/get-by-id conn :file id)]
|
||||
(if row true false)))
|
||||
|
||||
(defn- create-library-file-if-not-exists
|
||||
[conn project-id {:keys [name] :as library-file}]
|
||||
(let [id (uuid/namespaced +colors-uuid-ns+ name)]
|
||||
(when-not (library-file-exists? conn id)
|
||||
(log/info "Creating library-file:" name)
|
||||
(files/create-file conn {:id id
|
||||
:profile-id uuid/zero
|
||||
:project-id project-id
|
||||
:name name})
|
||||
(files/create-page conn {:file-id id}))
|
||||
id))
|
||||
|
||||
(defn- process-library
|
||||
[conn basedir project-id {:keys [name images colors] :as library}]
|
||||
(us/verify ::import-library library)
|
||||
(let [library-file-id (create-library-file-if-not-exists conn project-id library)]
|
||||
(when images
|
||||
(->> (assoc images :path (fs/join basedir (:path images)))
|
||||
(import-images conn library-file-id)))
|
||||
(when colors
|
||||
(import-colors conn library-file-id colors))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Entry Point
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn- project-exists?
|
||||
[conn id]
|
||||
(s/assert ::us/uuid id)
|
||||
(let [row (db/get-by-id conn :project id)]
|
||||
(if row true false)))
|
||||
|
||||
(defn- create-project-if-not-exists
|
||||
[conn {:keys [name] :as project}]
|
||||
(let [id (uuid/namespaced +colors-uuid-ns+ name)]
|
||||
(when-not (project-exists? conn id)
|
||||
(log/info "Creating project" name)
|
||||
(projects/create-project conn {:id id
|
||||
:team-id uuid/zero
|
||||
:name name
|
||||
:default? false}))
|
||||
id))
|
||||
|
||||
(defn- validate-path
|
||||
[path]
|
||||
(when-not path
|
||||
|
@ -295,20 +436,21 @@
|
|||
[]
|
||||
(mount/stop))
|
||||
|
||||
(defn- importer
|
||||
[conn basedir data]
|
||||
(let [images (:images data)
|
||||
icons (:icons data)
|
||||
colors (:colors data)]
|
||||
(run! #(process-images-library conn basedir %) images)
|
||||
(run! #(process-icons-library conn basedir %) icons)
|
||||
(run! #(process-colors-library conn %) colors)))
|
||||
;; (defn- importer
|
||||
;; [conn basedir data]
|
||||
;; (let [images (:images data)
|
||||
;; icons (:icons data)
|
||||
;; colors (:colors data)]
|
||||
;; (run! #(process-images-library conn basedir %) images)
|
||||
;; (run! #(process-icons-library conn basedir %) icons)
|
||||
;; (run! #(process-colors-library conn %) colors)))
|
||||
|
||||
(defn run
|
||||
[path]
|
||||
(let [[basedir data] (read-file path)]
|
||||
(let [[basedir libraries] (read-file path)]
|
||||
(db/with-atomic [conn db/pool]
|
||||
(importer conn basedir data))))
|
||||
(let [project-id (create-project-if-not-exists conn {:name "Media loader"})]
|
||||
(run! #(process-library conn basedir project-id %) libraries)))))
|
||||
|
||||
(defn -main
|
||||
[& [path]]
|
||||
|
|
|
@ -59,7 +59,11 @@
|
|||
|
||||
{:desc "Add session_id field to page_change table"
|
||||
:name "0011-add-session-id-field-to-page-change-table"
|
||||
:fn (mg/resource "migrations/0011-add-session-id-field-to-page-change-table.sql")}]})
|
||||
:fn (mg/resource "migrations/0011-add-session-id-field-to-page-change-table.sql")}
|
||||
|
||||
{:desc "Make libraries linked to a file"
|
||||
:name "0012-make-libraries-linked-to-a-file"
|
||||
:fn (mg/resource "migrations/0012-make-libraries-linked-to-a-file.sql")}]})
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Entry point
|
||||
|
|
|
@ -119,26 +119,27 @@
|
|||
(declare create-color)
|
||||
|
||||
(s/def ::create-color
|
||||
(s/keys :req-un [::profile-id ::name ::content ::library-id]
|
||||
(s/keys :req-un [::profile-id ::name ::content ::file-id]
|
||||
:opt-un [::id]))
|
||||
|
||||
(sm/defmutation ::create-color
|
||||
[{:keys [profile-id library-id] :as params}]
|
||||
[{:keys [profile-id file-id] :as params}]
|
||||
(db/with-atomic [conn db/pool]
|
||||
(let [lib (select-library-for-update conn library-id)]
|
||||
(teams/check-edition-permissions! conn profile-id (:team-id lib))
|
||||
(create-color conn params))))
|
||||
(create-color conn params)))
|
||||
;; (let [lib (select-library-for-update conn library-id)]
|
||||
;; (teams/check-edition-permissions! conn profile-id (:team-id lib))
|
||||
;; (create-color conn params))))
|
||||
|
||||
(def ^:private sql:create-color
|
||||
"insert into color (id, name, library_id, content)
|
||||
"insert into color (id, name, file_id, content)
|
||||
values ($1, $2, $3, $4) returning *")
|
||||
|
||||
(defn create-color
|
||||
[conn {:keys [id name library-id content]}]
|
||||
[conn {:keys [id name file-id content]}]
|
||||
(let [id (or id (uuid/next))]
|
||||
(db/insert! conn :color {:id id
|
||||
:name name
|
||||
:library-id library-id
|
||||
:file-id file-id
|
||||
:content content})))
|
||||
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
:is-admin true
|
||||
:can-edit true}))
|
||||
|
||||
(defn- create-file
|
||||
(defn create-file
|
||||
[conn {:keys [id profile-id name project-id] :as params}]
|
||||
(let [id (or id (uuid/next))
|
||||
file (db/insert! conn :file {:id id :project-id project-id :name name})]
|
||||
|
@ -70,7 +70,7 @@
|
|||
(create-file-profile conn))
|
||||
file))
|
||||
|
||||
(defn- create-page
|
||||
(defn create-page
|
||||
[conn {:keys [file-id] :as params}]
|
||||
(let [id (uuid/next)]
|
||||
(db/insert! conn :page
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
(s/def ::id ::us/uuid)
|
||||
(s/def ::name ::us/string)
|
||||
(s/def ::profile-id ::us/uuid)
|
||||
(s/def ::library-id ::us/uuid)
|
||||
(s/def ::file-id ::us/uuid)
|
||||
(s/def ::team-id ::us/uuid)
|
||||
(s/def ::url ::us/url)
|
||||
|
||||
|
@ -112,7 +112,7 @@
|
|||
(declare persist-image-thumbnail-on-fs)
|
||||
|
||||
(def valid-image-types?
|
||||
#{"image/jpeg", "image/png", "image/webp"})
|
||||
#{"image/jpeg", "image/png", "image/webp", "image/svg+xml"})
|
||||
|
||||
(s/def :uxbox$upload/filename ::us/string)
|
||||
(s/def :uxbox$upload/size ::us/integer)
|
||||
|
@ -128,17 +128,17 @@
|
|||
(s/def ::content ::upload)
|
||||
|
||||
(s/def ::add-image-from-url
|
||||
(s/keys :req-un [::profile-id ::library-id ::url]
|
||||
(s/keys :req-un [::profile-id ::file-id ::url]
|
||||
:opt-un [::id]))
|
||||
|
||||
(s/def ::upload-image
|
||||
(s/keys :req-un [::profile-id ::library-id ::name ::content]
|
||||
(s/keys :req-un [::profile-id ::file-id ::name ::content]
|
||||
:opt-un [::id]))
|
||||
|
||||
(sm/defmutation ::add-image-from-url
|
||||
[{:keys [profile-id library-id url] :as params}]
|
||||
[{:keys [profile-id file-id url] :as params}]
|
||||
(db/with-atomic [conn db/pool]
|
||||
(let [lib (select-library-for-update conn library-id)]
|
||||
(let [lib (select-library-for-update conn file-id)]
|
||||
(teams/check-edition-permissions! conn profile-id (:team-id lib))
|
||||
(let [content (images/download-image url)
|
||||
params' (merge params {:content content
|
||||
|
@ -146,14 +146,14 @@
|
|||
(create-image conn params')))))
|
||||
|
||||
(sm/defmutation ::upload-image
|
||||
[{:keys [profile-id library-id] :as params}]
|
||||
[{:keys [profile-id file-id] :as params}]
|
||||
(db/with-atomic [conn db/pool]
|
||||
(let [lib (select-library-for-update conn library-id)]
|
||||
(let [lib (select-library-for-update conn file-id)]
|
||||
(teams/check-edition-permissions! conn profile-id (:team-id lib))
|
||||
(create-image conn params))))
|
||||
|
||||
(defn create-image
|
||||
[conn {:keys [id content library-id name]}]
|
||||
[conn {:keys [id content file-id name]}]
|
||||
(when-not (valid-image-types? (:content-type content))
|
||||
(ex/raise :type :validation
|
||||
:code :image-type-not-allowed
|
||||
|
@ -165,11 +165,15 @@
|
|||
opts (assoc thumbnail-options
|
||||
:input {:mtype (:mtype info)
|
||||
:path path})
|
||||
thumb (persist-image-thumbnail-on-fs opts)]
|
||||
thumb (if-not (= (:mtype info) "image/svg+xml")
|
||||
(persist-image-thumbnail-on-fs opts)
|
||||
(assoc info
|
||||
:path path
|
||||
:quality 0))]
|
||||
|
||||
(-> (db/insert! conn :image
|
||||
{:id (or id (uuid/next))
|
||||
:library-id library-id
|
||||
:file-id file-id
|
||||
:name name
|
||||
:path (str path)
|
||||
:width (:width info)
|
||||
|
|
|
@ -28,9 +28,10 @@
|
|||
(s/def ::id ::us/uuid)
|
||||
(s/def ::profile-id ::us/uuid)
|
||||
(s/def ::team-id ::us/uuid)
|
||||
(s/def ::file-id ::us/uuid)
|
||||
(s/def ::library-id (s/nilable ::us/uuid))
|
||||
|
||||
;; --- Query: Colors Librarys
|
||||
;; --- Query: Colors Libraries
|
||||
|
||||
(def ^:private sql:libraries
|
||||
"select lib.*,
|
||||
|
@ -78,31 +79,31 @@
|
|||
(ex/raise :type :not-found))
|
||||
row))
|
||||
|
||||
;; --- Query: Colors (by library)
|
||||
;; --- Query: Colors (by file)
|
||||
|
||||
(declare retrieve-colors)
|
||||
|
||||
(s/def ::colors
|
||||
(s/keys :req-un [::profile-id ::library-id]))
|
||||
(s/keys :req-un [::profile-id ::file-id]))
|
||||
|
||||
(sq/defquery ::colors
|
||||
[{:keys [profile-id library-id] :as params}]
|
||||
[{:keys [profile-id file-id] :as params}]
|
||||
(db/with-atomic [conn db/pool]
|
||||
(let [lib (retrieve-library conn library-id)]
|
||||
(teams/check-read-permissions! conn profile-id (:team-id lib))
|
||||
(retrieve-colors conn library-id))))
|
||||
(retrieve-colors conn file-id)))
|
||||
;; (let [lib (retrieve-library conn library-id)]
|
||||
;; (teams/check-read-permissions! conn profile-id (:team-id lib))
|
||||
;; (retrieve-colors conn library-id))))
|
||||
|
||||
(def ^:private sql:colors
|
||||
"select color.*
|
||||
from color as color
|
||||
inner join color_library as lib on (lib.id = color.library_id)
|
||||
"select *
|
||||
from color
|
||||
where color.deleted_at is null
|
||||
and color.library_id = ?
|
||||
and color.file_id = ?
|
||||
order by created_at desc")
|
||||
|
||||
(defn- retrieve-colors
|
||||
[conn library-id]
|
||||
(db/exec! conn [sql:colors library-id]))
|
||||
[conn file-id]
|
||||
(db/exec! conn [sql:colors file-id]))
|
||||
|
||||
|
||||
;; --- Query: Color (by ID)
|
||||
|
|
|
@ -53,6 +53,11 @@
|
|||
and (ppr.is_admin = true or
|
||||
ppr.is_owner = true or
|
||||
ppr.can_edit = true)
|
||||
union
|
||||
select p.*
|
||||
from project as p
|
||||
where p.team_id = uuid_nil()
|
||||
and p.deleted_at is null
|
||||
)
|
||||
select distinct
|
||||
file.*,
|
||||
|
@ -80,23 +85,52 @@
|
|||
(mapv decode-row rows)))
|
||||
|
||||
|
||||
;; --- Query: Draft Files
|
||||
;; --- Query: Project Files
|
||||
|
||||
(def ^:private sql:files
|
||||
"select distinct
|
||||
"with projects as (
|
||||
select p.*
|
||||
from project as p
|
||||
inner join team_profile_rel as tpr on (tpr.team_id = p.team_id)
|
||||
where tpr.profile_id = ?
|
||||
and p.deleted_at is null
|
||||
and (tpr.is_admin = true or
|
||||
tpr.is_owner = true or
|
||||
tpr.can_edit = true)
|
||||
union
|
||||
select p.*
|
||||
from project as p
|
||||
inner join project_profile_rel as ppr on (ppr.project_id = p.id)
|
||||
where ppr.profile_id = ?
|
||||
and p.deleted_at is null
|
||||
and (ppr.is_admin = true or
|
||||
ppr.is_owner = true or
|
||||
ppr.can_edit = true)
|
||||
union
|
||||
select p.*
|
||||
from project as p
|
||||
where p.team_id = uuid_nil()
|
||||
and p.deleted_at is null
|
||||
)
|
||||
select distinct
|
||||
f.*,
|
||||
array_agg(pg.id) over pages_w as pages,
|
||||
first_value(pg.data) over pages_w as data
|
||||
from file as f
|
||||
inner join file_profile_rel as fp_r on (fp_r.file_id = f.id)
|
||||
left join page as pg on (f.id = pg.file_id)
|
||||
where fp_r.profile_id = ?
|
||||
and f.project_id = ?
|
||||
where f.project_id = ?
|
||||
and (exists (select *
|
||||
from file_profile_rel as fp_r
|
||||
where fp_r.profile_id = ?
|
||||
and fp_r.file_id = f.id
|
||||
and (fp_r.is_admin = true or
|
||||
fp_r.is_owner = true or
|
||||
fp_r.can_edit = true))
|
||||
or exists (select *
|
||||
from projects as p
|
||||
where p.id = f.project_id))
|
||||
and f.deleted_at is null
|
||||
and pg.deleted_at is null
|
||||
and (fp_r.is_admin = true or
|
||||
fp_r.is_owner = true or
|
||||
fp_r.can_edit = true)
|
||||
window pages_w as (partition by f.id order by pg.ordering
|
||||
range between unbounded preceding
|
||||
and unbounded following)
|
||||
|
@ -108,7 +142,9 @@
|
|||
|
||||
(sq/defquery ::files
|
||||
[{:keys [profile-id project-id] :as params}]
|
||||
(->> (db/exec! db/pool [sql:files profile-id project-id])
|
||||
(->> (db/exec! db/pool [sql:files
|
||||
profile-id profile-id
|
||||
project-id profile-id])
|
||||
(mapv decode-row)))
|
||||
|
||||
;; --- Query: File Permissions
|
||||
|
@ -136,7 +172,12 @@
|
|||
from project_profile_rel as ppr
|
||||
inner join file as f on (f.project_id = ppr.project_id)
|
||||
where f.id = ?
|
||||
and ppr.profile_id = ?;")
|
||||
and ppr.profile_id = ?
|
||||
union all
|
||||
select true, true, true
|
||||
from file as f
|
||||
inner join project as p on (f.project_id = p.id)
|
||||
and p.team_id = uuid_nil();")
|
||||
|
||||
(defn check-edition-permissions!
|
||||
[conn profile-id file-id]
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
(s/def ::name ::us/string)
|
||||
(s/def ::profile-id ::us/uuid)
|
||||
(s/def ::team-id ::us/uuid)
|
||||
(s/def ::library-id ::us/uuid)
|
||||
(s/def ::file-id ::us/uuid)
|
||||
|
||||
;; --- Query: Image Librarys
|
||||
|
||||
|
@ -77,32 +77,34 @@
|
|||
(declare retrieve-images)
|
||||
|
||||
(s/def ::images
|
||||
(s/keys :req-un [::profile-id ::library-id]))
|
||||
(s/keys :req-un [::profile-id ::file-id]))
|
||||
|
||||
;; TODO: check if we can resolve url with transducer for reduce
|
||||
;; garbage generation for each request
|
||||
|
||||
(sq/defquery ::images
|
||||
[{:keys [profile-id library-id] :as params}]
|
||||
[{:keys [profile-id file-id] :as params}]
|
||||
(db/with-atomic [conn db/pool]
|
||||
(let [lib (retrieve-library conn library-id)]
|
||||
(teams/check-read-permissions! conn profile-id (:team-id lib))
|
||||
(->> (retrieve-images conn library-id)
|
||||
(mapv #(images/resolve-urls % :path :uri))
|
||||
(mapv #(images/resolve-urls % :thumb-path :thumb-uri))))))
|
||||
(->> (retrieve-images conn file-id)
|
||||
(mapv #(images/resolve-urls % :path :uri))
|
||||
(mapv #(images/resolve-urls % :thumb-path :thumb-uri)))))
|
||||
;; (let [lib (retrieve-library conn file-id)]
|
||||
;; (teams/check-read-permissions! conn profile-id (:team-id lib))
|
||||
;; (->> (retrieve-images conn file-id)
|
||||
;; (mapv #(images/resolve-urls % :path :uri))
|
||||
;; (mapv #(images/resolve-urls % :thumb-path :thumb-uri))))))
|
||||
|
||||
|
||||
(def ^:private sql:images
|
||||
"select img.*
|
||||
"select *
|
||||
from image as img
|
||||
inner join image_library as lib on (lib.id = img.library_id)
|
||||
where img.deleted_at is null
|
||||
and img.library_id = ?
|
||||
and img.file_id = ?
|
||||
order by created_at desc")
|
||||
|
||||
(defn- retrieve-images
|
||||
[conn library-id]
|
||||
(db/exec! conn [sql:images library-id]))
|
||||
[conn file-id]
|
||||
(db/exec! conn [sql:images file-id]))
|
||||
|
||||
|
||||
|
||||
|
@ -125,9 +127,9 @@
|
|||
|
||||
(def ^:private sql:single-image
|
||||
"select img.*,
|
||||
lib.team_id as team_id
|
||||
file.team_id as team_id
|
||||
from image as img
|
||||
inner join image_library as lib on (lib.id = img.library_id)
|
||||
inner join file on (file.id = img.file_id)
|
||||
where img.deleted_at is null
|
||||
and img.id = ?
|
||||
order by created_at desc")
|
||||
|
|
|
@ -48,10 +48,19 @@
|
|||
and (ppr.is_admin = true or
|
||||
ppr.is_owner = true or
|
||||
ppr.can_edit = true)
|
||||
union
|
||||
select p.*,
|
||||
(select count(*) from file as f
|
||||
where f.project_id = p.id
|
||||
and deleted_at is null)
|
||||
from project as p
|
||||
where p.team_id = uuid_nil()
|
||||
and p.deleted_at is null
|
||||
)
|
||||
select *
|
||||
from projects
|
||||
where team_id = ?
|
||||
or team_id = uuid_nil()
|
||||
order by modified_at desc")
|
||||
|
||||
(def ^:private sql:project-by-id
|
||||
|
|
|
@ -134,6 +134,31 @@
|
|||
}
|
||||
}
|
||||
|
||||
.group-list {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.group-list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: $x-small;
|
||||
font-size: $fs11;
|
||||
color: $color-white;
|
||||
|
||||
& .color-block {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 10px;
|
||||
margin-right: $x-small;
|
||||
}
|
||||
|
||||
& span {
|
||||
margin-left: $x-small;
|
||||
color: $color-gray-30;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
.context-menu {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
|
|
|
@ -75,10 +75,9 @@
|
|||
(s/def ::layout-flags (s/coll-of ::layout-flag))
|
||||
|
||||
(def default-layout
|
||||
#{;; :sitemap
|
||||
;; :sitemap-pages
|
||||
;; :layers
|
||||
:assets
|
||||
#{:sitemap
|
||||
:sitemap-pages
|
||||
:layers
|
||||
:element-options
|
||||
:rules
|
||||
:display-grid
|
||||
|
@ -1441,6 +1440,7 @@
|
|||
(def add-image-from-url dwp/add-image-from-url)
|
||||
(def upload-image dwp/upload-image)
|
||||
(def delete-file-image dwp/delete-file-image)
|
||||
(def fetch-colors dwp/fetch-colors)
|
||||
(def rename-page dwp/rename-page)
|
||||
(def delete-page dwp/delete-page)
|
||||
(def create-empty-page dwp/create-empty-page)
|
||||
|
|
|
@ -289,7 +289,7 @@
|
|||
(ptk/reify ::fetch-images
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(->> (rp/query :file-images {:file-id file-id})
|
||||
(->> (rp/query :images {:file-id file-id})
|
||||
(rx/map images-fetched)))))
|
||||
|
||||
(defn images-fetched
|
||||
|
@ -300,6 +300,26 @@
|
|||
(let [images (d/index-by :id images)]
|
||||
(assoc state :workspace-images images)))))
|
||||
|
||||
;; --- Fetch Workspace Colors
|
||||
|
||||
(declare colors-fetched)
|
||||
|
||||
(defn fetch-colors
|
||||
[file-id]
|
||||
(ptk/reify ::fetch-colors
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(->> (rp/query :colors {:file-id file-id})
|
||||
(rx/map colors-fetched)))))
|
||||
|
||||
(defn colors-fetched
|
||||
[colors]
|
||||
(ptk/reify ::colors-fetched
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [colors (d/index-by :id colors)]
|
||||
(assoc state :workspace-colors colors)))))
|
||||
|
||||
|
||||
;; --- Upload Image
|
||||
|
||||
|
|
|
@ -60,6 +60,9 @@
|
|||
(def workspace-images
|
||||
(l/derived :workspace-images st/state))
|
||||
|
||||
(def workspace-colors
|
||||
(l/derived :workspace-colors st/state))
|
||||
|
||||
(def workspace-users
|
||||
(l/derived :workspace-users st/state))
|
||||
|
||||
|
|
|
@ -89,10 +89,24 @@
|
|||
[:div.asset-group
|
||||
[:div.group-title
|
||||
(tr "workspace.assets.colors")
|
||||
[:div.group-button {:on-click add-color} i/plus]]]))
|
||||
[:span (str "\u00A0(") (count colors) ")"] ;; Unicode 00A0 is non-breaking space
|
||||
[:div.group-button {:on-click add-color} i/plus]]
|
||||
[:div.group-list
|
||||
(for [color (sort-by :name colors)]
|
||||
[:div.group-list-item {:key (:name color)
|
||||
:on-context-menu #(println "context")}
|
||||
[:div.color-block {:style {:background-color (:content color)}}]
|
||||
(:name color)
|
||||
(when-not (= (:name color) (:content color))
|
||||
[:span (:content color)])])]]))
|
||||
|
||||
(mf/defc library-toolbox
|
||||
[{:keys [library-id images initial-open? search-term box-filter] :as props}]
|
||||
[{:keys [library-id
|
||||
images
|
||||
colors
|
||||
initial-open?
|
||||
search-term
|
||||
box-filter] :as props}]
|
||||
(let [open? (mf/use-state initial-open?)
|
||||
toggle-open #(swap! open? not)]
|
||||
[:div.tool-window
|
||||
|
@ -107,13 +121,14 @@
|
|||
(when (or (= box-filter :all) (= box-filter :graphics))
|
||||
[:& graphics-box {:library-id library-id :images images}])
|
||||
(when (or (= box-filter :all) (= box-filter :colors))
|
||||
[:& colors-box {:colors {}}])])]))
|
||||
[:& colors-box {:colors colors}])])]))
|
||||
|
||||
(mf/defc assets-toolbox
|
||||
[]
|
||||
(let [team-id (-> refs/workspace-project mf/deref :team-id)
|
||||
file-id (-> refs/workspace-file mf/deref :id)
|
||||
file-images (mf/deref refs/workspace-images)
|
||||
file-colors (mf/deref refs/workspace-colors)
|
||||
|
||||
state (mf/use-state {:search-term ""
|
||||
:box-filter :all})
|
||||
|
@ -121,6 +136,9 @@
|
|||
filtered-images (filter #(matches-search (:name %) (:search-term @state))
|
||||
(vals file-images))
|
||||
|
||||
filtered-colors (filter #(matches-search (:name %) (:search-term @state))
|
||||
(vals file-colors))
|
||||
|
||||
on-search-term-change (fn [event]
|
||||
(let [value (-> (dom/get-target event)
|
||||
(dom/get-value))]
|
||||
|
@ -135,7 +153,8 @@
|
|||
(mf/use-effect
|
||||
(mf/deps file-id)
|
||||
#(when file-id
|
||||
(st/emit! (dw/fetch-images file-id))))
|
||||
(st/emit! (dw/fetch-images file-id))
|
||||
(st/emit! (dw/fetch-colors file-id))))
|
||||
|
||||
[:div.assets-bar
|
||||
|
||||
|
@ -158,6 +177,7 @@
|
|||
|
||||
[:& library-toolbox {:library-id file-id
|
||||
:images filtered-images
|
||||
:colors filtered-colors
|
||||
:initial-open? true
|
||||
:search-term (:search-term @state)
|
||||
:box-filter (:box-filter @state)}]]))
|
||||
|
|
|
@ -1,54 +1,58 @@
|
|||
{:icons
|
||||
[{:name "Material Design (Action)"
|
||||
:path "./icons/material-action"
|
||||
:regex #"^.*_48px\.svg$"}
|
||||
[
|
||||
;; Icons
|
||||
{:name "Material Design (Action)"
|
||||
:images {:path "./icons/material-action"
|
||||
:regex #"^.*_48px\.svg$"}}
|
||||
{:name "Material Design (Alert)"
|
||||
:path "./icons/material-alert"
|
||||
:regex #"^.*_48px\.svg$"}
|
||||
:images {:path "./icons/material-alert"
|
||||
:regex #"^.*_48px\.svg$"}}
|
||||
{:name "Material Design (Av)"
|
||||
:path "./icons/material-av"
|
||||
:regex #"^.*_48px\.svg$"}
|
||||
:images {:path "./icons/material-av"
|
||||
:regex #"^.*_48px\.svg$"}}
|
||||
{:name "Material Design (Content)"
|
||||
:path "./icons/material-content"
|
||||
:regex #"^.*_48px\.svg$"}
|
||||
:images {:path "./icons/material-content"
|
||||
:regex #"^.*_48px\.svg$"}}
|
||||
{:name "Material Design (Device)"
|
||||
:path "./icons/material-device"
|
||||
:regex #"^.*_48px\.svg$"}
|
||||
:images {:path "./icons/material-device"
|
||||
:regex #"^.*_48px\.svg$"}}
|
||||
{:name "Material Design (Editor)"
|
||||
:path "./icons/material-editor"
|
||||
:regex #"^.*_48px\.svg$"}
|
||||
:images {:path "./icons/material-editor"
|
||||
:regex #"^.*_48px\.svg$"}}
|
||||
{:name "Material Design (File)"
|
||||
:path "./icons/material-file"
|
||||
:regex #"^.*_48px\.svg$"}
|
||||
:images {:path "./icons/material-file"
|
||||
:regex #"^.*_48px\.svg$"}}
|
||||
{:name "Material Design (Hardware)"
|
||||
:path "./icons/material-hardware"
|
||||
:regex #"^.*_48px\.svg$"}
|
||||
:images {:path "./icons/material-hardware"
|
||||
:regex #"^.*_48px\.svg$"}}
|
||||
{:name "Material Design (Image)"
|
||||
:path "./icons/material-image"
|
||||
:regex #"^.*_48px\.svg$"}
|
||||
:images {:path "./icons/material-image"
|
||||
:regex #"^.*_48px\.svg$"}}
|
||||
{:name "Material Design (Maps)"
|
||||
:path "./icons/material-maps"
|
||||
:regex #"^.*_48px\.svg$"}
|
||||
:images {:path "./icons/material-maps"
|
||||
:regex #"^.*_48px\.svg$"}}
|
||||
{:name "Material Design (Navigation)"
|
||||
:path "./icons/material-navigation"
|
||||
:regex #"^.*_48px\.svg$"}
|
||||
:images {:path "./icons/material-navigation"
|
||||
:regex #"^.*_48px\.svg$"}}
|
||||
{:name "Material Design (Notification)"
|
||||
:path "./icons/material-notification"
|
||||
:regex #"^.*_48px\.svg$"}
|
||||
:images {:path "./icons/material-notification"
|
||||
:regex #"^.*_48px\.svg$"}}
|
||||
{:name "Material Design (Places)"
|
||||
:path "./icons/material-places"
|
||||
:regex #"^.*_48px\.svg$"}
|
||||
:images {:path "./icons/material-places"
|
||||
:regex #"^.*_48px\.svg$"}}
|
||||
{:name "Material Design (Social)"
|
||||
:path "./icons/material-social"
|
||||
:regex #"^.*_48px\.svg$"}
|
||||
:images {:path "./icons/material-social"
|
||||
:regex #"^.*_48px\.svg$"}}
|
||||
{:name "Material Design (Toggle)"
|
||||
:path "./icons/material-toggle"
|
||||
:regex #"^.*_48px\.svg$"}
|
||||
]
|
||||
:images {:path "./icons/material-toggle"
|
||||
:regex #"^.*_48px\.svg$"}}
|
||||
|
||||
:colors
|
||||
[{:name "Flat design"
|
||||
:id #uuid "00000000-0000-0000-0000-00000000001"
|
||||
;; Images
|
||||
{:name "Unsplash"
|
||||
:images {:path "./images/unsplash"
|
||||
:regex #"^.*\.jpg$"}}
|
||||
|
||||
;; Colors
|
||||
{:name "Flat design"
|
||||
:colors ["turquoise-50" "#e8f8f5"
|
||||
"turquoise-100" "#d1f2eb"
|
||||
"turquoise-200" "#a3e4d7"
|
||||
|
@ -250,9 +254,7 @@
|
|||
"asbestos-800" "#515a5a"
|
||||
"asbestos-900" "#424949"]}
|
||||
|
||||
|
||||
{:name "Material design"
|
||||
:id #uuid "00000000-0000-0000-0000-000000000020"
|
||||
:colors ["red-50" "#ffebee"
|
||||
"red-100" "#ffcdd2"
|
||||
"red-200" "#ef9a9a"
|
||||
|
@ -509,5 +511,4 @@
|
|||
"blue-grey-900" "#263238"
|
||||
"white" "#ffffff"
|
||||
"black" "#000000"]}
|
||||
]}
|
||||
|
||||
]
|
||||
|
|
BIN
sample_media/images/unsplash/anna-pelzer.jpg
Normal file
BIN
sample_media/images/unsplash/anna-pelzer.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 120 KiB |
BIN
sample_media/images/unsplash/bruna-branco.jpg
Normal file
BIN
sample_media/images/unsplash/bruna-branco.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 156 KiB |
BIN
sample_media/images/unsplash/cayla1.jpg
Normal file
BIN
sample_media/images/unsplash/cayla1.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 75 KiB |
BIN
sample_media/images/unsplash/charles-deluvio.jpg
Normal file
BIN
sample_media/images/unsplash/charles-deluvio.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 45 KiB |
BIN
sample_media/images/unsplash/dan-gold.jpg
Normal file
BIN
sample_media/images/unsplash/dan-gold.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 185 KiB |
BIN
sample_media/images/unsplash/dose-juice.jpg
Normal file
BIN
sample_media/images/unsplash/dose-juice.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
Loading…
Reference in a new issue