diff --git a/frontend/resources/locales.json b/frontend/resources/locales.json index 758daca7d..eeba81af1 100644 --- a/frontend/resources/locales.json +++ b/frontend/resources/locales.json @@ -625,6 +625,13 @@ }, "used-in" : [ "src/app/main/ui/settings/password.cljs" ] }, + "dashboard.pin-unpin" : { + "translations" : { + "en" : "Pin/Unpin", + "es" : "Fijar/Desfijar" + }, + "used-in" : [ "src/app/main/ui/dashboard/project_menu.cljs" ] + }, "dashboard.projects-title" : { "translations" : { "ca" : "Projectes", diff --git a/frontend/resources/styles/main/partials/dashboard.scss b/frontend/resources/styles/main/partials/dashboard.scss index 38b467b49..f453cf0a3 100644 --- a/frontend/resources/styles/main/partials/dashboard.scss +++ b/frontend/resources/styles/main/partials/dashboard.scss @@ -49,6 +49,10 @@ margin-right: $medium; } + .edit-wrapper { + margin-right: $medium; + } + .info { font-size: 15px; line-height: 1rem; diff --git a/frontend/src/app/main/data/dashboard.cljs b/frontend/src/app/main/data/dashboard.cljs index 93a27e214..8483d58d0 100644 --- a/frontend/src/app/main/data/dashboard.cljs +++ b/frontend/src/app/main/data/dashboard.cljs @@ -353,8 +353,7 @@ (us/assert ::us/uuid id) (letfn [(duplicated [project state] (-> state - (assoc-in [:projects (:team-id project) (:id project)] project) - (assoc-in [:dashboard-local :project-for-edit] (:id project))))] + (assoc-in [:projects (:team-id project) (:id project)] project)))] (ptk/reify ::duplicate-project ptk/WatchEvent (watch [_ state stream] @@ -370,6 +369,22 @@ (rx/map #(partial duplicated %)) (rx/catch on-error))))))) +(defn move-project + [{:keys [id team-id] :as params}] + (us/assert ::us/uuid id) + (us/assert ::us/uuid team-id) + (ptk/reify ::move-project + ptk/WatchEvent + (watch [_ state stream] + (let [{:keys [on-success on-error] + :or {on-success identity + on-error identity}} (meta params)] + + (->> (rp/mutation! :move-project {:project-id id + :team-id team-id}) + (rx/tap on-success) + (rx/catch on-error)))))) + (def clear-project-for-edit (ptk/reify ::clear-project-for-edit ptk/UpdateEvent diff --git a/frontend/src/app/main/ui/dashboard/project_menu.cljs b/frontend/src/app/main/ui/dashboard/project_menu.cljs index 672e73c34..b319dca85 100644 --- a/frontend/src/app/main/ui/dashboard/project_menu.cljs +++ b/frontend/src/app/main/ui/dashboard/project_menu.cljs @@ -11,10 +11,13 @@ (:require [app.main.data.dashboard :as dd] [app.main.data.modal :as modal] + [app.main.repo :as rp] [app.main.store :as st] + [app.main.ui.context :as ctx] [app.main.ui.components.context-menu :refer [context-menu]] [app.util.i18n :as i18n :refer [tr]] [app.util.router :as rt] + [beicon.core :as rx] [rumext.alpha :as mf])) (mf/defc project-menu @@ -26,6 +29,9 @@ (let [top (or top 0) left (or left 0) + current-team-id (mf/use-ctx ctx/current-team-id) + teams (mf/use-state nil) + on-duplicate (mf/use-callback (mf/deps project) @@ -37,6 +43,24 @@ (st/emit! (dd/duplicate-project (with-meta project {:on-success on-success}))))) + toggle-pin + (mf/use-callback + (mf/deps project) + (st/emitf (dd/toggle-project-pin project))) + + on-move + (mf/use-callback + (mf/deps project) + (fn [team-id] + (let [data {:id (:id project) + :team-id team-id} + + mdata {:on-success + (st/emitf (rt/nav :dashboard-projects + {:team-id team-id}))}] + + (st/emitf (dd/move-project (with-meta data mdata)))))) + delete-fn (mf/use-callback (mf/deps project) @@ -54,12 +78,26 @@ :accept-label (tr "modals.delete-project-confirm.accept") :on-accept delete-fn})))] - [:& context-menu {:on-close on-menu-close - :show show? - :fixed? (or (not= top 0) (not= left 0)) - :top top - :left left - :options [[(tr "labels.rename") on-edit] - [(tr "dashboard.duplicate") on-duplicate] - [(tr "labels.delete") on-delete]]}])) + (mf/use-layout-effect + (mf/deps show?) + (fn [] + (if show? + (->> (rp/query! :teams) + (rx/subs #(reset! teams %))) + (reset! teams [])))) + + (when (seq @teams) + [:& context-menu {:on-close on-menu-close + :show show? + :fixed? (or (not= top 0) (not= left 0)) + :top top + :left left + :options [[(tr "labels.rename") on-edit] + [(tr "dashboard.duplicate") on-duplicate] + [(tr "dashboard.pin-unpin") toggle-pin] + [(tr "dashboard.move-to") nil + (for [team @teams] + [(:name team) (on-move (:id team))])] + [:separator] + [(tr "labels.delete") on-delete]]}]))) diff --git a/frontend/src/app/main/ui/dashboard/projects.cljs b/frontend/src/app/main/ui/dashboard/projects.cljs index 6d1a9799c..74b4433df 100644 --- a/frontend/src/app/main/ui/dashboard/projects.cljs +++ b/frontend/src/app/main/ui/dashboard/projects.cljs @@ -15,6 +15,8 @@ [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.dashboard.grid :refer [line-grid]] + [app.main.ui.dashboard.inline-edition :refer [inline-edition]] + [app.main.ui.dashboard.project-menu :refer [project-menu]] [app.main.ui.icons :as i] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [t tr]] @@ -60,6 +62,12 @@ team-id (:team-id project) file-count (or (:count project) 0) + dstate (mf/deref refs/dashboard-local) + edit-id (:project-for-edit dstate) + local (mf/use-state {:menu-open false + :menu-pos nil + :edition? (= (:id project) edit-id)}) + on-nav (mf/use-callback (mf/deps project) @@ -71,6 +79,26 @@ (mf/deps project) (st/emitf (dd/toggle-project-pin project))) + on-menu-click + (mf/use-callback (fn [event] + (let [position (dom/get-client-position event)] + (dom/prevent-default event) + (swap! local assoc :menu-open true + :menu-pos position)))) + + on-menu-close + (mf/use-callback #(swap! local assoc :menu-open false)) + + on-edit-open + (mf/use-callback #(swap! local assoc :edition? true)) + + on-edit + (mf/use-callback + (mf/deps project) + (fn [name] + (st/emit! (dd/rename-project (assoc project :name name))) + (swap! local assoc :edition? false))) + on-file-created (mf/use-callback (mf/deps project) @@ -96,7 +124,18 @@ {:class (when (:is-pinned project) "active") :on-click toggle-pin} i/pin]) - [:h2 {:on-click on-nav} (:name project)] + (if (:edition? @local) + [:& inline-edition {:content (:name project) + :on-end on-edit}] + [:h2 {:on-click on-nav + :on-context-menu on-menu-click} + (:name project)]) + [:& project-menu {:project project + :show? (:menu-open @local) + :left (:x (:menu-pos @local)) + :top (:y (:menu-pos @local)) + :on-edit on-edit-open + :on-menu-close on-menu-close}] [:span.info (str file-count " files")] (when (> file-count 0) (let [time (-> (:modified-at project)