mirror of
https://github.com/penpot/penpot.git
synced 2026-09-11 14:39:35 +00:00
✨ Add notification for nitrate when creating a team inside an organization (#8639)
This commit is contained in:
parent
6e19548bac
commit
8f35e451e6
@ -18,16 +18,16 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defn- request-builder
|
(defn- request-builder
|
||||||
[cfg method uri shared-key profile-id]
|
[cfg method uri shared-key profile-id request-params]
|
||||||
(fn []
|
(fn []
|
||||||
(http/req! cfg {:method method
|
(http/req! cfg (cond-> {:method method
|
||||||
:headers {"content-type" "application/json"
|
:headers {"content-type" "application/json"
|
||||||
"accept" "application/json"
|
"accept" "application/json"
|
||||||
"x-shared-key" shared-key
|
"x-shared-key" shared-key
|
||||||
"x-profile-id" (str profile-id)}
|
"x-profile-id" (str profile-id)}
|
||||||
:uri uri
|
:uri uri
|
||||||
:version :http1.1})))
|
:version :http1.1}
|
||||||
|
(= method :post) (assoc :body (json/encode request-params))))))
|
||||||
|
|
||||||
(defn- with-retries
|
(defn- with-retries
|
||||||
[handler max-retries]
|
[handler max-retries]
|
||||||
@ -60,9 +60,9 @@
|
|||||||
nil)))))
|
nil)))))
|
||||||
|
|
||||||
(defn- request-to-nitrate
|
(defn- request-to-nitrate
|
||||||
[cfg method uri schema {:keys [::rpc/profile-id] :as params}]
|
[cfg method uri schema {:keys [::rpc/profile-id request-params] :as params}]
|
||||||
(let [shared-key (-> cfg ::setup/shared-keys :nitrate)
|
(let [shared-key (-> cfg ::setup/shared-keys :nitrate)
|
||||||
full-http-call (-> (request-builder cfg method uri shared-key profile-id)
|
full-http-call (-> (request-builder cfg method uri shared-key profile-id request-params)
|
||||||
(with-retries 3)
|
(with-retries 3)
|
||||||
(with-validate uri schema))]
|
(with-validate uri schema))]
|
||||||
(full-http-call)))
|
(full-http-call)))
|
||||||
@ -86,6 +86,12 @@
|
|||||||
[:name ::sm/text]
|
[:name ::sm/text]
|
||||||
[:slug ::sm/text]])
|
[:slug ::sm/text]])
|
||||||
|
|
||||||
|
(def ^:private schema:team
|
||||||
|
[:map
|
||||||
|
[:id ::sm/uuid]
|
||||||
|
[:organizationId ::sm/uuid]
|
||||||
|
[:yourPenpot :boolean]])
|
||||||
|
|
||||||
;; TODO Unify with schemas on backend/src/app/http/management.clj
|
;; TODO Unify with schemas on backend/src/app/http/management.clj
|
||||||
(def ^:private schema:timestamp
|
(def ^:private schema:timestamp
|
||||||
(sm/type-schema
|
(sm/type-schema
|
||||||
@ -161,17 +167,40 @@
|
|||||||
(defn- get-team-org
|
(defn- get-team-org
|
||||||
[cfg {:keys [team-id] :as params}]
|
[cfg {:keys [team-id] :as params}]
|
||||||
(let [baseuri (cf/get :nitrate-backend-uri)]
|
(let [baseuri (cf/get :nitrate-backend-uri)]
|
||||||
(request-to-nitrate cfg :get (str baseuri "/api/teams/" (str team-id)) schema:organization params)))
|
(request-to-nitrate cfg :get
|
||||||
|
(str baseuri
|
||||||
|
"/api/teams/"
|
||||||
|
team-id)
|
||||||
|
schema:organization params)))
|
||||||
|
|
||||||
|
(defn- set-team-org
|
||||||
|
[cfg {:keys [organization-id team-id is-default] :as params}]
|
||||||
|
(let [baseuri (cf/get :nitrate-backend-uri)
|
||||||
|
params (assoc params :request-params {:teamId team-id
|
||||||
|
:yourPenpot (true? is-default)})]
|
||||||
|
(request-to-nitrate cfg :post
|
||||||
|
(str baseuri
|
||||||
|
"/api/organizations/"
|
||||||
|
organization-id
|
||||||
|
"/addTeam")
|
||||||
|
schema:team params)))
|
||||||
|
|
||||||
(defn- get-subscription
|
(defn- get-subscription
|
||||||
[cfg {:keys [profile-id] :as params}]
|
[cfg {:keys [profile-id] :as params}]
|
||||||
(let [baseuri (cf/get :nitrate-backend-uri)]
|
(let [baseuri (cf/get :nitrate-backend-uri)]
|
||||||
(request-to-nitrate cfg :get (str baseuri "/api/subscriptions/" (str profile-id)) schema:subscription params)))
|
(request-to-nitrate cfg :get
|
||||||
|
(str baseuri
|
||||||
|
"/api/subscriptions/"
|
||||||
|
profile-id)
|
||||||
|
schema:subscription params)))
|
||||||
|
|
||||||
(defn- get-connectivity
|
(defn- get-connectivity
|
||||||
[cfg params]
|
[cfg params]
|
||||||
(let [baseuri (cf/get :nitrate-backend-uri)]
|
(let [baseuri (cf/get :nitrate-backend-uri)]
|
||||||
(request-to-nitrate cfg :get (str baseuri "/api/connectivity") schema:connectivity params)))
|
(request-to-nitrate cfg :get
|
||||||
|
(str baseuri
|
||||||
|
"/api/connectivity")
|
||||||
|
schema:connectivity params)))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; INITIALIZATION
|
;; INITIALIZATION
|
||||||
@ -181,6 +210,7 @@
|
|||||||
[_ cfg]
|
[_ cfg]
|
||||||
(when (contains? cf/flags :nitrate)
|
(when (contains? cf/flags :nitrate)
|
||||||
{:get-team-org (partial get-team-org cfg)
|
{:get-team-org (partial get-team-org cfg)
|
||||||
|
:set-team-org (partial set-team-org cfg)
|
||||||
:get-subscription (partial get-subscription cfg)
|
:get-subscription (partial get-subscription cfg)
|
||||||
:connectivity (partial get-connectivity cfg)}))
|
:connectivity (partial get-connectivity cfg)}))
|
||||||
|
|
||||||
@ -224,6 +254,22 @@
|
|||||||
:cause cause)
|
:cause cause)
|
||||||
team)))
|
team)))
|
||||||
|
|
||||||
|
(defn set-team-organization
|
||||||
|
"Associates a team with an organization in Nitrate.
|
||||||
|
Requires organization-id and is-default in params.
|
||||||
|
Throws an exception if the request fails."
|
||||||
|
[cfg team params]
|
||||||
|
(let [params (assoc (or params {})
|
||||||
|
:team-id (:id team)
|
||||||
|
:organization-id (:organization-id params)
|
||||||
|
:is-default (:is-default params))
|
||||||
|
result (call cfg :set-team-org params)]
|
||||||
|
(when (nil? result)
|
||||||
|
(throw (ex-info "Failed to set team organization"
|
||||||
|
{:team-id (:id team)
|
||||||
|
:organization-id (:organization-id params)})))
|
||||||
|
team))
|
||||||
|
|
||||||
(defn connectivity
|
(defn connectivity
|
||||||
[cfg]
|
[cfg]
|
||||||
(call cfg :connectivity {}))
|
(call cfg :connectivity {}))
|
||||||
|
|||||||
@ -499,7 +499,9 @@
|
|||||||
[:map {:title "create-team"}
|
[:map {:title "create-team"}
|
||||||
[:name [:string {:max 250}]]
|
[:name [:string {:max 250}]]
|
||||||
[:features {:optional true} ::cfeat/features]
|
[:features {:optional true} ::cfeat/features]
|
||||||
[:id {:optional true} ::sm/uuid]])
|
[:id {:optional true} ::sm/uuid]
|
||||||
|
[:organization-id {:optional true} ::sm/uuid]
|
||||||
|
[:is-default {:optional true} :boolean]])
|
||||||
|
|
||||||
(sv/defmethod ::create-team
|
(sv/defmethod ::create-team
|
||||||
{::doc/added "1.17"
|
{::doc/added "1.17"
|
||||||
@ -531,6 +533,9 @@
|
|||||||
:role :owner)
|
:role :owner)
|
||||||
project (create-team-default-project conn params)]
|
project (create-team-default-project conn params)]
|
||||||
(create-team-role conn params)
|
(create-team-role conn params)
|
||||||
|
;; Set team organization in Nitrate if organization-id is provided
|
||||||
|
(when (and (contains? cf/flags :nitrate) (:organization-id params))
|
||||||
|
(nitrate/set-team-organization cfg-or-conn team params))
|
||||||
(assoc team :default-project-id (:id project))))
|
(assoc team :default-project-id (:id project))))
|
||||||
|
|
||||||
(defn- create-team*
|
(defn- create-team*
|
||||||
|
|||||||
@ -113,7 +113,7 @@
|
|||||||
{::doc/added "2.14"
|
{::doc/added "2.14"
|
||||||
::sm/params schema:notify-user-added-to-organization
|
::sm/params schema:notify-user-added-to-organization
|
||||||
::rpc/auth false}
|
::rpc/auth false}
|
||||||
[cfg {:keys [profile-id]}]
|
[cfg {:keys [profile-id organization-id]}]
|
||||||
(quotes/check! cfg {::quotes/id ::quotes/teams-per-profile
|
(quotes/check! cfg {::quotes/id ::quotes/teams-per-profile
|
||||||
::quotes/profile-id profile-id})
|
::quotes/profile-id profile-id})
|
||||||
|
|
||||||
@ -122,7 +122,9 @@
|
|||||||
(set/difference cfeat/no-team-inheritable-features))
|
(set/difference cfeat/no-team-inheritable-features))
|
||||||
params {:profile-id profile-id
|
params {:profile-id profile-id
|
||||||
:name "Default"
|
:name "Default"
|
||||||
:features features}
|
:features features
|
||||||
|
:organization-id organization-id
|
||||||
|
:is-default true}
|
||||||
team (db/tx-run! cfg teams/create-team params)]
|
team (db/tx-run! cfg teams/create-team params)]
|
||||||
(select-keys team [:id])))
|
(select-keys team [:id])))
|
||||||
|
|
||||||
|
|||||||
@ -255,7 +255,7 @@
|
|||||||
(-deref [_] team)))
|
(-deref [_] team)))
|
||||||
|
|
||||||
(defn create-team
|
(defn create-team
|
||||||
[{:keys [name] :as params}]
|
[{:keys [name organization-id] :as params}]
|
||||||
(dm/assert! (string? name))
|
(dm/assert! (string? name))
|
||||||
(ptk/reify ::create-team
|
(ptk/reify ::create-team
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
@ -264,7 +264,8 @@
|
|||||||
:or {on-success identity
|
:or {on-success identity
|
||||||
on-error rx/throw}} (meta params)
|
on-error rx/throw}} (meta params)
|
||||||
features features/global-enabled-features
|
features features/global-enabled-features
|
||||||
params {:name name :features features}]
|
params (cond-> {:name name :features features}
|
||||||
|
organization-id (assoc :organization-id organization-id))]
|
||||||
(->> (rp/cmd! :create-team (with-meta params (meta it)))
|
(->> (rp/cmd! :create-team (with-meta params (meta it)))
|
||||||
(rx/tap on-success)
|
(rx/tap on-success)
|
||||||
(rx/map team-created)
|
(rx/map team-created)
|
||||||
|
|||||||
@ -314,7 +314,9 @@
|
|||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps organization)
|
(mf/deps organization)
|
||||||
(fn []
|
(fn []
|
||||||
(dnt/go-to-nitrate-cc organization)))
|
(if (:organization-id organization)
|
||||||
|
(dnt/go-to-nitrate-cc organization)
|
||||||
|
(dnt/go-to-nitrate-cc))))
|
||||||
|
|
||||||
default-team-id (or (->> organizations
|
default-team-id (or (->> organizations
|
||||||
vals
|
vals
|
||||||
@ -371,7 +373,13 @@
|
|||||||
|
|
||||||
teams (dissoc teams default-team-id)
|
teams (dissoc teams default-team-id)
|
||||||
on-create-team-click
|
on-create-team-click
|
||||||
(mf/use-fn #(st/emit! (modal/show :team-form {})))
|
(mf/use-fn
|
||||||
|
(mf/deps team)
|
||||||
|
(fn []
|
||||||
|
(let [params (if (and (contains? cf/flags :nitrate) (:organization-id team))
|
||||||
|
{:organization-id (:organization-id team)}
|
||||||
|
{})]
|
||||||
|
(st/emit! (modal/show :team-form params)))))
|
||||||
|
|
||||||
on-team-click
|
on-team-click
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
@ -383,12 +391,12 @@
|
|||||||
|
|
||||||
[:> dropdown-menu* props
|
[:> dropdown-menu* props
|
||||||
[:> dropdown-menu-item* {:on-click on-team-click
|
[:> dropdown-menu-item* {:on-click on-team-click
|
||||||
:data-value (:default-team-id profile)
|
:data-value default-team-id
|
||||||
:class (stl/css :team-dropdown-item)}
|
:class (stl/css :team-dropdown-item)}
|
||||||
[:span {:class (stl/css :penpot-icon)} deprecated-icon/logo-icon]
|
[:span {:class (stl/css :penpot-icon)} deprecated-icon/logo-icon]
|
||||||
|
|
||||||
[:span {:class (stl/css :team-text)} (tr "dashboard.your-penpot")]
|
[:span {:class (stl/css :team-text)} (tr "dashboard.your-penpot")]
|
||||||
(when (= (:default-team-id profile) (:id team))
|
(when (= default-team-id (:id team))
|
||||||
tick-icon)]
|
tick-icon)]
|
||||||
|
|
||||||
(for [team-item (remove :is-default (vals teams))]
|
(for [team-item (remove :is-default (vals teams))]
|
||||||
|
|||||||
@ -24,7 +24,8 @@
|
|||||||
|
|
||||||
(def ^:private schema:team-form
|
(def ^:private schema:team-form
|
||||||
[:map {:title "TeamForm"}
|
[:map {:title "TeamForm"}
|
||||||
[:name [::sm/text {:max 250}]]])
|
[:name [::sm/text {:max 250}]]
|
||||||
|
[:organization-id {:optional true} [:maybe ::sm/uuid]]])
|
||||||
|
|
||||||
(defn- on-create-success
|
(defn- on-create-success
|
||||||
[_form response]
|
[_form response]
|
||||||
@ -50,7 +51,9 @@
|
|||||||
[form]
|
[form]
|
||||||
(let [mdata {:on-success (partial on-create-success form)
|
(let [mdata {:on-success (partial on-create-success form)
|
||||||
:on-error (partial on-error form)}
|
:on-error (partial on-error form)}
|
||||||
params {:name (get-in @form [:clean-data :name])}]
|
data (:clean-data @form)
|
||||||
|
params (cond-> {:name (:name data)}
|
||||||
|
(:organization-id data) (assoc :organization-id (:organization-id data)))]
|
||||||
(st/emit! (-> (dtm/create-team (with-meta params mdata))
|
(st/emit! (-> (dtm/create-team (with-meta params mdata))
|
||||||
(with-meta {::ev/origin :dashboard})))))
|
(with-meta {::ev/origin :dashboard})))))
|
||||||
|
|
||||||
@ -58,7 +61,8 @@
|
|||||||
[form]
|
[form]
|
||||||
(let [mdata {:on-success (partial on-update-success form)
|
(let [mdata {:on-success (partial on-update-success form)
|
||||||
:on-error (partial on-error form)}
|
:on-error (partial on-error form)}
|
||||||
team (get @form :clean-data)]
|
data (:clean-data @form)
|
||||||
|
team (select-keys data [:id :name])] ;; Only send name and id for updates
|
||||||
(st/emit! (dtm/update-team (with-meta team mdata))
|
(st/emit! (dtm/update-team (with-meta team mdata))
|
||||||
(modal/hide))))
|
(modal/hide))))
|
||||||
|
|
||||||
@ -72,10 +76,16 @@
|
|||||||
(mf/defc team-form-modal
|
(mf/defc team-form-modal
|
||||||
{::mf/register modal/components
|
{::mf/register modal/components
|
||||||
::mf/register-as :team-form}
|
::mf/register-as :team-form}
|
||||||
[{:keys [team] :as props}]
|
[{:keys [team organization-id] :as props}]
|
||||||
(let [initial (mf/use-memo (fn []
|
(let [initial (mf/use-memo
|
||||||
(or (some-> team (select-keys [:name :id]))
|
(mf/deps team organization-id)
|
||||||
{})))
|
(fn []
|
||||||
|
(if team
|
||||||
|
;; For existing teams, only include name and id (no organization changes)
|
||||||
|
(select-keys team [:name :id])
|
||||||
|
;; For new teams, include organization-id if provided
|
||||||
|
(cond-> {}
|
||||||
|
organization-id (assoc :organization-id organization-id)))))
|
||||||
form (fm/use-form :schema schema:team-form
|
form (fm/use-form :schema schema:team-form
|
||||||
:initial initial)
|
:initial initial)
|
||||||
handle-keydown
|
handle-keydown
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user