mirror of
https://github.com/penpot/penpot.git
synced 2025-05-18 08:06:10 +02:00
🎉 Add better feedback backend.
This commit is contained in:
parent
833944bebb
commit
0683c4a963
9 changed files with 26 additions and 60 deletions
|
@ -1 +1 @@
|
||||||
[FEEDBACK]: From {{ profile.email }}
|
[PENPOT FEEDBACK]: {{subject|abbreviate:19}} (from {% if profile %}{{ profile.email }}{% else %}{{from}}{% endif %})
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
{% if profile %}
|
||||||
Feedback from: {{profile.fullname}} <{{profile.email}}>
|
Feedback from: {{profile.fullname}} <{{profile.email}}>
|
||||||
|
|
||||||
Profile ID: {{profile.id}}
|
Profile ID: {{profile.id}}
|
||||||
|
{% else %}
|
||||||
|
Feedback from: {{from}}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
Subject: {{subject}}
|
Subject: {{subject}}
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,7 @@
|
||||||
(s/def ::error-report-webhook ::us/string)
|
(s/def ::error-report-webhook ::us/string)
|
||||||
(s/def ::feedback-destination ::us/string)
|
(s/def ::feedback-destination ::us/string)
|
||||||
(s/def ::feedback-enabled ::us/boolean)
|
(s/def ::feedback-enabled ::us/boolean)
|
||||||
|
(s/def ::feedback-token ::us/string)
|
||||||
(s/def ::github-client-id ::us/string)
|
(s/def ::github-client-id ::us/string)
|
||||||
(s/def ::github-client-secret ::us/string)
|
(s/def ::github-client-secret ::us/string)
|
||||||
(s/def ::gitlab-base-uri ::us/string)
|
(s/def ::gitlab-base-uri ::us/string)
|
||||||
|
@ -162,6 +163,7 @@
|
||||||
::error-report-webhook
|
::error-report-webhook
|
||||||
::feedback-destination
|
::feedback-destination
|
||||||
::feedback-enabled
|
::feedback-enabled
|
||||||
|
::feedback-token
|
||||||
::github-client-id
|
::github-client-id
|
||||||
::github-client-secret
|
::github-client-secret
|
||||||
::gitlab-base-uri
|
::gitlab-base-uri
|
||||||
|
|
|
@ -111,7 +111,7 @@
|
||||||
:body "internal server error"})))))))
|
:body "internal server error"})))))))
|
||||||
|
|
||||||
(defn- create-router
|
(defn- create-router
|
||||||
[{:keys [session rpc oauth metrics svgparse assets] :as cfg}]
|
[{:keys [session rpc oauth metrics svgparse assets feedback] :as cfg}]
|
||||||
(rr/router
|
(rr/router
|
||||||
[["/metrics" {:get (:handler metrics)}]
|
[["/metrics" {:get (:handler metrics)}]
|
||||||
|
|
||||||
|
@ -136,6 +136,8 @@
|
||||||
[middleware/cookies]]}
|
[middleware/cookies]]}
|
||||||
|
|
||||||
["/svg" {:post svgparse}]
|
["/svg" {:post svgparse}]
|
||||||
|
["/feedback" {:middleware [(:middleware session)]
|
||||||
|
:post feedback}]
|
||||||
|
|
||||||
["/oauth"
|
["/oauth"
|
||||||
["/google" {:post (get-in oauth [:google :handler])}]
|
["/google" {:post (get-in oauth [:google :handler])}]
|
||||||
|
|
|
@ -112,6 +112,7 @@
|
||||||
:svgparse (ig/ref :app.svgparse/handler)
|
:svgparse (ig/ref :app.svgparse/handler)
|
||||||
:storage (ig/ref :app.storage/storage)
|
:storage (ig/ref :app.storage/storage)
|
||||||
:sns-webhook (ig/ref :app.http.awsns/handler)
|
:sns-webhook (ig/ref :app.http.awsns/handler)
|
||||||
|
:feedback (ig/ref :app.http.feedback/handler)
|
||||||
:error-report-handler (ig/ref :app.loggers.mattermost/handler)}
|
:error-report-handler (ig/ref :app.loggers.mattermost/handler)}
|
||||||
|
|
||||||
:app.http.assets/handlers
|
:app.http.assets/handlers
|
||||||
|
@ -121,6 +122,9 @@
|
||||||
:cache-max-age (dt/duration {:hours 24})
|
:cache-max-age (dt/duration {:hours 24})
|
||||||
:signature-max-age (dt/duration {:hours 24 :minutes 5})}
|
:signature-max-age (dt/duration {:hours 24 :minutes 5})}
|
||||||
|
|
||||||
|
:app.http.feedback/handler
|
||||||
|
{:pool (ig/ref :app.db/pool)}
|
||||||
|
|
||||||
:app.http.oauth/all
|
:app.http.oauth/all
|
||||||
{:google (ig/ref :app.http.oauth/google)
|
{:google (ig/ref :app.http.oauth/google)
|
||||||
:gitlab (ig/ref :app.http.oauth/gitlab)
|
:gitlab (ig/ref :app.http.oauth/gitlab)
|
||||||
|
|
|
@ -135,7 +135,6 @@
|
||||||
'app.rpc.mutations.projects
|
'app.rpc.mutations.projects
|
||||||
'app.rpc.mutations.viewer
|
'app.rpc.mutations.viewer
|
||||||
'app.rpc.mutations.teams
|
'app.rpc.mutations.teams
|
||||||
'app.rpc.mutations.feedback
|
|
||||||
'app.rpc.mutations.ldap
|
'app.rpc.mutations.ldap
|
||||||
'app.rpc.mutations.verify-token)
|
'app.rpc.mutations.verify-token)
|
||||||
(map (partial process-method cfg))
|
(map (partial process-method cfg))
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
;;
|
|
||||||
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
|
||||||
;; defined by the Mozilla Public License, v. 2.0.
|
|
||||||
;;
|
|
||||||
;; Copyright (c) 2021 UXBOX Labs SL
|
|
||||||
|
|
||||||
(ns app.rpc.mutations.feedback
|
|
||||||
(:require
|
|
||||||
[app.common.exceptions :as ex]
|
|
||||||
[app.common.spec :as us]
|
|
||||||
[app.config :as cfg]
|
|
||||||
[app.db :as db]
|
|
||||||
[app.emails :as emails]
|
|
||||||
[app.rpc.queries.profile :as profile]
|
|
||||||
[app.util.services :as sv]
|
|
||||||
[clojure.spec.alpha :as s]))
|
|
||||||
|
|
||||||
(s/def ::subject ::us/string)
|
|
||||||
(s/def ::content ::us/string)
|
|
||||||
|
|
||||||
(s/def ::send-profile-feedback
|
|
||||||
(s/keys :req-un [::profile-id ::subject ::content]))
|
|
||||||
|
|
||||||
(sv/defmethod ::send-profile-feedback
|
|
||||||
[{:keys [pool] :as cfg} {:keys [profile-id subject content] :as params}]
|
|
||||||
(when-not (:feedback-enabled cfg/config)
|
|
||||||
(ex/raise :type :validation
|
|
||||||
:code :feedback-disabled
|
|
||||||
:hint "feedback module is disabled"))
|
|
||||||
|
|
||||||
(db/with-atomic [conn pool]
|
|
||||||
(let [profile (profile/retrieve-profile-data conn profile-id)]
|
|
||||||
(emails/send! conn emails/feedback
|
|
||||||
{:to (:feedback-destination cfg/config)
|
|
||||||
:profile profile
|
|
||||||
:subject subject
|
|
||||||
:content content})
|
|
||||||
nil)))
|
|
|
@ -106,6 +106,12 @@
|
||||||
(seq params))
|
(seq params))
|
||||||
(send-mutation! id form)))
|
(send-mutation! id form)))
|
||||||
|
|
||||||
|
(defmethod mutation :send-feedback
|
||||||
|
[id params]
|
||||||
|
(let [uri (str cfg/public-uri "/api/feedback")]
|
||||||
|
(->> (http/send! {:method :post :uri uri :body params})
|
||||||
|
(rx/mapcat handle-response))))
|
||||||
|
|
||||||
(defmethod mutation :update-profile-photo
|
(defmethod mutation :update-profile-photo
|
||||||
[id params]
|
[id params]
|
||||||
(let [form (js/FormData.)]
|
(let [form (js/FormData.)]
|
||||||
|
|
|
@ -30,16 +30,7 @@
|
||||||
(s/def ::feedback-form
|
(s/def ::feedback-form
|
||||||
(s/keys :req-un [::subject ::content]))
|
(s/keys :req-un [::subject ::content]))
|
||||||
|
|
||||||
(defn- on-error
|
(mf/defc feedback-form
|
||||||
[form error]
|
|
||||||
(st/emit! (dm/error (tr "errors.generic"))))
|
|
||||||
|
|
||||||
(defn- on-success
|
|
||||||
[form]
|
|
||||||
(st/emit! (dm/success (tr "notifications.profile-saved"))))
|
|
||||||
|
|
||||||
|
|
||||||
(mf/defc options-form
|
|
||||||
[]
|
[]
|
||||||
(let [profile (mf/deref refs/profile)
|
(let [profile (mf/deref refs/profile)
|
||||||
form (fm/use-form :spec ::feedback-form)
|
form (fm/use-form :spec ::feedback-form)
|
||||||
|
@ -50,6 +41,7 @@
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(mf/deps profile)
|
(mf/deps profile)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
|
(reset! loading false)
|
||||||
(st/emit! (dm/success (tr "labels.feedback-sent")))
|
(st/emit! (dm/success (tr "labels.feedback-sent")))
|
||||||
(swap! form assoc :data {} :touched {} :errors {})))
|
(swap! form assoc :data {} :touched {} :errors {})))
|
||||||
|
|
||||||
|
@ -58,7 +50,7 @@
|
||||||
(mf/deps profile)
|
(mf/deps profile)
|
||||||
(fn [{:keys [code] :as error}]
|
(fn [{:keys [code] :as error}]
|
||||||
(reset! loading false)
|
(reset! loading false)
|
||||||
(if (= code :feedbck-disabled)
|
(if (= code :feedback-disabled)
|
||||||
(st/emit! (dm/error (tr "labels.feedback-disabled")))
|
(st/emit! (dm/error (tr "labels.feedback-disabled")))
|
||||||
(st/emit! (dm/error (tr "errors.generic"))))))
|
(st/emit! (dm/error (tr "errors.generic"))))))
|
||||||
|
|
||||||
|
@ -68,9 +60,8 @@
|
||||||
(fn [form event]
|
(fn [form event]
|
||||||
(reset! loading true)
|
(reset! loading true)
|
||||||
(let [data (:clean-data @form)]
|
(let [data (:clean-data @form)]
|
||||||
(prn "on-submit" data)
|
(->> (rp/mutation! :send-feedback data)
|
||||||
(->> (rp/mutation! :send-profile-feedback data)
|
(rx/subs on-succes on-error)))))]
|
||||||
(rx/subs on-succes on-error #(reset! loading false))))))]
|
|
||||||
|
|
||||||
[:& fm/form {:class "feedback-form"
|
[:& fm/form {:class "feedback-form"
|
||||||
:on-submit on-submit
|
:on-submit on-submit
|
||||||
|
@ -117,4 +108,4 @@
|
||||||
[]
|
[]
|
||||||
[:div.dashboard-settings
|
[:div.dashboard-settings
|
||||||
[:div.form-container
|
[:div.form-container
|
||||||
[:& options-form]]])
|
[:& feedback-form]]])
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue