1<template> 2 <page-section :section-title="$t('pageInventory.powerSupplies')"> 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="powerSupplies.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 responsive="md" 22 sort-by="health" 23 show-empty 24 :items="powerSupplies" 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 @filtered="onFiltered" 32 > 33 <!-- Expand chevron icon --> 34 <template #cell(expandRow)="row"> 35 <b-button 36 variant="link" 37 data-test-id="hardwareStatus-button-expandPowerSupplies" 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 47 <!-- Health --> 48 <template #cell(health)="{ value }"> 49 <status-icon :status="statusIcon(value)" /> 50 {{ value }} 51 </template> 52 53 <template #row-details="{ item }"> 54 <b-container fluid> 55 <b-row> 56 <b-col sm="6" xl="4"> 57 <dl> 58 <!-- Name --> 59 <dt>{{ $t('pageInventory.table.name') }}:</dt> 60 <dd>{{ tableFormatter(item.name) }}</dd> 61 <!-- Part number --> 62 <dt>{{ $t('pageInventory.table.partNumber') }}:</dt> 63 <dd>{{ tableFormatter(item.partNumber) }}</dd> 64 <!-- Serial number --> 65 <dt>{{ $t('pageInventory.table.serialNumber') }}:</dt> 66 <dd>{{ tableFormatter(item.serialNumber) }}</dd> 67 <!-- Spare part number --> 68 <dt>{{ $t('pageInventory.table.sparePartNumber') }}:</dt> 69 <dd>{{ tableFormatter(item.sparePartNumber) }}</dd> 70 <!-- Model --> 71 <dt>{{ $t('pageInventory.table.model') }}:</dt> 72 <dd>{{ tableFormatter(item.model) }}</dd> 73 </dl> 74 </b-col> 75 <b-col sm="6" xl="4"> 76 <dl> 77 <!-- Status state --> 78 <dt>{{ $t('pageInventory.table.statusState') }}:</dt> 79 <dd>{{ tableFormatter(item.statusState) }}</dd> 80 <!-- Status Health rollup state --> 81 <dt>{{ $t('pageInventory.table.statusHealthRollup') }}:</dt> 82 <dd>{{ tableFormatter(item.statusHealth) }}</dd> 83 <!-- Efficiency percent --> 84 <dt>{{ $t('pageInventory.table.efficiencyPercent') }}:</dt> 85 <dd>{{ tableFormatter(item.efficiencyPercent) }}</dd> 86 <!-- Power input watts --> 87 <dt>{{ $t('pageInventory.table.powerInputWatts') }}:</dt> 88 <dd>{{ tableFormatter(item.powerInputWatts) }}</dd> 89 </dl> 90 </b-col> 91 </b-row> 92 <div class="section-divider mb-3 mt-3"></div> 93 <b-row> 94 <b-col sm="6" xl="4"> 95 <dl> 96 <!-- Manufacturer --> 97 <dt>{{ $t('pageInventory.table.manufacturer') }}:</dt> 98 <dd>{{ tableFormatter(item.manufacturer) }}</dd> 99 </dl> 100 </b-col> 101 <b-col sm="6" xl="4"> 102 <dl> 103 <!-- Firmware version --> 104 <dt>{{ $t('pageInventory.table.firmwareVersion') }}:</dt> 105 <dd>{{ tableFormatter(item.firmwareVersion) }}</dd> 106 </dl> 107 </b-col> 108 </b-row> 109 </b-container> 110 </template> 111 </b-table> 112 </page-section> 113</template> 114 115<script> 116import PageSection from '@/components/Global/PageSection'; 117import IconChevron from '@carbon/icons-vue/es/chevron--down/20'; 118 119import StatusIcon from '@/components/Global/StatusIcon'; 120import TableCellCount from '@/components/Global/TableCellCount'; 121import TableDataFormatterMixin from '@/components/Mixins/TableDataFormatterMixin'; 122import TableSortMixin from '@/components/Mixins/TableSortMixin'; 123import Search from '@/components/Global/Search'; 124import SearchFilterMixin, { 125 searchFilter, 126} from '@/components/Mixins/SearchFilterMixin'; 127import TableRowExpandMixin, { 128 expandRowLabel, 129} from '@/components/Mixins/TableRowExpandMixin'; 130 131export default { 132 components: { IconChevron, PageSection, StatusIcon, Search, TableCellCount }, 133 mixins: [ 134 TableRowExpandMixin, 135 TableDataFormatterMixin, 136 TableSortMixin, 137 SearchFilterMixin, 138 ], 139 data() { 140 return { 141 fields: [ 142 { 143 key: 'expandRow', 144 label: '', 145 tdClass: 'table-row-expand', 146 sortable: false, 147 }, 148 { 149 key: 'id', 150 label: this.$t('pageInventory.table.id'), 151 formatter: this.tableFormatter, 152 sortable: true, 153 }, 154 { 155 key: 'health', 156 label: this.$t('pageInventory.table.health'), 157 formatter: this.tableFormatter, 158 sortable: true, 159 tdClass: 'text-nowrap', 160 }, 161 { 162 key: 'locationNumber', 163 label: this.$t('pageInventory.table.locationNumber'), 164 formatter: this.tableFormatter, 165 sortable: true, 166 }, 167 { 168 key: 'identifyLed', 169 label: this.$t('pageInventory.table.identifyLed'), 170 formatter: this.tableFormatter, 171 }, 172 ], 173 searchFilter: searchFilter, 174 searchTotalFilteredRows: 0, 175 expandRowLabel: expandRowLabel, 176 }; 177 }, 178 computed: { 179 filteredRows() { 180 return this.searchFilter 181 ? this.searchTotalFilteredRows 182 : this.powerSupplies.length; 183 }, 184 powerSupplies() { 185 return this.$store.getters['powerSupply/powerSupplies']; 186 }, 187 }, 188 created() { 189 this.$store.dispatch('powerSupply/getAllPowerSupplies').finally(() => { 190 // Emit initial data fetch complete to parent component 191 this.$root.$emit('hardware-status-power-supplies-complete'); 192 }); 193 }, 194 methods: { 195 sortCompare(a, b, key) { 196 if (key === 'health') { 197 return this.sortStatus(a, b, key); 198 } 199 }, 200 onFiltered(filteredItems) { 201 this.searchTotalFilteredRows = filteredItems.length; 202 }, 203 }, 204}; 205</script> 206