Changeset View
Changeset View
Standalone View
Standalone View
src/resources/vue/Widgets/Menu.vue
<template> | <template> | ||||
<nav :id="mode + '-menu'" :class="'navbar navbar-light navbar-expand-' + (mode == 'header' ? 'lg' : 'sm')"> | <nav :id="mode + '-menu'" :class="'navbar navbar-light navbar-expand-' + (mode == 'header' ? 'lg' : 'sm')"> | ||||
<div class="container p-0"> | <div class="container p-0"> | ||||
<router-link class="navbar-brand" to="/" v-html="$root.logo(mode)"></router-link> | <router-link class="navbar-brand" to="/" v-html="$root.logo(mode)"></router-link> | ||||
<button v-if="mode == 'header'" class="navbar-toggler" type="button" | <button v-if="mode == 'header'" class="navbar-toggler" type="button" | ||||
data-bs-toggle="collapse" data-bs-target="#header-menu-navbar" | data-bs-toggle="collapse" data-bs-target="#header-menu-navbar" | ||||
aria-controls="header-menu-navbar" aria-expanded="false" :aria-label="$t('menu.toggle')" | aria-controls="header-menu-navbar" aria-expanded="false" :aria-label="$t('menu.toggle')" | ||||
> | > | ||||
<span class="navbar-toggler-icon"></span> | <span class="navbar-toggler-icon"></span> | ||||
</button> | </button> | ||||
<div :id="mode + '-menu-navbar'" :class="mode == 'header' ? 'collapse navbar-collapse justify-content-end' : ''"> | <div :id="mode + '-menu-navbar'" :class="mode == 'header' ? 'collapse navbar-collapse justify-content-end' : ''"> | ||||
<ul class="navbar-nav justify-content-end"> | <ul class="navbar-nav justify-content-end"> | ||||
<li class="nav-item" v-for="item in menu" :key="item.index"> | <li class="nav-item" v-for="item in menu" :key="item.label"> | ||||
<a v-if="item.href" :class="'nav-link link-' + item.index" :href="item.href">{{ item.title }}</a> | <a v-if="item.href" :class="'nav-link link-' + item.label" :href="item.href">{{ menuItemTitle(item) }}</a> | ||||
<router-link v-if="item.to" | <router-link v-if="item.to" | ||||
:class="'nav-link link-' + item.index" | :class="'nav-link link-' + item.label" | ||||
active-class="active" | active-class="active" | ||||
:to="item.to" | :to="item.to" | ||||
:exact="item.exact" | :exact="item.exact" | ||||
> | > | ||||
{{ item.title }} | {{ menuItemTitle(item) }} | ||||
</router-link> | </router-link> | ||||
</li> | </li> | ||||
<li class="nav-item" v-if="!loggedIn && $root.isUser"> | <li class="nav-item" v-if="!loggedIn && $root.isUser && !hasMenuItem('signup')"> | ||||
<router-link class="nav-link link-signup" active-class="active" :to="{name: 'signup'}">{{ $t('menu.signup') }}</router-link> | <router-link class="nav-link link-signup" active-class="active" :to="{name: 'signup'}">{{ $t('menu.signup') }}</router-link> | ||||
</li> | </li> | ||||
<li class="nav-item" v-if="loggedIn"> | <li class="nav-item" v-if="loggedIn && !hasMenuItem('dashboard')"> | ||||
<router-link class="nav-link link-dashboard" active-class="active" :to="{name: 'dashboard'}">{{ $t('menu.cockpit') }}</router-link> | <router-link class="nav-link link-dashboard" active-class="active" :to="{name: 'dashboard'}">{{ $t('menu.cockpit') }}</router-link> | ||||
</li> | </li> | ||||
<li class="nav-item" v-if="loggedIn"> | <li class="nav-item" v-if="loggedIn"> | ||||
<router-link class="nav-link menulogin link-logout" active-class="active" :to="{name: 'logout'}">{{ $t('menu.logout') }}</router-link> | <router-link class="nav-link menulogin link-logout" active-class="active" :to="{name: 'logout'}">{{ $t('menu.logout') }}</router-link> | ||||
</li> | </li> | ||||
<li class="nav-item" v-if="!loggedIn"> | <li class="nav-item" v-if="!loggedIn"> | ||||
<router-link class="nav-link menulogin link-login" :to="{name: 'login'}">{{ $t('menu.login') }}</router-link> | <router-link class="nav-link menulogin link-login" :to="{name: 'login'}">{{ $t('menu.login') }}</router-link> | ||||
</li> | </li> | ||||
Show All 29 Lines | export default { | ||||
buildYear: buildDate.getFullYear(), | buildYear: buildDate.getFullYear(), | ||||
copyright: window.config['app.company.copyright'] || '', | copyright: window.config['app.company.copyright'] || '', | ||||
languages: window.config['languages'] || [], | languages: window.config['languages'] || [], | ||||
menuList: [] | menuList: [] | ||||
} | } | ||||
}, | }, | ||||
computed: { | computed: { | ||||
loggedIn() { return !!this.$root.authInfo }, | loggedIn() { return !!this.$root.authInfo }, | ||||
menu() { return this.menuList.filter(item => !item.footer || this.mode == 'footer') }, | menu() { | ||||
// Filter menu by its position on the page, and user authentication state | |||||
return this.menuList.filter(item => { | |||||
return (!item.footer || this.mode == 'footer') | |||||
&& (!('authenticated' in item) || this.loggedIn === item.authenticated) | |||||
}) | |||||
}, | |||||
route() { return this.$route.name } | route() { return this.$route.name } | ||||
}, | }, | ||||
mounted() { | mounted() { | ||||
this.menuList = this.loadMenu() | this.menuList = this.loadMenu() | ||||
}, | }, | ||||
methods: { | methods: { | ||||
loadMenu() { | loadMenu() { | ||||
let menu = [] | let menu = [] | ||||
const lang = this.getLang() | |||||
const loggedIn = this.loggedIn | const loggedIn = this.loggedIn | ||||
window.config.menu.forEach(item => { | window.config.menu.forEach(item => { | ||||
item.title = item['title-' + lang] || item['title-en'] || item.title | if (!item.location || !item.label) { | ||||
if (!item.location || !item.title) { | |||||
console.error("Invalid menu entry", item) | console.error("Invalid menu entry", item) | ||||
return | return | ||||
} | } | ||||
// TODO: Different menu for different loggedIn state | |||||
if (item.location.match(/^https?:/)) { | if (item.location.match(/^https?:/)) { | ||||
item.href = item.location | item.href = item.location | ||||
} else { | } else { | ||||
item.to = { path: item.location } | item.to = { path: item.location } | ||||
} | } | ||||
item.exact = item.location == '/' | item.exact = item.location == '/' | ||||
item.index = item.page || item.title.toLowerCase().replace(/\s+/g, '') | |||||
menu.push(item) | menu.push(item) | ||||
}) | }) | ||||
return menu | return menu | ||||
}, | }, | ||||
hasMenuItem(label) { | |||||
return this.menuList.find(item => item.label == label) | |||||
}, | |||||
menuItemTitle(item) { | |||||
const lang = this.getLang() | |||||
return item['title-' + lang] || item['title-en'] || item.title || this.$t('menu.' + item.label) | |||||
}, | |||||
getLang() { | getLang() { | ||||
return getLang() | return getLang() | ||||
}, | }, | ||||
setLang(language) { | setLang(language) { | ||||
setLang(language) | setLang(language) | ||||
this.menuList = this.loadMenu() | |||||
} | } | ||||
} | } | ||||
} | } | ||||
</script> | </script> |