feat(ui): Make logo link and header configurable

Closes #213
This commit is contained in:
TwiN 2022-01-08 14:55:40 -05:00
parent 0e586e4152
commit fc016bd682
9 changed files with 53 additions and 20 deletions

View File

@ -180,9 +180,11 @@ If you want to test it locally, see [Docker](#docker).
| `web.address` | Address to listen on. | `0.0.0.0` | | `web.address` | Address to listen on. | `0.0.0.0` |
| `web.port` | Port to listen on. | `8080` | | `web.port` | Port to listen on. | `8080` |
| `ui` | UI configuration. | `{}` | | `ui` | UI configuration. | `{}` |
| `ui.title` | Title of the page. | `Health Dashboard ǀ Gatus` | | `ui.title` | [Title of the document](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title). | `Health Dashboard ǀ Gatus` |
| `ui.logo` | URL to the logo to display | `""` | | `ui.header` | Header at the top of the dashboard. | `Health Status` |
| `Maintenance` | [Maintenance](#maintenance). | `{}` | | `ui.logo` | URL to the logo to display. | `""` |
| `ui.link` | Link to open when the logo is clicked. | `""` |
| `maintenance` | [Maintenance configuration](#maintenance). | `{}` |
### Conditions ### Conditions

View File

@ -7,7 +7,9 @@ import (
const ( const (
defaultTitle = "Health Dashboard | Gatus" defaultTitle = "Health Dashboard | Gatus"
defaultHeader = "Health Status"
defaultLogo = "" defaultLogo = ""
defaultLink = ""
) )
var ( var (
@ -18,15 +20,19 @@ var (
// Config is the configuration for the UI of Gatus // Config is the configuration for the UI of Gatus
type Config struct { type Config struct {
Title string `yaml:"title"` // Title of the page Title string `yaml:"title,omitempty"` // Title of the page
Logo string `yaml:"logo"` // Logo to display on the page Header string `yaml:"header,omitempty"` // Header is the text at the top of 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
} }
// GetDefaultConfig returns a Config struct with the default values // GetDefaultConfig returns a Config struct with the default values
func GetDefaultConfig() *Config { func GetDefaultConfig() *Config {
return &Config{ return &Config{
Title: defaultTitle, Title: defaultTitle,
Header: defaultHeader,
Logo: defaultLogo, Logo: defaultLogo,
Link: defaultLink,
} }
} }
@ -35,6 +41,12 @@ func (cfg *Config) ValidateAndSetDefaults() error {
if len(cfg.Title) == 0 { if len(cfg.Title) == 0 {
cfg.Title = defaultTitle cfg.Title = defaultTitle
} }
if len(cfg.Header) == 0 {
cfg.Header = defaultHeader
}
if len(cfg.Header) == 0 {
cfg.Header = defaultLink
}
t, err := template.ParseFiles(StaticFolder + "/index.html") t, err := template.ParseFiles(StaticFolder + "/index.html")
if err != nil { if err != nil {
return err return err

View File

@ -9,10 +9,21 @@ func TestConfig_ValidateAndSetDefaults(t *testing.T) {
defer func() { defer func() {
StaticFolder = "./web/static" StaticFolder = "./web/static"
}() }()
cfg := &Config{Title: ""} cfg := &Config{
Title: "",
Header: "",
Logo: "",
Link: "",
}
if err := cfg.ValidateAndSetDefaults(); err != nil { if err := cfg.ValidateAndSetDefaults(); err != nil {
t.Error("expected no error, got", err.Error()) t.Error("expected no error, got", err.Error())
} }
if cfg.Title != defaultTitle {
t.Errorf("expected title to be %s, got %s", defaultTitle, cfg.Title)
}
if cfg.Header != defaultHeader {
t.Errorf("expected header to be %s, got %s", defaultHeader, cfg.Header)
}
} }
func TestGetDefaultConfig(t *testing.T) { func TestGetDefaultConfig(t *testing.T) {

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<script type="text/javascript"> <script type="text/javascript">
window.config = {logo: "{{ .Logo }}"}; window.config = {logo: "{{ .Logo }}", header: "{{ .Header }}", link: "{{ .Link }}"};
</script> </script>
<title>{{ .Title }}</title> <title>{{ .Title }}</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">

View File

@ -3,11 +3,13 @@
<div class="mb-2"> <div class="mb-2">
<div class="flex flex-wrap"> <div class="flex flex-wrap">
<div class="w-3/4 text-left my-auto"> <div class="w-3/4 text-left my-auto">
<div class="text-3xl xl:text-5xl lg:text-4xl font-light">Health Status</div> <div class="text-3xl xl:text-5xl lg:text-4xl font-light">{{ header }}</div>
</div> </div>
<div class="w-1/4 flex justify-end"> <div class="w-1/4 flex justify-end">
<img v-if="getLogo" :src="getLogo" alt="Gatus" class="object-scale-down" style="max-width: 100px; min-width: 50px; min-height:50px;"/> <a :href="link" target="_blank" style="width:100px">
<img v-if="logo" :src="logo" alt="Gatus" class="object-scale-down" style="max-width: 100px; min-width: 50px; min-height:50px;"/>
<img v-else src="./assets/logo.svg" alt="Gatus" class="object-scale-down" style="max-width: 100px; min-width: 50px; min-height:50px;"/> <img v-else src="./assets/logo.svg" alt="Gatus" class="object-scale-down" style="max-width: 100px; min-width: 50px; min-height:50px;"/>
</a>
</div> </div>
</div> </div>
</div> </div>
@ -57,8 +59,14 @@ export default {
} }
}, },
computed: { computed: {
getLogo() { logo() {
return window.config && window.config.logo && window.config.logo !== '{{ .Logo }}' ? window.config.logo : ""; return window.config && window.config.logo && window.config.logo !== '{{ .Logo }}' ? window.config.logo : "";
},
header() {
return window.config && window.config.header && window.config.header !== '{{ .Header }}' ? window.config.header : "Health Status";
},
link() {
return window.config && window.config.link && window.config.link !== '{{ .Link }}' ? window.config.link : null;
} }
}, },
data() { data() {

View File

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><script>window.config = {logo: "{{ .Logo }}"};</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="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="shortcut icon" href="/favicon.ico"/><meta property="description" content="Gatus is an advanced automated status page that lets you monitor your applications and configure alerts to notify you if there's an issue"/><script defer="defer" type="module" src="/js/chunk-vendors.js"></script><script defer="defer" type="module" src="/js/app.js"></script><link href="/css/app.css" rel="stylesheet"><script defer="defer" src="/js/chunk-vendors-legacy.js" nomodule></script><script defer="defer" src="/js/app-legacy.js" nomodule></script></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 }}"};</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="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="shortcut icon" href="/favicon.ico"/><meta property="description" content="Gatus is an advanced automated status page that lets you monitor your applications and configure alerts to notify you if there's an issue"/><script defer="defer" type="module" src="/js/chunk-vendors.js"></script><script defer="defer" type="module" src="/js/app.js"></script><link href="/css/app.css" rel="stylesheet"><script defer="defer" src="/js/chunk-vendors-legacy.js" nomodule></script><script defer="defer" src="/js/app-legacy.js" nomodule></script></head><body class="dark:bg-gray-900"><noscript><strong>Enable JavaScript to view this page.</strong></noscript><div id="app"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long