1<template> 2 <page-section :section-title="$t('pageInventory.processors')"> 3 <!-- Search --> 4 <b-row class="align-items-end"> 5 <b-col sm="6" md="5" xl="4"> 6 <search 7 @change-search="onChangeSearchInput" 8 @clear-search="onClearSearchInput" 9 /> 10 </b-col> 11 <b-col sm="6" md="3" xl="2"> 12 <table-cell-count 13 :filtered-items-count="filteredRows" 14 :total-number-of-cells="processors.length" 15 ></table-cell-count> 16 </b-col> 17 </b-row> 18 <b-table 19 sort-icon-left 20 no-sort-reset 21 hover 22 responsive="md" 23 show-empty 24 :items="processors" 25 :fields="fields" 26 :sort-desc="true" 27 :filter="searchFilter" 28 :empty-text="$t('global.table.emptyMessage')" 29 :empty-filtered-text="$t('global.table.emptySearchMessage')" 30 :busy="isBusy" 31 @filtered="onFiltered" 32 > 33 <!-- Expand button --> 34 <template #cell(expandRow)="row"> 35 <b-button 36 variant="link" 37 data-test-id="hardwareStatus-button-expandProcessors" 38 :title="expandRowLabel" 39 class="btn-icon-only" 40 @click="toggleRowDetails(row)" 41 > 42 <icon-chevron /> 43 <span class="sr-only">{{ expandRowLabel }}</span> 44 </b-button> 45 </template> 46 <!-- Health --> 47 <template #cell(health)="{ value }"> 48 <status-icon :status="statusIcon(value)" /> 49 {{ value }} 50 </template> 51 <!-- StatusState --> 52 <template #cell(statusState)="{ value }"> 53 <status-icon :status="statusStateIcon(value)" /> 54 {{ value }} 55 </template> 56 57 <!-- Toggle identify LED --> 58 <template #cell(identifyLed)="row"> 59 <b-form-checkbox 60 v-if="hasIdentifyLed(row.item.identifyLed)" 61 v-model="row.item.identifyLed" 62 name="switch" 63 switch 64 @change="toggleIdentifyLedValue(row.item)" 65 > 66 <span v-if="row.item.identifyLed"> 67 {{ $t('global.status.on') }} 68 </span> 69 <span v-else> {{ $t('global.status.off') }} </span> 70 </b-form-checkbox> 71 <div v-else>--</div> 72 </template> 73 74 <template #row-details="{ item }"> 75 <b-container fluid> 76 <b-row> 77 <b-col class="mt-2" sm="6" xl="6"> 78 <dl> 79 <!-- Name --> 80 <dt>{{ $t('pageInventory.table.name') }}:</dt> 81 <dd>{{ dataFormatter(item.name) }}</dd> 82 <!-- Part Number --> 83 <dt>{{ $t('pageInventory.table.partNumber') }}:</dt> 84 <dd>{{ dataFormatter(item.partNumber) }}</dd> 85 <!-- Serial Number --> 86 <dt>{{ $t('pageInventory.table.serialNumber') }}:</dt> 87 <dd>{{ dataFormatter(item.serialNumber) }}</dd> 88 <!-- Spare Part Number --> 89 <dt>{{ $t('pageInventory.table.sparePartNumber') }}:</dt> 90 <dd>{{ dataFormatter(item.sparePartNumber) }}</dd> 91 <!-- Model --> 92 <dt>{{ $t('pageInventory.table.model') }}:</dt> 93 <dd>{{ dataFormatter(item.model) }}</dd> 94 <!-- Asset Tag --> 95 <dt>{{ $t('pageInventory.table.assetTag') }}:</dt> 96 <dd>{{ dataFormatter(item.assetTag) }}</dd> 97 </dl> 98 </b-col> 99 <b-col class="mt-2" sm="6" xl="6"> 100 <dl> 101 <!-- Status state --> 102 <dt>{{ $t('pageInventory.table.statusState') }}:</dt> 103 <dd>{{ dataFormatter(item.statusState) }}</dd> 104 <!-- Health Rollup --> 105 <dt>{{ $t('pageInventory.table.healthRollup') }}:</dt> 106 <dd>{{ dataFormatter(item.healthRollup) }}</dd> 107 </dl> 108 </b-col> 109 </b-row> 110 <div class="section-divider mb-3 mt-3"></div> 111 <b-row> 112 <b-col class="mt-1" sm="6" xl="6"> 113 <dl> 114 <!-- Manufacturer --> 115 <dt>{{ $t('pageInventory.table.manufacturer') }}:</dt> 116 <dd>{{ dataFormatter(item.manufacturer) }}</dd> 117 <!-- Processor Type --> 118 <dt>{{ $t('pageInventory.table.processorType') }}:</dt> 119 <dd>{{ dataFormatter(item.processorType) }}</dd> 120 <!-- Processor Architecture --> 121 <dt>{{ $t('pageInventory.table.processorArchitecture') }}:</dt> 122 <dd>{{ dataFormatter(item.processorArchitecture) }}</dd> 123 <!-- Instruction Set --> 124 <dt>{{ $t('pageInventory.table.instructionSet') }}:</dt> 125 <dd>{{ dataFormatter(item.instructionSet) }}</dd> 126 <!-- Version --> 127 <dt>{{ $t('pageInventory.table.version') }}:</dt> 128 <dd>{{ dataFormatter(item.version) }}</dd> 129 </dl> 130 </b-col> 131 <b-col class="mt-1" sm="6" xl="6"> 132 <dl> 133 <!-- Min Speed MHz --> 134 <dt>{{ $t('pageInventory.table.minSpeedMHz') }}:</dt> 135 <dd> 136 {{ dataFormatter(item.minSpeedMHz) }} 137 {{ $t('unit.MHz') }} 138 </dd> 139 <!-- Max Speed MHz --> 140 <dt>{{ $t('pageInventory.table.maxSpeedMHz') }}:</dt> 141 <dd> 142 {{ dataFormatter(item.maxSpeedMHz) }} 143 {{ $t('unit.MHz') }} 144 </dd> 145 <!-- Total Cores --> 146 <dt>{{ $t('pageInventory.table.totalCores') }}:</dt> 147 <dd>{{ dataFormatter(item.totalCores) }}</dd> 148 <!-- Total Threads --> 149 <dt>{{ $t('pageInventory.table.totalThreads') }}:</dt> 150 <dd>{{ dataFormatter(item.totalThreads) }}</dd> 151 </dl> 152 </b-col> 153 </b-row> 154 </b-container> 155 </template> 156 </b-table> 157 </page-section> 158</template> 159 160<script> 161import PageSection from '@/components/Global/PageSection'; 162import IconChevron from '@carbon/icons-vue/es/chevron--down/20'; 163import StatusIcon from '@/components/Global/StatusIcon'; 164import TableCellCount from '@/components/Global/TableCellCount'; 165import BVToastMixin from '@/components/Mixins/BVToastMixin'; 166import TableSortMixin from '@/components/Mixins/TableSortMixin'; 167import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin'; 168import Search from '@/components/Global/Search'; 169import SearchFilterMixin, { 170 searchFilter, 171} from '@/components/Mixins/SearchFilterMixin'; 172import TableRowExpandMixin, { 173 expandRowLabel, 174} from '@/components/Mixins/TableRowExpandMixin'; 175 176export default { 177 components: { IconChevron, PageSection, StatusIcon, Search, TableCellCount }, 178 mixins: [ 179 BVToastMixin, 180 TableRowExpandMixin, 181 DataFormatterMixin, 182 TableSortMixin, 183 SearchFilterMixin, 184 ], 185 data() { 186 return { 187 isBusy: true, 188 fields: [ 189 { 190 key: 'expandRow', 191 label: '', 192 tdClass: 'table-row-expand', 193 sortable: false, 194 }, 195 { 196 key: 'id', 197 label: this.$t('pageInventory.table.id'), 198 formatter: this.dataFormatter, 199 sortable: true, 200 }, 201 { 202 key: 'health', 203 label: this.$t('pageInventory.table.health'), 204 formatter: this.dataFormatter, 205 sortable: true, 206 tdClass: 'text-nowrap', 207 }, 208 { 209 key: 'statusState', 210 label: this.$t('pageInventory.table.state'), 211 formatter: this.dataFormatter, 212 sortable: true, 213 tdClass: 'text-nowrap', 214 }, 215 { 216 key: 'locationNumber', 217 label: this.$t('pageInventory.table.locationNumber'), 218 formatter: this.dataFormatter, 219 sortable: true, 220 }, 221 { 222 key: 'identifyLed', 223 label: this.$t('pageInventory.table.identifyLed'), 224 formatter: this.dataFormatter, 225 sortable: false, 226 }, 227 ], 228 searchFilter: searchFilter, 229 searchTotalFilteredRows: 0, 230 expandRowLabel: expandRowLabel, 231 }; 232 }, 233 computed: { 234 filteredRows() { 235 return this.searchFilter 236 ? this.searchTotalFilteredRows 237 : this.processors.length; 238 }, 239 processors() { 240 return this.$store.getters['processors/processors']; 241 }, 242 }, 243 created() { 244 this.$store.dispatch('processors/getProcessorsInfo').finally(() => { 245 // Emit initial data fetch complete to parent component 246 this.$root.$emit('hardware-status-processors-complete'); 247 this.isBusy = false; 248 }); 249 }, 250 methods: { 251 onFiltered(filteredItems) { 252 this.searchTotalFilteredRows = filteredItems.length; 253 }, 254 toggleIdentifyLedValue(row) { 255 this.$store 256 .dispatch('processors/updateIdentifyLedValue', { 257 uri: row.uri, 258 identifyLed: row.identifyLed, 259 }) 260 .then((message) => this.successToast(message)) 261 .catch(({ message }) => this.errorToast(message)); 262 }, 263 // TO DO: remove hasIdentifyLed when the following is merged: 264 // https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/37045 265 hasIdentifyLed(identifyLed) { 266 return typeof identifyLed === 'boolean'; 267 }, 268 statusStateIcon(status) { 269 switch (status) { 270 case 'Enabled': 271 return 'success'; 272 case 'Absent': 273 return 'warning'; 274 default: 275 return ''; 276 } 277 }, 278 }, 279}; 280</script> 281