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