0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-12 07:41:43 -05:00

Integrate error handling for webhooks UI

This commit is contained in:
Andrey Antukh 2022-12-07 15:51:53 +01:00
parent edaa62b05b
commit 21abd98b95
4 changed files with 153 additions and 126 deletions

View file

@ -222,7 +222,7 @@
:body (http/transit-data {:events events})}] :body (http/transit-data {:events events})}]
(->> (http/send! params) (->> (http/send! params)
(rx/mapcat rp/handle-response) (rx/mapcat rp/handle-response)
(rx/catch (fn [cause] (rx/catch (fn [_]
(l/error :hint "unexpected error on persisting audit events") (l/error :hint "unexpected error on persisting audit events")
(rx/of nil))))) (rx/of nil)))))

View file

@ -587,53 +587,78 @@
(s/def ::webhook-form (s/def ::webhook-form
(s/keys :req-un [::uri ::mtype])) (s/keys :req-un [::uri ::mtype]))
(mf/defc webhook-modal {::mf/register modal/components (def valid-webhook-mtypes
::mf/register-as :webhook} [{:label "application/json" :value "application/json"}
{:label "application/x-www-form-urlencoded" :value "application/x-www-form-urlencoded"}
{:label "application/transit+json" :value "application/transit+json"}])
(defn- extract-status
[error-code]
(-> error-code (str/split #":") second))
(mf/defc webhook-modal
{::mf/register modal/components
::mf/register-as :webhook}
[{:keys [webhook] :as props}] [{:keys [webhook] :as props}]
(let [initial (mf/use-memo (fn [] (or webhook {:is-active false :mtype "application/json"}))) (let [initial (mf/use-memo (fn [] (or webhook {:is-active false :mtype "application/json"})))
form (fm/use-form :spec ::webhook-form form (fm/use-form :spec ::webhook-form
:initial initial) :initial initial)
mtypes [{:label "application/json" :value "application/json"}
{:label "application/x-www-form-urlencoded" :value "application/x-www-form-urlencoded"}
{:label "application/transit+json" :value "application/transit+json"}]
on-success on-success
(fn [message] (mf/use-fn
(st/emit! (dd/fetch-team-webhooks) (fn [_]
(msg/success message) (let [message (tr "dashboard.webhooks.create.success")]
(modal/hide))) (st/emit! (dd/fetch-team-webhooks)
(msg/success message)
(modal/hide)))))
on-error on-error
(fn [message {:keys [type code hint] :as error}] (mf/use-fn
(let [message (if (and (= type :validation) (= code :webhook-validation)) (fn [form {:keys [type code hint] :as error}]
(str message " " (if (and (= type :validation)
(case hint (= code :webhook-validation))
"ssl-validation" (tr "errors.webhooks.ssl-validation") (let [message (cond
"")) ;; TODO Add more error codes when back defines them (= hint "unknown")
message)] (tr "errors.webhooks.unexpected")
(rx/of (msg/error message)))) (= hint "ssl-validation-error")
(tr "errors.webhooks.ssl-validation")
(= hint "timeout")
(tr "errors.webhooks.timeout")
(= hint "connection-error")
(tr "errors.webhooks.connection")
(str/starts-with? hint "unexpected-status")
(tr "errors.webhooks.unexpected-status" (extract-status hint)))]
(swap! form assoc-in [:errors :uri] {:message message}))
(rx/throw error))))
on-create-submit on-create-submit
(fn [] (mf/use-fn
(let [mdata {:on-success #(on-success (tr "dashboard.webhooks.create.success")) (fn [form]
:on-error (partial on-error (tr "dashboard.webhooks.create.error"))} (let [cdata (:clean-data @form)
webhook {:uri (get-in @form [:clean-data :uri]) mdata {:on-success (partial on-success form)
:mtype (get-in @form [:clean-data :mtype]) :on-error (partial on-error form)}
:is-active (get-in @form [:clean-data :is-active])}] params {:uri (:uri cdata)
(st/emit! (dd/create-team-webhook (with-meta webhook mdata))))) :mtype (:mtype cdata)
:is-active (:is-active cdata)}]
(st/emit! (dd/create-team-webhook
(with-meta params mdata))))))
on-update-submit on-update-submit
(fn [] (mf/use-fn
(let [mdata {:on-success #(on-success (tr "dashboard.webhooks.update.success")) (fn [form]
:on-error (partial on-error (tr "dashboard.webhooks.update.error"))} (let [params (:clean-data @form)
webhook (get @form :clean-data)] mdata {:on-success (partial on-success form)
(st/emit! (dd/update-team-webhook (with-meta webhook mdata))))) :on-error (partial on-error form)}]
(st/emit! (dd/update-team-webhook
(with-meta params mdata))))))
on-submit on-submit
#(let [data (:clean-data @form)] (mf/use-fn
(if (:id data) (fn [form]
(on-update-submit) (prn @form)
(on-create-submit)))] (let [data (:clean-data @form)]
(if (:id data)
(on-update-submit form)
(on-create-submit form)))))]
[:div.modal-overlay [:div.modal-overlay
[:div.modal-container.webhooks-modal [:div.modal-container.webhooks-modal
@ -659,7 +684,7 @@
:placeholder (tr "modals.create-webhook.url.placeholder")}]] :placeholder (tr "modals.create-webhook.url.placeholder")}]]
[:div.fields-row [:div.fields-row
[:& fm/select {:options mtypes [:& fm/select {:options valid-webhook-mtypes
:label (tr "dashboard.webhooks.content-type") :label (tr "dashboard.webhooks.content-type")
:default "application/json" :default "application/json"
:name :mtype}]]] :name :mtype}]]]
@ -704,79 +729,75 @@
{:on-click #(st/emit! (modal/show :webhook {}))} {:on-click #(st/emit! (modal/show :webhook {}))}
[:span (tr "dashboard.webhooks.create")]]]]) [:span (tr "dashboard.webhooks.create")]]]])
(mf/defc webhook-actions
[{:keys [on-edit on-delete] :as props}]
(let [show? (mf/use-state false)]
[:*
[:span.icon {:on-click #(reset! show? true)} [i/actions]]
[:& dropdown {:show @show?
:on-close #(reset! show? false)}
[:ul.dropdown.actions-dropdown
[:li {:on-click on-edit} (tr "labels.edit")]
[:li {:on-click on-delete} (tr "labels.delete")]]]]))
(mf/defc webhook-actions (mf/defc last-delivery-icon
[{:keys [on-edit on-delete] :as props}] [{:keys [success? text] :as props}]
(let [show? (mf/use-state false)] [:div.last-delivery-icon
[:* [:div.tooltip
[:span.icon {:on-click #(reset! show? true)} [i/actions]] [:div.label text]
[:& dropdown {:show @show? [:div.arrow-down]]
:on-close #(reset! show? false)} (if success?
[:ul.dropdown.actions-dropdown [:span.icon.success i/msg-success]
[:li {:on-click on-edit} (tr "labels.edit")] [:span.icon.failure i/msg-warning])])
[:li {:on-click on-delete} (tr "labels.delete")]]]]))
(mf/defc last-delivery-icon (mf/defc webhook-item
[{:keys [success? text] :as props}] {::mf/wrap [mf/memo]}
[:div.last-delivery-icon [{:keys [webhook] :as props}]
[:div.tooltip (let [on-edit #(st/emit! (modal/show :webhook {:webhook webhook}))
[:div.label text] error-code (:error-code webhook)
[:div.arrow-down]]
(if success?
[:span.icon.success i/msg-success]
[:span.icon.failure i/msg-warning])])
(mf/defc webhook-item delete-fn
{::mf/wrap [mf/memo]} (fn []
[{:keys [webhook] :as props}] (let [params {:id (:id webhook)}
(let [on-edit #(st/emit! (modal/show :webhook {:webhook webhook})) mdata {:on-success #(st/emit! (dd/fetch-team-webhooks))}]
error-code (:error-code webhook) (st/emit! (dd/delete-team-webhook (with-meta params mdata)))))
extract-status
(fn [error-code]
(let [status (-> error-code
(str/split "-")
last
parse-long)]
(if (nil? status)
""
status)))
delete-fn
(fn []
(let [params {:id (:id webhook)}
mdata {:on-success #(st/emit! (dd/fetch-team-webhooks))}]
(st/emit! (dd/delete-team-webhook (with-meta params mdata)))))
on-delete #(st/emit! (modal/show
{:type :confirm
:title (tr "modals.delete-webhook.title")
:message (tr "modals.delete-webhook.message")
:accept-label (tr "modals.delete-webhook.accept")
:on-accept delete-fn}))
last-delivery-text (cond
(nil? error-code)
(tr "webhooks.last-delivery.success")
(= error-code "ssl-validation") on-delete
(str (tr "errors.webhooks.last-delivery") " " (tr "errors.webhooks.ssl-validation")) (fn []
(st/emit! (modal/show
{:type :confirm
:title (tr "modals.delete-webhook.title")
:message (tr "modals.delete-webhook.message")
:accept-label (tr "modals.delete-webhook.accept")
:on-accept delete-fn})))
(str/starts-with? error-code "unexpected-status") last-delivery-text
(str (tr "errors.webhooks.last-delivery") (if (nil? error-code)
" " (tr "webhooks.last-delivery.success")
(tr "errors.webhooks.unexpected-status" (extract-status error-code))) (str (tr "errors.webhooks.last-delivery")
(cond
(= error-code "ssl-validation-error")
(dm/str " " (tr "errors.webhooks.ssl-validation"))
:else (str/starts-with? error-code "unexpected-status")
(tr "errors.webhooks.last-delivery"))] (dm/str " " (tr "errors.webhooks.unexpected-status" (extract-status error-code))))))]
[:div.table-row
[:div.table-field.last-delivery
[:div.icon-container
[:& last-delivery-icon {:success? (nil? error-code) :text last-delivery-text}]]]
[:div.table-field.uri
[:div (:uri webhook)]]
[:div.table-field.active
[:div (if (:is-active webhook) (tr "labels.active") (tr "labels.inactive"))]]
[:div.table-field.actions
[:& webhook-actions {:on-edit on-edit
:on-delete on-delete}]]]))
[:div.table-row
[:div.table-field.last-delivery
[:div.icon-container
[:& last-delivery-icon
{:success? (nil? error-code)
:text last-delivery-text}]]]
[:div.table-field.uri
[:div (:uri webhook)]]
[:div.table-field.active
[:div (if (:is-active webhook)
(tr "labels.active")
(tr "labels.inactive"))]]
[:div.table-field.actions
[:& webhook-actions
{:on-edit on-edit
:on-delete on-delete}]]]))
(mf/defc webhooks-list (mf/defc webhooks-list
[{:keys [webhooks] :as props}] [{:keys [webhooks] :as props}]

View file

@ -690,6 +690,21 @@ msgstr "Is active"
msgid "dashboard.webhooks.active.explain" msgid "dashboard.webhooks.active.explain"
msgstr "When this hook is triggered event details will be delivered" msgstr "When this hook is triggered event details will be delivered"
msgid "dashboard.webhooks.update.success"
msgstr "Webhook updated successfully."
msgid "dashboard.webhooks.create.success"
msgstr "Webhook created successfully."
msgid "errors.webhooks.unexpected"
msgstr "Unexpected error on validating"
msgid "errors.webhooks.timeout"
msgstr "Timeout"
msgid "errors.webhooks.connection"
msgstr "Connection error, url not reacheable"
msgid "webhooks.last-delivery.success" msgid "webhooks.last-delivery.success"
msgstr "Last delivery was successfull." msgstr "Last delivery was successfull."
@ -702,18 +717,6 @@ msgstr "Error on SSL validation."
msgid "errors.webhooks.unexpected-status" msgid "errors.webhooks.unexpected-status"
msgstr "Unexpected status %s" msgstr "Unexpected status %s"
msgid "dashboard.webhooks.update.error"
msgstr "Error on updating webhook."
msgid "dashboard.webhooks.update.success"
msgstr "Webhook updated successfully."
msgid "dashboard.webhooks.create.error"
msgstr "Error on creating webhook."
msgid "dashboard.webhooks.create.success"
msgstr "Webhook created successfully."
#: src/app/main/ui/alert.cljs #: src/app/main/ui/alert.cljs
msgid "ds.alert-ok" msgid "ds.alert-ok"
msgstr "Ok" msgstr "Ok"

View file

@ -737,6 +737,21 @@ msgstr "Cuando se active este webhook se enviarán detalles del evento"
msgid "webhooks.last-delivery.success" msgid "webhooks.last-delivery.success"
msgstr "El último envío fue correcto." msgstr "El último envío fue correcto."
msgid "dashboard.webhooks.update.success"
msgstr "Webhook modificado con éxito"
msgid "dashboard.webhooks.create.success"
msgstr "Webhook creado con éxito"
msgid "errors.webhooks.timeout"
msgstr "Timeout"
msgid "errors.webhooks.unexpected"
msgstr "Error inesperado al validar"
msgid "errors.webhooks.connection"
msgstr "Error de conexion, la url no es alcanzable"
msgid "errors.webhooks.last-delivery" msgid "errors.webhooks.last-delivery"
msgstr "Hubo un problema en el último envío." msgstr "Hubo un problema en el último envío."
@ -746,18 +761,6 @@ msgstr "Error en la validación SSL."
msgid "errors.webhooks.unexpected-status" msgid "errors.webhooks.unexpected-status"
msgstr "Estado inesperado %s" msgstr "Estado inesperado %s"
msgid "dashboard.webhooks.update.error"
msgstr "Error modificando el webhook"
msgid "dashboard.webhooks.update.success"
msgstr "Webhook modificado con éxito"
msgid "dashboard.webhooks.create.error"
msgstr "Error creando con éxito"
msgid "dashboard.webhooks.create.success"
msgstr "Webhook creado con éxito"
#: src/app/main/ui/alert.cljs #: src/app/main/ui/alert.cljs
msgid "ds.alert-ok" msgid "ds.alert-ok"
msgstr "Ok" msgstr "Ok"