1a2988f40SDerick Montague<template> 2a2988f40SDerick Montague <div> 36859203cSDerick Montague <header id="page-header"> 480267970SDerick Montague <a 580267970SDerick Montague class="link-skip-nav btn btn-light" 680267970SDerick Montague href="#main-content" 780267970SDerick Montague @click="setFocus" 880267970SDerick Montague > 9e0b76c33SYoshie Muranaka {{ $t('appHeader.skipToContent') }} 10dc04feb5SYoshie Muranaka </a> 116859203cSDerick Montague 1221d6de00SMateusz Gapski <b-navbar type="dark" :aria-label="$t('appHeader.applicationHeader')"> 13dc04feb5SYoshie Muranaka <!-- Left aligned nav items --> 1474f8687dSYoshie Muranaka <b-button 156859203cSDerick Montague id="app-header-trigger" 1674f8687dSYoshie Muranaka class="nav-trigger" 1774f8687dSYoshie Muranaka aria-hidden="true" 1874f8687dSYoshie Muranaka type="button" 1974f8687dSYoshie Muranaka variant="link" 20057232b8SSurenNeware :class="{ open: isNavigationOpen }" 2174f8687dSYoshie Muranaka @click="toggleNavigation" 2274f8687dSYoshie Muranaka > 23a5cbc449SSurenNeware <icon-close 24a5cbc449SSurenNeware v-if="isNavigationOpen" 25a5cbc449SSurenNeware :title="$t('appHeader.titleHideNavigation')" 26a5cbc449SSurenNeware /> 27a5cbc449SSurenNeware <icon-menu 28a5cbc449SSurenNeware v-if="!isNavigationOpen" 29a5cbc449SSurenNeware :title="$t('appHeader.titleShowNavigation')" 30a5cbc449SSurenNeware /> 3174f8687dSYoshie Muranaka </b-button> 32dc04feb5SYoshie Muranaka <b-navbar-nav> 33c5c2ae99SSukanya Pandey <b-navbar-brand 34c5c2ae99SSukanya Pandey class="mr-0" 35c5c2ae99SSukanya Pandey to="/" 36c5c2ae99SSukanya Pandey data-test-id="appHeader-container-overview" 37c5c2ae99SSukanya Pandey > 3803505916SMateusz Gapski <img 3951abe87fSEd Tanous svg-inline 4003505916SMateusz Gapski class="header-logo" 4103505916SMateusz Gapski src="@/assets/images/logo-header.svg" 4203505916SMateusz Gapski :alt="altLogo" 4303505916SMateusz Gapski /> 441f8117f8SSurenNeware </b-navbar-brand> 4514172d74Skennyneedsmilky <div v-if="isNavTagPresent" :key="routerKey" class="pl-2 nav-tags"> 464dd7eabfSSukanya Pandey <span>|</span> 474dd7eabfSSukanya Pandey <span class="pl-3 asset-tag">{{ assetTag }}</span> 484dd7eabfSSukanya Pandey <span class="pl-3">{{ modelType }}</span> 494dd7eabfSSukanya Pandey <span class="pl-3">{{ serialNumber }}</span> 50c5c2ae99SSukanya Pandey </div> 51b8b6f791SYoshie Muranaka </b-navbar-nav> 52dc04feb5SYoshie Muranaka <!-- Right aligned nav items --> 53057232b8SSurenNeware <b-navbar-nav class="ml-auto helper-menu"> 54965cf673SDerick Montague <b-nav-item 55828dda9bSDerick Montague to="/logs/event-logs" 56965cf673SDerick Montague data-test-id="appHeader-container-health" 57965cf673SDerick Montague > 581ace1d91SYoshie Muranaka <status-icon :status="healthStatusIcon" /> 59057232b8SSurenNeware {{ $t('appHeader.health') }} 60b8b6f791SYoshie Muranaka </b-nav-item> 61965cf673SDerick Montague <b-nav-item 6268cbbe90SSandeepa Singh to="/operations/server-power-operations" 63965cf673SDerick Montague data-test-id="appHeader-container-power" 64965cf673SDerick Montague > 6571114febSDerick Montague <status-icon :status="serverStatusIcon" /> 66057232b8SSurenNeware {{ $t('appHeader.power') }} 67b8b6f791SYoshie Muranaka </b-nav-item> 686859203cSDerick Montague <!-- Using LI elements instead of b-nav-item to support semantic button elements --> 696859203cSDerick Montague <li class="nav-item"> 70965cf673SDerick Montague <b-button 71965cf673SDerick Montague id="app-header-refresh" 72965cf673SDerick Montague variant="link" 73965cf673SDerick Montague data-test-id="appHeader-button-refresh" 74965cf673SDerick Montague @click="refresh" 75965cf673SDerick Montague > 76a5cbc449SSurenNeware <icon-renew :title="$t('appHeader.titleRefresh')" /> 77057232b8SSurenNeware <span class="responsive-text">{{ $t('appHeader.refresh') }}</span> 786859203cSDerick Montague </b-button> 796859203cSDerick Montague </li> 80b1f559f0SSukanya Pandey <li class="nav-item"> 81965cf673SDerick Montague <b-dropdown 82965cf673SDerick Montague id="app-header-user" 83965cf673SDerick Montague variant="link" 84965cf673SDerick Montague right 85965cf673SDerick Montague data-test-id="appHeader-container-user" 86965cf673SDerick Montague > 87602e98aaSDerick Montague <template #button-content> 88a5cbc449SSurenNeware <icon-avatar :title="$t('appHeader.titleProfile')" /> 89057232b8SSurenNeware <span class="responsive-text">{{ username }}</span> 90b1f559f0SSukanya Pandey </template> 91965cf673SDerick Montague <b-dropdown-item 92965cf673SDerick Montague to="/profile-settings" 93965cf673SDerick Montague data-test-id="appHeader-link-profile" 94b1f559f0SSukanya Pandey >{{ $t('appHeader.profileSettings') }} 95b1f559f0SSukanya Pandey </b-dropdown-item> 96965cf673SDerick Montague <b-dropdown-item 97965cf673SDerick Montague data-test-id="appHeader-link-logout" 98965cf673SDerick Montague @click="logout" 99965cf673SDerick Montague > 100965cf673SDerick Montague {{ $t('appHeader.logOut') }} 101965cf673SDerick Montague </b-dropdown-item> 102b1f559f0SSukanya Pandey </b-dropdown> 1036859203cSDerick Montague </li> 104b8b6f791SYoshie Muranaka </b-navbar-nav> 105a2988f40SDerick Montague </b-navbar> 106a2988f40SDerick Montague </header> 1073be801aaSYoshie Muranaka <loading-bar /> 108a2988f40SDerick Montague </div> 109a2988f40SDerick Montague</template> 110a2988f40SDerick Montague 111a2988f40SDerick Montague<script> 112dd6aa0aaSSukanya Pandeyimport BVToastMixin from '@/components/Mixins/BVToastMixin'; 113e2fd1567SDerick Montagueimport IconAvatar from '@carbon/icons-vue/es/user--avatar/20'; 11474f8687dSYoshie Muranakaimport IconClose from '@carbon/icons-vue/es/close/20'; 11574f8687dSYoshie Muranakaimport IconMenu from '@carbon/icons-vue/es/menu/20'; 116e2fd1567SDerick Montagueimport IconRenew from '@carbon/icons-vue/es/renew/20'; 11761859097SSurenNewareimport StatusIcon from '@/components/Global/StatusIcon'; 11861859097SSurenNewareimport LoadingBar from '@/components/Global/LoadingBar'; 119883a0d59SEd Tanousimport { useI18n } from 'vue-i18n'; 120fb6c6de9SKonstantinimport { mapState } from 'vuex'; 121*de23ea23SSurya Vimport i18n from '@/i18n'; 12274f8687dSYoshie Muranaka 123a2988f40SDerick Montagueexport default { 124e2fd1567SDerick Montague name: 'AppHeader', 1253be801aaSYoshie Muranaka components: { 1263be801aaSYoshie Muranaka IconAvatar, 1273be801aaSYoshie Muranaka IconClose, 1283be801aaSYoshie Muranaka IconMenu, 1293be801aaSYoshie Muranaka IconRenew, 1303be801aaSYoshie Muranaka StatusIcon, 131602e98aaSDerick Montague LoadingBar, 1323be801aaSYoshie Muranaka }, 133dd6aa0aaSSukanya Pandey mixins: [BVToastMixin], 13414172d74Skennyneedsmilky props: { 13500cb42b6SKenneth Fullbright routerKey: { 13600cb42b6SKenneth Fullbright type: Number, 13700cb42b6SKenneth Fullbright default: 0, 13800cb42b6SKenneth Fullbright }, 13914172d74Skennyneedsmilky }, 14074f8687dSYoshie Muranaka data() { 14174f8687dSYoshie Muranaka return { 142883a0d59SEd Tanous $t: useI18n().t, 14303505916SMateusz Gapski isNavigationOpen: false, 144932aff93SDerick Montague altLogo: process.env.VUE_APP_COMPANY_NAME || 'Built on OpenBMC', 14574f8687dSYoshie Muranaka }; 14674f8687dSYoshie Muranaka }, 147b8b6f791SYoshie Muranaka computed: { 148fb6c6de9SKonstantin ...mapState('authentication', ['consoleWindow']), 1494dd7eabfSSukanya Pandey isNavTagPresent() { 1504dd7eabfSSukanya Pandey return this.assetTag || this.modelType || this.serialNumber; 1514dd7eabfSSukanya Pandey }, 152c5c2ae99SSukanya Pandey assetTag() { 153c5c2ae99SSukanya Pandey return this.$store.getters['global/assetTag']; 154c5c2ae99SSukanya Pandey }, 1554dd7eabfSSukanya Pandey modelType() { 1564dd7eabfSSukanya Pandey return this.$store.getters['global/modelType']; 1574dd7eabfSSukanya Pandey }, 1584dd7eabfSSukanya Pandey serialNumber() { 1594dd7eabfSSukanya Pandey return this.$store.getters['global/serialNumber']; 1604dd7eabfSSukanya Pandey }, 161dd6aa0aaSSukanya Pandey isAuthorized() { 162dd6aa0aaSSukanya Pandey return this.$store.getters['global/isAuthorized']; 163dd6aa0aaSSukanya Pandey }, 164aeb19816SDamian Celico userPrivilege() { 165aeb19816SDamian Celico return this.$store.getters['global/userPrivilege']; 166aeb19816SDamian Celico }, 16771114febSDerick Montague serverStatus() { 16871114febSDerick Montague return this.$store.getters['global/serverStatus']; 169dc04feb5SYoshie Muranaka }, 1701ace1d91SYoshie Muranaka healthStatus() { 1711ace1d91SYoshie Muranaka return this.$store.getters['eventLog/healthStatus']; 1721ace1d91SYoshie Muranaka }, 17371114febSDerick Montague serverStatusIcon() { 17471114febSDerick Montague switch (this.serverStatus) { 175e2fd1567SDerick Montague case 'on': 176e2fd1567SDerick Montague return 'success'; 177e2fd1567SDerick Montague case 'error': 178e2fd1567SDerick Montague return 'danger'; 179a3cbc659SYoshie Muranaka case 'diagnosticMode': 180a3cbc659SYoshie Muranaka return 'warning'; 181e2fd1567SDerick Montague case 'off': 182dc04feb5SYoshie Muranaka default: 183e2fd1567SDerick Montague return 'secondary'; 184dc04feb5SYoshie Muranaka } 1851ace1d91SYoshie Muranaka }, 1861ace1d91SYoshie Muranaka healthStatusIcon() { 1871ace1d91SYoshie Muranaka switch (this.healthStatus) { 188ce9a3ef3SYoshie Muranaka case 'OK': 1891ace1d91SYoshie Muranaka return 'success'; 190ce9a3ef3SYoshie Muranaka case 'Warning': 1911ace1d91SYoshie Muranaka return 'warning'; 192ce9a3ef3SYoshie Muranaka case 'Critical': 1931ace1d91SYoshie Muranaka return 'danger'; 1941ace1d91SYoshie Muranaka default: 1951ace1d91SYoshie Muranaka return 'secondary'; 1961ace1d91SYoshie Muranaka } 197b1f559f0SSukanya Pandey }, 198b1f559f0SSukanya Pandey username() { 199b1f559f0SSukanya Pandey return this.$store.getters['global/username']; 200602e98aaSDerick Montague }, 201b8b6f791SYoshie Muranaka }, 202dd6aa0aaSSukanya Pandey watch: { 203fb6c6de9SKonstantin consoleWindow() { 204883a0d59SEd Tanous if (this.consoleWindow === false) this.$eventBus.$consoleWindow?.close(); 205fb6c6de9SKonstantin }, 206dd6aa0aaSSukanya Pandey isAuthorized(value) { 207dd6aa0aaSSukanya Pandey if (value === false) { 208*de23ea23SSurya V this.errorToast(i18n.global.t('global.toast.unAuthDescription'), { 209*de23ea23SSurya V title: i18n.global.t('global.toast.unAuthTitle'), 210f92e2969SYoshie Muranaka }); 211dd6aa0aaSSukanya Pandey } 212602e98aaSDerick Montague }, 213dd6aa0aaSSukanya Pandey }, 21409e45cd4SDerick Montague created() { 215d624dae9SYoshie Muranaka // Reset auth state to check if user is authenticated based 216d624dae9SYoshie Muranaka // on available browser cookies 217d624dae9SYoshie Muranaka this.$store.dispatch('authentication/resetStoreState'); 2184dd7eabfSSukanya Pandey this.getSystemInfo(); 2191ace1d91SYoshie Muranaka this.getEvents(); 22009e45cd4SDerick Montague }, 22174f8687dSYoshie Muranaka mounted() { 22274f8687dSYoshie Muranaka this.$root.$on( 223edb8a774SSukanya Pandey 'change-is-navigation-open', 2248132399cSEd Tanous (isNavigationOpen) => (this.isNavigationOpen = isNavigationOpen), 22574f8687dSYoshie Muranaka ); 22674f8687dSYoshie Muranaka }, 227b8b6f791SYoshie Muranaka methods: { 2284dd7eabfSSukanya Pandey getSystemInfo() { 2294dd7eabfSSukanya Pandey this.$store.dispatch('global/getSystemInfo'); 230e080a1a7SDerick Montague }, 2311ace1d91SYoshie Muranaka getEvents() { 2321ace1d91SYoshie Muranaka this.$store.dispatch('eventLog/getEventLogData'); 2331ace1d91SYoshie Muranaka }, 234eb154bbcSYoshie Muranaka refresh() { 235eb154bbcSYoshie Muranaka this.$emit('refresh'); 236eb154bbcSYoshie Muranaka }, 237e080a1a7SDerick Montague logout() { 238c031b698SDerick Montague this.$store.dispatch('authentication/logout'); 23974f8687dSYoshie Muranaka }, 24074f8687dSYoshie Muranaka toggleNavigation() { 241edb8a774SSukanya Pandey this.$root.$emit('toggle-navigation'); 242602e98aaSDerick Montague }, 24380267970SDerick Montague setFocus(event) { 24480267970SDerick Montague event.preventDefault(); 24580267970SDerick Montague this.$root.$emit('skip-navigation'); 24680267970SDerick Montague }, 247602e98aaSDerick Montague }, 248a2988f40SDerick Montague}; 249a2988f40SDerick Montague</script> 250a2988f40SDerick Montague 251b1f559f0SSukanya Pandey<style lang="scss"> 2527d6b44cbSEd Tanous@import '@/assets/styles/bmc/helpers/_index.scss'; 2537d6b44cbSEd Tanous@import '@/assets/styles/bootstrap/_helpers.scss'; 2547d6b44cbSEd Tanous 2557d4b53bcSDerick Montague@mixin focus-box-shadow($padding-color: $navbar-color, $outline-color: $white) { 2568132399cSEd Tanous box-shadow: 2578132399cSEd Tanous inset 0 0 0 3px $padding-color, 2588132399cSEd Tanous inset 0 0 0 5px $outline-color; 2597d4b53bcSDerick Montague} 260b1f559f0SSukanya Pandey.app-header { 26175b48321SDerick Montague .link-skip-nav { 26275b48321SDerick Montague position: absolute; 26375b48321SDerick Montague top: -60px; 26475b48321SDerick Montague left: 0.5rem; 2657d6b44cbSEd Tanous //z-index: $zindex-popover; 2667d6b44cbSEd Tanous //transition: $duration--moderate-01 $exit-easing--expressive; 26775b48321SDerick Montague &:focus { 26875b48321SDerick Montague top: 0.5rem; 2697d6b44cbSEd Tanous //transition-timing-function: $entrance-easing--expressive; 27075b48321SDerick Montague } 27175b48321SDerick Montague } 2721ace1d91SYoshie Muranaka .navbar-text, 2736859203cSDerick Montague .nav-link, 2746859203cSDerick Montague .btn-link { 2751f8117f8SSurenNeware color: color('white') !important; 2766859203cSDerick Montague fill: currentColor; 2771f8117f8SSurenNeware padding: 0.68rem 1rem !important; 2781f8117f8SSurenNeware 2791f8117f8SSurenNeware &:hover { 2801f8117f8SSurenNeware background-color: theme-color-level(light, 10); 2811f8117f8SSurenNeware } 2821f8117f8SSurenNeware &:active { 2831f8117f8SSurenNeware background-color: theme-color-level(light, 9); 2841f8117f8SSurenNeware } 2851f8117f8SSurenNeware &:focus { 2867d4b53bcSDerick Montague @include focus-box-shadow; 2877d4b53bcSDerick Montague outline: 0; 2881ace1d91SYoshie Muranaka } 2891ace1d91SYoshie Muranaka } 2906859203cSDerick Montague 291dc04feb5SYoshie Muranaka .nav-item { 29201da8187SYoshie Muranaka fill: theme-color('light'); 293dc04feb5SYoshie Muranaka } 29474f8687dSYoshie Muranaka 29574f8687dSYoshie Muranaka .navbar { 29674f8687dSYoshie Muranaka padding: 0; 29721d6de00SMateusz Gapski background-color: $navbar-color; 2987d6b44cbSEd Tanous 299057232b8SSurenNeware @include media-breakpoint-up($responsive-layout-bp) { 30074f8687dSYoshie Muranaka height: $header-height; 301057232b8SSurenNeware } 3026859203cSDerick Montague 303057232b8SSurenNeware .helper-menu { 304057232b8SSurenNeware @include media-breakpoint-down(sm) { 30501da8187SYoshie Muranaka background-color: gray('800'); 306057232b8SSurenNeware width: 100%; 307057232b8SSurenNeware justify-content: flex-end; 308057232b8SSurenNeware 309057232b8SSurenNeware .nav-link, 310057232b8SSurenNeware .btn { 311057232b8SSurenNeware padding: $spacer / 1.125 $spacer / 2; 312057232b8SSurenNeware } 3137d4b53bcSDerick Montague 3147d4b53bcSDerick Montague .nav-link:focus, 3157d4b53bcSDerick Montague .btn:focus { 3167d4b53bcSDerick Montague @include focus-box-shadow($gray-800); 3177d4b53bcSDerick Montague } 318057232b8SSurenNeware } 319057232b8SSurenNeware 320057232b8SSurenNeware .responsive-text { 321057232b8SSurenNeware @include media-breakpoint-down(xs) { 3224dd7eabfSSukanya Pandey @include sr-only; 323057232b8SSurenNeware } 324057232b8SSurenNeware } 325057232b8SSurenNeware } 32674f8687dSYoshie Muranaka } 32774f8687dSYoshie Muranaka 32874f8687dSYoshie Muranaka .navbar-nav { 3294dd7eabfSSukanya Pandey @include media-breakpoint-up($responsive-layout-bp) { 33074f8687dSYoshie Muranaka padding: 0 $spacer; 3314dd7eabfSSukanya Pandey } 3321f8117f8SSurenNeware align-items: center; 3331f8117f8SSurenNeware 3341f8117f8SSurenNeware .navbar-brand, 3351f8117f8SSurenNeware .nav-link { 3361f8117f8SSurenNeware transition: $focus-transition; 3371f8117f8SSurenNeware } 3384dd7eabfSSukanya Pandey .nav-tags { 339c5c2ae99SSukanya Pandey color: theme-color-level(light, 3); 3404dd7eabfSSukanya Pandey @include media-breakpoint-down(xs) { 3414dd7eabfSSukanya Pandey @include sr-only; 3424dd7eabfSSukanya Pandey } 3434dd7eabfSSukanya Pandey .asset-tag { 3444dd7eabfSSukanya Pandey @include media-breakpoint-down($responsive-layout-bp) { 3454dd7eabfSSukanya Pandey @include sr-only; 3464dd7eabfSSukanya Pandey } 3474dd7eabfSSukanya Pandey } 348c5c2ae99SSukanya Pandey } 34974f8687dSYoshie Muranaka } 35074f8687dSYoshie Muranaka 35174f8687dSYoshie Muranaka .nav-trigger { 35201da8187SYoshie Muranaka fill: theme-color('light'); 35374f8687dSYoshie Muranaka width: $header-height; 35474f8687dSYoshie Muranaka height: $header-height; 35574f8687dSYoshie Muranaka transition: none; 3561f8117f8SSurenNeware display: inline-flex; 3571f8117f8SSurenNeware flex: 0 0 20px; 3581f8117f8SSurenNeware align-items: center; 35974f8687dSYoshie Muranaka 36074f8687dSYoshie Muranaka svg { 36174f8687dSYoshie Muranaka margin: 0; 36274f8687dSYoshie Muranaka } 36374f8687dSYoshie Muranaka 36474f8687dSYoshie Muranaka &:hover { 36501da8187SYoshie Muranaka fill: theme-color('light'); 3661f8117f8SSurenNeware background-color: theme-color-level(light, 10); 36774f8687dSYoshie Muranaka } 36874f8687dSYoshie Muranaka 369057232b8SSurenNeware &.open { 37001da8187SYoshie Muranaka background-color: gray('800'); 371057232b8SSurenNeware } 372057232b8SSurenNeware 37374f8687dSYoshie Muranaka @include media-breakpoint-up($responsive-layout-bp) { 37474f8687dSYoshie Muranaka display: none; 37574f8687dSYoshie Muranaka } 376dc04feb5SYoshie Muranaka } 377b1f559f0SSukanya Pandey 378b1f559f0SSukanya Pandey .dropdown-menu { 379057232b8SSurenNeware margin-top: 0; 3801f8117f8SSurenNeware 3811f8117f8SSurenNeware @include media-breakpoint-only(md) { 3821f8117f8SSurenNeware margin-top: 4px; 383b1f559f0SSukanya Pandey } 384b1f559f0SSukanya Pandey } 385057232b8SSurenNeware 386057232b8SSurenNeware .navbar-expand { 387057232b8SSurenNeware @include media-breakpoint-down(sm) { 388057232b8SSurenNeware flex-flow: wrap; 389057232b8SSurenNeware } 390057232b8SSurenNeware } 391057232b8SSurenNeware} 3921f8117f8SSurenNeware 3931f8117f8SSurenNeware.navbar-brand { 3941f8117f8SSurenNeware padding: $spacer/2; 3951f8117f8SSurenNeware height: $header-height; 3961f8117f8SSurenNeware line-height: 1; 3971f8117f8SSurenNeware &:focus { 3988132399cSEd Tanous box-shadow: 3998132399cSEd Tanous inset 0 0 0 3px $navbar-color, 4008132399cSEd Tanous inset 0 0 0 5px color('white'); 4011f8117f8SSurenNeware outline: 0; 4021f8117f8SSurenNeware } 4031f8117f8SSurenNeware} 404b8b6f791SYoshie Muranaka</style> 405