🎉 Link files to libraries

This commit is contained in:
Andrés Moya 2020-08-05 13:30:26 +02:00 committed by Andrey Antukh
parent 5ff0a723d5
commit 752038039c
22 changed files with 1080 additions and 318 deletions

View file

@ -41,7 +41,7 @@
ptk/UpdateEvent
(update [_ state]
(-> state
(assoc-in [:workspace-colors-library (:id color)] color)
(update-in [:workspace-file :colors] #(conj % color))
(assoc-in [:workspace-local :color-for-rename] (:id color))))))
(def clear-color-for-rename
@ -67,7 +67,7 @@
ptk/UpdateEvent
(update [_ state]
(-> state
(assoc-in [:workspace-colors-library (:id color)] color)))))
(update-in [:workspace-file :colors] #(d/replace-by-id % color))))))
(declare update-color-result)
@ -86,7 +86,7 @@
ptk/UpdateEvent
(update [_ state]
(-> state
(assoc-in [:workspace-colors-library (:id color)] color)))))
(update-in [:workspace-file :colors] #(d/replace-by-id % color))))))
(declare delete-color-result)
@ -104,5 +104,6 @@
ptk/UpdateEvent
(update [_ state]
(-> state
(d/dissoc-in [:workspace-colors-library color-id])))))
(update-in [:workspace-file :colors]
(fn [colors] (filter #(not= (:id %) color-id) colors)))))))

View file

@ -1433,8 +1433,9 @@
;; Persistence
(def set-file-shared dwp/set-file-shared)
(def fetch-media-library dwp/fetch-media-library)
(def fetch-colors-library dwp/fetch-colors-library)
(def fetch-shared-files dwp/fetch-shared-files)
(def link-file-to-library dwp/link-file-to-library)
(def unlink-file-from-library dwp/unlink-file-from-library)
(def add-media-object-from-url dwp/add-media-object-from-url)
(def upload-media-objects dwp/upload-media-objects)
(def delete-media-object dwp/delete-media-object)

View file

@ -137,6 +137,7 @@
::ordering
::data]))
(declare fetch-libraries-content)
(declare bundle-fetched)
(defn- fetch-bundle
@ -147,10 +148,18 @@
(->> (rx/zip (rp/query :file {:id file-id})
(rp/query :file-users {:id file-id})
(rp/query :project-by-id {:project-id project-id})
(rp/query :pages {:file-id file-id}))
(rp/query :pages {:file-id file-id})
(rp/query :media-objects {:file-id file-id :is-local false})
(rp/query :colors {:file-id file-id})
(rp/query :file-libraries {:file-id file-id}))
(rx/first)
(rx/map (fn [[file users project pages]]
(bundle-fetched file users project pages)))
(rx/mapcat
(fn [bundle]
(->> (fetch-libraries-content (get bundle 6))
(rx/map (fn [[lib-media-objects lib-colors]]
(conj bundle lib-media-objects lib-colors))))))
(rx/map (fn [bundle]
(apply bundle-fetched bundle)))
(rx/catch (fn [{:keys [type code] :as error}]
(cond
(= :not-found type)
@ -163,27 +172,78 @@
:else
(throw error))))))))
(defn- fetch-libraries-content
[libraries]
(if (empty? libraries)
(rx/of [{} {}])
(rx/zip
(->> ;; fetch media-objects list of each library, and concatenate in a sequence
(apply rx/zip (for [library libraries]
(->> (rp/query :media-objects {:file-id (:id library)
:is-local false})
(rx/map (fn [media-objects]
[(:id library) media-objects])))))
;; reorganize the sequence as a map {library-id -> media-objects}
(rx/map (fn [media-list]
(reduce (fn [result, [library-id media-objects]]
(assoc result library-id media-objects))
{}
media-list))))
(->> ;; fetch colorss list of each library, and concatenate in a vector
(apply rx/zip (for [library libraries]
(->> (rp/query :colors {:file-id (:id library)})
(rx/map (fn [colors]
[(:id library) colors])))))
;; reorganize the sequence as a map {library-id -> colors}
(rx/map (fn [colors-list]
(reduce (fn [result, [library-id colors]]
(assoc result library-id colors))
{}
colors-list)))))))
(defn- bundle-fetched
[file users project pages]
[file users project pages media-objects colors libraries lib-media-objects lib-colors]
(ptk/reify ::bundle-fetched
IDeref
(-deref [_]
{:file file
:users users
:project project
:pages pages})
:pages pages
:media-objects media-objects
:colors colors
:libraries libraries})
ptk/UpdateEvent
(update [_ state]
(let [assoc-page #(assoc-in %1 [:workspace-pages (:id %2)] %2)]
(let [assoc-page
#(assoc-in %1 [:workspace-pages (:id %2)] %2)
assoc-media-objects
#(assoc-in %1 [:workspace-libraries %2 :media-objects]
(get lib-media-objects %2))
assoc-colors
#(assoc-in %1 [:workspace-libraries %2 :colors]
(get lib-colors %2))]
(as-> state $$
(assoc $$
:workspace-file file
:workspace-file (assoc file
:media-objects media-objects
:colors colors)
:workspace-users (d/index-by :id users)
:workspace-pages {}
:workspace-project project)
:workspace-project project
:workspace-libraries (d/index-by :id libraries))
(reduce assoc-media-objects $$ (keys lib-media-objects))
(reduce assoc-colors $$ (keys lib-colors))
(reduce assoc-page $$ pages))))))
;; --- Set File shared
(defn set-file-shared
@ -200,6 +260,79 @@
(->> (rp/mutation :set-file-shared params)
(rx/ignore))))))
;; --- Fetch Shared Files
(declare shared-files-fetched)
(defn fetch-shared-files
[]
(ptk/reify ::fetch-shared-files
ptk/WatchEvent
(watch [_ state stream]
(let [params {}]
(->> (rp/query :shared-files params)
(rx/map shared-files-fetched))))))
(defn shared-files-fetched
[files]
(us/verify (s/every ::file) files)
(ptk/reify ::shared-files-fetched
ptk/UpdateEvent
(update [_ state]
(let [state (dissoc state :files)]
(assoc state :workspace-shared-files files)))))
;; --- Link and unlink Files
(declare file-linked)
(defn link-file-to-library
[file-id library-id]
(ptk/reify ::link-file-to-library
ptk/WatchEvent
(watch [_ state stream]
(let [params {:file-id file-id
:library-id library-id}]
(->> (->> (rp/mutation :link-file-to-library params)
(rx/mapcat
#(rx/zip (rp/query :file-library {:file-id library-id})
(rp/query :media-objects {:file-id library-id
:is-local false})
(rp/query :colors {:file-id library-id}))))
(rx/map file-linked))))))
(defn file-linked
[[library media-objects colors]]
(ptk/reify ::file-linked
ptk/UpdateEvent
(update [_ state]
(assoc-in state [:workspace-libraries (:id library)]
(assoc library
:media-objects media-objects
:colors colors)))))
(declare file-unlinked)
(defn unlink-file-from-library
[file-id library-id]
(ptk/reify ::unlink-file-from-library
ptk/WatchEvent
(watch [_ state stream]
(let [params {:file-id file-id
:library-id library-id}]
(->> (rp/mutation :unlink-file-from-library params)
(rx/map #(file-unlinked file-id library-id)))))))
(defn file-unlinked
[file-id library-id]
(ptk/reify ::file-unlinked
ptk/UpdateEvent
(update [_ state]
(d/dissoc-in state [:workspace-libraries library-id]))))
;; --- Fetch Pages
(declare page-fetched)
@ -298,46 +431,6 @@
(rx/of go-to-file)
(rx/empty))))))))))
;; --- Fetch Workspace Media library
(declare media-library-fetched)
(defn fetch-media-library
[file-id]
(ptk/reify ::fetch-media-library
ptk/WatchEvent
(watch [_ state stream]
(->> (rp/query :media-objects {:file-id file-id :is-local false})
(rx/map media-library-fetched)))))
(defn media-library-fetched
[media-objects]
(ptk/reify ::media-library-fetched
ptk/UpdateEvent
(update [_ state]
(let [media-objects (d/index-by :id media-objects)]
(assoc state :workspace-media-library media-objects)))))
;; --- Fetch Workspace Colors library
(declare colors-library-fetched)
(defn fetch-colors-library
[file-id]
(ptk/reify ::fetch-colors-library
ptk/WatchEvent
(watch [_ state stream]
(->> (rp/query :colors {:file-id file-id})
(rx/map colors-library-fetched)))))
(defn colors-library-fetched
[colors]
(ptk/reify ::colors-library-fetched
ptk/UpdateEvent
(update [_ state]
(let [colors (d/index-by :id colors)]
(assoc state :workspace-colors-library colors)))))
;; --- Upload local media objects
@ -357,6 +450,8 @@
on-error #(do (di/notify-finished-loading)
(di/process-error %))
is-library (not= file-id (:id (:workspace-file state)))
prepare
(fn [url]
@ -370,7 +465,7 @@
(rx/map prepare)
(rx/mapcat #(rp/mutation! :add-media-object-from-url %))
(rx/do on-success)
(rx/map (partial upload-media-objects-result file-id is-local))
(rx/map (partial upload-media-objects-result file-id is-local is-library))
(rx/catch on-error)))))))
(defn upload-media-objects
@ -389,6 +484,8 @@
on-error #(do (di/notify-finished-loading)
(di/process-error %))
is-library (not= file-id (:id (:workspace-file state)))
prepare
(fn [js-file]
{:name (.-name js-file)
@ -403,32 +500,43 @@
(rx/map prepare)
(rx/mapcat #(rp/mutation! :upload-media-object %))
(rx/do on-success)
(rx/map (partial upload-media-objects-result file-id is-local))
(rx/map (partial upload-media-objects-result file-id is-local is-library))
(rx/catch on-error)))))))
(defn upload-media-objects-result
[file-id is-local media-object]
[file-id is-local is-library media-object]
(us/verify ::us/uuid file-id)
(us/verify ::us/boolean is-local)
(us/verify ::cm/media-object media-object)
(ptk/reify ::upload-media-objects-result
ptk/UpdateEvent
(update [_ state]
(if is-local
(if is-local ;; the media-object is local to the file, not for its library
state
(assoc-in state
[:workspace-media-library (:id media-object)]
media-object)))))
(if is-library ;; the file is not the currently editing one, but a linked shared file
(update-in state
[:workspace-libraries file-id :media-objects]
#(conj % media-object))
(update-in state
[:workspace-file :media-objects]
#(conj % media-object)))))))
;; --- Delete media object
(defn delete-media-object
[id]
[file-id id]
(ptk/reify ::delete-media-object
ptk/UpdateEvent
(update [_ state]
(update state :workspace-media-library dissoc id))
(let [is-library (not= file-id (:id (:workspace-file state)))]
(if is-library
(update-in state
[:workspace-libraries file-id :media-objects]
(fn [media-objects] (filter #(not= (:id %) id) media-objects)))
(update-in state
[:workspace-file :media-objects]
(fn [media-objects] (filter #(not= (:id %) id) media-objects))))))
ptk/WatchEvent
(watch [_ state stream]

View file

@ -57,11 +57,11 @@
(def workspace-project
(l/derived :workspace-project st/state))
(def workspace-media-library
(l/derived :workspace-media-library st/state))
(def workspace-shared-files
(l/derived :workspace-shared-files st/state))
(def workspace-colors-library
(l/derived :workspace-colors-library st/state))
(def workspace-libraries
(l/derived :workspace-libraries st/state))
(def workspace-users
(l/derived :workspace-users st/state))

View file

@ -56,6 +56,7 @@
(def layers (icon-xref :layers))
(def letter-spacing (icon-xref :letter-spacing))
(def library (icon-xref :library))
(def libraries (icon-xref :libraries))
(def line (icon-xref :line))
(def line-height (icon-xref :line-height))
(def loader (icon-xref :loader))

View file

@ -18,7 +18,6 @@
[uxbox.main.refs :as refs]
[uxbox.main.store :as st]
[uxbox.main.streams :as ms]
[uxbox.main.ui.confirm]
[uxbox.main.ui.keyboard :as kbd]
[uxbox.main.ui.hooks :as hooks]
[uxbox.main.ui.workspace.viewport :refer [viewport coordinates]]

View file

@ -0,0 +1,155 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
;; Copyright (c) 2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
(ns uxbox.main.ui.workspace.libraries
(:require
[rumext.alpha :as mf]
[cuerdas.core :as str]
[uxbox.util.dom :as dom]
[uxbox.util.i18n :refer (tr)]
[uxbox.util.data :refer [classnames matches-search]]
[uxbox.main.store :as st]
[uxbox.main.refs :as refs]
[uxbox.main.data.workspace :as dw]
[uxbox.main.ui.icons :as i]
[uxbox.main.ui.modal :as modal]))
(mf/defc libraries-tab
[{:keys [file libraries shared-files] :as props}]
(let [state (mf/use-state {:search-term ""})
sorted-libraries (->> (vals libraries)
(sort-by #(str/lower (:name %))))
filtered-files (->> shared-files
(filter #(not= (:id %) (:id file)))
(filter #(nil? (get libraries (:id %))))
(filter #(matches-search (:name %) (:search-term @state)))
(sort-by #(str/lower (:name %))))
on-search-term-change (fn [event]
(let [value (-> (dom/get-target event)
(dom/get-value))]
(swap! state assoc :search-term value)))
on-search-clear-click (fn [event]
(swap! state assoc :search-term ""))
link-library (fn [library-id]
(st/emit! (dw/link-file-to-library (:id file) library-id)))
unlink-library (fn [library-id]
(st/emit! (dw/unlink-file-from-library (:id file) library-id)))
contents-str (fn [library graphics-count colors-count]
(str
(str/join " · "
(cond-> []
(< 0 graphics-count)
(conj (tr "workspace.libraries.graphics" graphics-count))
(< 0 colors-count)
(conj (tr "workspace.libraries.colors" colors-count))))
"\u00A0"))] ;; Include a &nbsp; so this block has always some content
[:*
[:div.section
[:div.section-title (tr "workspace.libraries.in-this-file")]
[:div.section-list
[:div.section-list-item
[:div.item-name (tr "workspace.libraries.file-library")]
[:div.item-contents (contents-str file
(count (:media-objects file))
(count (:colors file)))]]
(for [library sorted-libraries]
[:div.section-list-item {:key (:id library)}
[:div.item-name (:name library)]
[:div.item-contents (contents-str library
(count (:media-objects library))
(count (:colors library)))]
[:input.item-button {:type "button"
:value (tr "workspace.libraries.remove")
:on-click #(unlink-library (:id library))}]])
]]
[:div.section
[:div.section-title (tr "workspace.libraries.shared-libraries")]
[:div.libraries-search
[:input.search-input
{:placeholder (tr "workspace.libraries.search-shared-libraries")
:type "text"
:value (:search-term @state)
:on-change on-search-term-change}]
(if (str/empty? (:search-term @state))
[:div.search-icon
i/search]
[:div.search-icon.search-close
{:on-click on-search-clear-click}
i/close])]
(if (> (count filtered-files) 0)
[:div.section-list
(for [file filtered-files]
[:div.section-list-item {:key (:id file)}
[:div.item-name (:name file)]
[:div.item-contents (contents-str file
(:graphics-count file)
(:colors-count file))]
[:input.item-button {:type "button"
:value (tr "workspace.libraries.add")
:on-click #(link-library (:id file))}]])]
[:div.section-list-empty
i/library
(if (str/empty? (:search-term @state))
(tr "workspace.libraries.no-shared-libraries-available")
(tr "workspace.libraries.no-matches-for" (:search-term @state)))])]]))
(mf/defc updates-tab
[]
[:div])
(mf/defc libraries-dialog
[{:keys [] :as ctx}]
(let [state (mf/use-state {:current-tab :libraries})
current-tab (:current-tab @state)
file (mf/deref refs/workspace-file)
libraries (mf/deref refs/workspace-libraries)
shared-files (mf/deref refs/workspace-shared-files)
change-tab (fn [tab]
(swap! state assoc :current-tab tab))
close (fn [event]
(dom/prevent-default event)
(modal/hide!))]
(mf/use-effect
#(st/emit! (dw/fetch-shared-files)))
[:div.modal-overlay
[:div.modal.libraries-dialog
[:a.close {:on-click close} i/close]
[:div.modal-content
[:div.libraries-header
[:div.header-item
{:class (classnames :active (= current-tab :libraries))
:on-click #(change-tab :libraries)}
(tr "workspace.libraries.libraries")]
[:div.header-item
{:class (classnames :active (= current-tab :updates))
:on-click #(change-tab :updates)}
(tr "workspace.libraries.updates")]]
[:div.libraries-content
(case current-tab
:libraries
[:& libraries-tab {:file file
:libraries libraries
:shared-files shared-files}]
:updates
[:& updates-tab {}])]]]]))

View file

@ -29,20 +29,14 @@
[uxbox.util.timers :as timers]
[uxbox.common.uuid :as uuid]
[uxbox.util.i18n :as i18n :refer [tr]]
[uxbox.util.data :refer [classnames]]
[uxbox.util.data :refer [classnames matches-search]]
[uxbox.util.router :as rt]
[uxbox.main.ui.modal :as modal]
[uxbox.main.ui.colorpicker :refer [colorpicker most-used-colors]]
[uxbox.main.ui.components.tab-container :refer [tab-container tab-element]]
[uxbox.main.ui.components.file-uploader :refer [file-uploader]]
[uxbox.main.ui.components.context-menu :refer [context-menu]]))
(defn matches-search
[name search-term]
(if (str/empty? search-term)
true
(let [st (str/trim (str/lower search-term))
nm (str/trim (str/lower name))]
(str/includes? nm st))))
[uxbox.main.ui.components.context-menu :refer [context-menu]]
[uxbox.main.ui.workspace.libraries :refer [libraries-dialog]]))
(mf/defc modal-edit-color
[{:keys [color-value on-accept on-cancel] :as ctx}]
@ -72,7 +66,7 @@
[:a.close {:href "#" :on-click cancel} i/close]]])))
(mf/defc graphics-box
[{:keys [file-id media-objects] :as props}]
[{:keys [file-id local-library? media-objects] :as props}]
(let [state (mf/use-state {:menu-open false
:top nil
:left nil
@ -84,7 +78,7 @@
#(dom/click (mf/ref-val file-input))
delete-graphic
#(st/emit! (dw/delete-media-object (:object-id @state)))
#(st/emit! (dw/delete-media-object file-id (:object-id @state)))
on-files-selected
(fn [js-files]
@ -93,14 +87,15 @@
on-context-menu
(fn [object-id]
(fn [event]
(let [pos (dom/get-client-position event)
top (:y pos)
left (- (:x pos) 20)]
(dom/prevent-default event)
(swap! state assoc :menu-open true
:top top
:left left
:object-id object-id))))
(when local-library?
(let [pos (dom/get-client-position event)
top (:y pos)
left (- (:x pos) 20)]
(dom/prevent-default event)
(swap! state assoc :menu-open true
:top top
:left left
:object-id object-id)))))
on-drag-start
(fn [uri]
@ -112,14 +107,15 @@
[:div.group-title
(tr "workspace.assets.graphics")
[:span (str "\u00A0(") (count media-objects) ")"] ;; Unicode 00A0 is non-breaking space
[:div.group-button {:on-click add-graphic}
i/plus
[:& file-uploader {:accept cm/str-media-types
:multi true
:input-ref file-input
:on-selected on-files-selected}]]]
(when local-library?
[:div.group-button {:on-click add-graphic}
i/plus
[:& file-uploader {:accept cm/str-media-types
:multi true
:input-ref file-input
:on-selected on-files-selected}]])]
[:div.group-grid
(for [object (sort-by :name media-objects)]
(for [object media-objects]
[:div.grid-cell {:key (:id object)
:draggable true
:on-context-menu (on-context-menu (:id object))
@ -127,17 +123,18 @@
[:img {:src (:thumb-uri object)
:draggable false}] ;; Also need to add css pointer-events: none
[:div.cell-name (:name object)]])
[:& context-menu
{:selectable false
:show (:menu-open @state)
:on-close #(swap! state assoc :menu-open false)
:top (:top @state)
:left (:left @state)
:options [[(tr "workspace.assets.delete") delete-graphic]]}]]]))
(when local-library?
[:& context-menu
{:selectable false
:show (:menu-open @state)
:on-close #(swap! state assoc :menu-open false)
:top (:top @state)
:left (:left @state)
:options [[(tr "workspace.assets.delete") delete-graphic]]}])]]))
(mf/defc color-item
[{:keys [color file-id] :as props}]
[{:keys [color file-id local-library?] :as props}]
(let [workspace-local @refs/workspace-local
color-for-rename (:color-for-rename workspace-local)
@ -189,14 +186,15 @@
on-context-menu
(fn [event]
(let [pos (dom/get-client-position event)
top (:y pos)
left (- (:x pos) 20)]
(dom/prevent-default event)
(swap! state assoc
:menu-open true
:top top
:left left)))]
(when local-library?
(let [pos (dom/get-client-position event)
top (:y pos)
left (- (:x pos) 20)]
(dom/prevent-default event)
(swap! state assoc
:menu-open true
:top top
:left left))))]
(mf/use-effect
(mf/deps (:editing @state))
@ -220,18 +218,19 @@
(:name color)
(when-not (= (:name color) (:content color))
[:span (:content color)])])
[:& context-menu
{:selectable false
:show (:menu-open @state)
:on-close #(swap! state assoc :menu-open false)
:top (:top @state)
:left (:left @state)
:options [[(tr "workspace.assets.rename") rename-color-clicked]
[(tr "workspace.assets.edit") edit-color-clicked]
[(tr "workspace.assets.delete") delete-color]]}]]))
(when local-library?
[:& context-menu
{:selectable false
:show (:menu-open @state)
:on-close #(swap! state assoc :menu-open false)
:top (:top @state)
:left (:left @state)
:options [[(tr "workspace.assets.rename") rename-color-clicked]
[(tr "workspace.assets.edit") edit-color-clicked]
[(tr "workspace.assets.delete") delete-color]]}])]))
(mf/defc colors-box
[{:keys [file-id colors] :as props}]
[{:keys [file-id local-library? colors] :as props}]
(let [add-color
(fn [value opacity]
(st/emit! (dcol/create-color file-id value)))
@ -246,15 +245,18 @@
[:div.group-title
(tr "workspace.assets.colors")
[:span (str "\u00A0(") (count colors) ")"] ;; Unicode 00A0 is non-breaking space
[:div.group-button {:on-click add-color-clicked} i/plus]]
(when local-library?
[:div.group-button {:on-click add-color-clicked} i/plus])]
[:div.group-list
(for [color (sort-by :name colors)]
(for [color colors]
[:& color-item {:key (:id color)
:color color
:file-id file-id}])]]))
:file-id file-id
:local-library? local-library?}])]]))
(mf/defc file-library-toolbox
[{:keys [file-id
[{:keys [library
local-library?
shared?
media-objects
colors
@ -262,26 +264,41 @@
search-term
box-filter] :as props}]
(let [open? (mf/use-state initial-open?)
toggle-open #(swap! open? not)]
toggle-open #(swap! open? not)
router (mf/deref refs/router)
library-url (rt/resolve router :workspace
{:project-id (:project-id library)
:file-id (:id library)}
{:page-id (first (:pages library))})]
[:div.tool-window
[:div.tool-window-bar
[:div.collapse-library
{:class (classnames :open @open?)
:on-click toggle-open}
i/arrow-slide]
[:span (tr "workspace.assets.file-library")]
(when shared?
[:span.tool-badge (tr "workspace.assets.shared")])]
(if local-library?
[:*
[:span (tr "workspace.assets.file-library")]
(when shared?
[:span.tool-badge (tr "workspace.assets.shared")])]
[:*
[:span (:name library)]
[:span.tool-link
[:a {:href (str "#" library-url) :target "_blank"} i/chain]]])]
(when @open?
(let [show-graphics (and (or (= box-filter :all) (= box-filter :graphics))
(or (> (count media-objects) 0) (str/empty? search-term)))
show-colors (and (or (= box-filter :all) (= box-filter :colors))
(or (> (count colors) 0) (str/empty? search-term)))]
(or (> (count media-objects) 0) (str/empty? search-term)))
show-colors (and (or (= box-filter :all) (= box-filter :colors))
(or (> (count colors) 0) (str/empty? search-term)))]
[:div.tool-window-content
(when show-graphics
[:& graphics-box {:file-id file-id :media-objects media-objects}])
[:& graphics-box {:file-id (:id library)
:local-library? local-library?
:media-objects media-objects}])
(when show-colors
[:& colors-box {:file-id file-id :colors colors}])
[:& colors-box {:file-id (:id library)
:local-library? local-library?
:colors colors}])
(when (and (not show-graphics) (not show-colors))
[:div.asset-group
[:div.group-title (tr "workspace.assets.not-found")]])]))]))
@ -290,19 +307,27 @@
[]
(let [team-id (-> refs/workspace-project mf/deref :team-id)
file (mf/deref refs/workspace-file)
file-id (:id file)
file-media (mf/deref refs/workspace-media-library)
file-colors (mf/deref refs/workspace-colors-library)
libraries (mf/deref refs/workspace-libraries)
sorted-libraries (->> (vals libraries)
(sort-by #(str/lower (:name %))))
state (mf/use-state {:search-term ""
:box-filter :all})
filtered-media-objects (filter #(matches-search (:name %) (:search-term @state))
(vals file-media))
filtered-media-objects (fn [library-id]
(as-> libraries $$
(assoc $$ (:id file) file)
(get-in $$ [library-id :media-objects])
(filter #(matches-search (:name %) (:search-term @state)) $$)
(sort-by #(str/lower (:name %)) $$)))
filtered-colors (filter #(or (matches-search (:name %) (:search-term @state))
(matches-search (:content %) (:search-term @state)))
(vals file-colors))
filtered-colors (fn [library-id]
(as-> libraries $$
(assoc $$ (:id file) file)
(get-in $$ [library-id :colors])
(filter #(or (matches-search (:name %) (:search-term @state))
(matches-search (:content %) (:search-term @state))) $$)
(sort-by #(str/lower (:name %)) $$)))
on-search-term-change (fn [event]
(let [value (-> (dom/get-target event)
@ -318,17 +343,15 @@
(d/read-string))]
(swap! state assoc :box-filter value)))]
(mf/use-effect
(mf/deps file-id)
#(when file-id
(st/emit! (dw/fetch-media-library file-id))
(st/emit! (dw/fetch-colors-library file-id))))
[:div.assets-bar
[:div.tool-window
[:div.tool-window-content
[:div.assets-bar-title (tr "workspace.assets.assets")]
[:div.assets-bar-title
(tr "workspace.assets.assets")
[:div.libraries-button {:on-click #(modal/show! libraries-dialog {})}
i/libraries
(tr "workspace.assets.libraries")]]
[:div.search-block
[:input.search-input
@ -347,14 +370,25 @@
:on-change on-box-filter-change}
[:option {:value ":all"} (tr "workspace.assets.box-filter-all")]
[:option {:value ":graphics"} (tr "workspace.assets.box-filter-graphics")]
[:option {:value ":colors"} (tr "workspace.assets.box-filter-colors")]]
]]
[:option {:value ":colors"} (tr "workspace.assets.box-filter-colors")]]]]
[:& file-library-toolbox {:file-id file-id
[:& file-library-toolbox {:key (:id file)
:library file
:local-library? true
:shared? (:is-shared file)
:media-objects filtered-media-objects
:colors filtered-colors
:media-objects (filtered-media-objects (:id file))
:colors (filtered-colors (:id file))
:initial-open? true
:search-term (:search-term @state)
:box-filter (:box-filter @state)}]]))
:box-filter (:box-filter @state)}]
(for [library sorted-libraries]
[:& file-library-toolbox {:key (:id library)
:library library
:local-library? false
:shared? (:is-shared library)
:media-objects (filtered-media-objects (:id library))
:colors (filtered-colors (:id library))
:initial-open? false
:search-term (:search-term @state)
:box-filter (:box-filter @state)}])]))

View file

@ -180,6 +180,13 @@
"className"
(str/camel (name key))))))
(defn matches-search
[name search-term]
(if (str/empty? search-term)
true
(let [st (str/trim (str/lower search-term))
nm (str/trim (str/lower name))]
(str/includes? nm st))))
;; (defn coalesce
;; [^number v ^number n]