Commit b247a82d by Thomas Bosch Committed by Johannes Edmeier

Add customization for navbar and title

Using spring.boot.admin.ui.title/spring.boot.admin.ui.brand you can customise the page title and logo/title shown in the navbar closes #212
parent d7712b28
......@@ -98,9 +98,6 @@ Spring, Spring Boot and Spring Cloud are trademarks of [Pivotal Software, Inc.](
![Screenshot traces](/images/screenshot-trace.png)
*View http request traces*
![Screenshot hystrix](/images/screenshot-hystrix.png)
*View Hystrix dashboard*
![Screenshot journal](/images/screenshot-journal.png)
*View history of registered applications*
......
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
......@@ -38,6 +38,14 @@
| Headers not to be forwarded when making requests to clients.
| `"Cookie", "Set-Cookie", "Authorization"
| spring.boot.admin.ui.brand
| Brand to be shown in then navbar.
| `"<img src="assets/img/icon-spring-boot-admin.svg"><span>Spring Boot Admin</span>"`
| spring.boot.admin.ui.title
| Page-Title to be shown.
| `"Spring Boot Admin"`
|===
include::server-discovery.adoc[]
......
......@@ -60,19 +60,19 @@
}
},
"@babel/helper-module-imports": {
"version": "7.0.0-beta.49",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.49.tgz",
"integrity": "sha1-QdfVmJEBbEk0MqRvdGREZVKJDHU=",
"version": "7.0.0-beta.51",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.51.tgz",
"integrity": "sha1-zgBCgEX7t9XrwOp7+DV4nxU2arI=",
"dev": true,
"requires": {
"@babel/types": "7.0.0-beta.49",
"@babel/types": "7.0.0-beta.51",
"lodash": "^4.17.5"
},
"dependencies": {
"@babel/types": {
"version": "7.0.0-beta.49",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.49.tgz",
"integrity": "sha1-t+Oxw/TUz+Eb34yJ8e/V4WF7h6Y=",
"version": "7.0.0-beta.51",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.51.tgz",
"integrity": "sha1-2AK3tUO1g2x3iqaReXq/APPZfqk=",
"dev": true,
"requires": {
"esutils": "^2.0.2",
......@@ -984,9 +984,9 @@
"dev": true
},
"babel-plugin-lodash": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/babel-plugin-lodash/-/babel-plugin-lodash-3.3.3.tgz",
"integrity": "sha512-AyUjm1H3jCU3fdL6GHRW6hc8fTNAgZrvs5vk/LY/q6Z2yqpABdXB2JfEQq2dqCrhJkv7eZbUpRUu7hqBNZfZXw==",
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/babel-plugin-lodash/-/babel-plugin-lodash-3.3.4.tgz",
"integrity": "sha512-yDZLjK7TCkWl1gpBeBGmuaDIFhZKmkoL+Cu2MUUjv5VxUZx/z7tBGBCBcQs5RI1Bkz5LLmNdjx7paOyQtMovyg==",
"dev": true,
"requires": {
"@babel/helper-module-imports": "^7.0.0-beta.49",
......@@ -997,9 +997,9 @@
},
"dependencies": {
"@babel/types": {
"version": "7.0.0-beta.49",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.49.tgz",
"integrity": "sha1-t+Oxw/TUz+Eb34yJ8e/V4WF7h6Y=",
"version": "7.0.0-beta.51",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.51.tgz",
"integrity": "sha1-2AK3tUO1g2x3iqaReXq/APPZfqk=",
"dev": true,
"requires": {
"esutils": "^2.0.2",
......@@ -13121,9 +13121,9 @@
"integrity": "sha512-/ffmsiVuPC8PsWcFkZngdpas19ABm5mh2wA7iDqcltyCTwlgZjHGeJYOXkBMo422iPwIcviOtrTCUpSfXmToLQ=="
},
"vue-clickaway": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/vue-clickaway/-/vue-clickaway-2.2.2.tgz",
"integrity": "sha512-25SpjXKetL06GLYoLoC8pqAV6Cur9cQ//2g35GRFBV4FgoljbZZjTINR8g2NuVXXDMLSUXaKx5dutgO4PaDE7A==",
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/vue-clickaway/-/vue-clickaway-2.2.1.tgz",
"integrity": "sha512-VArdx5/BGgvSU0vBIbhg0NFypL/nvQr77gUripnGHxzxrEfLADBnadhjGgBM+8l9Uj67SJHGfWUhDhmat47F7A==",
"requires": {
"loose-envify": "^1.2.0"
}
......
......@@ -45,7 +45,7 @@
"babel-eslint": "^8.2.3",
"babel-jest": "^23.0.1",
"babel-loader": "^7.1.4",
"babel-plugin-lodash": "^3.3.3",
"babel-plugin-lodash": "^3.3.4",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.7.0",
"babel-preset-stage-2": "^6.24.1",
......
......@@ -24,12 +24,17 @@
<meta name="theme-color" content="#42d3a5">
<link rel="shortcut icon" href="assets/img/favicon.png" type="image/png">
<link href="assets/css/sba-core.css" rel="stylesheet">
<title>Spring Boot Admin</title>
<title th:text="${uiSettings.title}">Spring Boot Admin</title>
</head>
<body>
<div id="app"></div>
<script th:inline="javascript">
var SBA = {
uiSettings: /*[[${uiSettings}]]*/ {}
}
</script>
<script lang="javascript" src="assets/js/vendors.js" defer></script>
<script lang="javascript" src="assets/js/sba-core.js" defer></script>
</body>
......
......@@ -61,6 +61,7 @@ new Vue({
render(h) {
return h(sbaShell, {
props: {
views: this.views,
applications: this.applications,
error: this.error
}
......
......@@ -17,7 +17,7 @@
<template>
<div class="instances">
<sba-instance-header :instance="instance" :application="application" :class="headerClass"/>
<sba-instance-tabs :views="instanceViews" :instance="instance" :application="application" :class="headerClass"/>
<sba-instance-tabs :views="views" :instance="instance" :application="application" :class="headerClass"/>
<router-view v-if="instance" :instance="instance"/>
</div>
</template>
......@@ -33,6 +33,10 @@
type: String,
required: true
},
views: {
type: Array,
default: () => []
},
applications: {
type: Array,
default: () => [],
......@@ -49,9 +53,6 @@
application() {
return this.applications.findApplicationForInstance(this.instanceId);
},
instanceViews() {
return this.$root.views.filter(view => view.name.lastIndexOf('instance/') === 0);
},
headerClass() {
if (!this.instance) {
return '';
......
......@@ -17,7 +17,7 @@
<template>
<div id="app">
<sba-navbar :views="mainViews" :applications="applications" :error="error"/>
<router-view :applications="applications" :error="error"/>
<router-view :views="subViews" :applications="applications" :error="error"/>
</div>
</template>
......@@ -26,6 +26,10 @@
export default {
props: {
views: {
type: Array,
default: () => []
},
applications: {
type: Array,
default: () => [],
......@@ -38,7 +42,14 @@
components: {sbaNavbar},
computed: {
mainViews() {
return this.$root.views.filter(view => view.name.lastIndexOf('/') < 0);
return this.views.filter(view => !view.name.includes('/'))
},
activeMainViewName() {
const idx = this.$route.name.indexOf('/');
return idx < 0 ? this.$route.name : this.$route.name.substr(0, idx);
},
subViews() {
return this.views.filter(view => view.name.includes(this.activeMainViewName))
}
}
}
......
......@@ -18,10 +18,7 @@
<nav id="navigation" class="navbar is-fixed-top">
<div class="container">
<div class="navbar-brand">
<router-link class="navbar-item logo" to="/">
<img src="assets/img/icon-spring-boot-admin.svg">
<span>Spring Boot Admin</span>
</router-link>
<router-link class="navbar-item logo" to="/" v-html="brand"/>
<div class="navbar-burger burger" @click.stop="showMenu = !showMenu">
<span/>
......@@ -52,7 +49,8 @@
<script>
export default {
data: () => ({
showMenu: false
showMenu: false,
brand: '<img src="assets/img/icon-spring-boot-admin.svg"><span>Spring Boot Admin</span>'
}),
props: {
views: {
......@@ -68,6 +66,12 @@
default: null
}
},
created() {
/* global SBA */
if (SBA && SBA.uiSettings) {
this.brand = SBA.uiSettings.brand || this.brand;
}
},
mounted() {
document.documentElement.classList.add('has-navbar-fixed-top');
},
......
......@@ -56,7 +56,9 @@ public class AdminServerUiAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public UiController homeUiController() {
return new UiController(adminServerProperties.getContextPath());
return new UiController(adminServerProperties.getContextPath(),
uiProperties.getTitle(),
uiProperties.getBrand());
}
@Bean
......
......@@ -38,6 +38,16 @@ public class AdminServerUiProperties {
*/
private String templateLocation = CLASSPATH_RESOURCE_LOCATIONS[0];
/**
* Page-Title to be shown.
*/
private String title = "Spring Boot Admin";
/**
* Brand to be shown in then navbar.
*/
private String brand = "<img src=\"assets/img/icon-spring-boot-admin.svg\"><span>Spring Boot Admin</span>";
private boolean cacheTemplates = true;
private final Cache cache = new Cache();
......@@ -55,6 +65,7 @@ public class AdminServerUiProperties {
* include "no-cache" directive in Cache-Control http header.
*/
private Boolean noCache = false;
/**
* include "no-store" directive in Cache-Control http header.
*/
......@@ -74,5 +85,4 @@ public class AdminServerUiProperties {
}
}
}
......@@ -18,6 +18,8 @@ package de.codecentric.boot.admin.server.ui.web;
import de.codecentric.boot.admin.server.web.AdminController;
import java.util.HashMap;
import java.util.Map;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
......@@ -25,9 +27,13 @@ import org.springframework.web.bind.annotation.ModelAttribute;
@AdminController
public class UiController {
private final String adminContextPath;
private final Map<String, Object> uiSettings;
public UiController(String adminContextPath) {
public UiController(String adminContextPath, String title, String brand) {
this.adminContextPath = adminContextPath;
this.uiSettings = new HashMap<>();
this.uiSettings.put("title", title);
this.uiSettings.put("brand", brand);
}
@ModelAttribute(value = "adminContextPath", binding = false)
......@@ -35,6 +41,11 @@ public class UiController {
return adminContextPath;
}
@ModelAttribute(value = "uiSettings", binding = false)
public Map<String, Object> getUiSettings() {
return uiSettings;
}
@GetMapping(path = "/", produces = MediaType.TEXT_HTML_VALUE)
public String index() {
return "index";
......@@ -44,5 +55,4 @@ public class UiController {
public String login() {
return "login";
}
}
......@@ -171,7 +171,6 @@ public class StatusUpdaterTest {
.thenCancel()
.verify();
StepVerifier.create(repository.find(instance.getId())).assertNext(app -> {
assertThat(app.getStatusInfo().getStatus()).isEqualTo("DOWN");
assertThat(app.getStatusInfo().getDetails()).containsEntry("status", 503)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment