| <template> | 
 |   <div> | 
 |     <header id="page-header"> | 
 |       <a | 
 |         class="link-skip-nav btn btn-light" | 
 |         href="#main-content" | 
 |         @click="setFocus" | 
 |       > | 
 |         {{ $t('appHeader.skipToContent') }} | 
 |       </a> | 
 |  | 
 |       <b-navbar type="dark" :aria-label="$t('appHeader.applicationHeader')"> | 
 |         <!-- Left aligned nav items --> | 
 |         <b-button | 
 |           id="app-header-trigger" | 
 |           class="nav-trigger" | 
 |           aria-hidden="true" | 
 |           type="button" | 
 |           variant="link" | 
 |           :class="{ open: isNavigationOpen }" | 
 |           @click="toggleNavigation" | 
 |         > | 
 |           <icon-close | 
 |             v-if="isNavigationOpen" | 
 |             :title="$t('appHeader.titleHideNavigation')" | 
 |           /> | 
 |           <icon-menu | 
 |             v-if="!isNavigationOpen" | 
 |             :title="$t('appHeader.titleShowNavigation')" | 
 |           /> | 
 |         </b-button> | 
 |         <b-navbar-nav> | 
 |           <b-navbar-brand | 
 |             class="mr-0" | 
 |             to="/" | 
 |             data-test-id="appHeader-container-overview" | 
 |           > | 
 |             <img | 
 |               svg-inline | 
 |               class="header-logo" | 
 |               src="@/assets/images/logo-header.svg" | 
 |               :alt="altLogo" | 
 |             /> | 
 |           </b-navbar-brand> | 
 |           <div v-if="isNavTagPresent" :key="routerKey" class="pl-2 nav-tags"> | 
 |             <span>|</span> | 
 |             <span class="pl-3 asset-tag">{{ assetTag }}</span> | 
 |             <span class="pl-3">{{ modelType }}</span> | 
 |             <span class="pl-3">{{ serialNumber }}</span> | 
 |           </div> | 
 |         </b-navbar-nav> | 
 |         <!-- Right aligned nav items --> | 
 |         <b-navbar-nav class="ml-auto helper-menu"> | 
 |           <b-nav-item | 
 |             to="/logs/event-logs" | 
 |             data-test-id="appHeader-container-health" | 
 |           > | 
 |             <status-icon :status="healthStatusIcon" /> | 
 |             {{ $t('appHeader.health') }} | 
 |           </b-nav-item> | 
 |           <b-nav-item | 
 |             to="/operations/server-power-operations" | 
 |             data-test-id="appHeader-container-power" | 
 |           > | 
 |             <status-icon :status="serverStatusIcon" /> | 
 |             {{ $t('appHeader.power') }} | 
 |           </b-nav-item> | 
 |           <!-- Using LI elements instead of b-nav-item to support semantic button elements --> | 
 |           <li class="nav-item"> | 
 |             <b-button | 
 |               id="app-header-refresh" | 
 |               variant="link" | 
 |               data-test-id="appHeader-button-refresh" | 
 |               @click="refresh" | 
 |             > | 
 |               <icon-renew :title="$t('appHeader.titleRefresh')" /> | 
 |               <span class="responsive-text">{{ $t('appHeader.refresh') }}</span> | 
 |             </b-button> | 
 |           </li> | 
 |           <li class="nav-item"> | 
 |             <b-dropdown | 
 |               id="app-header-user" | 
 |               variant="link" | 
 |               right | 
 |               data-test-id="appHeader-container-user" | 
 |             > | 
 |               <template #button-content> | 
 |                 <icon-avatar :title="$t('appHeader.titleProfile')" /> | 
 |                 <span class="responsive-text">{{ username }}</span> | 
 |               </template> | 
 |               <b-dropdown-item | 
 |                 to="/profile-settings" | 
 |                 data-test-id="appHeader-link-profile" | 
 |                 >{{ $t('appHeader.profileSettings') }} | 
 |               </b-dropdown-item> | 
 |               <b-dropdown-item | 
 |                 data-test-id="appHeader-link-logout" | 
 |                 @click="logout" | 
 |               > | 
 |                 {{ $t('appHeader.logOut') }} | 
 |               </b-dropdown-item> | 
 |             </b-dropdown> | 
 |           </li> | 
 |         </b-navbar-nav> | 
 |       </b-navbar> | 
 |     </header> | 
 |     <loading-bar /> | 
 |   </div> | 
 | </template> | 
 |  | 
 | <script> | 
 | import BVToastMixin from '@/components/Mixins/BVToastMixin'; | 
 | import IconAvatar from '@carbon/icons-vue/es/user--avatar/20'; | 
 | import IconClose from '@carbon/icons-vue/es/close/20'; | 
 | import IconMenu from '@carbon/icons-vue/es/menu/20'; | 
 | import IconRenew from '@carbon/icons-vue/es/renew/20'; | 
 | import StatusIcon from '@/components/Global/StatusIcon'; | 
 | import LoadingBar from '@/components/Global/LoadingBar'; | 
 | import { mapState } from 'vuex'; | 
 |  | 
 | export default { | 
 |   name: 'AppHeader', | 
 |   components: { | 
 |     IconAvatar, | 
 |     IconClose, | 
 |     IconMenu, | 
 |     IconRenew, | 
 |     StatusIcon, | 
 |     LoadingBar, | 
 |   }, | 
 |   mixins: [BVToastMixin], | 
 |   props: { | 
 |     routerKey: { | 
 |       type: Number, | 
 |       default: 0, | 
 |     }, | 
 |   }, | 
 |   data() { | 
 |     return { | 
 |       isNavigationOpen: false, | 
 |       altLogo: process.env.VUE_APP_COMPANY_NAME || 'Built on OpenBMC', | 
 |     }; | 
 |   }, | 
 |   computed: { | 
 |     ...mapState('authentication', ['consoleWindow']), | 
 |     isNavTagPresent() { | 
 |       return this.assetTag || this.modelType || this.serialNumber; | 
 |     }, | 
 |     assetTag() { | 
 |       return this.$store.getters['global/assetTag']; | 
 |     }, | 
 |     modelType() { | 
 |       return this.$store.getters['global/modelType']; | 
 |     }, | 
 |     serialNumber() { | 
 |       return this.$store.getters['global/serialNumber']; | 
 |     }, | 
 |     isAuthorized() { | 
 |       return this.$store.getters['global/isAuthorized']; | 
 |     }, | 
 |     userPrivilege() { | 
 |       return this.$store.getters['global/userPrivilege']; | 
 |     }, | 
 |     serverStatus() { | 
 |       return this.$store.getters['global/serverStatus']; | 
 |     }, | 
 |     healthStatus() { | 
 |       return this.$store.getters['eventLog/healthStatus']; | 
 |     }, | 
 |     serverStatusIcon() { | 
 |       switch (this.serverStatus) { | 
 |         case 'on': | 
 |           return 'success'; | 
 |         case 'error': | 
 |           return 'danger'; | 
 |         case 'diagnosticMode': | 
 |           return 'warning'; | 
 |         case 'off': | 
 |         default: | 
 |           return 'secondary'; | 
 |       } | 
 |     }, | 
 |     healthStatusIcon() { | 
 |       switch (this.healthStatus) { | 
 |         case 'OK': | 
 |           return 'success'; | 
 |         case 'Warning': | 
 |           return 'warning'; | 
 |         case 'Critical': | 
 |           return 'danger'; | 
 |         default: | 
 |           return 'secondary'; | 
 |       } | 
 |     }, | 
 |     username() { | 
 |       return this.$store.getters['global/username']; | 
 |     }, | 
 |   }, | 
 |   watch: { | 
 |     consoleWindow() { | 
 |       if (this.consoleWindow === false) this.$eventBus.$consoleWindow.close(); | 
 |     }, | 
 |     isAuthorized(value) { | 
 |       if (value === false) { | 
 |         this.errorToast(this.$t('global.toast.unAuthDescription'), { | 
 |           title: this.$t('global.toast.unAuthTitle'), | 
 |         }); | 
 |       } | 
 |     }, | 
 |   }, | 
 |   created() { | 
 |     // Reset auth state to check if user is authenticated based | 
 |     // on available browser cookies | 
 |     this.$store.dispatch('authentication/resetStoreState'); | 
 |     this.getSystemInfo(); | 
 |     this.getEvents(); | 
 |   }, | 
 |   mounted() { | 
 |     this.$root.$on( | 
 |       'change-is-navigation-open', | 
 |       (isNavigationOpen) => (this.isNavigationOpen = isNavigationOpen), | 
 |     ); | 
 |   }, | 
 |   methods: { | 
 |     getSystemInfo() { | 
 |       this.$store.dispatch('global/getSystemInfo'); | 
 |     }, | 
 |     getEvents() { | 
 |       this.$store.dispatch('eventLog/getEventLogData'); | 
 |     }, | 
 |     refresh() { | 
 |       this.$emit('refresh'); | 
 |     }, | 
 |     logout() { | 
 |       this.$store.dispatch('authentication/logout'); | 
 |     }, | 
 |     toggleNavigation() { | 
 |       this.$root.$emit('toggle-navigation'); | 
 |     }, | 
 |     setFocus(event) { | 
 |       event.preventDefault(); | 
 |       this.$root.$emit('skip-navigation'); | 
 |     }, | 
 |   }, | 
 | }; | 
 | </script> | 
 |  | 
 | <style lang="scss"> | 
 | @mixin focus-box-shadow($padding-color: $navbar-color, $outline-color: $white) { | 
 |   box-shadow: | 
 |     inset 0 0 0 3px $padding-color, | 
 |     inset 0 0 0 5px $outline-color; | 
 | } | 
 | .app-header { | 
 |   .link-skip-nav { | 
 |     position: absolute; | 
 |     top: -60px; | 
 |     left: 0.5rem; | 
 |     z-index: $zindex-popover; | 
 |     transition: $duration--moderate-01 $exit-easing--expressive; | 
 |     &:focus { | 
 |       top: 0.5rem; | 
 |       transition-timing-function: $entrance-easing--expressive; | 
 |     } | 
 |   } | 
 |   .navbar-text, | 
 |   .nav-link, | 
 |   .btn-link { | 
 |     color: color('white') !important; | 
 |     fill: currentColor; | 
 |     padding: 0.68rem 1rem !important; | 
 |  | 
 |     &:hover { | 
 |       background-color: theme-color-level(light, 10); | 
 |     } | 
 |     &:active { | 
 |       background-color: theme-color-level(light, 9); | 
 |     } | 
 |     &:focus { | 
 |       @include focus-box-shadow; | 
 |       outline: 0; | 
 |     } | 
 |   } | 
 |  | 
 |   .nav-item { | 
 |     fill: theme-color('light'); | 
 |   } | 
 |  | 
 |   .navbar { | 
 |     padding: 0; | 
 |     background-color: $navbar-color; | 
 |     @include media-breakpoint-up($responsive-layout-bp) { | 
 |       height: $header-height; | 
 |     } | 
 |  | 
 |     .helper-menu { | 
 |       @include media-breakpoint-down(sm) { | 
 |         background-color: gray('800'); | 
 |         width: 100%; | 
 |         justify-content: flex-end; | 
 |  | 
 |         .nav-link, | 
 |         .btn { | 
 |           padding: $spacer / 1.125 $spacer / 2; | 
 |         } | 
 |  | 
 |         .nav-link:focus, | 
 |         .btn:focus { | 
 |           @include focus-box-shadow($gray-800); | 
 |         } | 
 |       } | 
 |  | 
 |       .responsive-text { | 
 |         @include media-breakpoint-down(xs) { | 
 |           @include sr-only; | 
 |         } | 
 |       } | 
 |     } | 
 |   } | 
 |  | 
 |   .navbar-nav { | 
 |     @include media-breakpoint-up($responsive-layout-bp) { | 
 |       padding: 0 $spacer; | 
 |     } | 
 |     align-items: center; | 
 |  | 
 |     .navbar-brand, | 
 |     .nav-link { | 
 |       transition: $focus-transition; | 
 |     } | 
 |     .nav-tags { | 
 |       color: theme-color-level(light, 3); | 
 |       @include media-breakpoint-down(xs) { | 
 |         @include sr-only; | 
 |       } | 
 |       .asset-tag { | 
 |         @include media-breakpoint-down($responsive-layout-bp) { | 
 |           @include sr-only; | 
 |         } | 
 |       } | 
 |     } | 
 |   } | 
 |  | 
 |   .nav-trigger { | 
 |     fill: theme-color('light'); | 
 |     width: $header-height; | 
 |     height: $header-height; | 
 |     transition: none; | 
 |     display: inline-flex; | 
 |     flex: 0 0 20px; | 
 |     align-items: center; | 
 |  | 
 |     svg { | 
 |       margin: 0; | 
 |     } | 
 |  | 
 |     &:hover { | 
 |       fill: theme-color('light'); | 
 |       background-color: theme-color-level(light, 10); | 
 |     } | 
 |  | 
 |     &.open { | 
 |       background-color: gray('800'); | 
 |     } | 
 |  | 
 |     @include media-breakpoint-up($responsive-layout-bp) { | 
 |       display: none; | 
 |     } | 
 |   } | 
 |  | 
 |   .dropdown-menu { | 
 |     margin-top: 0; | 
 |  | 
 |     @include media-breakpoint-only(md) { | 
 |       margin-top: 4px; | 
 |     } | 
 |   } | 
 |  | 
 |   .navbar-expand { | 
 |     @include media-breakpoint-down(sm) { | 
 |       flex-flow: wrap; | 
 |     } | 
 |   } | 
 | } | 
 |  | 
 | .navbar-brand { | 
 |   padding: $spacer/2; | 
 |   height: $header-height; | 
 |   line-height: 1; | 
 |   &:focus { | 
 |     box-shadow: | 
 |       inset 0 0 0 3px $navbar-color, | 
 |       inset 0 0 0 5px color('white'); | 
 |     outline: 0; | 
 |   } | 
 | } | 
 | </style> |