Skip to content

Commit

Permalink
feat(#2589): allow to set or override group icons in the instance sid…
Browse files Browse the repository at this point in the history
…ebar (#2608)
  • Loading branch information
SteKoe authored Jul 7, 2023
1 parent 8a5266c commit 68d5e0c
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 27 deletions.
23 changes: 18 additions & 5 deletions spring-boot-admin-docs/src/site/asciidoc/customize_ui.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,34 @@ include::{samples-dir}/spring-boot-admin-sample-custom-ui/src/index.js[tags=cust
<1> Name of the view and the route.
<2> Path in Vue router.
<3> The imported custom component, which will be rendered on the route.
<4> The handle for the custom view to be shown in the top navigation bar.
<5> Order for the view.
<6> Using `i18n.mergeLocaleMessage` allows to add custom translations.
<4> An optional group name that allows to bind views to a logical group (defaults to "none")
<5> The handle for the custom view to be shown in the top navigation bar.
<6> Order for the view.
<7> Using `i18n.mergeLocaleMessage` allows to add custom translations.

Views in the top navigation bar are sorted by ascending order.

If new top level routes are added to the frontend, they also must be known to the backend.
Add a `/META-INF/spring-boot-admin-server-ui/extensions/{name}/routes.txt` with all your new toplevel routes (one route per line).

Groups are used in instance sidebar to aggregate multiple views into a collapsible menu entry showing the group's name.
When a group contains just a single element, the label of the view is shown instead of the group's name.

==== Override/Set custom group icons ====
In order to override or set icons for (custom) groups you can use the `SBA.viewRegistry.setGroupIcon` function as follows:

[source,javascript]
----
include::{samples-dir}/spring-boot-admin-sample-custom-ui/src/index.js[tags=customization-ui-groups]
----
<1> Name of the group to set icon for
<2> Arbitrary HTML code (e.g. SVG image) that is inserted and parsed as icon.

[[customizing-custom-views-top-level]]
==== Adding a Top-Level View ====

Here is a simple top level view just listing all registered applications:
[source,html]

----
include::{samples-dir}/spring-boot-admin-sample-custom-ui/src/custom.vue[lines=17..-1]
----
Expand Down Expand Up @@ -109,8 +122,8 @@ include::{samples-dir}/spring-boot-admin-sample-custom-ui/src/custom-endpoint.vu
<2> Each instance has a preconfigured https://github.com/axios/axios[axios] instance to access the endpoints with the correct path and headers.

Registering the instance view works like for the top-level view with some additional properties:
[source,javascript]

[source,javascript]
----
include::{samples-dir}/spring-boot-admin-sample-custom-ui/src/index.js[tags=customization-ui-endpoint]
----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ SBA.use({
name: "custom", //<1>
path: "/custom", //<2>
component: custom, //<3>
handle, //<4>
order: 1000, //<5>
group: "custom", //<4>
handle, //<5>
order: 1000, //<6>
});
i18n.mergeLocaleMessage("en", {
custom: {
label: "My Extensions", //<6>
label: "My Extensions", //<7>
},
});
i18n.mergeLocaleMessage("de", {
Expand Down Expand Up @@ -78,3 +79,13 @@ SBA.viewRegistry.addView({
}, // <3>
});
// end::customization-ui-endpoint[]

// tag::customization-ui-groups[]
SBA.viewRegistry.setGroupIcon(
"custom", //<1>
`<svg xmlns='http://www.w3.org/2000/svg'
class='h-5 mr-3'
viewBox='0 0 576 512'><path d='M512 80c8.8 0 16 7.2 16 16V416c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16V96c0-8.8 7.2-16 16-16H512zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM200 208c14.2 0 27 6.1 35.8 16c8.8 9.9 24 10.7 33.9 1.9s10.7-24 1.9-33.9c-17.5-19.6-43.1-32-71.5-32c-53 0-96 43-96 96s43 96 96 96c28.4 0 54-12.4 71.5-32c8.8-9.9 8-25-1.9-33.9s-25-8-33.9 1.9c-8.8 9.9-21.6 16-35.8 16c-26.5 0-48-21.5-48-48s21.5-48 48-48zm144 48c0-26.5 21.5-48 48-48c14.2 0 27 6.1 35.8 16c8.8 9.9 24 10.7 33.9 1.9s10.7-24 1.9-33.9c-17.5-19.6-43.1-32-71.5-32c-53 0-96 43-96 96s43 96 96 96c28.4 0 54-12.4 71.5-32c8.8-9.9 8-25-1.9-33.9s-25-8-33.9 1.9c-8.8 9.9-21.6 16-35.8 16c-26.5 0-48-21.5-48-48z'/>
</svg>` //<2>
);
// end::customization-ui-groups[]
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ const emitCustomRouteAddedEvent = debounce(() => {
export function useViewRegistry() {
return {
views: viewRegistry.views,
setGroupIcon(name, icon) {
viewRegistry.setGroupIcon(name, icon);
},
addView(viewToAdd) {
const view = viewRegistry.addView(viewToAdd)[0];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { Text, VNode, h, markRaw, reactive, shallowRef, toRaw } from 'vue';
import { Router, createRouter, createWebHistory } from 'vue-router';

import sbaConfig from './sba-config';
import { VIEW_GROUP } from './views/ViewGroup.js';
import { VIEW_GROUP, VIEW_GROUP_ICON } from './views/ViewGroup.js';

let router: Router;

Expand Down Expand Up @@ -54,6 +54,10 @@ export default class ViewRegistry {
return router;
}

setGroupIcon(name, icon) {
VIEW_GROUP_ICON[name] = icon;
}

createRouter() {
const routesKnownToBackend = sbaConfig.uiSettings.routes.map(
(r) => new RegExp(`^${r.replace('/**', '(/.*)?')}$`)
Expand Down
16 changes: 16 additions & 0 deletions spring-boot-admin-server-ui/src/main/frontend/views/ViewGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,19 @@ export const VIEW_GROUP = {
NONE: 'none',
SECURITY: 'security',
};

export const VIEW_GROUP_ICON = {
[VIEW_GROUP.WEB]:
'<svg aria-hidden="true" focusable="false" data-prefix="fas" class="w-5 h-5 mr-3" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path fill="currentColor" d="M336.5 160C322 70.7 287.8 8 248 8s-74 62.7-88.5 152h177zM152 256c0 22.2 1.2 43.5 3.3 64h185.3c2.1-20.5 3.3-41.8 3.3-64s-1.2-43.5-3.3-64H155.3c-2.1 20.5-3.3 41.8-3.3 64zm324.7-96c-28.6-67.9-86.5-120.4-158-141.6 24.4 33.8 41.2 84.7 50 141.6h108zM177.2 18.4C105.8 39.6 47.8 92.1 19.3 160h108c8.7-56.9 25.5-107.8 49.9-141.6zM487.4 192H372.7c2.1 21 3.3 42.5 3.3 64s-1.2 43-3.3 64h114.6c5.5-20.5 8.6-41.8 8.6-64s-3.1-43.5-8.5-64zM120 256c0-21.5 1.2-43 3.3-64H8.6C3.2 212.5 0 233.8 0 256s3.2 43.5 8.6 64h114.6c-2-21-3.2-42.5-3.2-64zm39.5 96c14.5 89.3 48.7 152 88.5 152s74-62.7 88.5-152h-177zm159.3 141.6c71.4-21.2 129.4-73.7 158-141.6h-108c-8.8 56.9-25.6 107.8-50 141.6zM19.3 352c28.6 67.9 86.5 120.4 158 141.6-24.4-33.8-41.2-84.7-50-141.6h-108z"></path></svg>',
[VIEW_GROUP.INSIGHTS]:
'<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>',
[VIEW_GROUP.DATA]:
'<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"></path></svg>',
[VIEW_GROUP.JVM]:
'<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"></path><path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>',
[VIEW_GROUP.LOGGING]:
'<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path></svg>',
[VIEW_GROUP.NONE]: '<div class="h-5 w-5 mr-3">&nbsp;</div>',
[VIEW_GROUP.SECURITY]:
'<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"></path></svg>',
};
17 changes: 0 additions & 17 deletions spring-boot-admin-server-ui/src/main/frontend/views/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { VIEW_GROUP } from './ViewGroup.js';

const isStorybook = Object.prototype.hasOwnProperty.call(window, 'STORIES');

Expand All @@ -36,20 +35,4 @@ if (!isStorybook) {
});
}

export const VIEW_GROUP_ICON = {
[VIEW_GROUP.WEB]:
'<svg aria-hidden="true" focusable="false" data-prefix="fas" class="w-4 h-4 mr-3" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path fill="currentColor" d="M336.5 160C322 70.7 287.8 8 248 8s-74 62.7-88.5 152h177zM152 256c0 22.2 1.2 43.5 3.3 64h185.3c2.1-20.5 3.3-41.8 3.3-64s-1.2-43.5-3.3-64H155.3c-2.1 20.5-3.3 41.8-3.3 64zm324.7-96c-28.6-67.9-86.5-120.4-158-141.6 24.4 33.8 41.2 84.7 50 141.6h108zM177.2 18.4C105.8 39.6 47.8 92.1 19.3 160h108c8.7-56.9 25.5-107.8 49.9-141.6zM487.4 192H372.7c2.1 21 3.3 42.5 3.3 64s-1.2 43-3.3 64h114.6c5.5-20.5 8.6-41.8 8.6-64s-3.1-43.5-8.5-64zM120 256c0-21.5 1.2-43 3.3-64H8.6C3.2 212.5 0 233.8 0 256s3.2 43.5 8.6 64h114.6c-2-21-3.2-42.5-3.2-64zm39.5 96c14.5 89.3 48.7 152 88.5 152s74-62.7 88.5-152h-177zm159.3 141.6c71.4-21.2 129.4-73.7 158-141.6h-108c-8.8 56.9-25.6 107.8-50 141.6zM19.3 352c28.6 67.9 86.5 120.4 158 141.6-24.4-33.8-41.2-84.7-50-141.6h-108z"></path></svg>',
[VIEW_GROUP.INSIGHTS]:
'<svg xmlns="http://www.w3.org/2000/svg" class="h-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>',
[VIEW_GROUP.DATA]:
'<svg xmlns="http://www.w3.org/2000/svg" class="h-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"></path></svg>',
[VIEW_GROUP.JVM]:
'<svg xmlns="http://www.w3.org/2000/svg" class="h-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"></path><path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>',
[VIEW_GROUP.LOGGING]:
'<svg xmlns="http://www.w3.org/2000/svg" class="h-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path></svg>',
[VIEW_GROUP.NONE]: '',
[VIEW_GROUP.SECURITY]:
'<svg xmlns="http://www.w3.org/2000/svg" class="h-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"></path></svg>',
};

export default views;
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ import SbaButton from '@/components/sba-button.vue';
import Application from '@/services/application';
import Instance from '@/services/instance';
import { compareBy } from '@/utils/collections';
import { VIEW_GROUP_ICON } from '@/views';
import { VIEW_GROUP_ICON } from '@/views/ViewGroup';

export default defineComponent({
components: { SbaButton },
Expand Down

0 comments on commit 68d5e0c

Please sign in to comment.