Skip to content

Commit 2c078e6

Browse files
authored
feat: implement ability to override serviceUrl and set hideUrl per instance (#4591)
1 parent ff45074 commit 2c078e6

File tree

13 files changed

+291
-122
lines changed

13 files changed

+291
-122
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
server:
2+
shutdown: immediate

spring-boot-admin-samples/spring-boot-admin-sample-servlet/src/main/resources/application.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,34 @@ management:
3434
enabled: true
3535
health:
3636
show-details: ALWAYS
37+
server:
38+
port: 9999
39+
3740

3841
spring:
3942
application:
4043
name: spring-boot-admin-sample-servlet
44+
cloud:
45+
discovery:
46+
client:
47+
simple:
48+
instances:
49+
SBA:
50+
- uri: http://localhost:9999
51+
metadata:
52+
management.context-path: /actuator
53+
service-url: http://localhost:8080
54+
service-path: /
4155
boot:
4256
admin:
4357
client:
4458
url: http://localhost:8080
4559
instance:
4660
service-host-type: IP
4761
metadata:
62+
service-path: /foo
63+
service-url: http://localhost:8080
64+
hide-url: true
4865
tags:
4966
environment: test
5067
de-service-test-1: A large content
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
server:
2+
shutdown: immediate

spring-boot-admin-server-ui/src/main/frontend/components/sba-button.vue

Lines changed: 83 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,101 @@
11
<template>
2-
<button
2+
<component
3+
:is="as"
34
class="btn relative"
4-
:class="cssClasses"
5-
:disabled="disabled === true"
6-
:title="title"
7-
@click="$emit('click', $event)"
5+
v-bind="componentAttrs"
6+
@click="handleClick"
87
>
98
<slot />
10-
</button>
9+
</component>
1110
</template>
1211

13-
<script>
14-
export default {
15-
name: 'SbaButton',
16-
props: {
17-
title: {
18-
type: String,
19-
default: '',
20-
},
21-
size: {
22-
type: String,
23-
default: 'sm',
24-
validate(value) {
25-
return ['xs', 'sm', 'base'].includes(value);
26-
},
27-
},
28-
disabled: {
29-
type: Boolean,
30-
default: false,
31-
},
32-
primary: {
33-
type: Boolean,
34-
default: false,
12+
<script setup>
13+
import classNames from 'classnames';
14+
import { computed, useAttrs } from 'vue';
15+
16+
const props = defineProps({
17+
title: {
18+
type: String,
19+
default: '',
20+
},
21+
as: {
22+
type: String,
23+
default: 'button',
24+
validator(value) {
25+
return ['a', 'button'].includes(value);
3526
},
3627
},
37-
emits: ['click'],
38-
computed: {
39-
cssClasses() {
40-
return {
41-
'px-2 py-2 text-xs': this.size === 'xs',
42-
'px-3 py-2': this.size === 'sm',
43-
'px-4 py-3': this.size === 'base',
44-
'px-5 py-2.5': this.size === '',
45-
// Types
46-
'is-primary': this.primary === true,
47-
};
28+
href: {
29+
type: String,
30+
default: null,
31+
},
32+
size: {
33+
type: String,
34+
default: 'sm',
35+
validator(value) {
36+
return ['xs', 'sm', 'base'].includes(value);
4837
},
4938
},
39+
disabled: {
40+
type: Boolean,
41+
default: false,
42+
},
43+
primary: {
44+
type: Boolean,
45+
default: false,
46+
},
47+
});
48+
const attrs = useAttrs();
49+
50+
const cssClasses = computed(() => {
51+
return {
52+
'px-1 py-0 text-xs': props.size === '2xs',
53+
'px-2 py-2 text-xs': props.size === 'xs',
54+
'px-3 py-2': props.size === 'sm',
55+
'px-4 py-3': props.size === 'base',
56+
'px-5 py-2.5': props.size === '',
57+
// Types
58+
'is-primary': props.primary === true,
59+
};
60+
});
61+
62+
const componentAttrs = computed(() => {
63+
const common = {
64+
...attrs,
65+
title: props.title,
66+
class: classNames(attrs.class, cssClasses.value),
67+
};
68+
69+
if (props.as === 'a') {
70+
return {
71+
...common,
72+
href: props.href,
73+
};
74+
}
75+
if (props.as === 'button') {
76+
return {
77+
...common,
78+
disabled: props.disabled === true,
79+
type: props.type,
80+
};
81+
}
82+
return {};
83+
});
84+
85+
const emit = defineEmits(['click']);
86+
const handleClick = (event) => {
87+
if (props.as === 'button') {
88+
emit('click', event);
89+
}
90+
if (props.as === 'a') {
91+
event.stopPropagation();
92+
}
5093
};
5194
</script>
5295

5396
<style scoped>
5497
.btn {
55-
@apply rounded-l rounded-r font-medium text-sm text-center text-black border-gray-300 border border-gray-300 bg-white;
98+
@apply rounded-l rounded-r font-medium text-sm text-center text-black border-gray-300 border bg-white;
5699
@apply focus:ring-2 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500;
57100
@apply hover:bg-gray-100;
58101
}

spring-boot-admin-server-ui/src/main/frontend/components/sba-tag.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
'py-1 border border-gray-300 bg-white': !small,
55
'py-1 border text-xs bg-white': small,
66
}"
7-
class="inline-flex leading-none rounded shadow-sm text-sm overflow-hidden"
7+
class="inline-flex leading-none rounded text-sm overflow-hidden"
88
>
99
<span
1010
v-if="label"

spring-boot-admin-server-ui/src/main/frontend/services/instance.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ class Instance {
5959
registerErrorToastInterceptor(this.axios);
6060
}
6161

62+
get metadata() {
63+
return this.registration.metadata;
64+
}
65+
6266
get isUnregisterable() {
6367
return this.registration.source === 'http-api';
6468
}

spring-boot-admin-server-ui/src/main/frontend/views/applications/ApplicationListItemAction.vue

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
:title="$t('applications.actions.journal')"
66
@click.stop="navigate"
77
>
8-
<font-awesome-icon icon="history" />
8+
<font-awesome-icon :icon="faHistory" />
99
</sba-button>
1010
</router-link>
1111
<sba-button
@@ -15,7 +15,7 @@
1515
@click.stop="$emit('filter-settings', item)"
1616
>
1717
<font-awesome-icon
18-
:icon="hasActiveNotificationFilter ? 'bell-slash' : 'bell'"
18+
:icon="hasActiveNotificationFilter ? faBellSlash : faBell"
1919
/>
2020
</sba-button>
2121
<sba-button
@@ -24,27 +24,35 @@
2424
:title="$t('applications.actions.unregister')"
2525
@click.stop="actionHandler.unregister(item)"
2626
>
27-
<font-awesome-icon :icon="'trash'" />
27+
<font-awesome-icon :icon="faTrash" />
2828
</sba-button>
2929
<sba-button
3030
v-if="item.hasEndpoint('restart')"
3131
:title="$t('applications.actions.restart')"
3232
@click.stop="actionHandler.restart(item)"
3333
>
34-
<font-awesome-icon icon="undo-alt" />
34+
<font-awesome-icon :icon="faUndoAlt" />
3535
</sba-button>
3636
<sba-button
3737
v-if="item.hasEndpoint('shutdown')"
3838
:title="$t('applications.actions.shutdown')"
3939
class="is-danger btn-shutdown"
4040
@click.stop="actionHandler.shutdown(item)"
4141
>
42-
<font-awesome-icon :icon="['fa', 'power-off']" />
42+
<font-awesome-icon :icon="faPowerOff" />
4343
</sba-button>
4444
</sba-button-group>
4545
</template>
4646

4747
<script lang="ts" setup>
48+
import {
49+
faBell,
50+
faBellSlash,
51+
faHistory,
52+
faPowerOff,
53+
faTrash,
54+
faUndoAlt,
55+
} from '@fortawesome/free-solid-svg-icons';
4856
import { useNotificationCenter } from '@stekoe/vue-toast-notificationcenter';
4957
import { inject } from 'vue';
5058
import { useI18n } from 'vue-i18n';

spring-boot-admin-server-ui/src/main/frontend/views/applications/InstancesList.vue

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,41 @@
3333
<div class="flex gap-2 items-center">
3434
<div class="flex-1">
3535
<template v-if="instance.showUrl()">
36-
<a
37-
:href="
38-
instance.registration.serviceUrl ||
39-
instance.registration.healthUrl
40-
"
41-
@click.stop
36+
<span
4237
v-text="
4338
instance.registration.serviceUrl ||
4439
instance.registration.healthUrl
4540
"
4641
/>
42+
<div class="ml-1 inline-flex gap-1">
43+
<sba-button
44+
as="a"
45+
:href="instance.registration.serviceUrl"
46+
size="2xs"
47+
referrerpolicy="no-referrer"
48+
target="_blank"
49+
>
50+
<font-awesome-icon :icon="faHome" size="xs" />
51+
</sba-button>
52+
<sba-button
53+
as="a"
54+
:href="instance.registration.managementUrl"
55+
size="2xs"
56+
referrerpolicy="no-referrer"
57+
target="_blank"
58+
>
59+
<font-awesome-icon :icon="faClipboardList" size="xs" />
60+
</sba-button>
61+
<sba-button
62+
as="a"
63+
:href="instance.registration.healthUrl"
64+
size="2xs"
65+
referrerpolicy="no-referrer"
66+
target="_blank"
67+
>
68+
<font-awesome-icon :icon="faHeart" size="xs" />
69+
</sba-button>
70+
</div>
4771
<sba-tag
4872
v-if="instance.registration.metadata?.['group']"
4973
class="ml-2"
@@ -77,9 +101,16 @@
77101
</template>
78102

79103
<script lang="ts" setup>
104+
import {
105+
faClipboardList,
106+
faHeart,
107+
faHome,
108+
} from '@fortawesome/free-solid-svg-icons';
109+
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
80110
import { PropType } from 'vue';
81111
import { useRouter } from 'vue-router';
82112
113+
import SbaButton from '@/components/sba-button.vue';
83114
import SbaStatus from '@/components/sba-status.vue';
84115
import SbaTag from '@/components/sba-tag.vue';
85116
import SbaTags from '@/components/sba-tags.vue';

0 commit comments

Comments
 (0)