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