mirror of
https://github.com/penpot/penpot.git
synced 2025-05-04 13:35:54 +02:00
♻️ Refactor metrics namespace
This commit is contained in:
parent
ec3651d85b
commit
fd973d87fd
4 changed files with 185 additions and 145 deletions
|
@ -150,7 +150,7 @@
|
||||||
|
|
||||||
;; When metrics namespace is provided
|
;; When metrics namespace is provided
|
||||||
(when metrics
|
(when metrics
|
||||||
(->> (:registry metrics)
|
(->> (::mtx/registry metrics)
|
||||||
(PrometheusMetricsTrackerFactory.)
|
(PrometheusMetricsTrackerFactory.)
|
||||||
(.setMetricsTrackerFactory config)))
|
(.setMetricsTrackerFactory config)))
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,7 @@
|
||||||
[middleware/errors errors/handle]
|
[middleware/errors errors/handle]
|
||||||
[middleware/restrict-methods]]}
|
[middleware/restrict-methods]]}
|
||||||
|
|
||||||
["/metrics" {:handler (:handler metrics)}]
|
["/metrics" {:handler (::mtx/handler metrics)}]
|
||||||
["/assets" {:middleware [(:middleware session)]}
|
["/assets" {:middleware [(:middleware session)]}
|
||||||
["/by-id/:id" {:handler (:objects-handler assets)}]
|
["/by-id/:id" {:handler (:objects-handler assets)}]
|
||||||
["/by-file-media-id/:id" {:handler (:file-objects-handler assets)}]
|
["/by-file-media-id/:id" {:handler (:file-objects-handler assets)}]
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
(:refer-clojure :exclude [run!])
|
(:refer-clojure :exclude [run!])
|
||||||
(:require
|
(:require
|
||||||
[app.common.logging :as l]
|
[app.common.logging :as l]
|
||||||
|
[app.common.spec :as us]
|
||||||
|
[app.metrics.definition :as-alias mdef]
|
||||||
[clojure.spec.alpha :as s]
|
[clojure.spec.alpha :as s]
|
||||||
[integrant.core :as ig])
|
[integrant.core :as ig])
|
||||||
(:import
|
(:import
|
||||||
|
@ -16,11 +18,12 @@
|
||||||
io.prometheus.client.Counter$Child
|
io.prometheus.client.Counter$Child
|
||||||
io.prometheus.client.Gauge
|
io.prometheus.client.Gauge
|
||||||
io.prometheus.client.Gauge$Child
|
io.prometheus.client.Gauge$Child
|
||||||
io.prometheus.client.Summary
|
|
||||||
io.prometheus.client.Summary$Child
|
|
||||||
io.prometheus.client.Summary$Builder
|
|
||||||
io.prometheus.client.Histogram
|
io.prometheus.client.Histogram
|
||||||
io.prometheus.client.Histogram$Child
|
io.prometheus.client.Histogram$Child
|
||||||
|
io.prometheus.client.SimpleCollector
|
||||||
|
io.prometheus.client.Summary
|
||||||
|
io.prometheus.client.Summary$Builder
|
||||||
|
io.prometheus.client.Summary$Child
|
||||||
io.prometheus.client.exporter.common.TextFormat
|
io.prometheus.client.exporter.common.TextFormat
|
||||||
io.prometheus.client.hotspot.DefaultExports
|
io.prometheus.client.hotspot.DefaultExports
|
||||||
java.io.StringWriter))
|
java.io.StringWriter))
|
||||||
|
@ -28,7 +31,7 @@
|
||||||
(set! *warn-on-reflection* true)
|
(set! *warn-on-reflection* true)
|
||||||
|
|
||||||
(declare create-registry)
|
(declare create-registry)
|
||||||
(declare create)
|
(declare create-collector)
|
||||||
(declare handler)
|
(declare handler)
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
@ -37,128 +40,151 @@
|
||||||
|
|
||||||
(def default-metrics
|
(def default-metrics
|
||||||
{:update-file-changes
|
{:update-file-changes
|
||||||
{:name "penpot_rpc_update_file_changes_total"
|
{::mdef/name "penpot_rpc_update_file_changes_total"
|
||||||
:help "A total number of changes submitted to update-file."
|
::mdef/help "A total number of changes submitted to update-file."
|
||||||
:type :counter}
|
::mdef/type :counter}
|
||||||
|
|
||||||
:update-file-bytes-processed
|
:update-file-bytes-processed
|
||||||
{:name "penpot_rpc_update_file_bytes_processed_total"
|
{::mdef/name "penpot_rpc_update_file_bytes_processed_total"
|
||||||
:help "A total number of bytes processed by update-file."
|
::mdef/help "A total number of bytes processed by update-file."
|
||||||
:type :counter}
|
::mdef/type :counter}
|
||||||
|
|
||||||
:rpc-mutation-timing
|
:rpc-mutation-timing
|
||||||
{:name "penpot_rpc_mutation_timing"
|
{::mdef/name "penpot_rpc_mutation_timing"
|
||||||
:help "RPC mutation method call timming."
|
::mdef/help "RPC mutation method call timming."
|
||||||
:labels ["name"]
|
::mdef/labels ["name"]
|
||||||
:type :histogram}
|
::mdef/type :histogram}
|
||||||
|
|
||||||
:rpc-command-timing
|
:rpc-command-timing
|
||||||
{:name "penpot_rpc_command_timing"
|
{::mdef/name "penpot_rpc_command_timing"
|
||||||
:help "RPC command method call timming."
|
::mdef/help "RPC command method call timming."
|
||||||
:labels ["name"]
|
::mdef/labels ["name"]
|
||||||
:type :histogram}
|
::mdef/type :histogram}
|
||||||
|
|
||||||
:rpc-query-timing
|
:rpc-query-timing
|
||||||
{:name "penpot_rpc_query_timing"
|
{::mdef/name "penpot_rpc_query_timing"
|
||||||
:help "RPC query method call timing."
|
::mdef/help "RPC query method call timing."
|
||||||
:labels ["name"]
|
::mdef/labels ["name"]
|
||||||
:type :histogram}
|
::mdef/type :histogram}
|
||||||
|
|
||||||
:websocket-active-connections
|
:websocket-active-connections
|
||||||
{:name "penpot_websocket_active_connections"
|
{::mdef/name "penpot_websocket_active_connections"
|
||||||
:help "Active websocket connections gauge"
|
::mdef/help "Active websocket connections gauge"
|
||||||
:type :gauge}
|
::mdef/type :gauge}
|
||||||
|
|
||||||
:websocket-messages-total
|
:websocket-messages-total
|
||||||
{:name "penpot_websocket_message_total"
|
{::mdef/name "penpot_websocket_message_total"
|
||||||
:help "Counter of processed messages."
|
::mdef/help "Counter of processed messages."
|
||||||
:labels ["op"]
|
::mdef/labels ["op"]
|
||||||
:type :counter}
|
::mdef/type :counter}
|
||||||
|
|
||||||
:websocket-session-timing
|
:websocket-session-timing
|
||||||
{:name "penpot_websocket_session_timing"
|
{::mdef/name "penpot_websocket_session_timing"
|
||||||
:help "Websocket session timing (seconds)."
|
::mdef/help "Websocket session timing (seconds)."
|
||||||
:type :summary}
|
::mdef/type :summary}
|
||||||
|
|
||||||
:session-update-total
|
:session-update-total
|
||||||
{:name "penpot_http_session_update_total"
|
{::mdef/name "penpot_http_session_update_total"
|
||||||
:help "A counter of session update batch events."
|
::mdef/help "A counter of session update batch events."
|
||||||
:type :counter}
|
::mdef/type :counter}
|
||||||
|
|
||||||
:tasks-timing
|
:tasks-timing
|
||||||
{:name "penpot_tasks_timing"
|
{::mdef/name "penpot_tasks_timing"
|
||||||
:help "Background tasks timing (milliseconds)."
|
::mdef/help "Background tasks timing (milliseconds)."
|
||||||
:labels ["name"]
|
::mdef/labels ["name"]
|
||||||
:type :summary}
|
::mdef/type :summary}
|
||||||
|
|
||||||
:redis-eval-timing
|
:redis-eval-timing
|
||||||
{:name "penpot_redis_eval_timing"
|
{::mdef/name "penpot_redis_eval_timing"
|
||||||
:help "Redis EVAL commands execution timings (ms)"
|
::mdef/help "Redis EVAL commands execution timings (ms)"
|
||||||
:labels ["name"]
|
::mdef/labels ["name"]
|
||||||
:type :summary}
|
::mdef/type :summary}
|
||||||
|
|
||||||
:rpc-semaphore-queued-submissions
|
:rpc-semaphore-queued-submissions
|
||||||
{:name "penpot_rpc_semaphore_queued_submissions"
|
{::mdef/name "penpot_rpc_semaphore_queued_submissions"
|
||||||
:help "Current number of queued submissions on RPC-SEMAPHORE."
|
::mdef/help "Current number of queued submissions on RPC-SEMAPHORE."
|
||||||
:labels ["name"]
|
::mdef/labels ["name"]
|
||||||
:type :gauge}
|
::mdef/type :gauge}
|
||||||
|
|
||||||
:rpc-semaphore-used-permits
|
:rpc-semaphore-used-permits
|
||||||
{:name "penpot_rpc_semaphore_used_permits"
|
{::mdef/name "penpot_rpc_semaphore_used_permits"
|
||||||
:help "Current number of used permits on RPC-SEMAPHORE."
|
::mdef/help "Current number of used permits on RPC-SEMAPHORE."
|
||||||
:labels ["name"]
|
::mdef/labels ["name"]
|
||||||
:type :gauge}
|
::mdef/type :gauge}
|
||||||
|
|
||||||
:rpc-semaphore-acquires-total
|
:rpc-semaphore-acquires-total
|
||||||
{:name "penpot_rpc_semaphore_acquires_total"
|
{::mdef/name "penpot_rpc_semaphore_acquires_total"
|
||||||
:help "Total number of acquire operations on RPC-SEMAPHORE."
|
::mdef/help "Total number of acquire operations on RPC-SEMAPHORE."
|
||||||
:labels ["name"]
|
::mdef/labels ["name"]
|
||||||
:type :counter}
|
::mdef/type :counter}
|
||||||
|
|
||||||
:executors-active-threads
|
:executors-active-threads
|
||||||
{:name "penpot_executors_active_threads"
|
{::mdef/name "penpot_executors_active_threads"
|
||||||
:help "Current number of threads available in the executor service."
|
::mdef/help "Current number of threads available in the executor service."
|
||||||
:labels ["name"]
|
::mdef/labels ["name"]
|
||||||
:type :gauge}
|
::mdef/type :gauge}
|
||||||
|
|
||||||
:executors-completed-tasks
|
:executors-completed-tasks
|
||||||
{:name "penpot_executors_completed_tasks_total"
|
{::mdef/name "penpot_executors_completed_tasks_total"
|
||||||
:help "Aproximate number of completed tasks by the executor."
|
::mdef/help "Aproximate number of completed tasks by the executor."
|
||||||
:labels ["name"]
|
::mdef/labels ["name"]
|
||||||
:type :counter}
|
::mdef/type :counter}
|
||||||
|
|
||||||
:executors-running-threads
|
:executors-running-threads
|
||||||
{:name "penpot_executors_running_threads"
|
{::mdef/name "penpot_executors_running_threads"
|
||||||
:help "Current number of threads with state RUNNING."
|
::mdef/help "Current number of threads with state RUNNING."
|
||||||
:labels ["name"]
|
::mdef/labels ["name"]
|
||||||
:type :gauge}
|
::mdef/type :gauge}
|
||||||
|
|
||||||
:executors-queued-submissions
|
:executors-queued-submissions
|
||||||
{:name "penpot_executors_queued_submissions"
|
{::mdef/name "penpot_executors_queued_submissions"
|
||||||
:help "Current number of queued submissions."
|
::mdef/help "Current number of queued submissions."
|
||||||
:labels ["name"]
|
::mdef/labels ["name"]
|
||||||
:type :gauge}})
|
::mdef/type :gauge}})
|
||||||
|
|
||||||
|
(s/def ::mdef/name string?)
|
||||||
|
(s/def ::mdef/help string?)
|
||||||
|
(s/def ::mdef/labels (s/every string? :kind vector?))
|
||||||
|
(s/def ::mdef/type #{:gauge :counter :summary :histogram})
|
||||||
|
|
||||||
|
(s/def ::mdef/instance
|
||||||
|
#(instance? SimpleCollector %))
|
||||||
|
|
||||||
|
(s/def ::mdef/definition
|
||||||
|
(s/keys :req [::mdef/name
|
||||||
|
::mdef/help
|
||||||
|
::mdef/type]
|
||||||
|
:opt [::mdef/labels
|
||||||
|
::mdef/instance]))
|
||||||
|
|
||||||
|
(s/def ::definitions
|
||||||
|
(s/map-of keyword? ::mdef/definition))
|
||||||
|
|
||||||
|
(s/def ::registry
|
||||||
|
#(instance? CollectorRegistry %))
|
||||||
|
|
||||||
|
(s/def ::handler fn?)
|
||||||
|
(s/def ::metrics
|
||||||
|
(s/keys :req [::registry
|
||||||
|
::handler
|
||||||
|
::definitions]))
|
||||||
|
|
||||||
(defmethod ig/init-key ::metrics
|
(defmethod ig/init-key ::metrics
|
||||||
[_ _]
|
[_ _]
|
||||||
(l/info :action "initialize metrics")
|
(l/info :action "initialize metrics")
|
||||||
(let [registry (create-registry)
|
(let [registry (create-registry)
|
||||||
definitions (reduce-kv (fn [res k v]
|
definitions (reduce-kv (fn [res k v]
|
||||||
(->> (assoc v :registry registry)
|
(->> (assoc v ::registry registry)
|
||||||
(create)
|
(create-collector)
|
||||||
(assoc res k)))
|
(assoc res k)))
|
||||||
{}
|
{}
|
||||||
default-metrics)]
|
default-metrics)]
|
||||||
{:handler (partial handler registry)
|
|
||||||
:definitions definitions
|
|
||||||
:registry registry}))
|
|
||||||
|
|
||||||
|
(us/verify! ::definitions definitions)
|
||||||
|
|
||||||
;; TODO: revisit
|
{::handler (partial handler registry)
|
||||||
(s/def ::handler fn?)
|
::definitions definitions
|
||||||
(s/def ::registry #(instance? CollectorRegistry %))
|
::registry registry}))
|
||||||
(s/def ::metrics
|
|
||||||
(s/keys :req-un [::registry ::handler]))
|
|
||||||
|
|
||||||
(defn- handler
|
(defn- handler
|
||||||
[registry _ respond _]
|
[registry _ respond _]
|
||||||
|
@ -182,13 +208,16 @@
|
||||||
(def default-histogram-buckets
|
(def default-histogram-buckets
|
||||||
[1 5 10 25 50 75 100 250 500 750 1000 2500 5000 7500])
|
[1 5 10 25 50 75 100 250 500 750 1000 2500 5000 7500])
|
||||||
|
|
||||||
|
(defmulti run-collector! (fn [mdef _] (::mdef/type mdef)))
|
||||||
|
(defmulti create-collector ::mdef/type)
|
||||||
|
|
||||||
(defn run!
|
(defn run!
|
||||||
[{:keys [definitions]} {:keys [id] :as params}]
|
[{:keys [::definitions]} {:keys [id] :as params}]
|
||||||
(when-let [mobj (get definitions id)]
|
(when-let [mobj (get definitions id)]
|
||||||
((::fn mobj) params)
|
(run-collector! mobj params)
|
||||||
true))
|
true))
|
||||||
|
|
||||||
(defn create-registry
|
(defn- create-registry
|
||||||
[]
|
[]
|
||||||
(let [registry (CollectorRegistry.)]
|
(let [registry (CollectorRegistry.)]
|
||||||
(DefaultExports/register registry)
|
(DefaultExports/register registry)
|
||||||
|
@ -200,79 +229,89 @@
|
||||||
(and (.isArray ^Class oc)
|
(and (.isArray ^Class oc)
|
||||||
(= (.getComponentType oc) String))))
|
(= (.getComponentType oc) String))))
|
||||||
|
|
||||||
(defn make-counter
|
(defmethod run-collector! :counter
|
||||||
[{:keys [name help registry reg labels] :as props}]
|
[{:keys [::mdef/instance]} {:keys [inc labels] :or {inc 1 labels default-empty-labels}}]
|
||||||
|
(let [instance (.labels instance (if (is-array? labels) labels (into-array String labels)))]
|
||||||
|
(.inc ^Counter$Child instance (double inc))))
|
||||||
|
|
||||||
|
(defmethod run-collector! :gauge
|
||||||
|
[{:keys [::mdef/instance]} {:keys [inc dec labels val] :or {labels default-empty-labels}}]
|
||||||
|
(let [instance (.labels ^Gauge instance (if (is-array? labels) labels (into-array String labels)))]
|
||||||
|
(cond (number? inc) (.inc ^Gauge$Child instance (double inc))
|
||||||
|
(number? dec) (.dec ^Gauge$Child instance (double dec))
|
||||||
|
(number? val) (.set ^Gauge$Child instance (double val)))))
|
||||||
|
|
||||||
|
(defmethod run-collector! :summary
|
||||||
|
[{:keys [::mdef/instance]} {:keys [val labels] :or {labels default-empty-labels}}]
|
||||||
|
(let [instance (.labels ^Summary instance (if (is-array? labels) labels (into-array String labels)))]
|
||||||
|
(.observe ^Summary$Child instance val)))
|
||||||
|
|
||||||
|
(defmethod run-collector! :histogram
|
||||||
|
[{:keys [::mdef/instance]} {:keys [val labels] :or {labels default-empty-labels}}]
|
||||||
|
(let [instance (.labels ^Histogram instance (if (is-array? labels) labels (into-array String labels)))]
|
||||||
|
(.observe ^Histogram$Child instance val)))
|
||||||
|
|
||||||
|
(defmethod create-collector :counter
|
||||||
|
[{::mdef/keys [name help reg labels]
|
||||||
|
::keys [registry]
|
||||||
|
:as props}]
|
||||||
|
|
||||||
(let [registry (or registry reg)
|
(let [registry (or registry reg)
|
||||||
instance (.. (Counter/build)
|
instance (.. (Counter/build)
|
||||||
(name name)
|
(name name)
|
||||||
(help help))
|
(help help))]
|
||||||
_ (when (seq labels)
|
(when (seq labels)
|
||||||
(.labelNames instance (into-array String labels)))
|
(.labelNames instance (into-array String labels)))
|
||||||
instance (.register instance registry)]
|
|
||||||
|
|
||||||
{::instance instance
|
(assoc props ::mdef/instance (.register instance registry))))
|
||||||
::fn (fn [{:keys [inc labels] :or {inc 1 labels default-empty-labels}}]
|
|
||||||
(let [instance (.labels instance (if (is-array? labels) labels (into-array String labels)))]
|
|
||||||
(.inc ^Counter$Child instance (double inc))))}))
|
|
||||||
|
|
||||||
(defn make-gauge
|
(defmethod create-collector :gauge
|
||||||
[{:keys [name help registry reg labels] :as props}]
|
[{::mdef/keys [name help reg labels]
|
||||||
|
::keys [registry]
|
||||||
|
:as props}]
|
||||||
(let [registry (or registry reg)
|
(let [registry (or registry reg)
|
||||||
instance (.. (Gauge/build)
|
instance (.. (Gauge/build)
|
||||||
(name name)
|
(name name)
|
||||||
(help help))
|
(help help))]
|
||||||
_ (when (seq labels)
|
(when (seq labels)
|
||||||
(.labelNames instance (into-array String labels)))
|
(.labelNames instance (into-array String labels)))
|
||||||
instance (.register instance registry)]
|
|
||||||
{::instance instance
|
|
||||||
::fn (fn [{:keys [inc dec labels val] :or {labels default-empty-labels}}]
|
|
||||||
(let [instance (.labels ^Gauge instance (if (is-array? labels) labels (into-array String labels)))]
|
|
||||||
(cond (number? inc) (.inc ^Gauge$Child instance (double inc))
|
|
||||||
(number? dec) (.dec ^Gauge$Child instance (double dec))
|
|
||||||
(number? val) (.set ^Gauge$Child instance (double val)))))}))
|
|
||||||
|
|
||||||
(defn make-summary
|
(assoc props ::mdef/instance (.register instance registry))))
|
||||||
[{:keys [name help registry reg labels max-age quantiles buckets]
|
|
||||||
:or {max-age 3600 buckets 12 quantiles default-quantiles} :as props}]
|
(defmethod create-collector :summary
|
||||||
|
[{::mdef/keys [name help reg labels max-age quantiles buckets]
|
||||||
|
::keys [registry]
|
||||||
|
:or {max-age 3600 buckets 12 quantiles default-quantiles}
|
||||||
|
:as props}]
|
||||||
(let [registry (or registry reg)
|
(let [registry (or registry reg)
|
||||||
builder (doto (Summary/build)
|
builder (doto (Summary/build)
|
||||||
(.name name)
|
(.name name)
|
||||||
(.help help))
|
(.help help))]
|
||||||
_ (when (seq quantiles)
|
|
||||||
(.maxAgeSeconds ^Summary$Builder builder ^long max-age)
|
|
||||||
(.ageBuckets ^Summary$Builder builder buckets))
|
|
||||||
_ (doseq [[q e] quantiles]
|
|
||||||
(.quantile ^Summary$Builder builder q e))
|
|
||||||
_ (when (seq labels)
|
|
||||||
(.labelNames ^Summary$Builder builder (into-array String labels)))
|
|
||||||
instance (.register ^Summary$Builder builder registry)]
|
|
||||||
|
|
||||||
{::instance instance
|
(when (seq quantiles)
|
||||||
::fn (fn [{:keys [val labels] :or {labels default-empty-labels}}]
|
(.maxAgeSeconds ^Summary$Builder builder ^long max-age)
|
||||||
(let [instance (.labels ^Summary instance (if (is-array? labels) labels (into-array String labels)))]
|
(.ageBuckets ^Summary$Builder builder buckets))
|
||||||
(.observe ^Summary$Child instance val)))}))
|
|
||||||
|
|
||||||
(defn make-histogram
|
(doseq [[q e] quantiles]
|
||||||
[{:keys [name help registry reg labels buckets]
|
(.quantile ^Summary$Builder builder q e))
|
||||||
:or {buckets default-histogram-buckets}}]
|
|
||||||
|
(when (seq labels)
|
||||||
|
(.labelNames ^Summary$Builder builder (into-array String labels)))
|
||||||
|
|
||||||
|
(assoc props ::mdef/instance (.register ^Summary$Builder builder registry))))
|
||||||
|
|
||||||
|
(defmethod create-collector :histogram
|
||||||
|
[{::mdef/keys [name help reg labels buckets]
|
||||||
|
::keys [registry]
|
||||||
|
:or {buckets default-histogram-buckets}
|
||||||
|
:as props}]
|
||||||
(let [registry (or registry reg)
|
(let [registry (or registry reg)
|
||||||
instance (doto (Histogram/build)
|
instance (doto (Histogram/build)
|
||||||
(.name name)
|
(.name name)
|
||||||
(.help help)
|
(.help help)
|
||||||
(.buckets (into-array Double/TYPE buckets)))
|
(.buckets (into-array Double/TYPE buckets)))]
|
||||||
_ (when (seq labels)
|
|
||||||
(.labelNames instance (into-array String labels)))
|
|
||||||
instance (.register instance registry)]
|
|
||||||
|
|
||||||
{::instance instance
|
(when (seq labels)
|
||||||
::fn (fn [{:keys [val labels] :or {labels default-empty-labels}}]
|
(.labelNames instance (into-array String labels)))
|
||||||
(let [instance (.labels ^Histogram instance (if (is-array? labels) labels (into-array String labels)))]
|
|
||||||
(.observe ^Histogram$Child instance val)))}))
|
|
||||||
|
|
||||||
(defn create
|
(assoc props ::mdef/instance (.register instance registry))))
|
||||||
[{:keys [type] :as props}]
|
|
||||||
(case type
|
|
||||||
:counter (make-counter props)
|
|
||||||
:gauge (make-gauge props)
|
|
||||||
:summary (make-summary props)
|
|
||||||
:histogram (make-histogram props)))
|
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
[app.main.ui.settings.options :refer [options-page]]
|
[app.main.ui.settings.options :refer [options-page]]
|
||||||
[app.main.ui.settings.password :refer [password-page]]
|
[app.main.ui.settings.password :refer [password-page]]
|
||||||
[app.main.ui.settings.profile :refer [profile-page]]
|
[app.main.ui.settings.profile :refer [profile-page]]
|
||||||
[app.main.ui.settings.sidebar :refer [sidebar]]
|
[app.main.ui.settings.sidebar :refer [sidebar]]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
[app.util.router :as rt]
|
[app.util.router :as rt]
|
||||||
[rumext.alpha :as mf]))
|
[rumext.alpha :as mf]))
|
||||||
|
|
||||||
|
@ -31,10 +31,11 @@
|
||||||
(let [section (get-in route [:data :name])
|
(let [section (get-in route [:data :name])
|
||||||
profile (mf/deref refs/profile)
|
profile (mf/deref refs/profile)
|
||||||
locale (mf/deref i18n/locale)]
|
locale (mf/deref i18n/locale)]
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
#(when (nil? profile)
|
#(when (nil? profile)
|
||||||
(st/emit! (rt/nav :auth-login))))
|
(st/emit! (rt/nav :auth-login))))
|
||||||
|
|
||||||
[:section.dashboard-layout
|
[:section.dashboard-layout
|
||||||
[:& sidebar {:profile profile
|
[:& sidebar {:profile profile
|
||||||
:locale locale
|
:locale locale
|
||||||
|
|
Loading…
Add table
Reference in a new issue