feat: added placholders for notifications and incidents, fixed oauth

This commit is contained in:
Tine 2024-03-01 10:53:36 +01:00
parent 820e597d72
commit 8683a8b17e
Signed by: mentos1386
SSH key fingerprint: SHA256:MNtTsLbihYaWF8j1fkOHfkKNlnN1JQfxEU/rBU8nCGw
14 changed files with 262 additions and 32 deletions

View file

@ -6,20 +6,6 @@ import (
"time"
)
type OAuth2State struct {
State string `db:"state"`
ExpiresAt Time `db:"expires_at"`
}
type MonitorStatus string
const (
MonitorSuccess MonitorStatus = "SUCCESS"
MonitorFailure MonitorStatus = "FAILURE"
MonitorError MonitorStatus = "ERROR"
MonitorUnknown MonitorStatus = "UNKNOWN"
)
type Time struct {
Time time.Time
}
@ -54,9 +40,23 @@ func (t *Time) Scan(src any) error {
return nil
}
type OAuth2State struct {
State string `db:"state"`
ExpiresAt *Time `db:"expires_at"`
}
type MonitorStatus string
const (
MonitorSuccess MonitorStatus = "SUCCESS"
MonitorFailure MonitorStatus = "FAILURE"
MonitorError MonitorStatus = "ERROR"
MonitorUnknown MonitorStatus = "UNKNOWN"
)
type Monitor struct {
CreatedAt Time `db:"created_at"`
UpdatedAt Time `db:"updated_at"`
CreatedAt *Time `db:"created_at"`
UpdatedAt *Time `db:"updated_at"`
Id string `db:"id"`
Name string `db:"name"`
@ -73,7 +73,7 @@ type MonitorWithWorkerGroups struct {
}
type MonitorHistory struct {
CreatedAt Time `db:"created_at"`
CreatedAt *Time `db:"created_at"`
MonitorId string `db:"monitor_id"`
Status MonitorStatus `db:"status"`
@ -84,8 +84,8 @@ type MonitorHistory struct {
}
type WorkerGroup struct {
CreatedAt Time `db:"created_at"`
UpdatedAt Time `db:"updated_at"`
CreatedAt *Time `db:"created_at"`
UpdatedAt *Time `db:"updated_at"`
Id string `db:"id"`
Name string `db:"name"`

View file

@ -89,7 +89,7 @@ func (h *BaseHandler) OAuth2LoginGET(c echo.Context) error {
state := newRandomState()
err := services.CreateOAuth2State(ctx, h.db, &models.OAuth2State{
State: state,
ExpiresAt: models.Time{Time: time.Now().Add(5 * time.Minute)},
ExpiresAt: &models.Time{Time: time.Now().Add(5 * time.Minute)},
})
if err != nil {
return err

View file

@ -36,15 +36,19 @@ var SettingsPages = []*components.Page{
{Path: "/settings/worker-groups", Title: "Worker Groups", Breadcrumb: "Worker Groups"},
{Path: "/settings/worker-groups/create", Title: "Worker Groups Create", Breadcrumb: "Create"},
{Path: "/settings/notifications", Title: "Notifications", Breadcrumb: "Notifications"},
{Path: "/settings/notifications/create", Title: "Notifications Create", Breadcrumb: "Create"},
{Path: "/settings/incidents", Title: "Incidents", Breadcrumb: "Incidents"},
{Path: "/settings/incidents/create", Title: "Incidents Create", Breadcrumb: "Create"},
{Path: "/settings/temporal", Title: "Temporal", Breadcrumb: "Temporal"},
{Path: "/oauth2/logout", Title: "Logout", Breadcrumb: "Logout"},
}
var SettingsNavbar = []*components.Page{
GetPageByTitle(SettingsPages, "Overview"),
GetPageByTitle(SettingsPages, "Incidents"),
GetPageByTitle(SettingsPages, "Monitors"),
GetPageByTitle(SettingsPages, "Worker Groups"),
GetPageByTitle(SettingsPages, "Notifications"),
GetPageByTitle(SettingsPages, "Worker Groups"),
GetPageByTitle(SettingsPages, "Temporal"),
GetPageByTitle(SettingsPages, "Logout"),
}

View file

@ -0,0 +1,30 @@
package handlers
import (
"net/http"
"code.tjo.space/mentos1386/zdravko/web/templates/components"
"github.com/labstack/echo/v4"
)
type Incident struct{}
type SettingsIncidents struct {
*Settings
Incidents []*Incident
}
func (h *BaseHandler) SettingsIncidentsGET(c echo.Context) error {
cc := c.(AuthenticatedContext)
incidents := make([]*Incident, 0)
return c.Render(http.StatusOK, "settings_incidents.tmpl", &SettingsIncidents{
Settings: NewSettings(
cc.Principal.User,
GetPageByTitle(SettingsPages, "Incidents"),
[]*components.Page{GetPageByTitle(SettingsPages, "Incidents")},
),
Incidents: incidents,
})
}

View file

@ -0,0 +1,30 @@
package handlers
import (
"net/http"
"code.tjo.space/mentos1386/zdravko/web/templates/components"
"github.com/labstack/echo/v4"
)
type Notification struct{}
type SettingsNotifications struct {
*Settings
Notifications []*Notification
}
func (h *BaseHandler) SettingsNotificationsGET(c echo.Context) error {
cc := c.(AuthenticatedContext)
notifications := make([]*Notification, 0)
return c.Render(http.StatusOK, "settings_notifications.tmpl", &SettingsNotifications{
Settings: NewSettings(
cc.Principal.User,
GetPageByTitle(SettingsPages, "Notifications"),
[]*components.Page{GetPageByTitle(SettingsPages, "Notifications")},
),
Notifications: notifications,
})
}

View file

@ -35,8 +35,7 @@ type MonitorWithWorkerGroupsAndStatus struct {
type SettingsMonitors struct {
*Settings
Monitors []*MonitorWithWorkerGroupsAndStatus
MonitorsLength int
Monitors []*MonitorWithWorkerGroupsAndStatus
}
type SettingsMonitor struct {
@ -71,8 +70,7 @@ func (h *BaseHandler) SettingsMonitorsGET(c echo.Context) error {
GetPageByTitle(SettingsPages, "Monitors"),
[]*components.Page{GetPageByTitle(SettingsPages, "Monitors")},
),
Monitors: monitorsWithStatus,
MonitorsLength: len(monitorsWithStatus),
Monitors: monitorsWithStatus,
})
}

View file

@ -27,8 +27,7 @@ type WorkerGroupWithActiveWorkers struct {
type SettingsWorkerGroups struct {
*Settings
WorkerGroups []*WorkerGroupWithActiveWorkers
WorkerGroupsLength int
WorkerGroups []*WorkerGroupWithActiveWorkers
}
type SettingsWorker struct {
@ -62,8 +61,7 @@ func (h *BaseHandler) SettingsWorkerGroupsGET(c echo.Context) error {
GetPageByTitle(SettingsPages, "Worker Groups"),
[]*components.Page{GetPageByTitle(SettingsPages, "Worker Groups")},
),
WorkerGroups: workerGroupsWithActiveWorkers,
WorkerGroupsLength: len(workerGroupsWithActiveWorkers),
WorkerGroups: workerGroupsWithActiveWorkers,
})
}

View file

@ -16,7 +16,7 @@ func CreateOAuth2State(ctx context.Context, db *sqlx.DB, oauth2State *models.OAu
}
func DeleteOAuth2State(ctx context.Context, db *sqlx.DB, state string) (deleted bool, err error) {
res, err := db.ExecContext(ctx, "DELETE FROM oauth2_states WHERE state = $1 AND expires_at > datetime('now')", state)
res, err := db.ExecContext(ctx, "DELETE FROM oauth2_states WHERE state = $1 AND expires_at > strftime('%Y-%m-%dT%H:%M:%fZ')", state)
if err != nil {
return false, err
}

View file

@ -45,6 +45,7 @@ func Routes(
settings := e.Group("/settings")
settings.Use(h.Authenticated)
settings.GET("", h.SettingsOverviewGET)
settings.GET("/incidents", h.SettingsIncidentsGET)
settings.GET("/monitors", h.SettingsMonitorsGET)
settings.GET("/monitors/create", h.SettingsMonitorsCreateGET)
settings.POST("/monitors/create", h.SettingsMonitorsCreatePOST)
@ -53,6 +54,7 @@ func Routes(
settings.GET("/monitors/:id/delete", h.SettingsMonitorsDescribeDELETE)
settings.GET("/monitors/:id/disable", h.SettingsMonitorsDisableGET)
settings.GET("/monitors/:id/enable", h.SettingsMonitorsEnableGET)
settings.GET("/notifications", h.SettingsNotificationsGET)
settings.GET("/worker-groups", h.SettingsWorkerGroupsGET)
settings.GET("/worker-groups/create", h.SettingsWorkerGroupsCreateGET)
settings.POST("/worker-groups/create", h.SettingsWorkerGroupsCreatePOST)

View file

@ -0,0 +1,82 @@
{{ define "settings" }}
{{ $description := "Incidents can be manually created or based on monitors. They are used to notify about issues." }}
{{ $length := len .Incidents }}
{{ if eq $length 0 }}
<div class="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16">
<h1
class="mb-4 text-2xl font-extrabold tracking-tight leading-none text-gray-900 md:text-3xl lg:text-4xl"
>
There are no incidents yet.
</h1>
<p
class="mb-8 text-l font-normal text-gray-500 lg:text-l sm:px-8 lg:px-40"
>
{{ $description }}
</p>
<div
class="flex flex-col space-y-4 sm:flex-row sm:justify-center sm:space-y-0"
>
<a
href="/settings/incidents/create"
class="inline-flex justify-center items-center py-3 px-5 text-base font-medium text-center text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300"
>
Create First Worker Group
<svg class="feather ml-1 h-5 w-5 overflow-visible">
<use href="/static/icons/feather-sprite.svg#plus" />
</svg>
</a>
</div>
</div>
{{ else }}
<section>
<table>
<caption>
List of Incidents
<div class="mt-1 gap-4 grid grid-cols-1 md:grid-cols-[1fr,20%]">
<p>
{{ $description }}
</p>
<a
href="/settings/incidents/create"
class="h-min inline-flex justify-center items-center py-2 px-4 text-sm font-medium text-center text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300"
>
Create New
<svg class="feather h-5 w-5 overflow-visible">
<use href="/static/icons/feather-sprite.svg#plus" />
</svg>
</a>
</div>
</caption>
<thead>
<tr>
<th>Name</th>
<th>Notifications</th>
<th>Action</th>
</tr>
</thead>
{{ range .Incidents }}
<tbody>
<tr>
<th scope="row">
{{ .Name }}
</th>
<td>
{{ range .Notifications }}
<span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800"
>
{{ . }}
</span>
{{ end }}
</td>
<td>
<a href="/settings/incidents/{{ .Id }}" class="link">Details</a>
</td>
</tr>
</tbody>
{{ end }}
</table>
</section>
{{ end }}
{{ end }}

View file

@ -1,7 +1,8 @@
{{ define "settings" }}
{{ $description := "Monitors are constantly checking weather a service is online and working correctly." }}
{{ if eq .MonitorsLength 0 }}
{{ $length := len .Monitors }}
{{ if eq $length 0 }}
<div class="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16">
<h1
class="mb-4 text-2xl font-extrabold tracking-tight leading-none text-gray-900 md:text-3xl lg:text-4xl"

View file

@ -0,0 +1,82 @@
{{ define "settings" }}
{{ $description := "Notifications are connections to other services to notify about events." }}
{{ $length := len .Notifications }}
{{ if eq $length 0 }}
<div class="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16">
<h1
class="mb-4 text-2xl font-extrabold tracking-tight leading-none text-gray-900 md:text-3xl lg:text-4xl"
>
There are no notifications yet.
</h1>
<p
class="mb-8 text-l font-normal text-gray-500 lg:text-l sm:px-8 lg:px-40"
>
{{ $description }}
</p>
<div
class="flex flex-col space-y-4 sm:flex-row sm:justify-center sm:space-y-0"
>
<a
href="/settings/notifications/create"
class="inline-flex justify-center items-center py-3 px-5 text-base font-medium text-center text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300"
>
Create First Worker Group
<svg class="feather ml-1 h-5 w-5 overflow-visible">
<use href="/static/icons/feather-sprite.svg#plus" />
</svg>
</a>
</div>
</div>
{{ else }}
<section>
<table>
<caption>
List of Notifications
<div class="mt-1 gap-4 grid grid-cols-1 md:grid-cols-[1fr,20%]">
<p>
{{ $description }}
</p>
<a
href="/settings/notifications/create"
class="h-min inline-flex justify-center items-center py-2 px-4 text-sm font-medium text-center text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300"
>
Create New
<svg class="feather h-5 w-5 overflow-visible">
<use href="/static/icons/feather-sprite.svg#plus" />
</svg>
</a>
</div>
</caption>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Action</th>
</tr>
</thead>
{{ range .Notifications }}
<tbody>
<tr>
<th scope="row">
{{ .Name }}
</th>
<td>
<span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800"
>
{{ .Type }}
</span>
</td>
<td>
<a href="/settings/notifications/{{ .Id }}" class="link"
>Details</a
>
</td>
</tr>
</tbody>
{{ end }}
</table>
</section>
{{ end }}
{{ end }}

View file

@ -1,7 +1,8 @@
{{ define "settings" }}
{{ $description := "Worker Groups are used to match multiple workers together. They can be used to difirentiate between regions, environments, networks etc." }}
{{ if eq .WorkerGroupsLength 0 }}
{{ $length := len .WorkerGroups }}
{{ if eq $length 0 }}
<div class="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16">
<h1
class="mb-4 text-2xl font-extrabold tracking-tight leading-none text-gray-900 md:text-3xl lg:text-4xl"

View file

@ -44,6 +44,8 @@ func NewTemplates() *Templates {
"index.tmpl": load("pages/index.tmpl"),
"incidents.tmpl": load("pages/incidents.tmpl"),
"settings_overview.tmpl": loadSettings("pages/settings_overview.tmpl"),
"settings_incidents.tmpl": loadSettings("pages/settings_incidents.tmpl"),
"settings_notifications.tmpl": loadSettings("pages/settings_notifications.tmpl"),
"settings_worker_groups.tmpl": loadSettings("pages/settings_worker_groups.tmpl"),
"settings_worker_groups_create.tmpl": loadSettings("pages/settings_worker_groups_create.tmpl"),
"settings_worker_groups_describe.tmpl": loadSettings("pages/settings_worker_groups_describe.tmpl"),