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 to="/health/event-logs"> 19 {{ $t('appNavigation.eventLogs') }} 20 </b-nav-item> 21 <b-nav-item to="/health/hardware-status"> 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 to="/control/manage-power-usage"> 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 to="/control/server-led"> 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 to="/configuration/network-settings"> 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 / 4; 161 @include media-breakpoint-up($responsive-layout-bp) { 162 padding-top: $spacer; 163 } 164} 165 166.nav-item__nav { 167 list-style: none; 168 padding-left: 0; 169 margin-left: 0; 170 171 .nav-item { 172 outline: none; 173 } 174 175 .nav-link { 176 padding-left: $spacer * 4; 177 outline: none; 178 179 &:not(.nav-link--current) { 180 font-weight: normal; 181 } 182 } 183} 184 185.btn-link { 186 width: 100%; 187 text-align: left; 188 text-decoration: none !important; 189 border-radius: 0; 190 191 &.collapsed { 192 .icon-expand { 193 transform: rotate(180deg); 194 } 195 } 196} 197 198.icon-expand { 199 float: right; 200 margin-top: $spacer / 4; 201} 202 203.btn-link, 204.nav-link { 205 position: relative; 206 font-weight: $headings-font-weight; 207 padding-left: $spacer; // defining consistent padding for links and buttons 208 padding-right: $spacer; 209 color: $secondary; 210 211 &:hover { 212 background-color: $primary-nav-hover; 213 color: $dark; 214 } 215 216 &:focus { 217 box-shadow: $btn-focus-box-shadow; 218 color: $dark; 219 } 220} 221 222.nav-link--current, 223.nav-link--current:hover, 224.nav-link--current:focus { 225 font-weight: $headings-font-weight; 226 background-color: $secondary; 227 color: $light; 228 cursor: default; 229 230 &::before { 231 content: ''; 232 position: absolute; 233 top: 0; 234 bottom: 0; 235 left: 0; 236 width: 4px; 237 background-color: $primary; 238 } 239} 240 241.nav-container { 242 position: fixed; 243 width: $navigation-width; 244 top: $header-height; 245 bottom: 0; 246 left: 0; 247 z-index: $zindex-fixed; 248 overflow-y: auto; 249 background-color: $container-bgd; 250 transform: translateX(-$navigation-width); 251 transition: transform $exit-easing--productive $duration--moderate-02; 252 @include media-breakpoint-down(md) { 253 z-index: $zindex-fixed + 2; 254 } 255 256 &.open, 257 &:focus-within { 258 transform: translateX(0); 259 transition-timing-function: $entrance-easing--productive; 260 } 261 262 @include media-breakpoint-up($responsive-layout-bp) { 263 transition-duration: $duration--fast-01; 264 transform: translateX(0); 265 } 266} 267 268.nav-overlay { 269 position: fixed; 270 top: $header-height; 271 bottom: 0; 272 left: 0; 273 right: 0; 274 z-index: $zindex-fixed + 1; 275 background-color: $black; 276 opacity: 0.5; 277 278 &.fade-enter-active { 279 transition: opacity $duration--moderate-02 $entrance-easing--productive; 280 } 281 282 &.fade-leave-active { 283 transition: opacity $duration--fast-02 $exit-easing--productive; 284 } 285 286 &.fade-enter, 287 &.fade-leave-to { 288 opacity: 0; 289 } 290 291 @include media-breakpoint-up($responsive-layout-bp) { 292 display: none; 293 } 294} 295</style> 296