Skip to content

Commit e087c24

Browse files
authored
Replace custom views instead of appending them
resolves #1324
1 parent 5b5212b commit e087c24

File tree

7 files changed

+71
-23
lines changed

7 files changed

+71
-23
lines changed

spring-boot-admin-docs/src/main/asciidoc/customizing.adoc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,10 @@ Registering the instance view works like for the top-level view with some additi
109109
include::{samples-dir}/spring-boot-admin-sample-custom-ui/src/index.js[tags=customization-ui-endpoint]
110110
----
111111
<1> The parent must be 'instances' in order to render the new custom view for a single instance.
112-
<2> If you add a `isEnabled` callback you can figure out dynamically if the view should be show for the particular instance.
112+
<2> You can group views by assigning them to a group.
113+
<3> If you add a `isEnabled` callback you can figure out dynamically if the view should be show for the particular instance.
114+
115+
NOTE: You can override default views by putting the same group and name as the one you want to override.
113116

114117
=== Customizing Header Logo and Title ===
115118
You can set custom information in the header (i.e. displaying staging information or company name) by using following configuration properties:

spring-boot-admin-samples/spring-boot-admin-sample-custom-ui/src/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ SBA.use({
4141
path: 'custom',
4242
component: customEndpoint,
4343
label: 'Custom',
44+
group: 'Group', // <2>
4445
order: 1000,
45-
isEnabled: ({instance}) => instance.hasEndpoint('custom') // <2>
46+
isEnabled: ({instance}) => instance.hasEndpoint('custom') // <3>
4647
});
4748
}
4849
});

spring-boot-admin-server-ui/babel.config.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,10 @@
1717
module.exports = {
1818
presets: [
1919
'@vue/cli-plugin-babel/preset'
20-
]
20+
],
21+
env: {
22+
test: {
23+
plugins: ['babel-plugin-transform-require-context']
24+
}
25+
}
2126
};

spring-boot-admin-server-ui/package-lock.json

Lines changed: 14 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

spring-boot-admin-server-ui/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"babel-core": "7.0.0-bridge.0",
5353
"babel-eslint": "^10.1.0",
5454
"babel-jest": "^24.9.0",
55+
"babel-plugin-transform-require-context": "^0.1.1",
5556
"eslint": "^6.8.0",
5657
"eslint-plugin-vue": "^6.2.2",
5758
"html-loader": "^0.5.5",

spring-boot-admin-server-ui/src/main/frontend/viewRegistry.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
import {VIEW_GROUP} from './views';
1818

19+
import remove from 'lodash/remove';
20+
1921
const createTextVNode = (label) => {
2022
return {
2123
render() {
@@ -64,6 +66,12 @@ export default class ViewRegistry {
6466
this._views.push(view);
6567
}
6668

69+
_removeExistingView(view) {
70+
remove(this._views, (v) => {
71+
return v.name === view.name && v.group === view.group
72+
});
73+
}
74+
6775
_toRoutes(views, filter) {
6876
return views.filter(filter).map(
6977
p => {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2014-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import ViewRegistry from "./viewRegistry";
18+
19+
describe('viewRegistry', () => {
20+
describe('given view already in the registry', function () {
21+
22+
23+
it('it should replace the existing one', async () => {
24+
const viewRegistry = new ViewRegistry();
25+
26+
viewRegistry.addView(...[
27+
{name: 'view', group: 'group'},
28+
{name: 'duplicateView', group: 'group'},
29+
{name: 'duplicateView', group: 'group'}
30+
])
31+
32+
expect(viewRegistry.views).toHaveLength(2);
33+
});
34+
35+
});
36+
});

0 commit comments

Comments
 (0)