mirror of
https://github.com/TwiN/gatus.git
synced 2025-01-20 04:48:36 +01:00
feat(ui): Implement Custom CSS configuration (#943)
* feat(ui): Implement Custom CSS configuration * Update web/app/public/index.html
This commit is contained in:
parent
78c9a1bd41
commit
efbb739a44
@ -238,6 +238,7 @@ If you want to test it locally, see [Docker](#docker).
|
|||||||
| `ui.buttons` | List of buttons to display below the header. | `[]` |
|
| `ui.buttons` | List of buttons to display below the header. | `[]` |
|
||||||
| `ui.buttons[].name` | Text to display on the button. | Required `""` |
|
| `ui.buttons[].name` | Text to display on the button. | Required `""` |
|
||||||
| `ui.buttons[].link` | Link to open when the button is clicked. | Required `""` |
|
| `ui.buttons[].link` | Link to open when the button is clicked. | Required `""` |
|
||||||
|
| `ui.custom-css` | Custom CSS | `""` |
|
||||||
| `maintenance` | [Maintenance configuration](#maintenance). | `{}` |
|
| `maintenance` | [Maintenance configuration](#maintenance). | `{}` |
|
||||||
|
|
||||||
If you want more verbose logging, you may set the `GATUS_LOG_LEVEL` environment variable to `DEBUG`.
|
If you want more verbose logging, you may set the `GATUS_LOG_LEVEL` environment variable to `DEBUG`.
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/TwiN/gatus/v5/config"
|
"github.com/TwiN/gatus/v5/config"
|
||||||
|
"github.com/TwiN/gatus/v5/config/ui"
|
||||||
"github.com/TwiN/gatus/v5/config/web"
|
"github.com/TwiN/gatus/v5/config/web"
|
||||||
static "github.com/TwiN/gatus/v5/web"
|
static "github.com/TwiN/gatus/v5/web"
|
||||||
"github.com/TwiN/health"
|
"github.com/TwiN/health"
|
||||||
@ -31,6 +32,10 @@ func New(cfg *config.Config) *API {
|
|||||||
logr.Warnf("[api.New] nil web config passed as parameter. This should only happen in tests. Using default web configuration")
|
logr.Warnf("[api.New] nil web config passed as parameter. This should only happen in tests. Using default web configuration")
|
||||||
cfg.Web = web.GetDefaultConfig()
|
cfg.Web = web.GetDefaultConfig()
|
||||||
}
|
}
|
||||||
|
if cfg.UI == nil {
|
||||||
|
logr.Warnf("[api.New] nil ui config passed as parameter. This should only happen in tests. Using default ui configuration")
|
||||||
|
cfg.UI = ui.GetDefaultConfig()
|
||||||
|
}
|
||||||
api.router = api.createRouter(cfg)
|
api.router = api.createRouter(cfg)
|
||||||
return api
|
return api
|
||||||
}
|
}
|
||||||
@ -87,6 +92,8 @@ func (a *API) createRouter(cfg *config.Config) *fiber.App {
|
|||||||
statusCode, body := healthHandler.GetResponseStatusCodeAndBody()
|
statusCode, body := healthHandler.GetResponseStatusCodeAndBody()
|
||||||
return c.Status(statusCode).Send(body)
|
return c.Status(statusCode).Send(body)
|
||||||
})
|
})
|
||||||
|
// Custom CSS
|
||||||
|
app.Get("/css/custom.css", CustomCSSHandler{customCSS: cfg.UI.CustomCSS}.GetCustomCSS)
|
||||||
// Everything else falls back on static content
|
// Everything else falls back on static content
|
||||||
app.Use(redirect.New(redirect.Config{
|
app.Use(redirect.New(redirect.Config{
|
||||||
Rules: map[string]string{
|
Rules: map[string]string{
|
||||||
|
@ -25,6 +25,17 @@ func TestNew(t *testing.T) {
|
|||||||
Path: "/health",
|
Path: "/health",
|
||||||
ExpectedCode: fiber.StatusOK,
|
ExpectedCode: fiber.StatusOK,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "custom.css",
|
||||||
|
Path: "/css/custom.css",
|
||||||
|
ExpectedCode: fiber.StatusOK,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "custom.css-gzipped",
|
||||||
|
Path: "/css/custom.css",
|
||||||
|
ExpectedCode: fiber.StatusOK,
|
||||||
|
Gzip: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "metrics",
|
Name: "metrics",
|
||||||
Path: "/metrics",
|
Path: "/metrics",
|
||||||
|
14
api/custom_css.go
Normal file
14
api/custom_css.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CustomCSSHandler struct {
|
||||||
|
customCSS string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler CustomCSSHandler) GetCustomCSS(c *fiber.Ctx) error {
|
||||||
|
c.Set("Content-Type", "text/css")
|
||||||
|
return c.Status(200).SendString(handler.customCSS)
|
||||||
|
}
|
@ -14,6 +14,7 @@ const (
|
|||||||
defaultHeader = "Health Status"
|
defaultHeader = "Health Status"
|
||||||
defaultLogo = ""
|
defaultLogo = ""
|
||||||
defaultLink = ""
|
defaultLink = ""
|
||||||
|
defaultCustomCSS = ""
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -28,6 +29,7 @@ type Config struct {
|
|||||||
Logo string `yaml:"logo,omitempty"` // Logo to display on the page
|
Logo string `yaml:"logo,omitempty"` // Logo to display on the page
|
||||||
Link string `yaml:"link,omitempty"` // Link to open when clicking on the logo
|
Link string `yaml:"link,omitempty"` // Link to open when clicking on the logo
|
||||||
Buttons []Button `yaml:"buttons,omitempty"` // Buttons to display below the header
|
Buttons []Button `yaml:"buttons,omitempty"` // Buttons to display below the header
|
||||||
|
CustomCSS string `yaml:"custom-css,omitempty"` // Custom CSS to include in the page
|
||||||
}
|
}
|
||||||
|
|
||||||
// Button is the configuration for a button on the UI
|
// Button is the configuration for a button on the UI
|
||||||
@ -52,6 +54,7 @@ func GetDefaultConfig() *Config {
|
|||||||
Header: defaultHeader,
|
Header: defaultHeader,
|
||||||
Logo: defaultLogo,
|
Logo: defaultLogo,
|
||||||
Link: defaultLink,
|
Link: defaultLink,
|
||||||
|
CustomCSS: defaultCustomCSS,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,8 +69,14 @@ func (cfg *Config) ValidateAndSetDefaults() error {
|
|||||||
if len(cfg.Header) == 0 {
|
if len(cfg.Header) == 0 {
|
||||||
cfg.Header = defaultHeader
|
cfg.Header = defaultHeader
|
||||||
}
|
}
|
||||||
if len(cfg.Header) == 0 {
|
if len(cfg.Logo) == 0 {
|
||||||
cfg.Header = defaultLink
|
cfg.Logo = defaultLogo
|
||||||
|
}
|
||||||
|
if len(cfg.Link) == 0 {
|
||||||
|
cfg.Link = defaultLink
|
||||||
|
}
|
||||||
|
if len(cfg.CustomCSS) == 0 {
|
||||||
|
cfg.CustomCSS = defaultCustomCSS
|
||||||
}
|
}
|
||||||
for _, btn := range cfg.Buttons {
|
for _, btn := range cfg.Buttons {
|
||||||
if err := btn.Validate(); err != nil {
|
if err := btn.Validate(); err != nil {
|
||||||
@ -80,9 +89,5 @@ func (cfg *Config) ValidateAndSetDefaults() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
err = t.Execute(&buffer, cfg)
|
return t.Execute(&buffer, cfg)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
||||||
<link rel="manifest" href="/manifest.json" crossorigin="use-credentials" />
|
<link rel="manifest" href="/manifest.json" crossorigin="use-credentials" />
|
||||||
<link rel="shortcut icon" href="/favicon.ico" />
|
<link rel="shortcut icon" href="/favicon.ico" />
|
||||||
|
<link rel="stylesheet" href="/css/custom.css" />
|
||||||
<meta name="description" content="{{ .Description }}" />
|
<meta name="description" content="{{ .Description }}" />
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
<meta name="apple-mobile-web-app-title" content="{{ .Title }}" />
|
<meta name="apple-mobile-web-app-title" content="{{ .Title }}" />
|
||||||
|
@ -1 +1 @@
|
|||||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><script>window.config = {logo: "{{ .Logo }}", header: "{{ .Header }}", link: "{{ .Link }}", buttons: []};{{- range .Buttons}}window.config.buttons.push({name:"{{ .Name }}",link:"{{ .Link }}"});{{end}}</script><title>{{ .Title }}</title><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width,initial-scale=1"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json" crossorigin="use-credentials"/><link rel="shortcut icon" href="/favicon.ico"/><meta name="description" content="{{ .Description }}"/><meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/><meta name="apple-mobile-web-app-title" content="{{ .Title }}"/><meta name="application-name" content="{{ .Title }}"/><meta name="theme-color" content="#f7f9fb"/><script defer="defer" src="/js/chunk-vendors.js"></script><script defer="defer" src="/js/app.js"></script><link href="/css/app.css" rel="stylesheet"></head><body class="dark:bg-gray-900"><noscript><strong>Enable JavaScript to view this page.</strong></noscript><div id="app"></div></body></html>
|
<!doctype html><html lang="en"><head><meta charset="utf-8"/><script>window.config = {logo: "{{ .Logo }}", header: "{{ .Header }}", link: "{{ .Link }}", buttons: []};{{- range .Buttons}}window.config.buttons.push({name:"{{ .Name }}",link:"{{ .Link }}"});{{end}}</script><title>{{ .Title }}</title><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width,initial-scale=1"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json" crossorigin="use-credentials"/><link rel="shortcut icon" href="/favicon.ico"/><link rel="stylesheet" href="/css/custom.css"/><meta name="description" content="{{ .Description }}"/><meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/><meta name="apple-mobile-web-app-title" content="{{ .Title }}"/><meta name="application-name" content="{{ .Title }}"/><meta name="theme-color" content="#f7f9fb"/><script defer="defer" src="/js/chunk-vendors.js"></script><script defer="defer" src="/js/app.js"></script><link href="/css/app.css" rel="stylesheet"></head><body class="dark:bg-gray-900"><noscript><strong>Enable JavaScript to view this page.</strong></noscript><div id="app"></div></body></html>
|
Loading…
Reference in New Issue
Block a user