mirror of
https://github.com/penpot/penpot.git
synced 2025-05-22 19:16:10 +02:00
🐛 Card menu is hard to launch after search
This commit is contained in:
parent
45072c19a2
commit
8f867c03de
6 changed files with 111 additions and 46 deletions
|
@ -320,7 +320,9 @@
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(update state :dashboard-local
|
(update state :dashboard-local
|
||||||
assoc :selected-files #{}
|
assoc :selected-files #{}
|
||||||
:selected-project nil))))
|
:selected-project nil
|
||||||
|
:menu-open false
|
||||||
|
:menu-pos nil))))
|
||||||
|
|
||||||
(defn toggle-file-select
|
(defn toggle-file-select
|
||||||
[{:keys [id project-id] :as file}]
|
[{:keys [id project-id] :as file}]
|
||||||
|
@ -339,6 +341,53 @@
|
||||||
(assoc :selected-project project-id))))
|
(assoc :selected-project project-id))))
|
||||||
state)))))
|
state)))))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; Show grid menu
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(defn show-file-menu-with-position
|
||||||
|
[file-id pos]
|
||||||
|
(ptk/reify ::show-file-menu-with-position
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(update state :dashboard-local
|
||||||
|
assoc :menu-open true
|
||||||
|
:menu-pos pos
|
||||||
|
:file-id file-id))))
|
||||||
|
|
||||||
|
(defn show-file-menu
|
||||||
|
[]
|
||||||
|
(ptk/reify ::show-file-menu
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(update state :dashboard-local
|
||||||
|
assoc :menu-open true))))
|
||||||
|
|
||||||
|
(defn hide-file-menu
|
||||||
|
[]
|
||||||
|
(ptk/reify ::hide-file-menu
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(update state :dashboard-local
|
||||||
|
assoc :menu-open false))))
|
||||||
|
|
||||||
|
(defn start-edit-file-name
|
||||||
|
[file-id]
|
||||||
|
(ptk/reify ::start-edit-file-name
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(update state :dashboard-local
|
||||||
|
assoc :edition true
|
||||||
|
:file-id file-id))))
|
||||||
|
|
||||||
|
(defn stop-edit-file-name
|
||||||
|
[]
|
||||||
|
(ptk/reify ::stop-edit-file-name
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(update state :dashboard-local
|
||||||
|
assoc :edition false))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Data Modification
|
;; Data Modification
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
|
@ -82,15 +82,27 @@
|
||||||
(dm/get-in state [:dashboard-local :selected-project]))
|
(dm/get-in state [:dashboard-local :selected-project]))
|
||||||
st/state))
|
st/state))
|
||||||
|
|
||||||
(def dashboard-selected-files
|
(defn- dashboard-extract-selected
|
||||||
(l/derived (fn [state]
|
[files selected]
|
||||||
(let [get-file #(dm/get-in state [:dashboard-files %])
|
(let [get-file #(get files %)
|
||||||
sim-file #(select-keys % [:id :name :project-id :is-shared])
|
sim-file #(select-keys % [:id :name :project-id :is-shared])
|
||||||
selected (get-in state [:dashboard-local :selected-files])
|
|
||||||
xform (comp (map get-file)
|
xform (comp (map get-file)
|
||||||
(map sim-file))]
|
(map sim-file))]
|
||||||
(->> (into #{} xform selected)
|
(->> (into #{} xform selected)
|
||||||
(d/index-by :id))))
|
(d/index-by :id))))
|
||||||
|
|
||||||
|
(def dashboard-selected-search
|
||||||
|
(l/derived (fn [state]
|
||||||
|
;; we need to this because :dashboard-search-result is a list
|
||||||
|
;; of maps and we need a map of maps (using :id as key).
|
||||||
|
(let [files (d/index-by :id (:dashboard-search-result state))]
|
||||||
|
(dashboard-extract-selected files (dm/get-in state [:dashboard-local :selected-files]))))
|
||||||
|
st/state))
|
||||||
|
|
||||||
|
(def dashboard-selected-files
|
||||||
|
(l/derived (fn [state]
|
||||||
|
(dashboard-extract-selected (:dashboard-files state)
|
||||||
|
(dm/get-in state [:dashboard-local :selected-files])))
|
||||||
st/state =))
|
st/state =))
|
||||||
|
|
||||||
;; ---- Workspace refs
|
;; ---- Workspace refs
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
[app.util.keyboard :as kbd]
|
[app.util.keyboard :as kbd]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[goog.events :as events]
|
[goog.events :as events]
|
||||||
|
[okulary.core :as l]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(defn ^boolean uuid-str?
|
(defn ^boolean uuid-str?
|
||||||
|
@ -81,6 +82,7 @@
|
||||||
|
|
||||||
(mf/use-effect on-resize)
|
(mf/use-effect on-resize)
|
||||||
|
|
||||||
|
|
||||||
[:div {:class (stl/css :dashboard-content)
|
[:div {:class (stl/css :dashboard-content)
|
||||||
:on-click clear-selected-fn :ref container}
|
:on-click clear-selected-fn :ref container}
|
||||||
(case section
|
(case section
|
||||||
|
@ -137,6 +139,9 @@
|
||||||
|
|
||||||
nil)]))
|
nil)]))
|
||||||
|
|
||||||
|
(def dashboard-initialized
|
||||||
|
(l/derived :current-team-id st/state))
|
||||||
|
|
||||||
(mf/defc dashboard
|
(mf/defc dashboard
|
||||||
[{:keys [route profile] :as props}]
|
[{:keys [route profile] :as props}]
|
||||||
(let [section (get-in route [:data :name])
|
(let [section (get-in route [:data :name])
|
||||||
|
@ -150,7 +155,9 @@
|
||||||
team (get teams team-id)
|
team (get teams team-id)
|
||||||
|
|
||||||
projects (mf/deref refs/dashboard-projects)
|
projects (mf/deref refs/dashboard-projects)
|
||||||
project (get projects project-id)]
|
project (get projects project-id)
|
||||||
|
|
||||||
|
initialized? (mf/deref dashboard-initialized)]
|
||||||
|
|
||||||
(hooks/use-shortcuts ::dashboard sc/shortcuts)
|
(hooks/use-shortcuts ::dashboard sc/shortcuts)
|
||||||
|
|
||||||
|
@ -177,7 +184,7 @@
|
||||||
;; team-id because we want to completely refresh all the
|
;; team-id because we want to completely refresh all the
|
||||||
;; components on team change. Many components assumes that the
|
;; components on team change. Many components assumes that the
|
||||||
;; team is already set so don't put the team into mf/deps.
|
;; team is already set so don't put the team into mf/deps.
|
||||||
(when team
|
(when (and team initialized?)
|
||||||
[:main {:class (stl/css :dashboard)
|
[:main {:class (stl/css :dashboard)
|
||||||
:key (:id team)}
|
:key (:id team)}
|
||||||
[:& sidebar
|
[:& sidebar
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: $s-40 $s-256 1fr;
|
grid-template-columns: $s-40 $s-256 1fr;
|
||||||
grid-template-rows: $s-52 1fr;
|
grid-template-rows: $s-52 1fr;
|
||||||
height: 100vh;
|
height: 100.0vh;
|
||||||
|
|
||||||
:global(svg#loader-pencil) {
|
:global(svg#loader-pencil) {
|
||||||
fill: $df-secondary;
|
fill: $df-secondary;
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
other-teams (remove #(= (:id %) current-team-id) (vals @teams))
|
other-teams (remove #(= (:id %) current-team-id) (vals @teams))
|
||||||
current-projects (remove #(= (:id %) (:project-id file))
|
current-projects (remove #(= (:id %) (:project-id file))
|
||||||
(:projects current-team))
|
(:projects current-team))
|
||||||
|
|
||||||
on-new-tab
|
on-new-tab
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(let [path-params {:project-id (:project-id file)
|
(let [path-params {:project-id (:project-id file)
|
||||||
|
|
|
@ -215,31 +215,34 @@
|
||||||
|
|
||||||
(mf/defc grid-item
|
(mf/defc grid-item
|
||||||
{:wrap [mf/memo]}
|
{:wrap [mf/memo]}
|
||||||
[{:keys [file navigate? origin library-view?] :as props}]
|
[{:keys [file origin library-view?] :as props}]
|
||||||
(let [file-id (:id file)
|
(let [file-id (:id file)
|
||||||
local (mf/use-state {:menu-open false
|
selected-files (if (= origin :search)
|
||||||
:menu-pos nil
|
(mf/deref refs/dashboard-selected-search)
|
||||||
:edition false})
|
(mf/deref refs/dashboard-selected-files))
|
||||||
selected-files (mf/deref refs/dashboard-selected-files)
|
|
||||||
dashboard-local (mf/deref refs/dashboard-local)
|
dashboard-local (mf/deref refs/dashboard-local)
|
||||||
node-ref (mf/use-ref)
|
file-menu-open? (:menu-open dashboard-local)
|
||||||
menu-ref (mf/use-ref)
|
|
||||||
|
|
||||||
selected? (contains? selected-files file-id)
|
selected? (contains? selected-files file-id)
|
||||||
|
|
||||||
|
node-ref (mf/use-ref)
|
||||||
|
menu-ref (mf/use-ref)
|
||||||
|
|
||||||
on-menu-close
|
on-menu-close
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
#(swap! local assoc :menu-open false))
|
(fn [_]
|
||||||
|
(st/emit! (dd/hide-file-menu))))
|
||||||
|
|
||||||
on-select
|
on-select
|
||||||
|
(mf/use-fn
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(when (and (or (not selected?) (> (count selected-files) 1))
|
(when (or (not selected?) (> (count selected-files) 1))
|
||||||
(not (:menu-open @local)))
|
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(let [shift? (kbd/shift? event)]
|
(let [shift? (kbd/shift? event)]
|
||||||
(when-not shift?
|
(when-not shift?
|
||||||
(st/emit! (dd/clear-selected-files)))
|
(st/emit! (dd/clear-selected-files)))
|
||||||
(st/emit! (dd/toggle-file-select file)))))
|
(st/emit! (dd/toggle-file-select file))))))
|
||||||
|
|
||||||
on-navigate
|
on-navigate
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -254,6 +257,7 @@
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps selected-files)
|
(mf/deps selected-files)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
|
(st/emit! (dd/hide-file-menu))
|
||||||
(let [offset (dom/get-offset-position (.-nativeEvent event))
|
(let [offset (dom/get-offset-position (.-nativeEvent event))
|
||||||
|
|
||||||
select-current? (not (contains? selected-files (:id file)))
|
select-current? (not (contains? selected-files (:id file)))
|
||||||
|
@ -283,6 +287,7 @@
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps file selected?)
|
(mf/deps file selected?)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
|
(dom/stop-propagation event)
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(when-not selected?
|
(when-not selected?
|
||||||
(when-not (kbd/shift? event)
|
(when-not (kbd/shift? event)
|
||||||
|
@ -297,9 +302,7 @@
|
||||||
x (:left points)]
|
x (:left points)]
|
||||||
(gpt/point x y))
|
(gpt/point x y))
|
||||||
client-position)]
|
client-position)]
|
||||||
(swap! local assoc
|
(st/emit! (dd/show-file-menu-with-position file-id position)))))
|
||||||
:menu-open true
|
|
||||||
:menu-pos position))))
|
|
||||||
|
|
||||||
edit
|
edit
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -308,16 +311,14 @@
|
||||||
(let [name (str/trim name)]
|
(let [name (str/trim name)]
|
||||||
(when (not= name "")
|
(when (not= name "")
|
||||||
(st/emit! (dd/rename-file (assoc file :name name)))))
|
(st/emit! (dd/rename-file (assoc file :name name)))))
|
||||||
(swap! local assoc :edition false)))
|
(st/emit! (dd/stop-edit-file-name))))
|
||||||
|
|
||||||
on-edit
|
on-edit
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps file)
|
(mf/deps file)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(swap! local assoc
|
(st/emit! (dd/start-edit-file-name file-id))))
|
||||||
:edition true
|
|
||||||
:menu-open false)))
|
|
||||||
|
|
||||||
handle-key-down
|
handle-key-down
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
|
@ -331,10 +332,6 @@
|
||||||
(on-select event)) ;; TODO Fix this
|
(on-select event)) ;; TODO Fix this
|
||||||
)))]
|
)))]
|
||||||
|
|
||||||
(mf/with-effect [selected? local]
|
|
||||||
(when (and (not selected?) (:menu-open @local))
|
|
||||||
(swap! local assoc :menu-open false)))
|
|
||||||
|
|
||||||
[:li
|
[:li
|
||||||
{:class (stl/css-case :grid-item true :project-th true :library library-view?)}
|
{:class (stl/css-case :grid-item true :project-th true :library library-view?)}
|
||||||
[:button
|
[:button
|
||||||
|
@ -363,13 +360,13 @@
|
||||||
|
|
||||||
[:div {:class (stl/css :info-wrapper)}
|
[:div {:class (stl/css :info-wrapper)}
|
||||||
[:div {:class (stl/css :item-info)}
|
[:div {:class (stl/css :item-info)}
|
||||||
(if (:edition @local)
|
(if (and (= file-id (:file-id dashboard-local)) (:edition dashboard-local))
|
||||||
[:& inline-edition {:content (:name file)
|
[:& inline-edition {:content (:name file)
|
||||||
:on-end edit}]
|
:on-end edit}]
|
||||||
[:h3 (:name file)])
|
[:h3 (:name file)])
|
||||||
[:& grid-item-metadata {:modified-at (:modified-at file)}]]
|
[:& grid-item-metadata {:modified-at (:modified-at file)}]]
|
||||||
|
|
||||||
[:div {:class (stl/css-case :project-th-actions true :force-display (:menu-open @local))}
|
[:div {:class (stl/css-case :project-th-actions true :force-display (:menu-open dashboard-local))}
|
||||||
[:div
|
[:div
|
||||||
{:class (stl/css :project-th-icon :menu)
|
{:class (stl/css :project-th-icon :menu)
|
||||||
:tab-index "0"
|
:tab-index "0"
|
||||||
|
@ -381,16 +378,15 @@
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(on-menu-click event)))}
|
(on-menu-click event)))}
|
||||||
i/actions
|
i/actions
|
||||||
(when selected?
|
(when (and selected? file-menu-open?)
|
||||||
[:& file-menu {:files (vals selected-files)
|
[:& file-menu {:files (vals selected-files)
|
||||||
:show? (:menu-open @local)
|
:show? (:menu-open dashboard-local)
|
||||||
:left (+ 24 (:x (:menu-pos @local)))
|
:left (+ 24 (:x (:menu-pos dashboard-local)))
|
||||||
:top (:y (:menu-pos @local))
|
:top (:y (:menu-pos dashboard-local))
|
||||||
:navigate? navigate?
|
:navigate? true
|
||||||
:on-edit on-edit
|
:on-edit on-edit
|
||||||
:on-menu-close on-menu-close
|
:on-menu-close on-menu-close
|
||||||
:origin origin
|
:origin origin
|
||||||
:dashboard-local dashboard-local
|
|
||||||
:parent-id (str file-id "-action-menu")}])]]]]]))
|
:parent-id (str file-id "-action-menu")}])]]]]]))
|
||||||
|
|
||||||
(mf/defc grid
|
(mf/defc grid
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue