mirror of
https://github.com/mentos1386/zdravko.git
synced 2024-11-25 08:58:50 +00:00
feat: added placholders for notifications and incidents, fixed oauth
This commit is contained in:
parent
820e597d72
commit
8683a8b17e
14 changed files with 262 additions and 32 deletions
|
@ -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"`
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"),
|
||||
}
|
||||
|
|
30
internal/handlers/settings_incidents.go
Normal file
30
internal/handlers/settings_incidents.go
Normal 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,
|
||||
})
|
||||
}
|
30
internal/handlers/settings_notifications.go
Normal file
30
internal/handlers/settings_notifications.go
Normal 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,
|
||||
})
|
||||
}
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
82
web/templates/pages/settings_incidents.tmpl
Normal file
82
web/templates/pages/settings_incidents.tmpl
Normal 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 }}
|
|
@ -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"
|
||||
|
|
82
web/templates/pages/settings_notifications.tmpl
Normal file
82
web/templates/pages/settings_notifications.tmpl
Normal 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 }}
|
|
@ -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"
|
||||
|
|
|
@ -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"),
|
||||
|
|
Loading…
Reference in a new issue