From ca9a6c3e1d720e2788b93208d4f87cf7a56040ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20=C3=85hall?= Date: Sat, 29 Jun 2024 15:20:31 +0200 Subject: [PATCH 1/4] Initial add of notifications --- main.go | 20 +++++++++ notification_log.go | 62 +++++++++++++++++++++++++++ static/css/default_light/gruvbox.css | 3 ++ static/css/default_light/main.css | 2 +- static/css/default_light/problems.css | 2 +- static/css/gruvbox/main.css | 2 +- static/css/gruvbox/problems.css | 2 +- static/less/main.less | 4 +- views/components/menu.gotmpl | 7 +++ 9 files changed, 98 insertions(+), 6 deletions(-) diff --git a/main.go b/main.go index 8094e2d..fb11c0b 100644 --- a/main.go +++ b/main.go @@ -150,6 +150,8 @@ func main() { // {{{ service.Register("/trigger/run/{id}", false, false, actionTriggerRun) service.Register("/trigger/delete/{id}", false, false, actionTriggerDelete) + service.Register("/notifications", false, false, pageNotifications) + service.Register("/configuration", false, false, pageConfiguration) service.Register("/configuration/theme", false, false, actionConfigurationTheme) service.Register("/configuration/timezone", false, false, actionConfigurationTimezone) @@ -1194,3 +1196,21 @@ func actionConfigurationNotificationDelete(w http.ResponseWriter, r *http.Reques w.Header().Add("Location", "/configuration") w.WriteHeader(302) } // }}} + +func pageNotifications(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ + nss, err := notificationsSent() + if err != nil { + pageError(w, "/", werr.Wrap(err).Log()) + } + + page := Page{ + LAYOUT: "main", + PAGE: "notifications", + CONFIG: smonConfig.Settings, + Data: map[string]any{ + "Notifications": nss, + }, + } + + page.Render(w, r) +} // }}} diff --git a/notification_log.go b/notification_log.go index 7b70d35..a02495a 100644 --- a/notification_log.go +++ b/notification_log.go @@ -1,11 +1,29 @@ package main import ( + // External + werr "git.gibonuddevalla.se/go/wrappederror" + "github.com/jmoiron/sqlx" + // Internal "smon/notification" + // Standard + "time" ) +type NotificationSend struct { + Prio int + Service string + ID int + UUID string + Sent time.Time `db:"send"` + OK bool + Error []byte + Acknowledged bool + TriggerName string `db:"trigger_name"` +} + func notificationLog(notificationService *notification.Service, problemID int, err error) { if err == nil { logger.Info("notification", "service", (*notificationService).GetType(), "problemID", problemID, "prio", (*notificationService).GetPrio(), "ok", true) @@ -18,3 +36,47 @@ func notificationLog(notificationService *notification.Service, problemID int, e logger.Error("notification", "service", (*notificationService).GetType(), "problemID", problemID, "prio", (*notificationService).GetPrio(), "ok", false, "error", err) } } + +func notificationsSent() (nss []NotificationSend, err error) { + var rows *sqlx.Rows + rows, err = service.Db.Conn.Queryx( + ` + SELECT + n.prio, + n.service, + + t.name AS trigger_name, + + ns.id, + ns.uuid, + ns.send, + ns.ok, + ns.error, + ns.acknowledged + + FROM + public.notification_send ns + INNER JOIN notification n ON ns.notification_id = n.id + INNER JOIN problem p ON ns.problem_id = p.id + INNER JOIN "trigger" t ON p.trigger_id = t.id + + ORDER BY + send DESC + `) + if err != nil { + err = werr.Wrap(err) + return + } + defer rows.Close() + + for rows.Next() { + ns := NotificationSend{} + err = rows.StructScan(&ns) + if err != nil { + err = werr.Wrap(err) + return + } + nss = append(nss, ns) + } + return +} diff --git a/static/css/default_light/gruvbox.css b/static/css/default_light/gruvbox.css index 54b45b4..d0860ec 100644 --- a/static/css/default_light/gruvbox.css +++ b/static/css/default_light/gruvbox.css @@ -1,6 +1,9 @@ body { background-image: url(/images/v0/gruvbox/background.svg); } +#menu { + box-shadow: 2px 0px 5px 3px rgba(0, 0, 0, 0.25); +} #areas .area { box-shadow: 5px 5px 15px 0px rgba(0, 0, 0, 0.5); } diff --git a/static/css/default_light/main.css b/static/css/default_light/main.css index 30f8dae..10baf58 100644 --- a/static/css/default_light/main.css +++ b/static/css/default_light/main.css @@ -39,7 +39,7 @@ html { #layout { display: grid; grid-template-areas: "menu content"; - grid-template-columns: 104px 1fr; + grid-template-columns: 128px 1fr; height: 100vh; } #menu { diff --git a/static/css/default_light/problems.css b/static/css/default_light/problems.css index 3a415de..e597be8 100644 --- a/static/css/default_light/problems.css +++ b/static/css/default_light/problems.css @@ -46,7 +46,7 @@ } #areas .area .section .name { color: #000; - grid-column: 1 / -1; + grid-column: -1; font-weight: bold !important; line-height: 24px; } diff --git a/static/css/gruvbox/main.css b/static/css/gruvbox/main.css index b69f507..98f785f 100644 --- a/static/css/gruvbox/main.css +++ b/static/css/gruvbox/main.css @@ -39,7 +39,7 @@ html { #layout { display: grid; grid-template-areas: "menu content"; - grid-template-columns: 104px 1fr; + grid-template-columns: 128px 1fr; height: 100vh; } #menu { diff --git a/static/css/gruvbox/problems.css b/static/css/gruvbox/problems.css index 6c014f7..b26c2c1 100644 --- a/static/css/gruvbox/problems.css +++ b/static/css/gruvbox/problems.css @@ -46,7 +46,7 @@ } #areas .area .section .name { color: #f7edd7; - grid-column: 1 / -1; + grid-column: -1; font-weight: bold !important; line-height: 24px; } diff --git a/static/less/main.less b/static/less/main.less index 81d35a5..aa11833 100644 --- a/static/less/main.less +++ b/static/less/main.less @@ -52,7 +52,7 @@ html { #layout { display: grid; grid-template-areas: "menu content"; - grid-template-columns: 104px 1fr; + grid-template-columns: 128px 1fr; height: 100vh; } @@ -248,7 +248,7 @@ button { } .line { - grid-column: 1 / -1; + grid-column: ~"1 / -1"; border-bottom: 1px solid .lighterOrDarker(@bg1, 15%)[@result]; } diff --git a/views/components/menu.gotmpl b/views/components/menu.gotmpl index c0c1ddf..5a45fe0 100644 --- a/views/components/menu.gotmpl +++ b/views/components/menu.gotmpl @@ -28,6 +28,13 @@ +
+ + +
Notifications
+
+
+
From e728a302ee3f38762971e80008ac769c8795c253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20=C3=85hall?= Date: Sat, 29 Jun 2024 15:21:52 +0200 Subject: [PATCH 2/4] Added static resources --- static/css/default_light/notifications.css | 20 ++++++++ static/css/gruvbox/notifications.css | 20 ++++++++ static/images/default_light/notifications.svg | 51 +++++++++++++++++++ .../default_light/notifications_selected.svg | 49 ++++++++++++++++++ static/images/gruvbox/notifications.svg | 51 +++++++++++++++++++ .../images/gruvbox/notifications_selected.svg | 51 +++++++++++++++++++ static/less/notifications.less | 24 +++++++++ views/pages/notifications.gotmpl | 21 ++++++++ 8 files changed, 287 insertions(+) create mode 100644 static/css/default_light/notifications.css create mode 100644 static/css/gruvbox/notifications.css create mode 100644 static/images/default_light/notifications.svg create mode 100644 static/images/default_light/notifications_selected.svg create mode 100644 static/images/gruvbox/notifications.svg create mode 100644 static/images/gruvbox/notifications_selected.svg create mode 100644 static/less/notifications.less create mode 100644 views/pages/notifications.gotmpl diff --git a/static/css/default_light/notifications.css b/static/css/default_light/notifications.css new file mode 100644 index 0000000..8dc1736 --- /dev/null +++ b/static/css/default_light/notifications.css @@ -0,0 +1,20 @@ +#notifications { + display: grid; + grid-template-columns: repeat(4, min-content); + grid-gap: 4px 16px; + margin-top: 32px; + margin-bottom: 32px; + background-color: #2979b8; + padding: 16px 24px; + width: min-content; + border-top-left-radius: 8px; + border-top-right-radius: 8px; +} +#notifications div { + white-space: nowrap; + line-height: 24px; +} +#notifications .header { + font-weight: 800; + color: #7bb8eb; +} diff --git a/static/css/gruvbox/notifications.css b/static/css/gruvbox/notifications.css new file mode 100644 index 0000000..e454f96 --- /dev/null +++ b/static/css/gruvbox/notifications.css @@ -0,0 +1,20 @@ +#notifications { + display: grid; + grid-template-columns: repeat(4, min-content); + grid-gap: 4px 16px; + margin-top: 32px; + margin-bottom: 32px; + background-color: #333; + padding: 16px 24px; + width: min-content; + border-top-left-radius: 8px; + border-top-right-radius: 8px; +} +#notifications div { + white-space: nowrap; + line-height: 24px; +} +#notifications .header { + font-weight: 800; + color: #777; +} diff --git a/static/images/default_light/notifications.svg b/static/images/default_light/notifications.svg new file mode 100644 index 0000000..1e709b5 --- /dev/null +++ b/static/images/default_light/notifications.svg @@ -0,0 +1,51 @@ + + + + + + + + email-fast + email-fast-outline + + + diff --git a/static/images/default_light/notifications_selected.svg b/static/images/default_light/notifications_selected.svg new file mode 100644 index 0000000..46616f0 --- /dev/null +++ b/static/images/default_light/notifications_selected.svg @@ -0,0 +1,49 @@ + + + + + + + + email-fast + + + diff --git a/static/images/gruvbox/notifications.svg b/static/images/gruvbox/notifications.svg new file mode 100644 index 0000000..db6dace --- /dev/null +++ b/static/images/gruvbox/notifications.svg @@ -0,0 +1,51 @@ + + + + + + + + email-fast + email-fast-outline + + + diff --git a/static/images/gruvbox/notifications_selected.svg b/static/images/gruvbox/notifications_selected.svg new file mode 100644 index 0000000..00469dd --- /dev/null +++ b/static/images/gruvbox/notifications_selected.svg @@ -0,0 +1,51 @@ + + + + + + + + email-fast + email-fast-outline + + + diff --git a/static/less/notifications.less b/static/less/notifications.less new file mode 100644 index 0000000..f0a64f1 --- /dev/null +++ b/static/less/notifications.less @@ -0,0 +1,24 @@ +@import "theme-@{THEME}.less"; + +#notifications { + display: grid; + grid-template-columns: repeat(4, min-content); + grid-gap: 4px 16px; + margin-top: 32px; + margin-bottom: 32px; + background-color: @bg3; + padding: 16px 24px; + width: min-content; + border-top-left-radius: 8px; + border-top-right-radius: 8px; + + div { + white-space: nowrap; + line-height: 24px; + } + + .header { + font-weight: @bold; + color: @text3; + } +} diff --git a/views/pages/notifications.gotmpl b/views/pages/notifications.gotmpl new file mode 100644 index 0000000..45bb2a0 --- /dev/null +++ b/views/pages/notifications.gotmpl @@ -0,0 +1,21 @@ +{{ define "page" }} + + {{ block "page_label" . }}{{end}} + {{ $version := .VERSION }} + {{ $theme := .CONFIG.THEME }} + + +
+
Sent
+
OK
+
Trigger name
+
Service
+ {{ range .Data.Notifications }} +
{{ format_time .Sent }}
+
{{ if .OK }}✔{{ else }}✗{{ end }}
+
{{ .TriggerName }}
+
{{ .Prio }}:{{ .Service }}
+ {{ end }} +
+ +{{ end }} From b0ffce05f04ca2fb635abf673afc0513c572ee53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20=C3=85hall?= Date: Sat, 29 Jun 2024 18:09:56 +0200 Subject: [PATCH 3/4] Start of error reporting --- notification_log.go | 32 +++++++++++++++------- static/css/default_light/notifications.css | 2 +- static/css/default_light/problems.css | 2 +- static/css/gruvbox/notifications.css | 2 +- static/css/gruvbox/problems.css | 2 +- static/less/notifications.less | 2 +- static/less/problems.less | 2 +- views/pages/notifications.gotmpl | 2 ++ 8 files changed, 30 insertions(+), 16 deletions(-) diff --git a/notification_log.go b/notification_log.go index a02495a..d080cc9 100644 --- a/notification_log.go +++ b/notification_log.go @@ -9,19 +9,22 @@ import ( "smon/notification" // Standard + "database/sql" + "encoding/json" "time" ) type NotificationSend struct { - Prio int - Service string - ID int - UUID string - Sent time.Time `db:"send"` - OK bool - Error []byte - Acknowledged bool - TriggerName string `db:"trigger_name"` + Prio int + Service string + ID int + UUID string + Sent time.Time `db:"send"` + OK bool + Error sql.NullString + ErrorIndented string + Acknowledged bool + TriggerName string `db:"trigger_name"` } func notificationLog(notificationService *notification.Service, problemID int, err error) { @@ -51,7 +54,7 @@ func notificationsSent() (nss []NotificationSend, err error) { ns.uuid, ns.send, ns.ok, - ns.error, + ns.error::varchar, ns.acknowledged FROM @@ -76,6 +79,15 @@ func notificationsSent() (nss []NotificationSend, err error) { err = werr.Wrap(err) return } + + // Error contains json (can be NULL), + // and can at least be presented indented. + foo := make(map[string]any) + json.Unmarshal([]byte(ns.Error.String), &foo) + var j []byte + j, err = json.MarshalIndent(foo, "", " ") + ns.ErrorIndented = string(j) + nss = append(nss, ns) } return diff --git a/static/css/default_light/notifications.css b/static/css/default_light/notifications.css index 8dc1736..b051c08 100644 --- a/static/css/default_light/notifications.css +++ b/static/css/default_light/notifications.css @@ -1,6 +1,6 @@ #notifications { display: grid; - grid-template-columns: repeat(4, min-content); + grid-template-columns: repeat(5, min-content); grid-gap: 4px 16px; margin-top: 32px; margin-bottom: 32px; diff --git a/static/css/default_light/problems.css b/static/css/default_light/problems.css index e597be8..3a415de 100644 --- a/static/css/default_light/problems.css +++ b/static/css/default_light/problems.css @@ -46,7 +46,7 @@ } #areas .area .section .name { color: #000; - grid-column: -1; + grid-column: 1 / -1; font-weight: bold !important; line-height: 24px; } diff --git a/static/css/gruvbox/notifications.css b/static/css/gruvbox/notifications.css index e454f96..c6a1d82 100644 --- a/static/css/gruvbox/notifications.css +++ b/static/css/gruvbox/notifications.css @@ -1,6 +1,6 @@ #notifications { display: grid; - grid-template-columns: repeat(4, min-content); + grid-template-columns: repeat(5, min-content); grid-gap: 4px 16px; margin-top: 32px; margin-bottom: 32px; diff --git a/static/css/gruvbox/problems.css b/static/css/gruvbox/problems.css index b26c2c1..6c014f7 100644 --- a/static/css/gruvbox/problems.css +++ b/static/css/gruvbox/problems.css @@ -46,7 +46,7 @@ } #areas .area .section .name { color: #f7edd7; - grid-column: -1; + grid-column: 1 / -1; font-weight: bold !important; line-height: 24px; } diff --git a/static/less/notifications.less b/static/less/notifications.less index f0a64f1..8753486 100644 --- a/static/less/notifications.less +++ b/static/less/notifications.less @@ -2,7 +2,7 @@ #notifications { display: grid; - grid-template-columns: repeat(4, min-content); + grid-template-columns: repeat(5, min-content); grid-gap: 4px 16px; margin-top: 32px; margin-bottom: 32px; diff --git a/static/less/problems.less b/static/less/problems.less index e68a06e..601a9b4 100644 --- a/static/less/problems.less +++ b/static/less/problems.less @@ -52,7 +52,7 @@ .name { color: @text2; - grid-column: 1 / -1; + grid-column: ~"1 / -1"; font-weight: bold !important; line-height: 24px; } diff --git a/views/pages/notifications.gotmpl b/views/pages/notifications.gotmpl index 45bb2a0..f93e39a 100644 --- a/views/pages/notifications.gotmpl +++ b/views/pages/notifications.gotmpl @@ -10,11 +10,13 @@
OK
Trigger name
Service
+
Error
{{ range .Data.Notifications }}
{{ format_time .Sent }}
{{ if .OK }}✔{{ else }}✗{{ end }}
{{ .TriggerName }}
{{ .Prio }}:{{ .Service }}
+
{{ if .Error.Valid }}{{ .ErrorIndented }}{{ end }}
{{ end }}
From 17a22caa5d6d8164aba9bc53ed9189f349d8bfca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20=C3=85hall?= Date: Sat, 29 Jun 2024 19:30:26 +0200 Subject: [PATCH 4/4] Time filtering of notifications --- main.go | 42 +++++++++++- notification_log.go | 13 ++-- static/css/default_light/default_light.css | 7 +- static/css/default_light/notifications.css | 45 ++++++++++++ static/css/gruvbox/default_light.css | 7 +- static/css/gruvbox/notifications.css | 45 ++++++++++++ static/less/default_light.less | 6 +- static/less/notifications.less | 57 ++++++++++++++++ views/pages/notifications.gotmpl | 79 +++++++++++++++++++++- 9 files changed, 291 insertions(+), 10 deletions(-) diff --git a/main.go b/main.go index fb11c0b..01a6cf4 100644 --- a/main.go +++ b/main.go @@ -1198,7 +1198,45 @@ func actionConfigurationNotificationDelete(w http.ResponseWriter, r *http.Reques } // }}} func pageNotifications(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ - nss, err := notificationsSent() + var err error + + // GET parameters. + var timeFrom, timeTo time.Time + lastWeek := time.Now().Add(time.Duration(-7 * 24 * time.Hour)) + + timeFrom, err = parseHTMLDateTime(r.URL.Query().Get("f"), lastWeek) + if err != nil { + httpError(w, werr.Wrap(err).Log()) + return + } + + timeTo, err = parseHTMLDateTime(r.URL.Query().Get("t"), time.Now()) + if err != nil { + httpError(w, werr.Wrap(err).Log()) + return + } + + var presetTime int + now := time.Now() + presetStr := r.URL.Query().Get("preset") + if presetStr != "" { + presetTime, err = strconv.Atoi(presetStr) + if err != nil { + pageError(w, "/notifications", werr.Wrap(err).WithData(presetStr).Log()) + return + } + timeFrom = now.Add(time.Hour * -1 * time.Duration(presetTime)) + timeTo = now + } + + // Apply an optionally set offset (in seconds). + var offsetTime int + offsetTimeStr := r.URL.Query().Get("offset-time") + offsetTime, err = strconv.Atoi(offsetTimeStr) + timeFrom = timeFrom.Add(time.Second * time.Duration(offsetTime)) + timeTo = timeTo.Add(time.Second * time.Duration(offsetTime)) + + nss, err := notificationsSent(timeFrom, timeTo) if err != nil { pageError(w, "/", werr.Wrap(err).Log()) } @@ -1209,6 +1247,8 @@ func pageNotifications(w http.ResponseWriter, r *http.Request, _ *session.T) { / CONFIG: smonConfig.Settings, Data: map[string]any{ "Notifications": nss, + "TimeFrom": timeFrom.Format("2006-01-02T15:04:05"), + "TimeTo": timeTo.Format("2006-01-02T15:04:05"), }, } diff --git a/notification_log.go b/notification_log.go index d080cc9..c6d0a71 100644 --- a/notification_log.go +++ b/notification_log.go @@ -40,7 +40,7 @@ func notificationLog(notificationService *notification.Service, problemID int, e } } -func notificationsSent() (nss []NotificationSend, err error) { +func notificationsSent(from, to time.Time) (nss []NotificationSend, err error) { var rows *sqlx.Rows rows, err = service.Db.Conn.Queryx( ` @@ -57,15 +57,20 @@ func notificationsSent() (nss []NotificationSend, err error) { ns.error::varchar, ns.acknowledged - FROM - public.notification_send ns + FROM public.notification_send ns INNER JOIN notification n ON ns.notification_id = n.id INNER JOIN problem p ON ns.problem_id = p.id INNER JOIN "trigger" t ON p.trigger_id = t.id + WHERE + ns.send >= $1 AND + ns.send <= $2 ORDER BY send DESC - `) + `, + from, + to, + ) if err != nil { err = werr.Wrap(err) return diff --git a/static/css/default_light/default_light.css b/static/css/default_light/default_light.css index 57e3f8c..638f1a5 100644 --- a/static/css/default_light/default_light.css +++ b/static/css/default_light/default_light.css @@ -40,11 +40,16 @@ button:focus { #areas .area .section .name { font-weight: normal; } +dialog { + border-radius: 8px; +} +dialog, #datapoints, #problems-list, #acknowledged-list, #values, -#services { +#services, +#notifications { background-color: #fff !important; border: 1px solid #ddd; box-shadow: 5px 5px 8px 0px rgba(0, 0, 0, 0.25); diff --git a/static/css/default_light/notifications.css b/static/css/default_light/notifications.css index b051c08..a39d982 100644 --- a/static/css/default_light/notifications.css +++ b/static/css/default_light/notifications.css @@ -1,3 +1,42 @@ +#time-select { + display: grid; + grid-template-columns: min-content min-content; + grid-gap: 6px 16px; + padding: 16px; + border: 1px solid #7bb8eb; + width: min-content; + border-radius: 6px; +} +#time-select button { + width: 100px; + margin-top: 12px; + justify-self: end; +} +#time-select #time-offsets { + display: grid; + grid-template-columns: min-content repeat(3, min-content); + grid-gap: 16px; + margin-top: 16px; + align-items: center; + justify-items: center; +} +#time-select #time-offsets .header-1 { + font-weight: bold; + justify-self: start; +} +#time-select #time-offsets .header-2 { + font-weight: bold; + justify-self: start; + grid-column: 2 / -1; +} +#time-select #time-offsets .preset { + white-space: nowrap; + justify-self: start; + padding-right: 32px; +} +input[type="datetime-local"] { + padding: 6px; +} #notifications { display: grid; grid-template-columns: repeat(5, min-content); @@ -18,3 +57,9 @@ font-weight: 800; color: #7bb8eb; } +#notifications .ok { + color: #0a0; +} +#notifications .error { + color: #a00; +} diff --git a/static/css/gruvbox/default_light.css b/static/css/gruvbox/default_light.css index 3361608..95d95f2 100644 --- a/static/css/gruvbox/default_light.css +++ b/static/css/gruvbox/default_light.css @@ -40,11 +40,16 @@ button:focus { #areas .area .section .name { font-weight: normal; } +dialog { + border-radius: 8px; +} +dialog, #datapoints, #problems-list, #acknowledged-list, #values, -#services { +#services, +#notifications { background-color: #fff !important; border: 1px solid #ddd; box-shadow: 5px 5px 8px 0px rgba(0, 0, 0, 0.25); diff --git a/static/css/gruvbox/notifications.css b/static/css/gruvbox/notifications.css index c6a1d82..aaeab41 100644 --- a/static/css/gruvbox/notifications.css +++ b/static/css/gruvbox/notifications.css @@ -1,3 +1,42 @@ +#time-select { + display: grid; + grid-template-columns: min-content min-content; + grid-gap: 6px 16px; + padding: 16px; + border: 1px solid #777; + width: min-content; + border-radius: 6px; +} +#time-select button { + width: 100px; + margin-top: 12px; + justify-self: end; +} +#time-select #time-offsets { + display: grid; + grid-template-columns: min-content repeat(3, min-content); + grid-gap: 16px; + margin-top: 16px; + align-items: center; + justify-items: center; +} +#time-select #time-offsets .header-1 { + font-weight: bold; + justify-self: start; +} +#time-select #time-offsets .header-2 { + font-weight: bold; + justify-self: start; + grid-column: 2 / -1; +} +#time-select #time-offsets .preset { + white-space: nowrap; + justify-self: start; + padding-right: 32px; +} +input[type="datetime-local"] { + padding: 6px; +} #notifications { display: grid; grid-template-columns: repeat(5, min-content); @@ -18,3 +57,9 @@ font-weight: 800; color: #777; } +#notifications .ok { + color: #0a0; +} +#notifications .error { + color: #a00; +} diff --git a/static/less/default_light.less b/static/less/default_light.less index 542a083..ba51838 100644 --- a/static/less/default_light.less +++ b/static/less/default_light.less @@ -58,7 +58,11 @@ button { } } -#datapoints, #problems-list, #acknowledged-list, #values, #services { +dialog { + border-radius: 8px; +} + +dialog, #datapoints, #problems-list, #acknowledged-list, #values, #services, #notifications { background-color: #fff !important; border: 1px solid #ddd; box-shadow: 5px 5px 8px 0px rgba(0,0,0,0.25); diff --git a/static/less/notifications.less b/static/less/notifications.less index 8753486..62037d6 100644 --- a/static/less/notifications.less +++ b/static/less/notifications.less @@ -1,5 +1,54 @@ @import "theme-@{THEME}.less"; +#time-select { + display: grid; + grid-template-columns: min-content min-content; + grid-gap: 6px 16px; + + padding: 16px; + border: 1px solid @text3; + width: min-content; + border-radius: 6px; + + button { + //grid-column: ~"1 / -1"; + width: 100px; + margin-top: 12px; + justify-self: end; + } + + #time-offsets { + display: grid; + grid-template-columns: min-content repeat(3, min-content); + grid-gap: 16px; + margin-top: 16px; + + align-items: center; + justify-items: center; + + .header-1 { + font-weight: bold; + justify-self: start; + } + + .header-2 { + font-weight: bold; + justify-self: start; + grid-column: ~"2 / -1"; + } + + .preset { + white-space: nowrap; + justify-self: start; + padding-right: 32px; + } + } +} + +input[type="datetime-local"] { + padding: 6px; +} + #notifications { display: grid; grid-template-columns: repeat(5, min-content); @@ -21,4 +70,12 @@ font-weight: @bold; color: @text3; } + + .ok { + color: #0a0; + } + + .error { + color: #a00; + } } diff --git a/views/pages/notifications.gotmpl b/views/pages/notifications.gotmpl index f93e39a..afe39b3 100644 --- a/views/pages/notifications.gotmpl +++ b/views/pages/notifications.gotmpl @@ -4,6 +4,67 @@ {{ $version := .VERSION }} {{ $theme := .CONFIG.THEME }} + + +
+ + + +
+
From
+
To
+ + + +
+
Presets
+
Offsets
+ +
+ +
+
Hour
+
+ + + +
+
Day
+
+ + + +
+
Week
+
+ + + +
+
Month
+
+
+ +
+
Sent
@@ -13,10 +74,24 @@
Error
{{ range .Data.Notifications }}
{{ format_time .Sent }}
-
{{ if .OK }}✔{{ else }}✗{{ end }}
+
{{ if .OK }}{{ else }}{{ end }}
{{ .TriggerName }}
{{ .Prio }}:{{ .Service }}
-
{{ if .Error.Valid }}{{ .ErrorIndented }}{{ end }}
+
+ {{ if .Error.Valid }} + + +
+
{{ .ErrorIndented }}
+
+ +
+
+
+ {{ else }} + + {{ end }} +
{{ end }}