mirror of
https://github.com/penpot/penpot.git
synced 2025-12-12 06:24:17 +01:00
Merge pull request #4902 from penpot/niwinz-notifications-improvements
✨ Improvements to notifications
This commit is contained in:
@@ -194,6 +194,12 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defn notify!
|
(defn notify!
|
||||||
|
"Send flash notifications.
|
||||||
|
|
||||||
|
This method allows send flash notifications to specified target destinations.
|
||||||
|
The message can be a free text or a preconfigured one.
|
||||||
|
|
||||||
|
The destination can be: all, profile-id, team-id, or a coll of them."
|
||||||
[{:keys [::mbus/msgbus ::db/pool]} & {:keys [dest code message level]
|
[{:keys [::mbus/msgbus ::db/pool]} & {:keys [dest code message level]
|
||||||
:or {code :generic level :info}
|
:or {code :generic level :info}
|
||||||
:as params}]
|
:as params}]
|
||||||
@@ -201,10 +207,6 @@
|
|||||||
["invalid level %" level]
|
["invalid level %" level]
|
||||||
(contains? #{:success :error :info :warning} level))
|
(contains? #{:success :error :info :warning} level))
|
||||||
|
|
||||||
(dm/verify!
|
|
||||||
["invalid code: %" code]
|
|
||||||
(contains? #{:generic :upgrade-version} code))
|
|
||||||
|
|
||||||
(letfn [(send [dest]
|
(letfn [(send [dest]
|
||||||
(l/inf :hint "sending notification" :dest (str dest))
|
(l/inf :hint "sending notification" :dest (str dest))
|
||||||
(let [message {:type :notification
|
(let [message {:type :notification
|
||||||
@@ -230,6 +232,9 @@
|
|||||||
|
|
||||||
(resolve-dest [dest]
|
(resolve-dest [dest]
|
||||||
(cond
|
(cond
|
||||||
|
(= :all dest)
|
||||||
|
[uuid/zero]
|
||||||
|
|
||||||
(uuid? dest)
|
(uuid? dest)
|
||||||
[dest]
|
[dest]
|
||||||
|
|
||||||
@@ -245,14 +250,15 @@
|
|||||||
(mapcat resolve-dest))
|
(mapcat resolve-dest))
|
||||||
dest)
|
dest)
|
||||||
|
|
||||||
(and (coll? dest)
|
(and (vector? dest)
|
||||||
(every? coll? dest))
|
(every? vector? dest))
|
||||||
(sequence (comp
|
(sequence (comp
|
||||||
(map vec)
|
(map vec)
|
||||||
(mapcat resolve-dest))
|
(mapcat resolve-dest))
|
||||||
dest)
|
dest)
|
||||||
|
|
||||||
(vector? dest)
|
(and (vector? dest)
|
||||||
|
(keyword? (first dest)))
|
||||||
(let [[op param] dest]
|
(let [[op param] dest]
|
||||||
(cond
|
(cond
|
||||||
(= op :email)
|
(= op :email)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
[app.main.data.modal :as modal]
|
[app.main.data.modal :as modal]
|
||||||
[app.main.features :as features]
|
[app.main.features :as features]
|
||||||
[app.main.repo :as rp]
|
[app.main.repo :as rp]
|
||||||
|
[app.main.store :as st]
|
||||||
[app.util.i18n :refer [tr]]
|
[app.util.i18n :refer [tr]]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
@@ -58,6 +59,10 @@
|
|||||||
[]
|
[]
|
||||||
(.reload js/location))
|
(.reload js/location))
|
||||||
|
|
||||||
|
(defn hide-notifications!
|
||||||
|
[]
|
||||||
|
(st/emit! msg/hide))
|
||||||
|
|
||||||
(defn handle-notification
|
(defn handle-notification
|
||||||
[{:keys [message code level] :as params}]
|
[{:keys [message code level] :as params}]
|
||||||
(ptk/reify ::show-notification
|
(ptk/reify ::show-notification
|
||||||
@@ -75,6 +80,15 @@
|
|||||||
:actions [{:label "Refresh" :callback force-reload!}]
|
:actions [{:label "Refresh" :callback force-reload!}]
|
||||||
:tag :notification)))
|
:tag :notification)))
|
||||||
|
|
||||||
|
:maintenance
|
||||||
|
(rx/of (msg/dialog
|
||||||
|
:content (tr "notifications.by-code.maintenance")
|
||||||
|
:controls :inline-actions
|
||||||
|
:type level
|
||||||
|
:actions [{:label (tr "labels.accept")
|
||||||
|
:callback hide-notifications!}]
|
||||||
|
:tag :notification))
|
||||||
|
|
||||||
(rx/of (msg/dialog
|
(rx/of (msg/dialog
|
||||||
:content message
|
:content message
|
||||||
:controls :close
|
:controls :close
|
||||||
|
|||||||
@@ -15,12 +15,9 @@
|
|||||||
(declare hide)
|
(declare hide)
|
||||||
(declare show)
|
(declare show)
|
||||||
|
|
||||||
(def default-animation-timeout 600)
|
|
||||||
(def default-timeout 7000)
|
(def default-timeout 7000)
|
||||||
|
|
||||||
(def ^:private
|
(def ^:private schema:message
|
||||||
schema:message
|
|
||||||
(sm/define
|
|
||||||
[:map {:title "Message"}
|
[:map {:title "Message"}
|
||||||
[:type [::sm/one-of #{:success :error :info :warning}]]
|
[:type [::sm/one-of #{:success :error :info :warning}]]
|
||||||
[:status {:optional true}
|
[:status {:optional true}
|
||||||
@@ -44,13 +41,16 @@
|
|||||||
[:vector
|
[:vector
|
||||||
[:map
|
[:map
|
||||||
[:label :string]
|
[:label :string]
|
||||||
[:callback ::sm/fn]]]]]))
|
[:callback ::sm/fn]]]]])
|
||||||
|
|
||||||
|
(def ^:private valid-message?
|
||||||
|
(sm/validator schema:message))
|
||||||
|
|
||||||
(defn show
|
(defn show
|
||||||
[data]
|
[data]
|
||||||
(dm/assert!
|
(dm/assert!
|
||||||
"expected valid message map"
|
"expected valid message map"
|
||||||
(sm/check! schema:message data))
|
(valid-message? data))
|
||||||
|
|
||||||
(ptk/reify ::show
|
(ptk/reify ::show
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
@@ -76,14 +76,7 @@
|
|||||||
(ptk/reify ::hide
|
(ptk/reify ::hide
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(d/update-when state :message assoc :status :hide))
|
(dissoc state :message))))
|
||||||
|
|
||||||
ptk/WatchEvent
|
|
||||||
(watch [_ _ stream]
|
|
||||||
(let [stopper (rx/filter (ptk/type? ::show) stream)]
|
|
||||||
(->> (rx/of #(dissoc % :message))
|
|
||||||
(rx/delay default-animation-timeout)
|
|
||||||
(rx/take-until stopper))))))
|
|
||||||
|
|
||||||
(defn hide-tag
|
(defn hide-tag
|
||||||
[tag]
|
[tag]
|
||||||
|
|||||||
@@ -17,33 +17,38 @@
|
|||||||
(mf/defc notifications-hub
|
(mf/defc notifications-hub
|
||||||
[]
|
[]
|
||||||
(let [message (mf/deref refs/message)
|
(let [message (mf/deref refs/message)
|
||||||
|
on-close (mf/use-fn #(st/emit! dmsg/hide))
|
||||||
on-close #(st/emit! dmsg/hide)
|
context? (and (nil? (:timeout message))
|
||||||
|
(nil? (:actions message)))
|
||||||
toast-message {:type (or (:type message) :info)
|
inline? (or (= :inline (:notification-type message))
|
||||||
:links (:links message)
|
(= :floating (:position message)))
|
||||||
:on-close on-close
|
toast? (or (= :toast (:notification-type message))
|
||||||
:content (:content message)}
|
(some? (:timeout message)))]
|
||||||
|
|
||||||
inline-message {:actions (:actions message)
|
|
||||||
:links (:links message)
|
|
||||||
:content (:content message)}
|
|
||||||
|
|
||||||
context-message {:type (or (:type message) :info)
|
|
||||||
:links (:links message)
|
|
||||||
:content (:content message)}
|
|
||||||
|
|
||||||
is-context-msg (and (nil? (:timeout message)) (nil? (:actions message)))
|
|
||||||
is-toast-msg (or (= :toast (:notification-type message)) (some? (:timeout message)))
|
|
||||||
is-inline-msg (or (= :inline (:notification-type message)) (and (some? (:position message)) (= :floating (:position message))))]
|
|
||||||
|
|
||||||
(when message
|
(when message
|
||||||
(cond
|
(cond
|
||||||
is-toast-msg
|
toast?
|
||||||
[:& toast-notification toast-message]
|
[:& toast-notification
|
||||||
is-inline-msg
|
{:type (or (:type message) :info)
|
||||||
[:& inline-notification inline-message]
|
:links (:links message)
|
||||||
is-context-msg
|
:on-close on-close
|
||||||
[:& context-notification context-message]
|
:content (:content message)}]
|
||||||
|
|
||||||
|
inline?
|
||||||
|
[:& inline-notification
|
||||||
|
{:actions (:actions message)
|
||||||
|
:links (:links message)
|
||||||
|
:content (:content message)}]
|
||||||
|
|
||||||
|
context?
|
||||||
|
[:& context-notification
|
||||||
|
{:type (or (:type message) :info)
|
||||||
|
:links (:links message)
|
||||||
|
:content (:content message)}]
|
||||||
|
|
||||||
:else
|
:else
|
||||||
[:& toast-notification toast-message]))))
|
[:& toast-notification
|
||||||
|
{:type (or (:type message) :info)
|
||||||
|
:links (:links message)
|
||||||
|
:on-close on-close
|
||||||
|
:content (:content message)}]))))
|
||||||
|
|||||||
@@ -38,12 +38,10 @@
|
|||||||
neutral-icon))
|
neutral-icon))
|
||||||
|
|
||||||
(mf/defc toast-notification
|
(mf/defc toast-notification
|
||||||
"These are ephemeral elements that disappear when
|
"These are ephemeral elements that disappear when the close button
|
||||||
the close button is pressed,
|
is pressed, the page is refreshed, the page is navigated to another
|
||||||
the page is refreshed,
|
page or after 7 seconds, which is enough time to be read, except for
|
||||||
the page is navigated to another page or
|
error messages that require user interaction."
|
||||||
after 7 seconds, which is enough time to be read,
|
|
||||||
except for error messages that require user interaction."
|
|
||||||
|
|
||||||
{::mf/props :obj}
|
{::mf/props :obj}
|
||||||
[{:keys [type content on-close links] :as props}]
|
[{:keys [type content on-close links] :as props}]
|
||||||
|
|||||||
@@ -2209,6 +2209,10 @@ msgstr "Update a component in a shared library"
|
|||||||
msgid "notifications.by-code.upgrade-version"
|
msgid "notifications.by-code.upgrade-version"
|
||||||
msgstr "A new version is available, please refresh the page"
|
msgstr "A new version is available, please refresh the page"
|
||||||
|
|
||||||
|
#: src/app/main/data/common.cljs
|
||||||
|
msgid "notifications.by-code.maintenance"
|
||||||
|
msgstr "Maintenance break: we will be down for a short maintenance within 5 minutes."
|
||||||
|
|
||||||
#: src/app/main/ui/dashboard/team.cljs
|
#: src/app/main/ui/dashboard/team.cljs
|
||||||
msgid "notifications.invitation-email-sent"
|
msgid "notifications.invitation-email-sent"
|
||||||
msgstr "Invitation sent successfully"
|
msgstr "Invitation sent successfully"
|
||||||
|
|||||||
@@ -2285,6 +2285,10 @@ msgstr "Actualizar un componente en biblioteca"
|
|||||||
msgid "notifications.by-code.upgrade-version"
|
msgid "notifications.by-code.upgrade-version"
|
||||||
msgstr "Una nueva versión está disponible, por favor actualiza la página"
|
msgstr "Una nueva versión está disponible, por favor actualiza la página"
|
||||||
|
|
||||||
|
#: src/app/main/data/common.cljs
|
||||||
|
msgid "notifications.by-code.maintenance"
|
||||||
|
msgstr "Pausa de mantenimiento: en los próximos 5 minutos estaremos fuera de servicio por un breve mantenimiento."
|
||||||
|
|
||||||
#: src/app/main/ui/dashboard/team.cljs
|
#: src/app/main/ui/dashboard/team.cljs
|
||||||
msgid "notifications.invitation-email-sent"
|
msgid "notifications.invitation-email-sent"
|
||||||
msgstr "Invitación enviada con éxito"
|
msgstr "Invitación enviada con éxito"
|
||||||
|
|||||||
Reference in New Issue
Block a user