1<template> 2 <div> 3 <div class="nav-container" :class="{ open: isNavigationOpen }"> 4 <nav ref="nav" :aria-label="$t('appNavigation.primaryNavigation')"> 5 <b-nav vertical> 6 <b-nav-item to="/"> 7 <icon-overview /> 8 {{ $t('appNavigation.overview') }} 9 </b-nav-item> 10 11 <li class="nav-item"> 12 <b-button v-b-toggle.health-menu variant="link"> 13 <icon-health /> 14 {{ $t('appNavigation.health') }} 15 <icon-expand class="icon-expand" /> 16 </b-button> 17 <b-collapse id="health-menu" tag="ul" class="nav-item__nav"> 18 <b-nav-item href="javascript:void(0)"> 19 {{ $t('appNavigation.eventLog') }} 20 </b-nav-item> 21 <b-nav-item href="javascript:void(0)"> 22 {{ $t('appNavigation.hardwareStatus') }} 23 </b-nav-item> 24 <b-nav-item to="/health/sensors"> 25 {{ $t('appNavigation.sensors') }} 26 </b-nav-item> 27 </b-collapse> 28 </li> 29 30 <li class="nav-item"> 31 <b-button v-b-toggle.control-menu variant="link"> 32 <icon-control /> 33 {{ $t('appNavigation.control') }} 34 <icon-expand class="icon-expand" /> 35 </b-button> 36 <b-collapse id="control-menu" tag="ul" class="nav-item__nav"> 37 <b-nav-item href="javascript:void(0)"> 38 {{ $t('appNavigation.managePowerUsage') }} 39 </b-nav-item> 40 <b-nav-item to="/control/reboot-bmc"> 41 {{ $t('appNavigation.rebootBmc') }} 42 </b-nav-item> 43 <b-nav-item href="javascript:void(0)"> 44 {{ $t('appNavigation.serverLed') }} 45 </b-nav-item> 46 <b-nav-item to="/control/server-power-operations"> 47 {{ $t('appNavigation.serverPowerOperations') }} 48 </b-nav-item> 49 </b-collapse> 50 </li> 51 52 <li class="nav-item"> 53 <b-button v-b-toggle.configuration-menu variant="link"> 54 <icon-configuration /> 55 {{ $t('appNavigation.configuration') }} 56 <icon-expand class="icon-expand" /> 57 </b-button> 58 <b-collapse id="configuration-menu" tag="ul" class="nav-item__nav"> 59 <b-nav-item href="javascript:void(0)"> 60 {{ $t('appNavigation.firmware') }} 61 </b-nav-item> 62 <b-nav-item href="javascript:void(0)"> 63 {{ $t('appNavigation.networkSettings') }} 64 </b-nav-item> 65 <b-nav-item href="javascript:void(0)"> 66 {{ $t('appNavigation.snmpSettings') }} 67 </b-nav-item> 68 </b-collapse> 69 </li> 70 71 <li class="nav-item"> 72 <b-button v-b-toggle.access-control-menu variant="link"> 73 <icon-access-control /> 74 {{ $t('appNavigation.accessControl') }} 75 <icon-expand class="icon-expand" /> 76 </b-button> 77 <b-collapse id="access-control-menu" tag="ul" class="nav-item__nav"> 78 <b-nav-item to="/access-control/ldap"> 79 {{ $t('appNavigation.ldap') }} 80 </b-nav-item> 81 <b-nav-item to="/access-control/local-user-management"> 82 {{ $t('appNavigation.localUserManagement') }} 83 </b-nav-item> 84 <b-nav-item to="/access-control/ssl-certificates"> 85 {{ $t('appNavigation.sslCertificates') }} 86 </b-nav-item> 87 </b-collapse> 88 </li> 89 </b-nav> 90 </nav> 91 </div> 92 <transition name="fade"> 93 <div 94 v-if="isNavigationOpen" 95 id="nav-overlay" 96 class="nav-overlay" 97 @click="toggleIsOpen" 98 ></div> 99 </transition> 100 </div> 101</template> 102 103<script> 104import IconAnalytics from '@carbon/icons-vue/es/analytics/16'; 105import IconDataCheck from '@carbon/icons-vue/es/data--check/16'; 106import IconSettingsAdjust from '@carbon/icons-vue/es/settings--adjust/16'; 107import IconSettings from '@carbon/icons-vue/es/settings/16'; 108import IconPassword from '@carbon/icons-vue/es/password/16'; 109import IconChevronUp from '@carbon/icons-vue/es/chevron--up/16'; 110 111export default { 112 name: 'AppNavigation', 113 components: { 114 iconOverview: IconAnalytics, 115 iconHealth: IconDataCheck, 116 iconControl: IconSettingsAdjust, 117 iconConfiguration: IconSettings, 118 iconAccessControl: IconPassword, 119 iconExpand: IconChevronUp 120 }, 121 data() { 122 return { 123 isNavigationOpen: false 124 }; 125 }, 126 watch: { 127 $route: function() { 128 this.isNavigationOpen = false; 129 }, 130 isNavigationOpen: function(isNavigationOpen) { 131 this.$root.$emit('change:isNavigationOpen', isNavigationOpen); 132 } 133 }, 134 mounted() { 135 this.$root.$on('toggle:navigation', () => this.toggleIsOpen()); 136 }, 137 methods: { 138 toggleIsOpen() { 139 this.isNavigationOpen = !this.isNavigationOpen; 140 } 141 } 142}; 143</script> 144 145<style scoped lang="scss"> 146@import 'src/assets/styles/helpers'; 147 148svg { 149 fill: currentColor; 150 height: 1.2rem; 151 width: 1.2rem; 152 margin-left: 0 !important; //!important overriding button specificity 153 vertical-align: text-bottom; 154 &:not(.icon-expand) { 155 margin-right: $spacer; 156 } 157} 158 159.nav { 160 padding-top: $spacer; 161} 162 163.nav-item__nav { 164 list-style: none; 165 padding-left: 0; 166 margin-left: 0; 167 168 .nav-link { 169 padding-left: $spacer * 4; 170 171 &:not(.nav-link--current) { 172 font-weight: normal; 173 } 174 } 175} 176 177.btn-link { 178 width: 100%; 179 text-align: left; 180 text-decoration: none !important; 181 border-radius: 0; 182 183 &.collapsed { 184 .icon-expand { 185 transform: rotate(180deg); 186 } 187 } 188} 189 190.icon-expand { 191 float: right; 192 margin-top: $spacer / 4; 193} 194 195.btn-link, 196.nav-link { 197 position: relative; 198 font-weight: $headings-font-weight; 199 padding-left: $spacer; // defining consistent padding for links and buttons 200 padding-right: $spacer; 201 color: $secondary; 202 203 &:hover { 204 background-color: $primary-nav-hover; 205 color: $dark; 206 } 207 208 &:focus { 209 box-shadow: $btn-focus-box-shadow; 210 color: $dark; 211 } 212} 213 214.nav-link--current, 215.nav-link--current:hover, 216.nav-link--current:focus { 217 font-weight: $headings-font-weight; 218 background-color: $secondary; 219 color: $light; 220 cursor: default; 221 222 &::before { 223 content: ''; 224 position: absolute; 225 top: 0; 226 bottom: 0; 227 left: 0; 228 width: 4px; 229 background-color: $primary; 230 } 231} 232 233.nav-container { 234 position: fixed; 235 width: $navigation-width; 236 top: $header-height; 237 bottom: 0; 238 left: 0; 239 z-index: $zindex-fixed; 240 overflow-y: auto; 241 background-color: $container-bgd; 242 transform: translateX(-$navigation-width); 243 transition: transform $exit-easing--productive $duration--moderate-02; 244 245 &.open { 246 transform: translateX(0); 247 transition-timing-function: $entrance-easing--productive; 248 } 249 250 @include media-breakpoint-up($responsive-layout-bp) { 251 transition-duration: $duration--fast-01; 252 transform: translateX(0); 253 } 254} 255 256.nav-overlay { 257 position: fixed; 258 top: $header-height; 259 bottom: 0; 260 left: 0; 261 right: 0; 262 z-index: $zindex-fixed - 1; 263 background-color: $black; 264 opacity: 0.5; 265 266 &.fade-enter-active { 267 transition: opacity $duration--moderate-02 $entrance-easing--productive; 268 } 269 270 &.fade-leave-active { 271 transition: opacity $duration--fast-02 $exit-easing--productive; 272 } 273 274 &.fade-enter, 275 &.fade-leave-to { 276 opacity: 0; 277 } 278 279 @include media-breakpoint-up($responsive-layout-bp) { 280 display: none; 281 } 282} 283</style> 284