1<template> 2 <div> 3 <page-section :section-title="sectionTitle"> 4 <b-row class="row-cols-1 row-cols-md-2"> 5 <!-- Running image --> 6 <b-col class="mb-3"> 7 <b-card class="h-100"> 8 <template #header> 9 <p class="fw-bold m-0"> 10 {{ $t('pageFirmware.cardTitleRunning') }} 11 </p> 12 </template> 13 <dl class="mb-0"> 14 <dt>{{ $t('pageFirmware.cardBodyVersion') }}</dt> 15 <dd class="mb-0">{{ runningVersion }}</dd> 16 </dl> 17 </b-card> 18 </b-col> 19 20 <!-- Backup image --> 21 <b-col class="mb-3"> 22 <b-card class="h-100"> 23 <template #header> 24 <p class="fw-bold m-0"> 25 {{ $t('pageFirmware.cardTitleBackup') }} 26 </p> 27 </template> 28 <dl> 29 <dt>{{ $t('pageFirmware.cardBodyVersion') }}</dt> 30 <dd> 31 <status-icon v-if="showBackupImageStatus" status="danger" /> 32 <span 33 v-if="showBackupImageStatus" 34 class="visually-hidden-focusable" 35 > 36 {{ backupStatus }} 37 </span> 38 {{ backupVersion }} 39 </dd> 40 </dl> 41 <b-btn 42 v-if="!switchToBackupImageDisabled" 43 data-test-id="firmware-button-switchToRunning" 44 variant="link" 45 size="sm" 46 class="py-0 px-1 mt-2" 47 :disabled="isPageDisabled || !backup || !isServerOff" 48 @click="showSwitchToRunning = true" 49 > 50 <icon-switch class="d-none d-sm-inline-block" /> 51 {{ $t('pageFirmware.cardActionSwitchToRunning') }} 52 </b-btn> 53 </b-card> 54 </b-col> 55 </b-row> 56 </page-section> 57 <modal-switch-to-running 58 v-model="showSwitchToRunning" 59 :backup="backupVersion" 60 @ok="switchToRunning" 61 /> 62 </div> 63</template> 64 65<script> 66import IconSwitch from '@carbon/icons-vue/es/arrows--horizontal/20'; 67import PageSection from '@/components/Global/PageSection'; 68import LoadingBarMixin, { loading } from '@/components/Mixins/LoadingBarMixin'; 69import BVToastMixin from '@/components/Mixins/BVToastMixin'; 70 71import ModalSwitchToRunning from './FirmwareModalSwitchToRunning'; 72import { useI18n } from 'vue-i18n'; 73import i18n from '@/i18n'; 74 75export default { 76 components: { IconSwitch, ModalSwitchToRunning, PageSection }, 77 mixins: [BVToastMixin, LoadingBarMixin], 78 props: { 79 isPageDisabled: { 80 required: true, 81 type: Boolean, 82 default: false, 83 }, 84 isServerOff: { 85 required: true, 86 type: Boolean, 87 default: false, 88 }, 89 }, 90 data() { 91 return { 92 $t: useI18n().t, 93 loading, 94 switchToBackupImageDisabled: 95 process.env.VUE_APP_SWITCH_TO_BACKUP_IMAGE_DISABLED === 'true', 96 showSwitchToRunning: false, 97 }; 98 }, 99 computed: { 100 isSingleFileUploadEnabled() { 101 return this.$store.getters['firmware/isSingleFileUploadEnabled']; 102 }, 103 sectionTitle() { 104 if (this.isSingleFileUploadEnabled) { 105 return i18n.global.t('pageFirmware.sectionTitleBmcCardsCombined'); 106 } 107 return i18n.global.t('pageFirmware.sectionTitleBmcCards'); 108 }, 109 running() { 110 return this.$store.getters['firmware/activeBmcFirmware']; 111 }, 112 backup() { 113 return this.$store.getters['firmware/backupBmcFirmware']; 114 }, 115 runningVersion() { 116 return this.running?.version || '--'; 117 }, 118 backupVersion() { 119 return this.backup?.version || '--'; 120 }, 121 backupStatus() { 122 return this.backup?.status || null; 123 }, 124 showBackupImageStatus() { 125 return ( 126 this.backupStatus === 'Critical' || this.backupStatus === 'Warning' 127 ); 128 }, 129 }, 130 methods: { 131 switchToRunning() { 132 this.startLoader(); 133 const timerId = setTimeout(() => { 134 this.endLoader(); 135 this.infoToast( 136 i18n.global.t('pageFirmware.toast.verifySwitchMessage'), 137 { 138 title: i18n.global.t('pageFirmware.toast.verifySwitch'), 139 refreshAction: true, 140 }, 141 ); 142 }, 60000); 143 144 this.$store 145 .dispatch('firmware/switchBmcFirmwareAndReboot') 146 .then(() => 147 this.infoToast( 148 i18n.global.t('pageFirmware.toast.rebootStartedMessage'), 149 { 150 title: i18n.global.t('pageFirmware.toast.rebootStarted'), 151 }, 152 ), 153 ) 154 .catch(({ message }) => { 155 this.errorToast(message); 156 clearTimeout(timerId); 157 this.endLoader(); 158 }); 159 }, 160 }, 161}; 162</script> 163