Customizing the navigation bar to display elements based on user roles:
<b-navbar-toggle
right
class="jh-navbar-toggler d-lg-none"
href="javascript:void(0);"
data-toggle="collapse"
target="header-tabs"
aria-expanded="false"
aria-label="Toggle navigation">
<font-awesome-icon icon="bars"/>
</b-navbar-toggle>
<b-collapse is-nav id="header-tabs">
<b-navbar-nav class="ml-auto">
<b-nav-item-dropdown
right
id="pass-menu"
v-if="hasAnyAuthority('ROLE_USER') && authenticated"
:class="{'router-link-active': subIsActive('/pass')}"
active-class="active"
class="pointer">
<span slot="button-content" class="navbar-dropdown-menu">
<font-awesome-icon icon="ticket-alt"/>
<span>First element</span>
</span>
</b-nav-item-dropdown>
<b-nav-item-dropdown
right
id="dictionaries-menu"
v-if="hasAnyAuthority('ROLE_ADMIN') && authenticated"
:class="{'router-link-active': subIsActive('/dictionary')}"
active-class="active"
class="pointer">
<span slot="button-content" class="navbar-dropdown-menu">
<font-awesome-icon icon="book"/>
<span>Second element</span>
</span>
</b-nav-item-dropdown>
</b-navbar-nav>
Sometimes, setting different roles for these elements causes an issue where an infinite loop occurs and the system becomes unresponsive.
The code snippet below shows how roles are checked in Vue component:
@Component
export default class JhiNavbar extends Vue {
@Inject('loginService')
private loginService: () => LoginService;
@Inject('accountService') private accountService: () => AccountService;
public version = VERSION ? 'v' + VERSION : '';
private currentLanguage = this.$store.getters.currentLanguage;
private languages: any = this.$store.getters.languages;
private hasAnyAuthorityValue = false;
created() {}
public get authenticated(): boolean {
return this.$store.getters.authenticated;
}
public hasAnyAuthority(authorities: any): boolean {
this.accountService()
.hasAnyAuthorityAndCheckAuth(authorities)
.then(value => {
this.hasAnyAuthorityValue = value;
});
return this.hasAnyAuthorityValue;
}
}
Below is the service responsible for managing user accounts:
export default class AccountService {
constructor(private store: Store<any>, private router: VueRouter) {
this.init();
}
public init(): void {
this.retrieveProfiles();
}
public retrieveProfiles(): void {
axios.get('management/info').then(res => {
if (res.data && res.data.activeProfiles) {
this.store.commit('setRibbonOnProfiles', res.data['display-ribbon-on-profiles']);
this.store.commit('setActiveProfiles', res.data['activeProfiles']);
}
});
}
// Other methods related to account retrieval and authorization checks...
A workaround provided by @bigless involves creating separate functions to check for admin and user roles:
...
private hasAdminAuthorityValue = false;
private hasUserAuthorityValue = false;
...
public hasAdminAuthority(): boolean {
this.accountService()
.hasAnyAuthorityAndCheckAuth('ROLE_ADMIN')
.then(value => {
this.hasAdminAuthorityValue = value;
});
return this.hasAdminAuthorityValue;
}
public hasUserAuthority(): boolean {
this.accountService()
.hasAnyAuthorityAndCheckAuth('ROLE_USER')
.then(value => {
this.hasUserAuthorityValue = value;
});
return this.hasUserAuthorityValue;
}