🔥 improved deletes and library flow

This commit is contained in:
alonso.torres 2020-03-20 10:01:15 +01:00
parent a0a031dbc2
commit fdb3b8aacb
7 changed files with 135 additions and 237 deletions

View file

@ -246,66 +246,6 @@
;;;; NEW ;;;; NEW
(declare fetch-color-libraries-result)
(defn fetch-color-libraries
[team-id]
(s/assert ::us/uuid team-id)
(ptk/reify ::fetch-color-libraries
ptk/WatchEvent
(watch [_ state stream]
(->> (rp/query! :color-libraries {:team-id team-id})
(rx/map fetch-color-libraries-result)))))
(defn fetch-color-libraries-result [result]
(ptk/reify ::fetch-color-libraries-result
ptk/UpdateEvent
(update [_ state]
(-> state
(assoc-in [:library :color-libraries] result)))))
(declare fetch-color-library-result)
(defn fetch-color-library
[library-id]
(ptk/reify ::fetch-color-library
ptk/UpdateEvent
(update [_ state]
(-> state
(assoc-in [:library :selected-items] nil)))
ptk/WatchEvent
(watch [_ state stream]
(->> (rp/query! :colors {:library-id library-id})
(rx/map fetch-color-library-result)))))
(defn fetch-color-library-result
[data]
(ptk/reify ::fetch-color-library
ptk/UpdateEvent
(update [_ state]
(-> state
(assoc-in [:library :selected-items] data)))))
(declare create-color-library-result)
(defn create-color-library
[team-id name]
(ptk/reify ::create-color-library
ptk/WatchEvent
(watch [_ state stream]
(->> (rp/mutation! :create-color-library {:team-id team-id
:name name})
(rx/map create-color-library-result)))))
(defn create-color-library-result [result]
(ptk/reify ::create-color-library-result
ptk/UpdateEvent
(update [_ state]
(-> state
(update-in [:library :color-libraries] #(into [result] %))))))
(declare create-color-result) (declare create-color-result)
(defn create-color (defn create-color

View file

@ -34,66 +34,6 @@
::modified-at ::modified-at
::user-id])) ::user-id]))
(declare fetch-icon-libraries-result)
(defn fetch-icon-libraries
[team-id]
(s/assert ::us/uuid team-id)
(ptk/reify ::fetch-icon-libraries
ptk/WatchEvent
(watch [_ state stream]
(->> (rp/query! :icon-libraries {:team-id team-id})
(rx/map fetch-icon-libraries-result)))))
(defn fetch-icon-libraries-result [result]
(ptk/reify ::fetch-icon-libraries-result
ptk/UpdateEvent
(update [_ state]
(-> state
(assoc-in [:library :icon-libraries] result)))))
(declare fetch-icon-library-result)
(defn fetch-icon-library
[library-id]
(ptk/reify ::fetch-icon-library
ptk/UpdateEvent
(update [_ state]
(-> state
(assoc-in [:library :selected-items] nil)))
ptk/WatchEvent
(watch [_ state stream]
(->> (rp/query! :icons {:library-id library-id})
(rx/map fetch-icon-library-result)))))
(defn fetch-icon-library-result
[data]
(ptk/reify ::fetch-icon-library
ptk/UpdateEvent
(update [_ state]
(-> state
(assoc-in [:library :selected-items] data)))))
(declare create-icon-library-result)
(defn create-icon-library
[team-id name]
(ptk/reify ::create-icon-library
ptk/WatchEvent
(watch [_ state stream]
(->> (rp/mutation! :create-icon-library {:team-id team-id
:name name})
(rx/map create-icon-library-result)))))
(defn create-icon-library-result [result]
(ptk/reify ::create-icon-library-result
ptk/UpdateEvent
(update [_ state]
(-> state
(update-in [:library :icon-libraries] #(into [result] %))))))
;; rename-icon-library ;; rename-icon-library
;; delete-icon-library ;; delete-icon-library

View file

@ -350,67 +350,6 @@
;;;;;;; NEW ;;;;;;; NEW
(declare fetch-image-libraries-result)
(defn fetch-image-libraries
[team-id]
(s/assert ::us/uuid team-id)
(ptk/reify ::fetch-image-libraries
ptk/WatchEvent
(watch [_ state stream]
(->> (rp/query! :image-libraries {:team-id team-id})
(rx/map fetch-image-libraries-result)))))
(defn fetch-image-libraries-result [result]
(ptk/reify ::fetch-image-libraries-result
ptk/UpdateEvent
(update [_ state]
(-> state
(assoc-in [:library :image-libraries] result)))))
(declare fetch-image-library-result)
(defn fetch-image-library
[library-id]
(ptk/reify ::fetch-image-library
ptk/UpdateEvent
(update [_ state]
(-> state
(assoc-in [:library :selected-items] nil)))
ptk/WatchEvent
(watch [_ state stream]
(->> (rp/query! :images {:library-id library-id})
(rx/map fetch-image-library-result)))))
(defn fetch-image-library-result
[data]
(ptk/reify ::fetch-image-library
ptk/UpdateEvent
(update [_ state]
(-> state
(assoc-in [:library :selected-items] data)))))
(declare create-image-library-result)
(defn create-image-library
[team-id name]
(ptk/reify ::create-image-library
ptk/WatchEvent
(watch [_ state stream]
(->> (rp/mutation! :create-image-library {:team-id team-id
:name name})
(rx/map create-image-library-result)))))
(defn create-image-library-result [result]
(ptk/reify ::create-image-library-result
ptk/UpdateEvent
(update [_ state]
(-> state
(update-in [:library :image-libraries] #(into [result] %))))))
;; --- Create Image ;; --- Create Image
(declare create-images-result) (declare create-images-result)
(def allowed-file-types #{"image/jpeg" "image/png"}) (def allowed-file-types #{"image/jpeg" "image/png"})

View file

@ -127,6 +127,11 @@
(defn delete-library (defn delete-library
[type library-id] [type library-id]
(ptk/reify ::delete-library (ptk/reify ::delete-library
ptk/UpdateEvent
(update [_ state]
(-> state
(assoc-in [:library :last-deleted-library] library-id)))
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
(let [method (case type (let [method (case type
@ -172,4 +177,31 @@
(-> state (-> state
(update-in [:library :selected-items library-id] update-fn)))))) (update-in [:library :selected-items library-id] update-fn))))))
;; Rename library item ;; Batch delete
(declare batch-delete-item-result)
(defn batch-delete-item
[type library-id item-ids]
(ptk/reify ::batch-delete-item
ptk/WatchEvent
(watch [_ state stream]
(let [method (case type
:icons :delete-icon
:images :delete-image
:palettes :delete-color)]
(->> (rx/from item-ids)
(rx/flat-map #(rp/mutation! method {:id %}))
(rx/last)
(rx/map #(batch-delete-item-result type library-id item-ids)))))))
(defn batch-delete-item-result
[type library-id item-ids]
(ptk/reify ::batch-delete-item-result
ptk/UpdateEvent
(update [_ state]
(let [item-ids-set (set item-ids)
update-fn (fn [items]
(filter #(not (item-ids-set (:id %))) items))]
(-> state
(update-in [:library :selected-items library-id] update-fn))))))

View file

@ -87,7 +87,8 @@
:dashboard-library-images-index :dashboard-library-images-index
:dashboard-library-palettes :dashboard-library-palettes
:dashboard-library-palettes-index) :dashboard-library-palettes-index)
(mf/element library-page #js {:team-id team-id (mf/element library-page #js {:key library-id
:team-id team-id
:library-id library-id :library-id library-id
:section library-section}) :section library-section})

View file

@ -17,6 +17,7 @@
[uxbox.util.i18n :as i18n :refer [t tr]] [uxbox.util.i18n :as i18n :refer [t tr]]
[uxbox.util.color :as uc] [uxbox.util.color :as uc]
[uxbox.util.dom :as dom] [uxbox.util.dom :as dom]
[uxbox.util.time :as dt]
[uxbox.main.data.library :as dlib] [uxbox.main.data.library :as dlib]
[uxbox.main.data.icons :as dico] [uxbox.main.data.icons :as dico]
[uxbox.main.data.images :as dimg] [uxbox.main.data.images :as dimg]
@ -118,14 +119,14 @@
:on-click :on-click
(fn [] (fn []
(let [path (keyword (str "dashboard-library-" (name section)))] (let [path (keyword (str "dashboard-library-" (name section)))]
(dico/fetch-icon-library (:id item)) (dlib/retrieve-libraries :icons (:id item))
(st/emit! (rt/nav path {:team-id team-id :library-id (:id item)}))))} (st/emit! (rt/nav path {:team-id team-id :library-id (:id item)}))))}
[:& editable-label {:value (:name item) [:& editable-label {:value (:name item)
:on-change #(st/emit! (dlib/rename-library section library-id %))}] :on-change #(st/emit! (dlib/rename-library section library-id %))}]
])]])) ])]]))
(mf/defc library-top-menu (mf/defc library-top-menu
[{:keys [selected section library-id team-id]}] [{:keys [selected section library-id team-id on-delete-selected]}]
(let [state (mf/use-state {:is-open false (let [state (mf/use-state {:is-open false
:editing-name false}) :editing-name false})
locale (i18n/use-locale) locale (i18n/use-locale)
@ -155,7 +156,9 @@
(st/emit! (rt/nav path {:team-id team-id}))))]]}]] (st/emit! (rt/nav path {:team-id team-id}))))]]}]]
[:div.library-top-menu-actions [:div.library-top-menu-actions
[:a.library-top-menu-actions-delete i/trash] [:a.library-top-menu-actions-delete
{:on-click #(when on-delete-selected (on-delete-selected))}
i/trash]
(if (= section :palettes) (if (= section :palettes)
[:button.btn-dashboard [:button.btn-dashboard
@ -176,18 +179,25 @@
:style {:display "none"}}]])]])) :style {:display "none"}}]])]]))
(mf/defc library-icon-card (mf/defc library-icon-card
[{:keys [id name url content metadata library-id]}] [{:keys [item on-select on-unselect]}]
(let [locale (i18n/use-locale) (let [{:keys [id name url content metadata library-id modified-at]} item
state (mf/use-state {:is-open false})] locale (i18n/use-locale)
state (mf/use-state {:is-open false
:selected false})
time (dt/timeago modified-at {:locale locale})
handle-change (fn []
(swap! state update :selected not)
(if (:selected @state)
(when on-unselect (on-unselect id))
(when on-select (on-select id))))]
[:div.library-card.library-icon [:div.library-card.library-icon
[:div.input-checkbox.check-primary [:div.input-checkbox.check-primary
[:input {:type "checkbox" [:input {:type "checkbox"
:id (str "icon-" id) :id (str "icon-" id)
:on-change #(println "toggle-selection") :on-change handle-change
#_(:checked false)}] :checked (:selected @state)}]
[:label {:for (str "icon-" id)}]] [:label {:for (str "icon-" id)}]]
[:div.library-card-image [:div.library-card-image
#_[:object { :data url :type "image/svg+xml" }]
[:svg {:view-box (->> metadata :view-box (str/join " ")) [:svg {:view-box (->> metadata :view-box (str/join " "))
:width (:width metadata) :width (:width metadata)
:height (:height metadata) :height (:height metadata)
@ -195,7 +205,7 @@
[:div.library-card-footer [:div.library-card-footer
[:div.library-card-footer-name name] [:div.library-card-footer-name name]
[:div.library-card-footer-timestamp "Less than 5 seconds ago"] [:div.library-card-footer-timestamp time]
[:div.library-card-footer-menu [:div.library-card-footer-menu
{ :on-click #(swap! state update :is-open not) } { :on-click #(swap! state update :is-open not) }
i/actions] i/actions]
@ -206,21 +216,28 @@
#(st/emit! (dlib/delete-item :icons library-id id))]]}]]])) #(st/emit! (dlib/delete-item :icons library-id id))]]}]]]))
(mf/defc library-image-card (mf/defc library-image-card
[{:keys [id name thumb-uri library-id]}] [{:keys [item on-select on-unselect]}]
(let [locale (i18n/use-locale) (let [{:keys [id name thumb-uri library-id modified-at]} item
state (mf/use-state {:is-open false})] locale (i18n/use-locale)
state (mf/use-state {:is-open false})
time (dt/timeago modified-at {:locale locale})
handle-change (fn []
(swap! state update :selected not)
(if (:selected @state)
(when on-unselect (on-unselect id))
(when on-select (on-select id))))]
[:div.library-card.library-image [:div.library-card.library-image
[:div.input-checkbox.check-primary [:div.input-checkbox.check-primary
[:input {:type "checkbox" [:input {:type "checkbox"
:id (str "image-" id) :id (str "image-" id)
:on-change #(println "toggle-selection") :on-change handle-change
#_(:checked false)}] #_(:checked false)}]
[:label {:for (str "image-" id)}]] [:label {:for (str "image-" id)}]]
[:div.library-card-image [:div.library-card-image
[:img {:src thumb-uri}]] [:img {:src thumb-uri}]]
[:div.library-card-footer [:div.library-card-footer
[:div.library-card-footer-name name] [:div.library-card-footer-name name]
[:div.library-card-footer-timestamp "Less than 5 seconds ago"] [:div.library-card-footer-timestamp time]
[:div.library-card-footer-menu [:div.library-card-footer-menu
{ :on-click #(swap! state update :is-open not) } { :on-click #(swap! state update :is-open not) }
i/actions] i/actions]
@ -231,15 +248,21 @@
#(st/emit! (dlib/delete-item :images library-id id))]]}]]])) #(st/emit! (dlib/delete-item :images library-id id))]]}]]]))
(mf/defc library-color-card (mf/defc library-color-card
[{ :keys [ id content library-id] }] [{:keys [item on-select on-unselect]}]
(let [{:keys [ id content library-id modified-at]} item
locale (i18n/use-locale)
state (mf/use-state {:is-open false})
handle-change (fn []
(swap! state update :selected not)
(if (:selected @state)
(when on-unselect (on-unselect id))
(when on-select (on-select id))))]
(when content (when content
(let [locale (i18n/use-locale)
state (mf/use-state {:is-open false})]
[:div.library-card.library-color [:div.library-card.library-color
[:div.input-checkbox.check-primary [:div.input-checkbox.check-primary
[:input {:type "checkbox" [:input {:type "checkbox"
:id (str "color-" id) :id (str "color-" id)
:on-change #(println "toggle-selection") :on-change handle-change
#_(:checked false)}] #_(:checked false)}]
[:label {:for (str "color-" id)}]] [:label {:for (str "color-" id)}]]
[:div.library-card-image [:div.library-card-image
@ -266,21 +289,34 @@
(-> (comp (l/key :library) (l/key :selected-items) (l/key library-id)) (-> (comp (l/key :library) (l/key :selected-items) (l/key library-id))
(l/derive st/state))) (l/derive st/state)))
(def last-deleted-library-ref
(-> (comp (l/key :library) (l/key :last-deleted-library))
(l/derive st/state)))
(mf/defc library-page (mf/defc library-page
[{:keys [team-id library-id section]}] [{:keys [team-id library-id section]}]
(let [libraries (mf/deref (libraries-ref section)) (let [state (mf/use-state {:selected #{}})
libraries (mf/deref (libraries-ref section))
items (mf/deref (selected-items-ref library-id)) items (mf/deref (selected-items-ref library-id))
last-deleted-library (mf/deref last-deleted-library-ref)
selected-library (first (filter #(= (:id %) library-id) libraries))] selected-library (first (filter #(= (:id %) library-id) libraries))]
(mf/use-effect {:fn #(st/emit! (dlib/retrieve-libraries section team-id))
:deps (mf/deps section team-id)})
(mf/use-effect {:fn #(when library-id
(st/emit! (dlib/retrieve-library-data section library-id)))
:deps (mf/deps library-id)})
(mf/use-effect {:fn #(if (and (nil? library-id) (> (count libraries) 0)) (mf/use-effect {:fn #(if (and (nil? library-id) (> (count libraries) 0))
(let [path (keyword (str "dashboard-library-" (name section)))] (let [path (keyword (str "dashboard-library-" (name section)))]
(st/emit! (rt/nav path {:team-id team-id :library-id (:id (first libraries))})))) (st/emit! (rt/nav path {:team-id team-id :library-id (:id (first libraries))}))))
:deps (mf/deps library-id section team-id)}) :deps (mf/deps libraries)})
(mf/use-effect {:fn #(if (and library-id (not (some (fn [{id :id}] (= library-id id)) libraries)))
(let [path (keyword (str "dashboard-library-" (name section) "-index"))]
(st/emit! (rt/nav path {:team-id team-id}))))
:deps (mf/deps libraries)})
(mf/use-effect {:fn #(st/emit! (dlib/retrieve-libraries section team-id))
:deps (mf/deps section team-id)})
(mf/use-effect {:fn #(when (and library-id (not= last-deleted-library library-id))
(st/emit! (dlib/retrieve-library-data section library-id)))
:deps (mf/deps library-id last-deleted-library)})
[:div.library-page [:div.library-page
[:& library-header {:section section :team-id team-id}] [:& library-header {:section section :team-id team-id}]
@ -288,7 +324,14 @@
(if library-id (if library-id
[:section.library-content [:section.library-content
[:& library-top-menu {:selected selected-library :section section :library-id library-id :team-id team-id}] [:& library-top-menu
{:selected selected-library
:section section
:library-id library-id
:team-id team-id
:on-delete-selected
#(when (-> @state :selected count (> 0))
(st/emit! (dlib/batch-delete-item section library-id (:selected @state))))}]
[:* [:*
;; TODO: Fix the chunked list ;; TODO: Fix the chunked list
#_[:& chunked-list {:items items #_[:& chunked-list {:items items
@ -303,11 +346,15 @@
(if (> (count items) 0) (if (> (count items) 0)
[:div.library-page-cards-container [:div.library-page-cards-container
(for [item items] (for [item items]
(let [item (assoc item :key (:id item))] (let [item (assoc item :key (:id item))
props {:item item
:key (:id item)
:on-select #(swap! state update :selected conj %)
:on-unselect #(swap! state update :selected disj %)}]
(case section (case section
:icons [:& library-icon-card item] :icons [:& library-icon-card props]
:images [:& library-image-card item] :images [:& library-image-card props]
:palettes [:& library-color-card item ])))] :palettes [:& library-color-card props])))]
[:div.library-content-empty [:div.library-content-empty
[:p.library-content-empty-text "You still have no elements in this library"]])]] [:p.library-content-empty-text "You still have no elements in this library"]])]]

View file

@ -57,7 +57,6 @@
(st/emit! (dw/rename-shape (:id shape) name)) (st/emit! (dw/rename-shape (:id shape) name))
(swap! local assoc :edition false))) (swap! local assoc :edition false)))
on-key-down (fn [event] on-key-down (fn [event]
(js/console.log event)
(when (kbd/enter? event) (when (kbd/enter? event)
(on-blur event))) (on-blur event)))
on-click (fn [event] on-click (fn [event]