Deletion of notification services.

This commit is contained in:
Magnus Åhall 2024-06-28 17:18:08 +02:00
parent c7ad2aa1b6
commit a736ae60af
10 changed files with 74 additions and 9 deletions

20
main.go
View File

@ -155,6 +155,7 @@ func main() { // {{{
service.Register("/configuration/timezone", false, false, actionConfigurationTimezone) service.Register("/configuration/timezone", false, false, actionConfigurationTimezone)
service.Register("/configuration/notification", false, false, pageConfigurationNotification) service.Register("/configuration/notification", false, false, pageConfigurationNotification)
service.Register("/configuration/notification/update/{prio}", false, false, actionConfigurationNotificationUpdate) service.Register("/configuration/notification/update/{prio}", false, false, actionConfigurationNotificationUpdate)
service.Register("/configuration/notification/delete/{prio}", false, false, actionConfigurationNotificationDelete)
service.Register("/entry/{datapoint}", false, false, actionEntryDatapoint) service.Register("/entry/{datapoint}", false, false, actionEntryDatapoint)
go nodataLoop() go nodataLoop()
@ -1085,7 +1086,8 @@ func pageConfigurationNotification(w http.ResponseWriter, r *http.Request, _ *se
var service notification.Service var service notification.Service
if notificationType != "" { if notificationType != "" {
// Create a new instance of the selected notification type. // Create a new instance of the selected notification type.
service = notification.GetInstance(notificationType) service = notification.NewInstance(notificationType)
logger.Info("FOO", "service", fmt.Sprintf("%p %#v\n", service, service))
} else { } else {
// Find the existing service for editing. // Find the existing service for editing.
prio, err := strconv.Atoi(prioStr) prio, err := strconv.Atoi(prioStr)
@ -1138,7 +1140,7 @@ func actionConfigurationNotificationUpdate(w http.ResponseWriter, r *http.Reques
// prio -1 means a new service, not existing in database. // prio -1 means a new service, not existing in database.
var svc *notification.Service var svc *notification.Service
if prio == -1 { if prio == -1 {
emptyService := notification.GetInstance(r.PostFormValue("type")) emptyService := notification.NewInstance(r.PostFormValue("type"))
svc = &emptyService svc = &emptyService
} else { } else {
svc = notificationManager.GetService(prio) svc = notificationManager.GetService(prio)
@ -1178,3 +1180,17 @@ func actionConfigurationNotificationUpdate(w http.ResponseWriter, r *http.Reques
w.Header().Add("Location", "/configuration") w.Header().Add("Location", "/configuration")
w.WriteHeader(302) w.WriteHeader(302)
} // }}} } // }}}
func actionConfigurationNotificationDelete(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
prioStr := r.PathValue("prio")
prio, err := strconv.Atoi(prioStr)
if err != nil {
pageError(w, "/configuration", werr.Wrap(err).Log())
return
}
DeleteNotificationService(prio)
notificationManager.RemoveService(prio)
w.Header().Add("Location", "/configuration")
w.WriteHeader(302)
} // }}}

View File

@ -37,6 +37,16 @@ func ServiceFactory(t string, config []byte, prio int, ackURL string, logger *sl
return nil, werr.New("Unknown notification service, '%s'", t).WithCode("002-0000") return nil, werr.New("Unknown notification service, '%s'", t).WithCode("002-0000")
} }
func NewInstance(typ string) Service {
switch typ {
case "NTFY":
return new(NTFY)
case "SCRIPT":
return new(Script)
}
return nil
}
func GetInstance(typ string) Service { func GetInstance(typ string) Service {
for _, svc := range allServices { for _, svc := range allServices {
if strings.ToLower(svc.GetType()) == strings.ToLower(typ) { if strings.ToLower(svc.GetType()) == strings.ToLower(typ) {

View File

@ -60,6 +60,12 @@ func (nm *Manager) GetService(prio int) *Service {
return nil return nil
} }
func (nm *Manager) RemoveService(prioToRemove int) {
nm.services = slices.DeleteFunc(nm.services, func(svc Service) bool {
return svc.GetPrio() == prioToRemove
})
}
func (nm *Manager) Send(problemID int, msg []byte, fn func(*Service, error)) (err error) { func (nm *Manager) Send(problemID int, msg []byte, fn func(*Service, error)) (err error) {
for i, service := range nm.services { for i, service := range nm.services {
nm.logger.Info("notification", "service", service.GetType(), "prio", service.GetPrio()) nm.logger.Info("notification", "service", service.GetType(), "prio", service.GetPrio())

View File

@ -95,6 +95,8 @@ func (script Script) Send(problemID int, msg []byte) (err error) {
func (script *Script) Update(values url.Values) (err error) { func (script *Script) Update(values url.Values) (err error) {
updated := Script{} updated := Script{}
script.updated = &updated
updated.Prio, err = strconv.Atoi(values.Get("prio")) updated.Prio, err = strconv.Atoi(values.Get("prio"))
if err != nil { if err != nil {
return werr.Wrap(err) return werr.Wrap(err)
@ -105,8 +107,6 @@ func (script *Script) Update(values url.Values) (err error) {
return werr.New("Filename cannot be empty") return werr.New("Filename cannot be empty")
} }
updated.Filename = strings.TrimSpace(givenFilename) updated.Filename = strings.TrimSpace(givenFilename)
script.updated = &updated
return return
} }

View File

@ -116,6 +116,22 @@ func UpdateNotificationService(svc notification.Service) (created bool, err erro
} }
return return
} // }}} } // }}}
func DeleteNotificationService(prio int) (err error) { // {{{
_, err = service.Db.Conn.Exec(
`
DELETE FROM public.notification
WHERE
prio = $1
`,
prio,
)
if err != nil {
return werr.Wrap(err).WithData(struct{ Prio int }{prio})
}
return
} // }}}
func AcknowledgeNotification(uuid string) (err error) { // {{{ func AcknowledgeNotification(uuid string) (err error) { // {{{
/* /*

View File

@ -26,7 +26,7 @@
} }
#services { #services {
display: grid; display: grid;
grid-template-columns: repeat(3, min-content); grid-template-columns: repeat(4, min-content);
gap: 10px 24px; gap: 10px 24px;
background-color: #2979b8; background-color: #2979b8;
width: min-content; width: min-content;
@ -41,3 +41,6 @@
#services div { #services div {
white-space: nowrap; white-space: nowrap;
} }
#services img.delete {
height: 16px;
}

View File

@ -26,7 +26,7 @@
} }
#services { #services {
display: grid; display: grid;
grid-template-columns: repeat(3, min-content); grid-template-columns: repeat(4, min-content);
gap: 10px 24px; gap: 10px 24px;
background-color: #333; background-color: #333;
width: min-content; width: min-content;
@ -41,3 +41,6 @@
#services div { #services div {
white-space: nowrap; white-space: nowrap;
} }
#services img.delete {
height: 16px;
}

View File

@ -39,7 +39,7 @@
#services { #services {
display: grid; display: grid;
grid-template-columns: repeat(3, min-content); grid-template-columns: repeat(4, min-content);
gap: 10px 24px; gap: 10px 24px;
background-color: @bg3; background-color: @bg3;
width: min-content; width: min-content;
@ -55,4 +55,8 @@
div { div {
white-space: nowrap; white-space: nowrap;
} }
img.delete {
height: 16px;
}
} }

View File

@ -68,6 +68,11 @@
const nType = select.value const nType = select.value
location.href = `/configuration/notification?type=${nType}` location.href = `/configuration/notification?type=${nType}`
} }
function deleteNotification(prio) {
if (!confirm(`Are you sure you want to delete notification with prio ${prio}?`))
return
location.href = `/configuration/notification/delete/${prio}`;
}
</script> </script>
{{ block "page_label" . }}{{end}} {{ block "page_label" . }}{{end}}
@ -126,11 +131,13 @@
<div class="header">Prio</div> <div class="header">Prio</div>
<div class="header">Type</div> <div class="header">Type</div>
<div class="header">Target</div> <div class="header">Target</div>
<div></div>
<div class="line"></div> <div class="line"></div>
{{ range .Data.NotificationServices }} {{ range .Data.NotificationServices }}
<div><a href="/configuration/notification?prio={{ .GetPrio }}">{{ .GetPrio }}</a></div> <div><a href="/configuration/notification?prio={{ .GetPrio }}">{{ .GetPrio }}</a></div>
<div><a href="/configuration/notification?prio={{ .GetPrio }}">{{ .GetType }}</a></div> <div><a href="/configuration/notification?prio={{ .GetPrio }}">{{ .GetType }}</a></div>
<div><a href="/configuration/notification?prio={{ .GetPrio }}">{{ .String }}</a></div> <div><a href="/configuration/notification?prio={{ .GetPrio }}">{{ .String }}</a></div>
<div><img onclick="deleteNotification({{ .GetPrio }})" class="delete" src="/images/{{ $version }}/{{ $theme }}/delete.svg"></div>
{{ end }} {{ end }}
</div> </div>

View File

@ -19,8 +19,8 @@ button {
} }
</style> </style>
<form action="/configuration/notification/update/{{ .Data.Service.GetPrio }}" method="post"> <form action="/configuration/notification/update/{{ if .Data.Service.Exists }}{{ .Data.Service.GetPrio }}{{ else }}-1{{ end }}" method="post">
<input type="hidden" name="type" value="Script"> <input type="hidden" name="type" value="SCRIPT">
<div class="grid"> <div class="grid">
<div>Prio:</div> <div>Prio:</div>
<input type="number" min=0 name="prio" value="{{ .Data.Service.GetPrio }}"> <input type="number" min=0 name="prio" value="{{ .Data.Service.GetPrio }}">