mirror of
https://github.com/mentos1386/zdravko.git
synced 2024-11-25 00:58:07 +00:00
feat: ui, logger and other general improvements
This commit is contained in:
parent
4afb709b87
commit
b68c348f2a
10 changed files with 143 additions and 132 deletions
|
@ -2,7 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"log"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -20,7 +20,19 @@ type StartableAndStoppable interface {
|
||||||
Stop() error
|
Stop() error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setupLogger() {
|
||||||
|
opts := &slog.HandlerOptions{
|
||||||
|
Level: slog.LevelDebug,
|
||||||
|
}
|
||||||
|
|
||||||
|
logger := slog.New(slog.NewTextHandler(os.Stdout, opts))
|
||||||
|
|
||||||
|
slog.SetDefault(logger)
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
setupLogger()
|
||||||
|
|
||||||
var startServer bool
|
var startServer bool
|
||||||
var startWorker bool
|
var startWorker bool
|
||||||
var startTemporal bool
|
var startTemporal bool
|
||||||
|
@ -28,47 +40,47 @@ func main() {
|
||||||
flag.BoolVar(&startServer, "server", false, "Start the server")
|
flag.BoolVar(&startServer, "server", false, "Start the server")
|
||||||
flag.BoolVar(&startWorker, "worker", false, "Start the worker")
|
flag.BoolVar(&startWorker, "worker", false, "Start the worker")
|
||||||
flag.BoolVar(&startTemporal, "temporal", false, "Start the temporal")
|
flag.BoolVar(&startTemporal, "temporal", false, "Start the temporal")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
println("Starting zdravko...")
|
slog.Info("Starting zdravko...", "server", startServer, "worker", startWorker, "temporal", startTemporal)
|
||||||
println("Server: ", startServer)
|
|
||||||
println("Worker: ", startWorker)
|
|
||||||
println("Temporal: ", startTemporal)
|
|
||||||
|
|
||||||
if !startServer && !startWorker && !startTemporal {
|
if !startServer && !startWorker && !startTemporal {
|
||||||
log.Fatal("At least one of the following must be set: --server, --worker, --temporal")
|
slog.Error("At least one of the following must be set: --server, --worker, --temporal")
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
var servers [3]StartableAndStoppable
|
var servers [3]StartableAndStoppable
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
if startTemporal {
|
if startTemporal {
|
||||||
log.Println("Setting up Temporal")
|
slog.Info("Setting up Temporal")
|
||||||
cfg := config.NewTemporalConfig()
|
cfg := config.NewTemporalConfig()
|
||||||
temporal, err := temporal.NewTemporal(cfg)
|
temporal, err := temporal.NewTemporal(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Unable to create temporal: %v", err)
|
slog.Error("Unable to create temporal", "error", err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
servers[0] = temporal
|
servers[0] = temporal
|
||||||
}
|
}
|
||||||
|
|
||||||
if startServer {
|
if startServer {
|
||||||
log.Println("Setting up Server")
|
slog.Info("Setting up Server")
|
||||||
cfg := config.NewServerConfig()
|
cfg := config.NewServerConfig()
|
||||||
server, err := server.NewServer(cfg)
|
server, err := server.NewServer(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Unable to create server: %v", err)
|
slog.Error("Unable to create server", "error", err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
servers[1] = server
|
servers[1] = server
|
||||||
}
|
}
|
||||||
|
|
||||||
if startWorker {
|
if startWorker {
|
||||||
log.Println("Setting up Worker")
|
slog.Info("Setting up Worker")
|
||||||
cfg := config.NewWorkerConfig()
|
cfg := config.NewWorkerConfig()
|
||||||
worker, err := worker.NewWorker(cfg)
|
worker, err := worker.NewWorker(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Unable to create worker: %v", err)
|
slog.Error("Unable to create worker", "error", err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
servers[2] = worker
|
servers[2] = worker
|
||||||
}
|
}
|
||||||
|
@ -79,13 +91,14 @@ func main() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
println("Starting", srv.Name())
|
slog.Info("Starting", "name", srv.Name())
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
err := srv.Start()
|
err := srv.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Unable to start %s: %v", srv.Name(), err)
|
slog.Error("Unable to start", "name", srv.Name(), "error", err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
@ -94,16 +107,16 @@ func main() {
|
||||||
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
|
||||||
go func() {
|
go func() {
|
||||||
for sig := range c {
|
for sig := range c {
|
||||||
log.Printf("Received signal: %v", sig)
|
slog.Info("Received signal", "signal", sig)
|
||||||
for _, srv := range servers {
|
for _, srv := range servers {
|
||||||
if srv == nil {
|
if srv == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
println("Stopping", srv.Name())
|
slog.Info("Stopping", "name", srv.Name())
|
||||||
err := srv.Stop()
|
err := srv.Stop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Unable to stop server %s: %v", srv.Name(), err)
|
slog.Error("Unable to stop server", "name", srv.Name(), "error", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ func NewServer(cfg *config.ServerConfig) (*Server, error) {
|
||||||
return &Server{
|
return &Server{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
echo: echo.New(),
|
echo: echo.New(),
|
||||||
logger: slog.Default().WithGroup("server"),
|
logger: slog.Default(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,12 @@ func (s *Server) Start() error {
|
||||||
|
|
||||||
s.worker = NewWorker(temporalClient, s.cfg, s.logger, sqliteDb, kvStore)
|
s.worker = NewWorker(temporalClient, s.cfg, s.logger, sqliteDb, kvStore)
|
||||||
|
|
||||||
s.echo.Renderer = templates.NewTemplates()
|
templates, err := templates.NewTemplates(s.logger)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to create templates")
|
||||||
|
}
|
||||||
|
s.echo.Renderer = templates
|
||||||
|
|
||||||
s.echo.Use(middleware.Logger())
|
s.echo.Use(middleware.Logger())
|
||||||
s.echo.Use(middleware.Recover())
|
s.echo.Use(middleware.Recover())
|
||||||
s.echo.Use(middleware.Secure())
|
s.echo.Use(middleware.Secure())
|
||||||
|
|
|
@ -66,7 +66,7 @@ type Worker struct {
|
||||||
func NewWorker(cfg *config.WorkerConfig) (*Worker, error) {
|
func NewWorker(cfg *config.WorkerConfig) (*Worker, error) {
|
||||||
return &Worker{
|
return &Worker{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
logger: slog.Default().WithGroup("worker"),
|
logger: slog.Default(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,18 +82,18 @@ code {
|
||||||
background: repeating-linear-gradient(
|
background: repeating-linear-gradient(
|
||||||
0deg,
|
0deg,
|
||||||
var(--color-orange-300),
|
var(--color-orange-300),
|
||||||
var(--color-orange-300) 10%,
|
var(--color-orange-300) 33%,
|
||||||
var(--color-orange-400) 10%,
|
var(--color-orange-400) 33%,
|
||||||
var(--color-orange-400) 20%
|
var(--color-orange-400) 66%
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#page-index .history.degraded:hover > .bar {
|
#page-index .history.degraded:hover > .bar {
|
||||||
background: repeating-linear-gradient(
|
background: repeating-linear-gradient(
|
||||||
0deg,
|
0deg,
|
||||||
var(--color-orange-400),
|
var(--color-orange-400),
|
||||||
var(--color-orange-400) 10%,
|
var(--color-orange-400) 33%,
|
||||||
var(--color-orange-500) 10%,
|
var(--color-orange-500) 33%,
|
||||||
var(--color-orange-500) 20%
|
var(--color-orange-500) 66%
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1020,10 +1020,6 @@ video {
|
||||||
height: min-content;
|
height: min-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.w-12 {
|
|
||||||
width: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w-20 {
|
.w-20 {
|
||||||
width: 5rem;
|
width: 5rem;
|
||||||
}
|
}
|
||||||
|
@ -1386,16 +1382,16 @@ 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;
|
||||||
|
@ -1514,6 +1510,11 @@ video {
|
||||||
color: rgb(107 33 168 / var(--tw-text-opacity));
|
color: rgb(107 33 168 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-red-500 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(239 68 68 / var(--tw-text-opacity));
|
||||||
|
}
|
||||||
|
|
||||||
.text-red-600 {
|
.text-red-600 {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(220 38 38 / var(--tw-text-opacity));
|
color: rgb(220 38 38 / var(--tw-text-opacity));
|
||||||
|
@ -1743,9 +1744,9 @@ code {
|
||||||
background: repeating-linear-gradient(
|
background: repeating-linear-gradient(
|
||||||
0deg,
|
0deg,
|
||||||
var(--color-orange-300),
|
var(--color-orange-300),
|
||||||
var(--color-orange-300) 10%,
|
var(--color-orange-300) 33%,
|
||||||
var(--color-orange-400) 10%,
|
var(--color-orange-400) 33%,
|
||||||
var(--color-orange-400) 20%
|
var(--color-orange-400) 66%
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1753,9 +1754,9 @@ code {
|
||||||
background: repeating-linear-gradient(
|
background: repeating-linear-gradient(
|
||||||
0deg,
|
0deg,
|
||||||
var(--color-orange-400),
|
var(--color-orange-400),
|
||||||
var(--color-orange-400) 10%,
|
var(--color-orange-400) 33%,
|
||||||
var(--color-orange-500) 10%,
|
var(--color-orange-500) 33%,
|
||||||
var(--color-orange-500) 20%
|
var(--color-orange-500) 66%
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2133,8 +2134,8 @@ code {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sm\:justify-evenly {
|
.sm\:justify-between {
|
||||||
justify-content: space-evenly;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sm\:px-8 {
|
.sm\:px-8 {
|
||||||
|
|
|
@ -17,8 +17,12 @@
|
||||||
<link rel="stylesheet" href="/static/css/tailwind.css" />
|
<link rel="stylesheet" href="/static/css/tailwind.css" />
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-gray-100 flex flex-col">
|
<body class="bg-gray-100 flex flex-col">
|
||||||
<header class="flex flex-col sm:flex-row items-center sm:justify-evenly p-4 gap-2">
|
<header
|
||||||
<a href="/" class="text-2xl font-bold">zdravko.mnts.dev</a>
|
class="container max-w-screen-md flex flex-col sm:flex-row items-center sm:justify-between p-4 gap-2"
|
||||||
|
>
|
||||||
|
<a href="/" class="hover:underline text-2xl font-bold"
|
||||||
|
>zdravko.mnts.dev</a
|
||||||
|
>
|
||||||
<nav class="navbar flex sm:flex-row flex-col flex-wrap space-x-2 gap-1">
|
<nav class="navbar flex sm:flex-row flex-col flex-wrap space-x-2 gap-1">
|
||||||
{{ range .Navbar }}
|
{{ range .Navbar }}
|
||||||
<a
|
<a
|
||||||
|
@ -31,21 +35,28 @@
|
||||||
</a>
|
</a>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</nav>
|
</nav>
|
||||||
<img
|
|
||||||
src="https://avatars.githubusercontent.com/u/1910649?v=4"
|
|
||||||
alt="Profile Image"
|
|
||||||
class="rounded-full w-12 h-12"
|
|
||||||
></img>
|
|
||||||
</header>
|
</header>
|
||||||
{{ template "main" . }}
|
{{ template "main" . }}
|
||||||
<div class="container mx-auto">
|
<div class="container mx-auto">
|
||||||
<footer class="text-center text-gray-600 text-xs mt-8 mb-4">
|
<footer class="text-center text-gray-600 text-xs mt-8 mb-4">
|
||||||
© {{ Now.UTC.Year }} Zdravko -
|
Powered by
|
||||||
|
<a class="hover:underline" href="https://zdravko.mnts.dev">Zdravko</a>
|
||||||
|
-
|
||||||
<a
|
<a
|
||||||
class="hover:underline"
|
class="hover:underline"
|
||||||
href="https://github.com/mentos1386/zdravko"
|
href="https://github.com/mentos1386/zdravko"
|
||||||
>Open Source</a
|
>Open Source</a
|
||||||
>
|
>
|
||||||
|
- Made with <span class="text-red-500">❤</span> by
|
||||||
|
<a class="hover:underline" href="https://mnts.dev/about"
|
||||||
|
>Mentos1386</a
|
||||||
|
>
|
||||||
|
and
|
||||||
|
<a
|
||||||
|
class="hover:underline"
|
||||||
|
href="https://github.com/mentos1386/zdravko/graphs/contributors"
|
||||||
|
>others</a
|
||||||
|
>.
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
<script src="/static/js/htmx.min.js"></script>
|
<script src="/static/js/htmx.min.js"></script>
|
||||||
|
|
0
web/templates/components/footer.tmpl
Normal file
0
web/templates/components/footer.tmpl
Normal file
0
web/templates/components/head.tmpl
Normal file
0
web/templates/components/head.tmpl
Normal file
|
@ -1,4 +1,22 @@
|
||||||
{{ define "main" }}
|
{{ define "main" }}
|
||||||
|
{{ $outcomeText := "All services are online." }}
|
||||||
|
{{ $outcomeIcon := "check" }}
|
||||||
|
{{ $outcomeColor := "bg-green-300" }}
|
||||||
|
{{ if eq .Outcome "DOWN" }}
|
||||||
|
{{ $outcomeText = "Some services are down." }}
|
||||||
|
{{ $outcomeIcon = "alert-circle" }}
|
||||||
|
{{ $outcomeColor = "bg-red-300" }}
|
||||||
|
{{ else if eq .Outcome "DEGRADED" }}
|
||||||
|
{{ $outcomeText = "Some services are degraded." }}
|
||||||
|
{{ $outcomeIcon = "alert-triangle" }}
|
||||||
|
{{ $outcomeColor = "bg-orange-300" }}
|
||||||
|
{{ else }}
|
||||||
|
{{ $outcomeText = "We are unable to determine current status." }}
|
||||||
|
{{ $outcomeIcon = "help-circle" }}
|
||||||
|
{{ $outcomeColor = "bg-gray-300" }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
id="page-index"
|
id="page-index"
|
||||||
class="container max-w-screen-md flex flex-col mt-20 gap-20"
|
class="container max-w-screen-md flex flex-col mt-20 gap-20"
|
||||||
|
@ -32,61 +50,21 @@
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{{ else }}
|
{{ else }}
|
||||||
{{ if eq .Outcome "HEALTHY" }}
|
<div class="flex flex-col items-center">
|
||||||
<div class="flex flex-col items-center">
|
<svg
|
||||||
<svg
|
class="feather h-20 w-20 rounded-full {{ $outcomeColor }} p-4 overflow-visible"
|
||||||
class="feather h-20 w-20 rounded-full bg-green-300 p-4 overflow-visible"
|
>
|
||||||
>
|
<use href="/static/icons/feather-sprite.svg#{{ $outcomeIcon }}" />
|
||||||
<use href="/static/icons/feather-sprite.svg#check" />
|
</svg>
|
||||||
</svg>
|
<h1 class="text-gray-800 mt-4 text-xl font-bold">
|
||||||
<h1 class="text-gray-700 mt-4 text-lg">All services are online</h1>
|
{{ $outcomeText }}
|
||||||
<p class="text-gray-700 text-sm">
|
</h1>
|
||||||
Last updated on
|
<p class="text-gray-700 text-sm">
|
||||||
{{ Now.UTC.Format "Jan 02 at 15:04 MST" }}
|
Last updated on
|
||||||
</p>
|
{{ Now.UTC.Format "Jan 02 at 15:04 MST" }}
|
||||||
</div>
|
</p>
|
||||||
{{ else if eq .Outcome "UNKNOWN" }}
|
</div>
|
||||||
<div class="flex flex-col items-center">
|
|
||||||
<svg
|
|
||||||
class="feather h-20 w-20 rounded-full bg-gray-300 p-4 overflow-visible"
|
|
||||||
>
|
|
||||||
<use href="/static/icons/feather-sprite.svg#help-circle" />
|
|
||||||
</svg>
|
|
||||||
<h1 class="text-gray-700 mt-4 text-lg">
|
|
||||||
We are unable to determine current status
|
|
||||||
</h1>
|
|
||||||
<p class="text-gray-700 text-sm">
|
|
||||||
Last updated on
|
|
||||||
{{ Now.UTC.Format "Jan 02 at 15:04 MST" }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{{ else if eq .Outcome "DOWN" }}
|
|
||||||
<div class="flex flex-col items-center">
|
|
||||||
<svg
|
|
||||||
class="feather h-20 w-20 rounded-full bg-red-300 p-4 overflow-visible"
|
|
||||||
>
|
|
||||||
<use href="/static/icons/feather-sprite.svg#alert-circle" />
|
|
||||||
</svg>
|
|
||||||
<h1 class="text-gray-700 mt-4 text-lg">Some services are down</h1>
|
|
||||||
<p class="text-gray-700 text-sm">
|
|
||||||
Last updated on
|
|
||||||
{{ Now.UTC.Format "Jan 02 at 15:04 MST" }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{{ else if eq .Outcome "DEGRADED" }}
|
|
||||||
<div class="flex flex-col items-center">
|
|
||||||
<svg
|
|
||||||
class="feather h-20 w-20 rounded-full bg-orange-300 p-4 overflow-visible"
|
|
||||||
>
|
|
||||||
<use href="/static/icons/feather-sprite.svg#alert-triangle" />
|
|
||||||
</svg>
|
|
||||||
<h1 class="text-gray-700 mt-4 text-lg">Degraded services</h1>
|
|
||||||
<p class="text-gray-700 text-sm">
|
|
||||||
Last updated on
|
|
||||||
{{ Now.UTC.Format "Jan 02 at 15:04 MST" }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
<div class="targets flex flex-col gap-4">
|
<div class="targets flex flex-col gap-4">
|
||||||
<div
|
<div
|
||||||
class="inline-flex gap-1 justify-center md:justify-end time-range"
|
class="inline-flex gap-1 justify-center md:justify-end time-range"
|
||||||
|
|
|
@ -3,7 +3,8 @@ package templates
|
||||||
import (
|
import (
|
||||||
"embed"
|
"embed"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"io/fs"
|
||||||
|
"log/slog"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
@ -18,6 +19,7 @@ var templates embed.FS
|
||||||
const base = "components/base.tmpl"
|
const base = "components/base.tmpl"
|
||||||
|
|
||||||
type Templates struct {
|
type Templates struct {
|
||||||
|
logger *slog.Logger
|
||||||
templates map[string]*template.Template
|
templates map[string]*template.Template
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,40 +54,41 @@ func loadSettings(files ...string) *template.Template {
|
||||||
return load(files...)
|
return load(files...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTemplates() *Templates {
|
func NewTemplates(logger *slog.Logger) (*Templates, error) {
|
||||||
return &Templates{
|
t := Templates{
|
||||||
templates: map[string]*template.Template{
|
logger: logger,
|
||||||
"404.tmpl": load("pages/404.tmpl"),
|
templates: map[string]*template.Template{},
|
||||||
"index.tmpl": load("pages/index.tmpl"),
|
|
||||||
"incidents.tmpl": load("pages/incidents.tmpl"),
|
|
||||||
"settings_home.tmpl": loadSettings("pages/settings_home.tmpl"),
|
|
||||||
"settings_triggers.tmpl": loadSettings("pages/settings_triggers.tmpl"),
|
|
||||||
"settings_triggers_create.tmpl": loadSettings("pages/settings_triggers_create.tmpl"),
|
|
||||||
"settings_triggers_describe.tmpl": loadSettings("pages/settings_triggers_describe.tmpl"),
|
|
||||||
"settings_targets.tmpl": loadSettings("pages/settings_targets.tmpl"),
|
|
||||||
"settings_targets_create.tmpl": loadSettings("pages/settings_targets_create.tmpl"),
|
|
||||||
"settings_targets_describe.tmpl": loadSettings("pages/settings_targets_describe.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"),
|
|
||||||
"settings_checks.tmpl": loadSettings("pages/settings_checks.tmpl"),
|
|
||||||
"settings_checks_create.tmpl": loadSettings("pages/settings_checks_create.tmpl"),
|
|
||||||
"settings_checks_describe.tmpl": loadSettings("pages/settings_checks_describe.tmpl"),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err := fs.WalkDir(templates, "pages", func(path string, d fs.DirEntry, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if strings.Contains(path, ".tmpl") {
|
||||||
|
t.logger.Debug("Loading template", "path", path)
|
||||||
|
pathWithoutPrefix := strings.TrimPrefix(path, "pages/")
|
||||||
|
|
||||||
|
if strings.Contains(path, "settings") {
|
||||||
|
t.templates[pathWithoutPrefix] = loadSettings(path)
|
||||||
|
} else {
|
||||||
|
t.templates[pathWithoutPrefix] = load(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
return &t, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Templates) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
|
func (t *Templates) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
|
||||||
if t.templates[name] == nil {
|
if t.templates[name] == nil {
|
||||||
log.Printf("template not found: %s", name)
|
t.logger.Error("template not found", "template", name)
|
||||||
return echo.ErrNotFound
|
return echo.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
err := t.templates[name].ExecuteTemplate(w, "base", data)
|
err := t.templates[name].ExecuteTemplate(w, "base", data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error rendering template: %s", err)
|
t.logger.Error("error rendering template", "template", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
|
Loading…
Reference in a new issue