feat: groups for monitors

This commit is contained in:
Tine 2024-03-03 15:28:25 +01:00
parent 571fee81f5
commit 24e8414e03
Signed by: mentos1386
SSH key fingerprint: SHA256:MNtTsLbihYaWF8j1fkOHfkKNlnN1JQfxEU/rBU8nCGw
13 changed files with 258 additions and 116 deletions

View file

@ -58,8 +58,9 @@ type Monitor struct {
CreatedAt *Time `db:"created_at"` CreatedAt *Time `db:"created_at"`
UpdatedAt *Time `db:"updated_at"` UpdatedAt *Time `db:"updated_at"`
Id string `db:"id"` Id string `db:"id"`
Name string `db:"name"` Name string `db:"name"`
Group string `db:"group"`
Schedule string `db:"schedule"` Schedule string `db:"schedule"`
Script string `db:"script"` Script string `db:"script"`

View file

@ -9,6 +9,7 @@ CREATE TABLE oauth2_states (
CREATE TABLE monitors ( CREATE TABLE monitors (
id TEXT NOT NULL, id TEXT NOT NULL,
name TEXT NOT NULL, name TEXT NOT NULL,
"group" TEXT NOT NULL DEFAULT 'default',
schedule TEXT NOT NULL, schedule TEXT NOT NULL,
script TEXT NOT NULL, script TEXT NOT NULL,

View file

@ -17,8 +17,8 @@ primary_region = 'waw'
ROOT_URL = 'https://zdravko.mnts.dev' ROOT_URL = 'https://zdravko.mnts.dev'
TEMPORAL_SERVER_HOST = 'server.process.zdravko.internal:7233' TEMPORAL_SERVER_HOST = 'server.process.zdravko.internal:7233'
TEMPORAL_DATABASE_PATH = '/data/temporal-7.db' TEMPORAL_DATABASE_PATH = '/data/temporal-8.db'
DATABASE_PATH = '/data/zdravko-7.db' DATABASE_PATH = '/data/zdravko-8.db'
[processes] [processes]
server = '--temporal --server' server = '--temporal --server'

View file

@ -13,14 +13,15 @@ import (
type IndexData struct { type IndexData struct {
*components.Base *components.Base
HealthChecks []*HealthCheck Monitors map[string][]*Monitor
MonitorsLength int MonitorsLength int
TimeRange string TimeRange string
Status models.MonitorStatus Status models.MonitorStatus
} }
type HealthCheck struct { type Monitor struct {
Name string Name string
Group string
Status models.MonitorStatus Status models.MonitorStatus
History *History History *History
} }
@ -96,7 +97,7 @@ func (h *BaseHandler) Index(c echo.Context) error {
overallStatus := models.MonitorSuccess overallStatus := models.MonitorSuccess
monitorsWithHistory := make([]*HealthCheck, len(monitors)) monitorsWithHistory := make([]*Monitor, len(monitors))
for i, monitor := range monitors { for i, monitor := range monitors {
history, err := services.GetMonitorHistoryForMonitor(ctx, h.db, monitor.Id) history, err := services.GetMonitorHistoryForMonitor(ctx, h.db, monitor.Id)
if err != nil { if err != nil {
@ -118,21 +119,26 @@ func (h *BaseHandler) Index(c echo.Context) error {
overallStatus = status overallStatus = status
} }
monitorsWithHistory[i] = &HealthCheck{ monitorsWithHistory[i] = &Monitor{
Name: monitor.Name, Name: monitor.Name,
Group: monitor.Group,
Status: status, Status: status,
History: historyResult, History: historyResult,
} }
} }
monitorsByGroup := map[string][]*Monitor{}
for _, monitor := range monitorsWithHistory {
monitorsByGroup[monitor.Group] = append(monitorsByGroup[monitor.Group], monitor)
}
return c.Render(http.StatusOK, "index.tmpl", &IndexData{ return c.Render(http.StatusOK, "index.tmpl", &IndexData{
Base: &components.Base{ Base: &components.Base{
NavbarActive: GetPageByTitle(Pages, "Status"), NavbarActive: GetPageByTitle(Pages, "Status"),
Navbar: Pages, Navbar: Pages,
}, },
HealthChecks: monitorsWithHistory, Monitors: monitorsByGroup,
MonitorsLength: len(monitors), TimeRange: timeRange,
TimeRange: timeRange, Status: overallStatus,
Status: overallStatus,
}) })
} }

View file

@ -5,6 +5,7 @@ import (
"database/sql" "database/sql"
"fmt" "fmt"
"net/http" "net/http"
"slices"
"strings" "strings"
"code.tjo.space/mentos1386/zdravko/database/models" "code.tjo.space/mentos1386/zdravko/database/models"
@ -17,12 +18,14 @@ import (
type CreateMonitor struct { type CreateMonitor struct {
Name string `validate:"required"` Name string `validate:"required"`
Group string `validate:"required"`
WorkerGroups string `validate:"required"` WorkerGroups string `validate:"required"`
Schedule string `validate:"required,cron"` Schedule string `validate:"required,cron"`
Script string `validate:"required"` Script string `validate:"required"`
} }
type UpdateMonitor struct { type UpdateMonitor struct {
Group string `validate:"required"`
WorkerGroups string `validate:"required"` WorkerGroups string `validate:"required"`
Schedule string `validate:"required,cron"` Schedule string `validate:"required,cron"`
Script string `validate:"required"` Script string `validate:"required"`
@ -35,7 +38,8 @@ type MonitorWithWorkerGroupsAndStatus struct {
type SettingsMonitors struct { type SettingsMonitors struct {
*Settings *Settings
Monitors []*MonitorWithWorkerGroupsAndStatus Monitors map[string][]*MonitorWithWorkerGroupsAndStatus
MonitorGroups []string
} }
type SettingsMonitor struct { type SettingsMonitor struct {
@ -64,13 +68,23 @@ func (h *BaseHandler) SettingsMonitorsGET(c echo.Context) error {
} }
} }
monitorGroups := []string{}
monitorsByGroup := map[string][]*MonitorWithWorkerGroupsAndStatus{}
for _, monitor := range monitorsWithStatus {
monitorsByGroup[monitor.Group] = append(monitorsByGroup[monitor.Group], monitor)
if slices.Contains(monitorGroups, monitor.Group) == false {
monitorGroups = append(monitorGroups, monitor.Group)
}
}
return c.Render(http.StatusOK, "settings_monitors.tmpl", &SettingsMonitors{ return c.Render(http.StatusOK, "settings_monitors.tmpl", &SettingsMonitors{
Settings: NewSettings( Settings: NewSettings(
cc.Principal.User, cc.Principal.User,
GetPageByTitle(SettingsPages, "Monitors"), GetPageByTitle(SettingsPages, "Monitors"),
[]*components.Page{GetPageByTitle(SettingsPages, "Monitors")}, []*components.Page{GetPageByTitle(SettingsPages, "Monitors")},
), ),
Monitors: monitorsWithStatus, Monitors: monitorsByGroup,
MonitorGroups: monitorGroups,
}) })
} }
@ -174,6 +188,7 @@ func (h *BaseHandler) SettingsMonitorsDescribePOST(c echo.Context) error {
monitorId := c.Param("id") monitorId := c.Param("id")
update := UpdateMonitor{ update := UpdateMonitor{
Group: c.FormValue("group"),
WorkerGroups: strings.TrimSpace(c.FormValue("workergroups")), WorkerGroups: strings.TrimSpace(c.FormValue("workergroups")),
Schedule: c.FormValue("schedule"), Schedule: c.FormValue("schedule"),
Script: c.FormValue("script"), Script: c.FormValue("script"),
@ -187,6 +202,7 @@ func (h *BaseHandler) SettingsMonitorsDescribePOST(c echo.Context) error {
if err != nil { if err != nil {
return err return err
} }
monitor.Group = update.Group
monitor.Schedule = update.Schedule monitor.Schedule = update.Schedule
monitor.Script = update.Script monitor.Script = update.Script
@ -251,6 +267,7 @@ func (h *BaseHandler) SettingsMonitorsCreatePOST(c echo.Context) error {
create := CreateMonitor{ create := CreateMonitor{
Name: c.FormValue("name"), Name: c.FormValue("name"),
Group: c.FormValue("group"),
Schedule: c.FormValue("schedule"), Schedule: c.FormValue("schedule"),
WorkerGroups: c.FormValue("workergroups"), WorkerGroups: c.FormValue("workergroups"),
Script: c.FormValue("script"), Script: c.FormValue("script"),
@ -282,6 +299,7 @@ func (h *BaseHandler) SettingsMonitorsCreatePOST(c echo.Context) error {
monitor := &models.Monitor{ monitor := &models.Monitor{
Name: create.Name, Name: create.Name,
Group: create.Group,
Id: monitorId, Id: monitorId,
Schedule: create.Schedule, Schedule: create.Schedule,
Script: create.Script, Script: create.Script,

View file

@ -62,7 +62,7 @@ func SetMonitorStatus(ctx context.Context, temporal client.Client, id string, st
func CreateMonitor(ctx context.Context, db *sqlx.DB, monitor *models.Monitor) error { func CreateMonitor(ctx context.Context, db *sqlx.DB, monitor *models.Monitor) error {
_, err := db.NamedExecContext(ctx, _, err := db.NamedExecContext(ctx,
"INSERT INTO monitors (id, name, script, schedule) VALUES (:id, :name, :script, :schedule)", `INSERT INTO monitors (id, name, "group", script, schedule) VALUES (:id, :name, :group, :script, :schedule)`,
monitor, monitor,
) )
return err return err
@ -70,7 +70,7 @@ func CreateMonitor(ctx context.Context, db *sqlx.DB, monitor *models.Monitor) er
func UpdateMonitor(ctx context.Context, db *sqlx.DB, monitor *models.Monitor) error { func UpdateMonitor(ctx context.Context, db *sqlx.DB, monitor *models.Monitor) error {
_, err := db.NamedExecContext(ctx, _, err := db.NamedExecContext(ctx,
"UPDATE monitors SET name=:name, script=:script, schedule=:schedule WHERE id=:id", `UPDATE monitors SET "group"=:group, script=:script, schedule=:schedule WHERE id=:id`,
monitor, monitor,
) )
return err return err
@ -126,6 +126,7 @@ func GetMonitorWithWorkerGroups(ctx context.Context, db *sqlx.DB, id string) (*m
SELECT SELECT
monitors.id, monitors.id,
monitors.name, monitors.name,
monitors."group",
monitors.script, monitors.script,
monitors.schedule, monitors.schedule,
monitors.created_at, monitors.created_at,
@ -150,6 +151,7 @@ WHERE monitors.id=$1
err = rows.Scan( err = rows.Scan(
&monitor.Id, &monitor.Id,
&monitor.Name, &monitor.Name,
&monitor.Group,
&monitor.Script, &monitor.Script,
&monitor.Schedule, &monitor.Schedule,
&monitor.CreatedAt, &monitor.CreatedAt,
@ -181,6 +183,7 @@ func GetMonitorsWithWorkerGroups(ctx context.Context, db *sqlx.DB) ([]*models.Mo
SELECT SELECT
monitors.id, monitors.id,
monitors.name, monitors.name,
monitors."group",
monitors.script, monitors.script,
monitors.schedule, monitors.schedule,
monitors.created_at, monitors.created_at,
@ -205,6 +208,7 @@ ORDER BY monitors.name
err = rows.Scan( err = rows.Scan(
&monitor.Id, &monitor.Id,
&monitor.Name, &monitor.Name,
&monitor.Group,
&monitor.Script, &monitor.Script,
&monitor.Schedule, &monitor.Schedule,
&monitor.CreatedAt, &monitor.CreatedAt,

View file

@ -56,10 +56,10 @@ code {
@apply bg-blue-700 text-white; @apply bg-blue-700 text-white;
} }
.monitors { .monitors .monitors-list {
@apply grid justify-items-stretch justify-stretch items-center mt-20 bg-white shadow-md p-5 rounded-lg; @apply grid justify-items-stretch justify-stretch items-center bg-white shadow-md p-5 py-2 rounded-lg;
} }
.monitors > div:not(:last-child) { .monitors .monitors-list > div:not(:last-child) {
@apply mb-3; @apply mb-3;
} }
.monitors .time-range > a { .monitors .time-range > a {
@ -113,9 +113,16 @@ code {
.settings section table thead th { .settings section table thead th {
@apply px-6 py-4 text-center text-xs font-semibold text-gray-600 uppercase tracking-wider; @apply px-6 py-4 text-center text-xs font-semibold text-gray-600 uppercase tracking-wider;
} }
.settings section table tbody tr {
@apply odd:bg-white even:bg-gray-50;
}
.settings section table tbody tr th { .settings section table tbody tr th {
@apply px-6 py-4 font-medium text-gray-900 whitespace-nowrap text-center; @apply px-6 py-4 font-medium text-gray-900 whitespace-nowrap text-center;
} }
.settings section table tbody tr td { .settings section table tbody tr td {
@apply px-6 py-4 text-center whitespace-nowrap; @apply px-6 py-4 text-center whitespace-nowrap;
} }
.settings section table tbody tr.row-special {
@apply bg-gray-100;
@apply font-semibold text-xs uppercase tracking-wider;
}

View file

@ -697,6 +697,10 @@ video {
height: 1.25rem; height: 1.25rem;
} }
.h-6 {
height: 1.5rem;
}
.h-8 { .h-8 {
height: 2rem; height: 2rem;
} }
@ -731,6 +735,10 @@ video {
width: 1.25rem; width: 1.25rem;
} }
.w-6 {
width: 1.5rem;
}
.w-fit { .w-fit {
width: -moz-fit-content; width: -moz-fit-content;
width: fit-content; width: fit-content;
@ -796,6 +804,10 @@ video {
gap: 0.5rem; gap: 0.5rem;
} }
.gap-20 {
gap: 5rem;
}
.gap-4 { .gap-4 {
gap: 1rem; gap: 1rem;
} }
@ -1039,11 +1051,21 @@ video {
line-height: 1.5rem; line-height: 1.5rem;
} }
.text-lg {
font-size: 1.125rem;
line-height: 1.75rem;
}
.text-sm { .text-sm {
font-size: 0.875rem; font-size: 0.875rem;
line-height: 1.25rem; line-height: 1.25rem;
} }
.text-xl {
font-size: 1.25rem;
line-height: 1.75rem;
}
.text-xs { .text-xs {
font-size: 0.75rem; font-size: 0.75rem;
line-height: 1rem; line-height: 1rem;
@ -1322,8 +1344,7 @@ code {
color: rgb(255 255 255 / var(--tw-text-opacity)); color: rgb(255 255 255 / var(--tw-text-opacity));
} }
.monitors { .monitors .monitors-list {
margin-top: 5rem;
display: grid; display: grid;
align-items: center; align-items: center;
justify-content: stretch; justify-content: stretch;
@ -1332,12 +1353,14 @@ code {
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity)); background-color: rgb(255 255 255 / var(--tw-bg-opacity));
padding: 1.25rem; padding: 1.25rem;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
} }
.monitors > div:not(:last-child) { .monitors .monitors-list > div:not(:last-child) {
margin-bottom: 0.75rem; margin-bottom: 0.75rem;
} }
@ -1581,6 +1604,16 @@ code {
color: rgb(75 85 99 / var(--tw-text-opacity)); color: rgb(75 85 99 / var(--tw-text-opacity));
} }
.settings section table tbody tr:nth-child(odd) {
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.settings section table tbody tr:nth-child(even) {
--tw-bg-opacity: 1;
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
}
.settings section table tbody tr th { .settings section table tbody tr th {
white-space: nowrap; white-space: nowrap;
padding-left: 1.5rem; padding-left: 1.5rem;
@ -1602,6 +1635,16 @@ code {
text-align: center; text-align: center;
} }
.settings section table tbody tr.row-special {
--tw-bg-opacity: 1;
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
font-size: 0.75rem;
line-height: 1rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.hover\:bg-blue-800:hover { .hover\:bg-blue-800:hover {
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgb(30 64 175 / var(--tw-bg-opacity)); background-color: rgb(30 64 175 / var(--tw-bg-opacity));
@ -1703,6 +1746,11 @@ code {
justify-self: end; justify-self: end;
} }
.sm\:px-0 {
padding-left: 0px;
padding-right: 0px;
}
.sm\:px-8 { .sm\:px-8 {
padding-left: 2rem; padding-left: 2rem;
padding-right: 2rem; padding-right: 2rem;

View file

@ -1,6 +1,7 @@
{{ define "main" }} {{ define "main" }}
<div class="container max-w-screen-md flex flex-col mt-20"> <div class="container max-w-screen-md flex flex-col mt-20 gap-20">
{{ if eq .MonitorsLength 0 }} {{ $length := len .Monitors }}
{{ if eq $length 0 }}
<section> <section>
<div class="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16"> <div class="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16">
<h1 <h1
@ -57,13 +58,15 @@
</p> </p>
</div> </div>
{{ end }} {{ end }}
<div class="monitors"> <div class="monitors flex flex-col gap-4">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2"> <div class="grid grid-cols-1 sm:grid-cols-2 px-4 sm:px-0">
<p class="text-l font-normal text-gray-800 text-center sm:text-left"> <h2
class="text-xl font-normal text-gray-800 text-center sm:text-left"
>
Monitors Monitors
</p> </h2>
<div <div
class="inline-flex gap-1 rounded-md shadow-sm justify-self-center sm:justify-self-end time-range py-1 px-1 bg-gray-100" class="inline-flex gap-1 rounded-md shadow-sm justify-self-center sm:justify-self-end time-range py-1 px-1 bg-white"
role="group" role="group"
> >
<a <a
@ -86,46 +89,61 @@
> >
</div> </div>
</div> </div>
{{ range .HealthChecks }} {{ range $group, $monitors := .Monitors }}
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2"> <div class="monitors-list">
<div class="flex items-center"> <h3 class="text-lg font-semibold flex flex-row gap-2">
{{ if eq .Status "SUCCESS" }} <!--<span
<span class="flex w-3 h-3 bg-green-400 rounded-full self-center"
class="flex w-3 h-3 me-2 bg-green-400 rounded-full" ></span>-->
></span> <span class="flex-1">{{ $group }}</span>
{{ else if eq .Status "FAILURE" }} <svg class="feather h-6 w-6 overflow-visible self-center">
<span class="flex w-3 h-3 me-2 bg-red-400 rounded-full"></span> <use href="/static/icons/feather-sprite.svg#chevron-down" />
{{ else }} </svg>
<span class="flex w-3 h-3 me-2 bg-gray-200 rounded-full"></span> </h3>
{{ end }} {{ range $monitors }}
<p>{{ .Name }}</p> <div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
</div> <div class="flex items-center gap-2">
<div class="justify-self-end text-sm"> {{ if eq .Status "SUCCESS" }}
{{ .History.Uptime }}% uptime <span class="flex w-3 h-3 bg-green-400 rounded-full"></span>
</div> {{ else if eq .Status "FAILURE" }}
<div <span class="flex w-3 h-3 bg-red-400 rounded-full"></span>
class="grid gap-px col-span-2 grid-flow-col h-8 rounded overflow-hidden" {{ else }}
> <span class="flex w-3 h-3 bg-gray-200 rounded-full"></span>
{{ range .History.List }} {{ end }}
{{ if eq . "SUCCESS" }} <h4>{{ .Name }}</h4>
<div class="bg-green-400 hover:bg-green-500 flex-auto"></div> </div>
{{ else if eq . "FAILURE" }} <div class="justify-self-end text-sm">
<div class="bg-red-400 hover:bg-red-500 flex-auto"></div> {{ .History.Uptime }}% uptime
{{ else }} </div>
<div class="bg-gray-200 hover:bg-gray-300 flex-auto"></div> <div
{{ end }} class="grid gap-px col-span-2 grid-flow-col h-8 rounded overflow-hidden"
{{ end }} >
</div> {{ range .History.List }}
<div class="text-slate-500 justify-self-start text-sm"> {{ if eq . "SUCCESS" }}
{{ if eq $.TimeRange "90days" }} <div
90 days ago class="bg-green-400 hover:bg-green-500 flex-auto"
{{ else if eq $.TimeRange "48hours" }} ></div>
48 hours ago {{ else if eq . "FAILURE" }}
{{ else if eq $.TimeRange "90minutes" }} <div class="bg-red-400 hover:bg-red-500 flex-auto"></div>
90 minutes ago {{ else }}
{{ end }} <div
</div> class="bg-gray-200 hover:bg-gray-300 flex-auto"
<div class="text-slate-500 justify-self-end text-sm">Now</div> ></div>
{{ end }}
{{ end }}
</div>
<div class="text-slate-500 justify-self-start text-sm">
{{ if eq $.TimeRange "90days" }}
90 days ago
{{ else if eq $.TimeRange "48hours" }}
48 hours ago
{{ else if eq $.TimeRange "90minutes" }}
90 minutes ago
{{ end }}
</div>
<div class="text-slate-500 justify-self-end text-sm">Now</div>
</div>
{{ end }}
</div> </div>
{{ end }} {{ end }}
</div> </div>

View file

@ -50,6 +50,7 @@
</caption> </caption>
<thead class="text-xs text-gray-700 uppercase bg-gray-50"> <thead class="text-xs text-gray-700 uppercase bg-gray-50">
<tr> <tr>
<th scope="col">Group</th>
<th scope="col">Name</th> <th scope="col">Name</th>
<th scope="col">Worker Groups</th> <th scope="col">Worker Groups</th>
<th scope="col">Status</th> <th scope="col">Status</th>
@ -57,51 +58,71 @@
<th scope="col">Action</th> <th scope="col">Action</th>
</tr> </tr>
</thead> </thead>
{{ range .Monitors }} <tbody>
<tbody> {{ range .MonitorGroups }}
<tr> {{ $currentGroup := . }}
<tr class="row-special">
<th scope="row"> <th scope="row">
{{ .Name }} {{ . }}
</th> </th>
<td> <td></td>
{{ range .WorkerGroups }} <td></td>
<span <td></td>
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800" <td></td>
> <td></td>
{{ . }}
</span>
{{ end }}
</td>
<td>
{{ if eq .Status "ACTIVE" }}
<span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800"
>
ACTIVE
</span>
{{ else if eq .Status "PAUSED" }}
<span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800"
>
PAUSED
</span>
{{ else }}
<span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800"
>
UNKNOWN
</span>
{{ end }}
</td>
<td>
{{ .Schedule }}
</td>
<td>
<a href="/settings/monitors/{{ .Id }}" class="link">Details</a>
</td>
</tr> </tr>
</tbody> {{ range $group, $monitors := $.Monitors }}
{{ end }} {{ if eq $group $currentGroup }}
{{ range $monitors }}
<tr>
<th scope="row"></th>
<th scope="row">
{{ .Name }}
</th>
<td>
{{ range .WorkerGroups }}
<span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800"
>
{{ . }}
</span>
{{ end }}
</td>
<td>
{{ if eq .Status "ACTIVE" }}
<span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800"
>
ACTIVE
</span>
{{ else if eq .Status "PAUSED" }}
<span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800"
>
PAUSED
</span>
{{ else }}
<span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800"
>
UNKNOWN
</span>
{{ end }}
</td>
<td>
{{ .Schedule }}
</td>
<td>
<a href="/settings/monitors/{{ .Id }}" class="link"
>Details</a
>
</td>
</tr>
{{ end }}
{{ end }}
{{ end }}
{{ end }}
</tbody>
</table> </table>
</section> </section>
{{ end }} {{ end }}

View file

@ -2,8 +2,20 @@
<section class="p-5"> <section class="p-5">
<form action="/settings/monitors/create" method="post"> <form action="/settings/monitors/create" method="post">
<label for="name">Name</label> <label for="name">Name</label>
<input type="name" name="name" id="name" placeholder="Github.com" /> <input type="text" name="name" id="name" placeholder="Github.com" />
<p>Name of the monitor can be anything.</p> <p>Name of the monitor can be anything.</p>
<label for="group">Group</label>
<input
type="text"
name="group"
id="group"
placeholder="default"
value="default"
/>
<p>
Group monitors together. This affects how they are presented on the
homepage.
</p>
<label for="workergroups">Worker Groups</label> <label for="workergroups">Worker Groups</label>
<input <input
type="text" type="text"

View file

@ -2,6 +2,12 @@
<section class="p-5"> <section class="p-5">
<form action="/settings/monitors/{{ .Monitor.Id }}" method="post"> <form action="/settings/monitors/{{ .Monitor.Id }}" method="post">
<h2>Configuration</h2> <h2>Configuration</h2>
<label for="group">Group</label>
<input type="text" name="group" id="group" value="{{ .Monitor.Group }}" />
<p>
Group monitors together. This affects how they are presented on the
homepage.
</p>
<label for="workergroups">Worker Groups</label> <label for="workergroups">Worker Groups</label>
<input <input
type="text" type="text"

View file

@ -56,8 +56,8 @@
<th>Action</th> <th>Action</th>
</tr> </tr>
</thead> </thead>
{{ range .WorkerGroups }} <tbody>
<tbody> {{ range .WorkerGroups }}
<tr> <tr>
<th scope="row"> <th scope="row">
{{ .Name }} {{ .Name }}
@ -86,8 +86,8 @@
> >
</td> </td>
</tr> </tr>
</tbody> {{ end }}
{{ end }} </tbody>
</table> </table>
</section> </section>
{{ end }} {{ end }}