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 39*51abe87fSEd 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'; 119fb6c6de9SKonstantinimport { mapState } from 'vuex'; 12074f8687dSYoshie Muranaka 121a2988f40SDerick Montagueexport default { 122e2fd1567SDerick Montague name: 'AppHeader', 1233be801aaSYoshie Muranaka components: { 1243be801aaSYoshie Muranaka IconAvatar, 1253be801aaSYoshie Muranaka IconClose, 1263be801aaSYoshie Muranaka IconMenu, 1273be801aaSYoshie Muranaka IconRenew, 1283be801aaSYoshie Muranaka StatusIcon, 129602e98aaSDerick Montague LoadingBar, 1303be801aaSYoshie Muranaka }, 131dd6aa0aaSSukanya Pandey mixins: [BVToastMixin], 13214172d74Skennyneedsmilky props: { 13300cb42b6SKenneth Fullbright routerKey: { 13400cb42b6SKenneth Fullbright type: Number, 13500cb42b6SKenneth Fullbright default: 0, 13600cb42b6SKenneth Fullbright }, 13714172d74Skennyneedsmilky }, 13874f8687dSYoshie Muranaka data() { 13974f8687dSYoshie Muranaka return { 14003505916SMateusz Gapski isNavigationOpen: false, 141932aff93SDerick Montague altLogo: process.env.VUE_APP_COMPANY_NAME || 'Built on OpenBMC', 14274f8687dSYoshie Muranaka }; 14374f8687dSYoshie Muranaka }, 144b8b6f791SYoshie Muranaka computed: { 145fb6c6de9SKonstantin ...mapState('authentication', ['consoleWindow']), 1464dd7eabfSSukanya Pandey isNavTagPresent() { 1474dd7eabfSSukanya Pandey return this.assetTag || this.modelType || this.serialNumber; 1484dd7eabfSSukanya Pandey }, 149c5c2ae99SSukanya Pandey assetTag() { 150c5c2ae99SSukanya Pandey return this.$store.getters['global/assetTag']; 151c5c2ae99SSukanya Pandey }, 1524dd7eabfSSukanya Pandey modelType() { 1534dd7eabfSSukanya Pandey return this.$store.getters['global/modelType']; 1544dd7eabfSSukanya Pandey }, 1554dd7eabfSSukanya Pandey serialNumber() { 1564dd7eabfSSukanya Pandey return this.$store.getters['global/serialNumber']; 1574dd7eabfSSukanya Pandey }, 158dd6aa0aaSSukanya Pandey isAuthorized() { 159dd6aa0aaSSukanya Pandey return this.$store.getters['global/isAuthorized']; 160dd6aa0aaSSukanya Pandey }, 161aeb19816SDamian Celico userPrivilege() { 162aeb19816SDamian Celico return this.$store.getters['global/userPrivilege']; 163aeb19816SDamian Celico }, 16471114febSDerick Montague serverStatus() { 16571114febSDerick Montague return this.$store.getters['global/serverStatus']; 166dc04feb5SYoshie Muranaka }, 1671ace1d91SYoshie Muranaka healthStatus() { 1681ace1d91SYoshie Muranaka return this.$store.getters['eventLog/healthStatus']; 1691ace1d91SYoshie Muranaka }, 17071114febSDerick Montague serverStatusIcon() { 17171114febSDerick Montague switch (this.serverStatus) { 172e2fd1567SDerick Montague case 'on': 173e2fd1567SDerick Montague return 'success'; 174e2fd1567SDerick Montague case 'error': 175e2fd1567SDerick Montague return 'danger'; 176a3cbc659SYoshie Muranaka case 'diagnosticMode': 177a3cbc659SYoshie Muranaka return 'warning'; 178e2fd1567SDerick Montague case 'off': 179dc04feb5SYoshie Muranaka default: 180e2fd1567SDerick Montague return 'secondary'; 181dc04feb5SYoshie Muranaka } 1821ace1d91SYoshie Muranaka }, 1831ace1d91SYoshie Muranaka healthStatusIcon() { 1841ace1d91SYoshie Muranaka switch (this.healthStatus) { 185ce9a3ef3SYoshie Muranaka case 'OK': 1861ace1d91SYoshie Muranaka return 'success'; 187ce9a3ef3SYoshie Muranaka case 'Warning': 1881ace1d91SYoshie Muranaka return 'warning'; 189ce9a3ef3SYoshie Muranaka case 'Critical': 1901ace1d91SYoshie Muranaka return 'danger'; 1911ace1d91SYoshie Muranaka default: 1921ace1d91SYoshie Muranaka return 'secondary'; 1931ace1d91SYoshie Muranaka } 194b1f559f0SSukanya Pandey }, 195b1f559f0SSukanya Pandey username() { 196b1f559f0SSukanya Pandey return this.$store.getters['global/username']; 197602e98aaSDerick Montague }, 198b8b6f791SYoshie Muranaka }, 199dd6aa0aaSSukanya Pandey watch: { 200fb6c6de9SKonstantin consoleWindow() { 201fb6c6de9SKonstantin if (this.consoleWindow === false) this.$eventBus.$consoleWindow.close(); 202fb6c6de9SKonstantin }, 203dd6aa0aaSSukanya Pandey isAuthorized(value) { 204dd6aa0aaSSukanya Pandey if (value === false) { 205f92e2969SYoshie Muranaka this.errorToast(this.$t('global.toast.unAuthDescription'), { 206f92e2969SYoshie Muranaka title: this.$t('global.toast.unAuthTitle'), 207f92e2969SYoshie Muranaka }); 208dd6aa0aaSSukanya Pandey } 209602e98aaSDerick Montague }, 210dd6aa0aaSSukanya Pandey }, 21109e45cd4SDerick Montague created() { 212d624dae9SYoshie Muranaka // Reset auth state to check if user is authenticated based 213d624dae9SYoshie Muranaka // on available browser cookies 214d624dae9SYoshie Muranaka this.$store.dispatch('authentication/resetStoreState'); 2154dd7eabfSSukanya Pandey this.getSystemInfo(); 2161ace1d91SYoshie Muranaka this.getEvents(); 21709e45cd4SDerick Montague }, 21874f8687dSYoshie Muranaka mounted() { 21974f8687dSYoshie Muranaka this.$root.$on( 220edb8a774SSukanya Pandey 'change-is-navigation-open', 2218132399cSEd Tanous (isNavigationOpen) => (this.isNavigationOpen = isNavigationOpen), 22274f8687dSYoshie Muranaka ); 22374f8687dSYoshie Muranaka }, 224b8b6f791SYoshie Muranaka methods: { 2254dd7eabfSSukanya Pandey getSystemInfo() { 2264dd7eabfSSukanya Pandey this.$store.dispatch('global/getSystemInfo'); 227e080a1a7SDerick Montague }, 2281ace1d91SYoshie Muranaka getEvents() { 2291ace1d91SYoshie Muranaka this.$store.dispatch('eventLog/getEventLogData'); 2301ace1d91SYoshie Muranaka }, 231eb154bbcSYoshie Muranaka refresh() { 232eb154bbcSYoshie Muranaka this.$emit('refresh'); 233eb154bbcSYoshie Muranaka }, 234e080a1a7SDerick Montague logout() { 235c031b698SDerick Montague this.$store.dispatch('authentication/logout'); 23674f8687dSYoshie Muranaka }, 23774f8687dSYoshie Muranaka toggleNavigation() { 238edb8a774SSukanya Pandey this.$root.$emit('toggle-navigation'); 239602e98aaSDerick Montague }, 24080267970SDerick Montague setFocus(event) { 24180267970SDerick Montague event.preventDefault(); 24280267970SDerick Montague this.$root.$emit('skip-navigation'); 24380267970SDerick Montague }, 244602e98aaSDerick Montague }, 245a2988f40SDerick Montague}; 246a2988f40SDerick Montague</script> 247a2988f40SDerick Montague 248b1f559f0SSukanya Pandey<style lang="scss"> 2497d4b53bcSDerick Montague@mixin focus-box-shadow($padding-color: $navbar-color, $outline-color: $white) { 2508132399cSEd Tanous box-shadow: 2518132399cSEd Tanous inset 0 0 0 3px $padding-color, 2528132399cSEd Tanous inset 0 0 0 5px $outline-color; 2537d4b53bcSDerick Montague} 254b1f559f0SSukanya Pandey.app-header { 25575b48321SDerick Montague .link-skip-nav { 25675b48321SDerick Montague position: absolute; 25775b48321SDerick Montague top: -60px; 25875b48321SDerick Montague left: 0.5rem; 25974f8687dSYoshie Muranaka z-index: $zindex-popover; 26074f8687dSYoshie Muranaka transition: $duration--moderate-01 $exit-easing--expressive; 26175b48321SDerick Montague &:focus { 26275b48321SDerick Montague top: 0.5rem; 26374f8687dSYoshie Muranaka transition-timing-function: $entrance-easing--expressive; 26475b48321SDerick Montague } 26575b48321SDerick Montague } 2661ace1d91SYoshie Muranaka .navbar-text, 2676859203cSDerick Montague .nav-link, 2686859203cSDerick Montague .btn-link { 2691f8117f8SSurenNeware color: color('white') !important; 2706859203cSDerick Montague fill: currentColor; 2711f8117f8SSurenNeware padding: 0.68rem 1rem !important; 2721f8117f8SSurenNeware 2731f8117f8SSurenNeware &:hover { 2741f8117f8SSurenNeware background-color: theme-color-level(light, 10); 2751f8117f8SSurenNeware } 2761f8117f8SSurenNeware &:active { 2771f8117f8SSurenNeware background-color: theme-color-level(light, 9); 2781f8117f8SSurenNeware } 2791f8117f8SSurenNeware &:focus { 2807d4b53bcSDerick Montague @include focus-box-shadow; 2817d4b53bcSDerick Montague outline: 0; 2821ace1d91SYoshie Muranaka } 2831ace1d91SYoshie Muranaka } 2846859203cSDerick Montague 285dc04feb5SYoshie Muranaka .nav-item { 28601da8187SYoshie Muranaka fill: theme-color('light'); 287dc04feb5SYoshie Muranaka } 28874f8687dSYoshie Muranaka 28974f8687dSYoshie Muranaka .navbar { 29074f8687dSYoshie Muranaka padding: 0; 29121d6de00SMateusz Gapski background-color: $navbar-color; 292057232b8SSurenNeware @include media-breakpoint-up($responsive-layout-bp) { 29374f8687dSYoshie Muranaka height: $header-height; 294057232b8SSurenNeware } 2956859203cSDerick Montague 296057232b8SSurenNeware .helper-menu { 297057232b8SSurenNeware @include media-breakpoint-down(sm) { 29801da8187SYoshie Muranaka background-color: gray('800'); 299057232b8SSurenNeware width: 100%; 300057232b8SSurenNeware justify-content: flex-end; 301057232b8SSurenNeware 302057232b8SSurenNeware .nav-link, 303057232b8SSurenNeware .btn { 304057232b8SSurenNeware padding: $spacer / 1.125 $spacer / 2; 305057232b8SSurenNeware } 3067d4b53bcSDerick Montague 3077d4b53bcSDerick Montague .nav-link:focus, 3087d4b53bcSDerick Montague .btn:focus { 3097d4b53bcSDerick Montague @include focus-box-shadow($gray-800); 3107d4b53bcSDerick Montague } 311057232b8SSurenNeware } 312057232b8SSurenNeware 313057232b8SSurenNeware .responsive-text { 314057232b8SSurenNeware @include media-breakpoint-down(xs) { 3154dd7eabfSSukanya Pandey @include sr-only; 316057232b8SSurenNeware } 317057232b8SSurenNeware } 318057232b8SSurenNeware } 31974f8687dSYoshie Muranaka } 32074f8687dSYoshie Muranaka 32174f8687dSYoshie Muranaka .navbar-nav { 3224dd7eabfSSukanya Pandey @include media-breakpoint-up($responsive-layout-bp) { 32374f8687dSYoshie Muranaka padding: 0 $spacer; 3244dd7eabfSSukanya Pandey } 3251f8117f8SSurenNeware align-items: center; 3261f8117f8SSurenNeware 3271f8117f8SSurenNeware .navbar-brand, 3281f8117f8SSurenNeware .nav-link { 3291f8117f8SSurenNeware transition: $focus-transition; 3301f8117f8SSurenNeware } 3314dd7eabfSSukanya Pandey .nav-tags { 332c5c2ae99SSukanya Pandey color: theme-color-level(light, 3); 3334dd7eabfSSukanya Pandey @include media-breakpoint-down(xs) { 3344dd7eabfSSukanya Pandey @include sr-only; 3354dd7eabfSSukanya Pandey } 3364dd7eabfSSukanya Pandey .asset-tag { 3374dd7eabfSSukanya Pandey @include media-breakpoint-down($responsive-layout-bp) { 3384dd7eabfSSukanya Pandey @include sr-only; 3394dd7eabfSSukanya Pandey } 3404dd7eabfSSukanya Pandey } 341c5c2ae99SSukanya Pandey } 34274f8687dSYoshie Muranaka } 34374f8687dSYoshie Muranaka 34474f8687dSYoshie Muranaka .nav-trigger { 34501da8187SYoshie Muranaka fill: theme-color('light'); 34674f8687dSYoshie Muranaka width: $header-height; 34774f8687dSYoshie Muranaka height: $header-height; 34874f8687dSYoshie Muranaka transition: none; 3491f8117f8SSurenNeware display: inline-flex; 3501f8117f8SSurenNeware flex: 0 0 20px; 3511f8117f8SSurenNeware align-items: center; 35274f8687dSYoshie Muranaka 35374f8687dSYoshie Muranaka svg { 35474f8687dSYoshie Muranaka margin: 0; 35574f8687dSYoshie Muranaka } 35674f8687dSYoshie Muranaka 35774f8687dSYoshie Muranaka &:hover { 35801da8187SYoshie Muranaka fill: theme-color('light'); 3591f8117f8SSurenNeware background-color: theme-color-level(light, 10); 36074f8687dSYoshie Muranaka } 36174f8687dSYoshie Muranaka 362057232b8SSurenNeware &.open { 36301da8187SYoshie Muranaka background-color: gray('800'); 364057232b8SSurenNeware } 365057232b8SSurenNeware 36674f8687dSYoshie Muranaka @include media-breakpoint-up($responsive-layout-bp) { 36774f8687dSYoshie Muranaka display: none; 36874f8687dSYoshie Muranaka } 369dc04feb5SYoshie Muranaka } 370b1f559f0SSukanya Pandey 371b1f559f0SSukanya Pandey .dropdown-menu { 372057232b8SSurenNeware margin-top: 0; 3731f8117f8SSurenNeware 3741f8117f8SSurenNeware @include media-breakpoint-only(md) { 3751f8117f8SSurenNeware margin-top: 4px; 376b1f559f0SSukanya Pandey } 377b1f559f0SSukanya Pandey } 378057232b8SSurenNeware 379057232b8SSurenNeware .navbar-expand { 380057232b8SSurenNeware @include media-breakpoint-down(sm) { 381057232b8SSurenNeware flex-flow: wrap; 382057232b8SSurenNeware } 383057232b8SSurenNeware } 384057232b8SSurenNeware} 3851f8117f8SSurenNeware 3861f8117f8SSurenNeware.navbar-brand { 3871f8117f8SSurenNeware padding: $spacer/2; 3881f8117f8SSurenNeware height: $header-height; 3891f8117f8SSurenNeware line-height: 1; 3901f8117f8SSurenNeware &:focus { 3918132399cSEd Tanous box-shadow: 3928132399cSEd Tanous inset 0 0 0 3px $navbar-color, 3938132399cSEd Tanous inset 0 0 0 5px color('white'); 3941f8117f8SSurenNeware outline: 0; 3951f8117f8SSurenNeware } 3961f8117f8SSurenNeware} 397b8b6f791SYoshie Muranaka</style> 398