1<template> 2 <page-section :section-title="$t('pageInventory.bmcManager')"> 3 <b-table 4 responsive="md" 5 hover 6 thead-class="table-light" 7 :items="items" 8 :fields="fields" 9 show-empty 10 :empty-text="$t('global.table.emptyMessage')" 11 :busy="isBusy" 12 > 13 <!-- Expand chevron icon --> 14 <template #cell(expandRow)="row"> 15 <b-button 16 variant="link" 17 data-test-id="hardwareStatus-button-expandBmc" 18 :title="expandRowLabel" 19 class="btn-icon-only" 20 :class="{ collapsed: !row.detailsShowing }" 21 @click="toggleRowDetails(row)" 22 > 23 <icon-chevron /> 24 <span class="visually-hidden">{{ expandRowLabel }}</span> 25 </b-button> 26 </template> 27 28 <!-- Health --> 29 <template #cell(health)="{ value }"> 30 <status-icon :status="statusIcon(value)" /> 31 {{ value }} 32 </template> 33 34 <!-- Toggle identify LED --> 35 <template #cell(identifyLed)="row"> 36 <b-form-checkbox 37 v-if="hasIdentifyLed(row.item.identifyLed)" 38 v-model="row.item.identifyLed" 39 name="switch" 40 switch 41 @change="toggleIdentifyLedValue(row.item)" 42 > 43 <span v-if="row.item.identifyLed"> 44 {{ $t('global.status.on') }} 45 </span> 46 <span v-else> {{ $t('global.status.off') }} </span> 47 </b-form-checkbox> 48 <div v-else>--</div> 49 </template> 50 51 <template #row-details="{ item }"> 52 <b-container fluid> 53 <b-row> 54 <b-col class="mt-2" sm="6" xl="6"> 55 <dl> 56 <!-- Name --> 57 <dt>{{ $t('pageInventory.table.name') }}:</dt> 58 <dd>{{ dataFormatter(item.name) }}</dd> 59 <!-- Part number --> 60 <dt>{{ $t('pageInventory.table.partNumber') }}:</dt> 61 <dd>{{ dataFormatter(item.partNumber) }}</dd> 62 <!-- Serial number --> 63 <dt>{{ $t('pageInventory.table.serialNumber') }}:</dt> 64 <dd>{{ dataFormatter(item.serialNumber) }}</dd> 65 <!-- Spare part number --> 66 <dt>{{ $t('pageInventory.table.sparePartNumber') }}:</dt> 67 <dd> 68 {{ dataFormatter(item.sparePartNumber) }} 69 </dd> 70 <!-- Model --> 71 <dt>{{ $t('pageInventory.table.model') }}:</dt> 72 <dd>{{ dataFormatter(item.model) }}</dd> 73 <!-- UUID --> 74 <dt>{{ $t('pageInventory.table.uuid') }}:</dt> 75 <dd>{{ dataFormatter(item.uuid) }}</dd> 76 <!-- Service entry point UUID --> 77 <dt>{{ $t('pageInventory.table.serviceEntryPointUuid') }}:</dt> 78 <dd> 79 {{ dataFormatter(item.serviceEntryPointUuid) }} 80 </dd> 81 </dl> 82 </b-col> 83 <b-col class="mt-2" sm="6" xl="6"> 84 <dl> 85 <!-- Status state --> 86 <dt>{{ $t('pageInventory.table.statusState') }}:</dt> 87 <dd>{{ dataFormatter(item.statusState) }}</dd> 88 <!-- Power state --> 89 <dt>{{ $t('pageInventory.table.power') }}:</dt> 90 <dd>{{ dataFormatter(item.powerState) }}</dd> 91 <!-- Health rollup --> 92 <dt>{{ $t('pageInventory.table.healthRollup') }}:</dt> 93 <dd>{{ dataFormatter(item.healthRollup) }}</dd> 94 <!-- BMC date and time --> 95 <dt>{{ $t('pageInventory.table.bmcDateTime') }}:</dt> 96 <dd> 97 {{ $filters.formatDate(item.dateTime) }} 98 {{ $filters.formatTime(item.dateTime) }} 99 </dd> 100 <!-- Reset date and time --> 101 <dt>{{ $t('pageInventory.table.lastResetTime') }}:</dt> 102 <dd> 103 {{ $filters.formatDate(item.lastResetTime) }} 104 {{ $filters.formatTime(item.lastResetTime) }} 105 </dd> 106 </dl> 107 </b-col> 108 </b-row> 109 <div class="section-divider mb-3 mt-3"></div> 110 <b-row> 111 <b-col class="mt-2" sm="6" xl="6"> 112 <dl> 113 <!-- Manufacturer --> 114 <dt>{{ $t('pageInventory.table.manufacturer') }}:</dt> 115 <dd>{{ dataFormatter(item.manufacturer) }}</dd> 116 <!-- Description --> 117 <dt>{{ $t('pageInventory.table.description') }}:</dt> 118 <dd>{{ dataFormatter(item.description) }}</dd> 119 <!-- Manager type --> 120 <dt>{{ $t('pageInventory.table.managerType') }}:</dt> 121 <dd>{{ dataFormatter(item.managerType) }}</dd> 122 </dl> 123 </b-col> 124 <b-col class="mt-2" sm="6" xl="6"> 125 <!-- Firmware Version --> 126 <dl> 127 <dt>{{ $t('pageInventory.table.firmwareVersion') }}:</dt> 128 <dd>{{ item.firmwareVersion }}</dd> 129 </dl> 130 <!-- Graphical console --> 131 <p class="mt-1 mb-2 h6 float-none m-0"> 132 {{ $t('pageInventory.table.graphicalConsole') }} 133 </p> 134 <dl class="ms-4"> 135 <dt>{{ $t('pageInventory.table.connectTypesSupported') }}:</dt> 136 <dd> 137 {{ dataFormatterArray(item.graphicalConsoleConnectTypes) }} 138 </dd> 139 <dt>{{ $t('pageInventory.table.maxConcurrentSessions') }}:</dt> 140 <dd> 141 {{ dataFormatter(item.graphicalConsoleMaxSessions) }} 142 </dd> 143 <dt>{{ $t('pageInventory.table.serviceEnabled') }}:</dt> 144 <dd> 145 {{ dataFormatter(item.graphicalConsoleEnabled) }} 146 </dd> 147 </dl> 148 </b-col> 149 </b-row> 150 </b-container> 151 </template> 152 </b-table> 153 </page-section> 154</template> 155 156<script> 157import PageSection from '@/components/Global/PageSection'; 158import IconChevron from '@carbon/icons-vue/es/chevron--down/20'; 159import StatusIcon from '@/components/Global/StatusIcon'; 160import BVToastMixin from '@/components/Mixins/BVToastMixin'; 161import TableRowExpandMixin, { 162 expandRowLabel, 163} from '@/components/Mixins/TableRowExpandMixin'; 164import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin'; 165import { useI18n } from 'vue-i18n'; 166import i18n from '@/i18n'; 167 168export default { 169 components: { IconChevron, PageSection, StatusIcon }, 170 mixins: [BVToastMixin, TableRowExpandMixin, DataFormatterMixin], 171 data() { 172 return { 173 $t: useI18n().t, 174 isBusy: true, 175 fields: [ 176 { 177 key: 'expandRow', 178 label: '', 179 tdClass: 'table-row-expand', 180 }, 181 { 182 key: 'id', 183 label: i18n.global.t('pageInventory.table.id'), 184 formatter: this.dataFormatter, 185 }, 186 { 187 key: 'health', 188 label: i18n.global.t('pageInventory.table.health'), 189 formatter: this.dataFormatter, 190 }, 191 { 192 key: 'locationNumber', 193 label: i18n.global.t('pageInventory.table.locationNumber'), 194 formatter: this.dataFormatter, 195 }, 196 { 197 key: 'identifyLed', 198 label: i18n.global.t('pageInventory.table.identifyLed'), 199 formatter: this.dataFormatter, 200 }, 201 ], 202 expandRowLabel: expandRowLabel, 203 }; 204 }, 205 computed: { 206 bmc() { 207 return this.$store.getters['bmc/bmc']; 208 }, 209 items() { 210 if (this.bmc) { 211 return [this.bmc]; 212 } else { 213 return []; 214 } 215 }, 216 }, 217 created() { 218 this.$store.dispatch('bmc/getBmcInfo').finally(() => { 219 // Emit initial data fetch complete to parent component 220 require('@/eventBus').default.$emit( 221 'hardware-status-bmc-manager-complete', 222 ); 223 this.isBusy = false; 224 }); 225 }, 226 methods: { 227 toggleIdentifyLedValue(row) { 228 this.$store 229 .dispatch('bmc/updateIdentifyLedValue', { 230 uri: row.uri, 231 identifyLed: row.identifyLed, 232 }) 233 .then((message) => this.successToast(message)) 234 .catch(({ message }) => this.errorToast(message)); 235 }, 236 // TO DO: remove hasIdentifyLed method once the following story is merged: 237 // https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/43179 238 hasIdentifyLed(identifyLed) { 239 return typeof identifyLed === 'boolean'; 240 }, 241 }, 242}; 243</script> 244