Initial add of notifications

This commit is contained in:
Magnus Åhall 2024-06-29 15:20:31 +02:00
parent 24cf7fd4cc
commit ca9a6c3e1d
9 changed files with 98 additions and 6 deletions

20
main.go
View File

@ -150,6 +150,8 @@ func main() { // {{{
service.Register("/trigger/run/{id}", false, false, actionTriggerRun) service.Register("/trigger/run/{id}", false, false, actionTriggerRun)
service.Register("/trigger/delete/{id}", false, false, actionTriggerDelete) service.Register("/trigger/delete/{id}", false, false, actionTriggerDelete)
service.Register("/notifications", false, false, pageNotifications)
service.Register("/configuration", false, false, pageConfiguration) service.Register("/configuration", false, false, pageConfiguration)
service.Register("/configuration/theme", false, false, actionConfigurationTheme) service.Register("/configuration/theme", false, false, actionConfigurationTheme)
service.Register("/configuration/timezone", false, false, actionConfigurationTimezone) 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.Header().Add("Location", "/configuration")
w.WriteHeader(302) 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)
} // }}}

View File

@ -1,11 +1,29 @@
package main package main
import ( import (
// External
werr "git.gibonuddevalla.se/go/wrappederror"
"github.com/jmoiron/sqlx"
// Internal // Internal
"smon/notification" "smon/notification"
// Standard // 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) { func notificationLog(notificationService *notification.Service, problemID int, err error) {
if err == nil { if err == nil {
logger.Info("notification", "service", (*notificationService).GetType(), "problemID", problemID, "prio", (*notificationService).GetPrio(), "ok", true) 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) 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
}

View File

@ -1,6 +1,9 @@
body { body {
background-image: url(/images/v0/gruvbox/background.svg); background-image: url(/images/v0/gruvbox/background.svg);
} }
#menu {
box-shadow: 2px 0px 5px 3px rgba(0, 0, 0, 0.25);
}
#areas .area { #areas .area {
box-shadow: 5px 5px 15px 0px rgba(0, 0, 0, 0.5); box-shadow: 5px 5px 15px 0px rgba(0, 0, 0, 0.5);
} }

View File

@ -39,7 +39,7 @@ html {
#layout { #layout {
display: grid; display: grid;
grid-template-areas: "menu content"; grid-template-areas: "menu content";
grid-template-columns: 104px 1fr; grid-template-columns: 128px 1fr;
height: 100vh; height: 100vh;
} }
#menu { #menu {

View File

@ -46,7 +46,7 @@
} }
#areas .area .section .name { #areas .area .section .name {
color: #000; color: #000;
grid-column: 1 / -1; grid-column: -1;
font-weight: bold !important; font-weight: bold !important;
line-height: 24px; line-height: 24px;
} }

View File

@ -39,7 +39,7 @@ html {
#layout { #layout {
display: grid; display: grid;
grid-template-areas: "menu content"; grid-template-areas: "menu content";
grid-template-columns: 104px 1fr; grid-template-columns: 128px 1fr;
height: 100vh; height: 100vh;
} }
#menu { #menu {

View File

@ -46,7 +46,7 @@
} }
#areas .area .section .name { #areas .area .section .name {
color: #f7edd7; color: #f7edd7;
grid-column: 1 / -1; grid-column: -1;
font-weight: bold !important; font-weight: bold !important;
line-height: 24px; line-height: 24px;
} }

View File

@ -52,7 +52,7 @@ html {
#layout { #layout {
display: grid; display: grid;
grid-template-areas: "menu content"; grid-template-areas: "menu content";
grid-template-columns: 104px 1fr; grid-template-columns: 128px 1fr;
height: 100vh; height: 100vh;
} }
@ -248,7 +248,7 @@ button {
} }
.line { .line {
grid-column: 1 / -1; grid-column: ~"1 / -1";
border-bottom: 1px solid .lighterOrDarker(@bg1, 15%)[@result]; border-bottom: 1px solid .lighterOrDarker(@bg1, 15%)[@result];
} }

View File

@ -28,6 +28,13 @@
</a> </a>
</div> </div>
<div class="entry {{ if eq .MENU "notifications" }}selected{{ end }}">
<a href="/notifications">
<img src="/images/{{ .VERSION }}/{{ .CONFIG.THEME }}/notifications{{ if eq .MENU "notifications" }}_selected{{ end }}.svg" style="width: 36px">
<div class="label">Notifications</div>
</a>
</div>
<div class="entry {{ if eq .MENU "configuration" }}selected{{ end }}"> <div class="entry {{ if eq .MENU "configuration" }}selected{{ end }}">
<a href="/configuration"> <a href="/configuration">
<img src="/images/{{ .VERSION }}/{{ .CONFIG.THEME }}/configuration{{ if eq .MENU "configuration" }}_selected{{ end }}.svg"> <img src="/images/{{ .VERSION }}/{{ .CONFIG.THEME }}/configuration{{ if eq .MENU "configuration" }}_selected{{ end }}.svg">