1<template> 2 <div> 3 <div class="nav-container" :class="{ open: isNavigationOpen }"> 4 <nav ref="nav"> 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 href="javascript:void(0)"> 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 href="javascript:void(0)"> 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 href="javascript:void(0)"> 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 class="nav-overlay" 96 @click="toggleIsOpen" 97 ></div> 98 </transition> 99 </div> 100</template> 101 102<script> 103import IconAnalytics from '@carbon/icons-vue/es/analytics/16'; 104import IconDataCheck from '@carbon/icons-vue/es/data--check/16'; 105import IconSettingsAdjust from '@carbon/icons-vue/es/settings--adjust/16'; 106import IconSettings from '@carbon/icons-vue/es/settings/16'; 107import IconPassword from '@carbon/icons-vue/es/password/16'; 108import IconChevronUp from '@carbon/icons-vue/es/chevron--up/16'; 109 110export default { 111 name: 'AppNavigation', 112 components: { 113 iconOverview: IconAnalytics, 114 iconHealth: IconDataCheck, 115 iconControl: IconSettingsAdjust, 116 iconConfiguration: IconSettings, 117 iconAccessControl: IconPassword, 118 iconExpand: IconChevronUp 119 }, 120 data() { 121 return { 122 isNavigationOpen: false 123 }; 124 }, 125 watch: { 126 $route: function() { 127 this.isNavigationOpen = false; 128 }, 129 isNavigationOpen: function(isNavigationOpen) { 130 this.$root.$emit('change:isNavigationOpen', isNavigationOpen); 131 } 132 }, 133 mounted() { 134 this.$root.$on('toggle:navigation', () => this.toggleIsOpen()); 135 }, 136 methods: { 137 toggleIsOpen() { 138 this.isNavigationOpen = !this.isNavigationOpen; 139 } 140 } 141}; 142</script> 143 144<style scoped lang="scss"> 145svg { 146 fill: currentColor; 147 height: 1.2rem; 148 width: 1.2rem; 149 margin-left: 0 !important; //!important overriding button specificity 150 vertical-align: text-bottom; 151 &:not(.icon-expand) { 152 margin-right: $spacer; 153 } 154} 155 156.nav { 157 padding-top: $spacer; 158} 159 160.nav-item__nav { 161 list-style: none; 162 padding-left: 0; 163 margin-left: 0; 164 165 .nav-link { 166 padding-left: $spacer * 4; 167 168 &:not(.nav-link--current) { 169 font-weight: normal; 170 } 171 } 172} 173 174.btn-link { 175 width: 100%; 176 text-align: left; 177 text-decoration: none !important; 178 border-radius: 0; 179 180 &.collapsed { 181 .icon-expand { 182 transform: rotate(180deg); 183 } 184 } 185} 186 187.icon-expand { 188 float: right; 189 margin-top: $spacer / 4; 190} 191 192.btn-link, 193.nav-link { 194 position: relative; 195 font-weight: $headings-font-weight; 196 padding-left: $spacer; // defining consistent padding for links and buttons 197 padding-right: $spacer; 198 color: $secondary; 199 200 &:hover { 201 background-color: $primary-nav-hover; 202 color: $dark; 203 } 204 205 &:focus { 206 box-shadow: $btn-focus-box-shadow; 207 color: $dark; 208 } 209} 210 211.nav-link--current, 212.nav-link--current:hover, 213.nav-link--current:focus { 214 font-weight: $headings-font-weight; 215 background-color: $secondary; 216 color: $light; 217 cursor: default; 218 219 &::before { 220 content: ''; 221 position: absolute; 222 top: 0; 223 bottom: 0; 224 left: 0; 225 width: 4px; 226 background-color: $primary; 227 } 228} 229 230.nav-container { 231 position: fixed; 232 width: $navigation-width; 233 top: $header-height; 234 bottom: 0; 235 left: 0; 236 z-index: $zindex-fixed; 237 overflow-y: auto; 238 background-color: $container-bgd; 239 transform: translateX(-$navigation-width); 240 transition: transform $exit-easing--productive $duration--moderate-02; 241 242 &.open { 243 transform: translateX(0); 244 transition-timing-function: $entrance-easing--productive; 245 } 246 247 @include media-breakpoint-up($responsive-layout-bp) { 248 transition-duration: $duration--fast-01; 249 transform: translateX(0); 250 } 251} 252 253.nav-overlay { 254 position: fixed; 255 top: $header-height; 256 bottom: 0; 257 left: 0; 258 right: 0; 259 z-index: $zindex-fixed - 1; 260 background-color: $black; 261 opacity: 0.5; 262 263 &.fade-enter-active { 264 transition: opacity $duration--moderate-02 $entrance-easing--productive; 265 } 266 267 &.fade-leave-active { 268 transition: opacity $duration--fast-02 $exit-easing--productive; 269 } 270 271 &.fade-enter, 272 &.fade-leave-to { 273 opacity: 0; 274 } 275 276 @include media-breakpoint-up($responsive-layout-bp) { 277 display: none; 278 } 279} 280</style> 281