diff --git a/backend/src/app/rpc/mutations/teams.clj b/backend/src/app/rpc/mutations/teams.clj index 098c51c7f..09d0f112d 100644 --- a/backend/src/app/rpc/mutations/teams.clj +++ b/backend/src/app/rpc/mutations/teams.clj @@ -104,25 +104,52 @@ ;; --- Mutation: Leave Team +(s/def ::reassign-to ::us/uuid) (s/def ::leave-team - (s/keys :req-un [::profile-id ::id])) + (s/keys :req-un [::profile-id ::id] + :opt-un [::reassign-to])) (sv/defmethod ::leave-team - [{:keys [pool] :as cfg} {:keys [id profile-id] :as params}] + [{:keys [pool] :as cfg} {:keys [id profile-id reassign-to]}] (db/with-atomic [conn pool] (let [perms (teams/get-permissions conn profile-id id) members (teams/retrieve-team-members conn id)] - (when (:is-owner perms) + (cond + ;; we can only proceed if there are more members in the team + ;; besides the current profile + (<= (count members) 1) + (ex/raise :type :validation + :code :cant-leave-team + :context {:members (count members)}) + + ;; if the `reassign-to` is filled and has a different value + ;; than the current profile-id, we proceed to reassing the + ;; owner role to profile identified by the `reassign-to`. + (and reassign-to (not= reassign-to profile-id)) + (let [member (d/seek #(= reassign-to (:id %)) members)] + (when-not member + (ex/raise :type :not-found :code :member-does-not-exist)) + + ;; unasign owner role to current profile + (db/update! conn :team-profile-rel + {:is-owner false} + {:team-id id + :profile-id profile-id}) + + ;; assign owner role to new profile + (db/update! conn :team-profile-rel + (role->params :owner) + {:team-id id :profile-id reassign-to})) + + ;; and finally, if all other conditions does not match and the + ;; current profile is owner, we dont allow it because there + ;; must always be an owner. + (:is-owner perms) (ex/raise :type :validation :code :owner-cant-leave-team :hint "releasing owner before leave")) - (when-not (> (count members) 1) - (ex/raise :type :validation - :code :cant-leave-team - :context {:members (count members)})) - (db/delete! conn :team-profile-rel {:profile-id profile-id :team-id id}) diff --git a/frontend/src/app/main/data/dashboard.cljs b/frontend/src/app/main/data/dashboard.cljs index 82ec0cb6a..d7d85d94f 100644 --- a/frontend/src/app/main/data/dashboard.cljs +++ b/frontend/src/app/main/data/dashboard.cljs @@ -397,16 +397,13 @@ (let [{:keys [on-success on-error] :or {on-success identity on-error rx/throw}} (meta params) - team-id (:current-team-id state)] - (rx/concat - (when (uuid? reassign-to) - (->> (rp/mutation! :update-team-member-role {:team-id team-id - :role :owner - :member-id reassign-to}) - (rx/ignore))) - (->> (rp/mutation! :leave-team {:id team-id}) - (rx/tap on-success) - (rx/catch on-error))))))) + team-id (:current-team-id state) + params (cond-> {:id team-id} + (uuid? reassign-to) + (assoc :reassign-to reassign-to))] + (->> (rp/mutation! :leave-team params) + (rx/tap on-success) + (rx/catch on-error)))))) (defn invite-team-member [{:keys [email role] :as params}]