diff --git a/backend/src/app/rpc/management/nitrate.clj b/backend/src/app/rpc/management/nitrate.clj index c6178cda54..ecb52d139f 100644 --- a/backend/src/app/rpc/management/nitrate.clj +++ b/backend/src/app/rpc/management/nitrate.clj @@ -45,6 +45,7 @@ {:id (:id profile) :name (:fullname profile) :email (:email profile) + :created-at (:created-at profile) :photo-url (files/resolve-public-uri (get profile :photo-id))}) ;; ---- API: authenticate diff --git a/backend/test/backend_tests/rpc_management_nitrate_test.clj b/backend/test/backend_tests/rpc_management_nitrate_test.clj index 8ca30ccfce..cf7596d99e 100644 --- a/backend/test/backend_tests/rpc_management_nitrate_test.clj +++ b/backend/test/backend_tests/rpc_management_nitrate_test.clj @@ -38,6 +38,7 @@ (t/is (= (:id profile) (-> out :result :id))) (t/is (= "Nitrate User" (-> out :result :name))) (t/is (= (:email profile) (-> out :result :email))) + (t/is (= (:created-at profile) (-> out :result :created-at))) (t/is (nil? (-> out :result :photo-url))))) (t/deftest authenticate-requires-authentication diff --git a/frontend/src/app/main/data/nitrate.cljs b/frontend/src/app/main/data/nitrate.cljs index 279c622934..62f045ea63 100644 --- a/frontend/src/app/main/data/nitrate.cljs +++ b/frontend/src/app/main/data/nitrate.cljs @@ -6,6 +6,7 @@ [app.common.uuid :as uuid] [app.config :as cf] [app.main.data.common :as dcm] + [app.main.data.event :as ev] [app.main.data.modal :as modal] [app.main.data.notifications :as ntf] [app.main.data.team :as dt] @@ -54,22 +55,35 @@ (rx/map (fn [connectivity] (modal/show popup-type (merge (or connectivity {}) extra-props))))))))) +(defn build-admin-console-url + ([path] + (build-admin-console-url cf/public-uri path nil)) + ([path query-params] + (build-admin-console-url cf/public-uri path query-params)) + ([public-uri path query-params] + (dm/str + (cond-> (u/join public-uri "admin-console/" path) + (seq query-params) (assoc :query (u/map->query-string query-params)))))) + (defn go-to-nitrate-ac ([] - (st/emit! (rt/nav-raw :href "/admin-console/"))) + (st/emit! (rt/nav-raw :href (build-admin-console-url "")))) ([{:keys [organization-id organization-slug]}] (if (and organization-id organization-slug) - (let [href (dm/str "/admin-console/organization/" + (let [path (dm/str "organization/" (u/percent-encode organization-slug) "/" (u/percent-encode (str organization-id)) - "/people/")] + "/people/") + href (build-admin-console-url path)] (st/emit! (rt/nav-raw :href href))) - (st/emit! (rt/nav-raw :href "/admin-console/"))))) + (st/emit! (rt/nav-raw :href (build-admin-console-url "")))))) (defn go-to-nitrate-ac-create-organization - [] - (st/emit! (rt/nav-raw :href "/admin-console/?action=create-organization"))) + [event-origin] + (let [href (build-admin-console-url "" {:action "create-organization" + :origin event-origin})] + (st/emit! (rt/nav-raw :href href)))) (defn can-send-invitations? [{:keys [organization profile-id team-permissions]}] @@ -81,11 +95,12 @@ (def go-to-subscription-url (u/join cf/public-uri "#/settings/subscriptions")) -(def go-to-ac-url "/admin-console/") +(def go-to-ac-url (build-admin-console-url "")) (defn go-to-nitrate-billing [] - (let [href (dm/str "/admin-console/licenses/billing?callback=" (js/encodeURIComponent go-to-subscription-url))] + (let [href (build-admin-console-url "licenses/billing" + {:callback go-to-subscription-url})] (st/emit! (rt/nav-raw :href href)))) (def nitrate-checkout-error-token "nitrate-checkout-error") @@ -104,7 +119,7 @@ :cancel-callback (build nitrate-checkout-cancelled-token)})) (defn go-to-buy-nitrate-license - [subscription base-url] + [subscription base-url event-origin subscription-mode] (let [{:keys [success-callback error-callback finish-error-callback cancel-callback]} (build-nitrate-callback-urls base-url) params {:subscription subscription @@ -112,8 +127,19 @@ :error_callback error-callback :finish_error_callback finish-error-callback :cancel_callback cancel-callback} - href (dm/str "/admin-console/licenses/start?" (u/map->query-string params))] - (st/emit! (rt/nav-raw :href href)))) + href (build-admin-console-url "licenses/start" params) + event (ev/event {::ev/name "start-nitrate-checkout" + ::ev/origin event-origin + :product "nitrate:enterprise" + :billing-period subscription + :subscription-mode subscription-mode})] + (->> st/stream + (rx/filter (ptk/type? ::ev/chunk-persisted)) + (rx/take 1) + (rx/timeout 2000 (rx/of :timeout)) + (rx/subs! (fn [_] + (st/emit! (rt/nav-raw :href href))))) + (st/emit! event (ptk/data-event ::ev/force-persist {})))) (defn fetch-connectivity [] diff --git a/frontend/src/app/main/ui/dashboard/sidebar.cljs b/frontend/src/app/main/ui/dashboard/sidebar.cljs index d64063b522..f828134445 100644 --- a/frontend/src/app/main/ui/dashboard/sidebar.cljs +++ b/frontend/src/app/main/ui/dashboard/sidebar.cljs @@ -320,7 +320,8 @@ (st/emit! (dnt/show-nitrate-popup :nitrate-form {:show-contact-sales-option true})) (dnt/is-valid-license? profile) - (dnt/go-to-nitrate-ac-create-organization) + (dnt/go-to-nitrate-ac-create-organization + "dashboard:organization-switcher") :else (st/emit! (dnt/show-nitrate-popup :nitrate-form))))) @@ -766,7 +767,8 @@ (st/emit! (dnt/show-nitrate-popup :nitrate-form {:show-contact-sales-option true})) (dnt/is-valid-license? profile) - (dnt/go-to-nitrate-ac-create-organization) + (dnt/go-to-nitrate-ac-create-organization + "dashboard:organization-switcher") :else (st/emit! (dnt/show-nitrate-popup :nitrate-form)))))] diff --git a/frontend/src/app/main/ui/dashboard/subscription.cljs b/frontend/src/app/main/ui/dashboard/subscription.cljs index e09bea4f71..95b83aa221 100644 --- a/frontend/src/app/main/ui/dashboard/subscription.cljs +++ b/frontend/src/app/main/ui/dashboard/subscription.cljs @@ -169,7 +169,9 @@ {:show-contact-sales-option true}))))) handle-go-to-cc - (mf/use-fn dnt/go-to-nitrate-ac-create-organization) + (mf/use-fn + #(dnt/go-to-nitrate-ac-create-organization + "dashboard:first-organization-promotional-banner")) handle-open-renew-modal (mf/use-fn #(st/emit! (modal/show :nitrate-code-activation {:renew? true})))] diff --git a/frontend/src/app/main/ui/nitrate/nitrate_activation_success_modal.cljs b/frontend/src/app/main/ui/nitrate/nitrate_activation_success_modal.cljs index d2e1a7bd24..41978b71e7 100644 --- a/frontend/src/app/main/ui/nitrate/nitrate_activation_success_modal.cljs +++ b/frontend/src/app/main/ui/nitrate/nitrate_activation_success_modal.cljs @@ -36,7 +36,8 @@ (mf/use-fn (fn [] (modal/hide!) - (dnt/go-to-nitrate-ac-create-organization)))] + (dnt/go-to-nitrate-ac-create-organization + "admin-console:after-payment-organization-naming-form")))] [:div {:class (stl/css :modal-overlay)} [:div {:class (stl/css :modal-dialog)} diff --git a/frontend/src/app/main/ui/nitrate/nitrate_form.cljs b/frontend/src/app/main/ui/nitrate/nitrate_form.cljs index ef973f111f..24361df2c3 100644 --- a/frontend/src/app/main/ui/nitrate/nitrate_form.cljs +++ b/frontend/src/app/main/ui/nitrate/nitrate_form.cljs @@ -30,7 +30,11 @@ on-click (mf/use-fn (fn [] - (dnt/go-to-buy-nitrate-license "monthly" dnt/go-to-ac-url))) + (dnt/go-to-buy-nitrate-license + "monthly" + dnt/go-to-ac-url + "dashboard:plan-confirmation-modal" + (if (:subscription profile) "paid" "trial")))) on-activate-click (mf/use-fn @@ -101,5 +105,3 @@ [:a {:class (stl/css :link) :on-click on-activate-click} (tr "nitrate.form.enter-code")]]]])]]]])) - - diff --git a/frontend/src/app/main/ui/settings/subscription.cljs b/frontend/src/app/main/ui/settings/subscription.cljs index e1b13d9ce8..bdd82bb890 100644 --- a/frontend/src/app/main/ui/settings/subscription.cljs +++ b/frontend/src/app/main/ui/settings/subscription.cljs @@ -477,7 +477,10 @@ (st/emit! (ev/event {::ev/name "open-subscription-modal" ::ev/origin "settings"})) (if (= subscription-type "nitrate") - (st/emit! (dnt/show-nitrate-popup :nitrate-dialog {:nitrate-license nitrate-license})) + (st/emit! (dnt/show-nitrate-popup + :nitrate-dialog + {:nitrate-license nitrate-license + :event-origin "settings:plan-confirmation-modal"})) (st/emit! (modal/show :management-dialog {:subscription-type subscription-type @@ -749,7 +752,7 @@ (mf/defc subscribe-nitrate-dialog {::mf/register modal/components ::mf/register-as :nitrate-dialog} - [{:keys [nitrate-license show-contact-sales-option] :as connectivity}] + [{:keys [nitrate-license show-contact-sales-option event-origin] :as connectivity}] ;; TODO add translations for this texts when we have the definitive ones (let [online? (:licenses connectivity) handle-close-dialog @@ -760,7 +763,11 @@ on-subscribe-click (mf/use-fn (fn [] - (dnt/go-to-buy-nitrate-license "monthly" (rt/get-current-href))))] + (dnt/go-to-buy-nitrate-license + "monthly" + (rt/get-current-href) + event-origin + (if nitrate-license "paid" "trial"))))] [:div {:class (stl/css :modal-overlay)} [:div {:class (stl/css :modal-dialog)} diff --git a/frontend/test/frontend_tests/data/nitrate_test.cljs b/frontend/test/frontend_tests/data/nitrate_test.cljs index bd5175f277..744f8f1b16 100644 --- a/frontend/test/frontend_tests/data/nitrate_test.cljs +++ b/frontend/test/frontend_tests/data/nitrate_test.cljs @@ -10,6 +10,27 @@ [app.main.data.nitrate :as dnt] [cljs.test :as t :include-macros true])) +(t/deftest build-admin-console-url-preserves-public-uri-subpath + (t/testing "builds admin console routes below the configured Penpot subpath" + (let [public-uri (u/uri "https://example.com/penpot/")] + (t/is (= "https://example.com/penpot/admin-console/" + (dnt/build-admin-console-url public-uri "" nil))) + (t/is (= "https://example.com/penpot/admin-console/organization/my-org/organization-id/people/" + (dnt/build-admin-console-url + public-uri + "organization/my-org/organization-id/people/" + nil))) + (t/is (= {:action "create-organization" + :origin "dashboard:organization-switcher"} + (-> (dnt/build-admin-console-url + public-uri + "" + {:action "create-organization" + :origin "dashboard:organization-switcher"}) + u/uri + :query + u/query-string->map)))))) + (t/deftest build-nitrate-callback-urls-preserves-hash-query (t/testing "appends subscription to an existing query inside the hash route" (let [callbacks (dnt/build-nitrate-callback-urls