1<template> 2 <page-section :section-title="$t('pageInventory.chassis')"> 3 <b-table 4 responsive="md" 5 hover 6 :items="chassis" 7 :fields="fields" 8 show-empty 9 :empty-text="$t('global.table.emptyMessage')" 10 > 11 <!-- Expand chevron icon --> 12 <template #cell(expandRow)="row"> 13 <b-button 14 variant="link" 15 data-test-id="hardwareStatus-button-expandChassis" 16 :title="expandRowLabel" 17 class="btn-icon-only" 18 @click="toggleRowDetails(row)" 19 > 20 <icon-chevron /> 21 <span class="sr-only">{{ expandRowLabel }}</span> 22 </b-button> 23 </template> 24 25 <!-- Health --> 26 <template #cell(health)="{ value }"> 27 <status-icon :status="statusIcon(value)" /> 28 {{ value }} 29 </template> 30 <!-- Toggle identify LED --> 31 <template #cell(identifyLed)="row"> 32 <b-form-checkbox 33 v-if="hasIdentifyLed(row.item.identifyLed)" 34 v-model="row.item.identifyLed" 35 name="switch" 36 switch 37 @change="toggleIdentifyLedValue(row.item)" 38 > 39 <span v-if="row.item.identifyLed"> 40 {{ $t('global.status.on') }} 41 </span> 42 <span v-else> {{ $t('global.status.off') }} </span> 43 </b-form-checkbox> 44 <div v-else>--</div> 45 </template> 46 <template #row-details="{ item }"> 47 <b-container fluid> 48 <b-row> 49 <b-col class="mt-2" sm="6" xl="6"> 50 <dl> 51 <!-- Name --> 52 <dt>{{ $t('pageInventory.table.name') }}:</dt> 53 <dd>{{ dataFormatter(item.name) }}</dd> 54 <!-- Part number --> 55 <dt>{{ $t('pageInventory.table.partNumber') }}:</dt> 56 <dd>{{ dataFormatter(item.partNumber) }}</dd> 57 <!-- Serial Number --> 58 <dt>{{ $t('pageInventory.table.serialNumber') }}:</dt> 59 <dd>{{ dataFormatter(item.serialNumber) }}</dd> 60 <!-- Model --> 61 <dt>{{ $t('pageInventory.table.model') }}:</dt> 62 <dd class="mb-2"> 63 {{ dataFormatter(item.model) }} 64 </dd> 65 <!-- Asset tag --> 66 <dt>{{ $t('pageInventory.table.assetTag') }}:</dt> 67 <dd class="mb-2"> 68 {{ dataFormatter(item.assetTag) }} 69 </dd> 70 </dl> 71 </b-col> 72 <b-col class="mt-2" sm="6" xl="6"> 73 <dl> 74 <!-- Status state --> 75 <dt>{{ $t('pageInventory.table.statusState') }}:</dt> 76 <dd>{{ dataFormatter(item.statusState) }}</dd> 77 <!-- Power state --> 78 <dt>{{ $t('pageInventory.table.power') }}:</dt> 79 <dd>{{ dataFormatter(item.power) }}</dd> 80 <!-- Health rollup --> 81 <dt>{{ $t('pageInventory.table.healthRollup') }}:</dt> 82 <dd>{{ dataFormatter(item.healthRollup) }}</dd> 83 </dl> 84 </b-col> 85 </b-row> 86 <div class="section-divider mb-3 mt-3"></div> 87 <b-row> 88 <b-col class="mt-2" sm="6" xl="6"> 89 <dl> 90 <!-- Manufacturer --> 91 <dt>{{ $t('pageInventory.table.manufacturer') }}:</dt> 92 <dd>{{ dataFormatter(item.manufacturer) }}</dd> 93 <!-- Chassis Type --> 94 <dt>{{ $t('pageInventory.table.chassisType') }}:</dt> 95 <dd>{{ dataFormatter(item.chassisType) }}</dd> 96 </dl> 97 </b-col> 98 <b-col class="mt-2" sm="6" xl="6"> 99 <dl> 100 <!-- Min power --> 101 <dt>{{ $t('pageInventory.table.minPowerWatts') }}:</dt> 102 <dd>{{ dataFormatter(item.minPowerWatts) }}</dd> 103 <!-- Max power --> 104 <dt>{{ $t('pageInventory.table.maxPowerWatts') }}:</dt> 105 <dd>{{ dataFormatter(item.maxPowerWatts) }}</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'; 118import BVToastMixin from '@/components/Mixins/BVToastMixin'; 119import StatusIcon from '@/components/Global/StatusIcon'; 120 121import TableRowExpandMixin, { 122 expandRowLabel, 123} from '@/components/Mixins/TableRowExpandMixin'; 124import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin'; 125 126export default { 127 components: { IconChevron, PageSection, StatusIcon }, 128 mixins: [BVToastMixin, TableRowExpandMixin, DataFormatterMixin], 129 data() { 130 return { 131 fields: [ 132 { 133 key: 'expandRow', 134 label: '', 135 tdClass: 'table-row-expand', 136 }, 137 { 138 key: 'id', 139 label: this.$t('pageInventory.table.id'), 140 formatter: this.dataFormatter, 141 }, 142 { 143 key: 'health', 144 label: this.$t('pageInventory.table.health'), 145 formatter: this.dataFormatter, 146 tdClass: 'text-nowrap', 147 }, 148 { 149 key: 'locationNumber', 150 label: this.$t('pageInventory.table.locationNumber'), 151 formatter: this.dataFormatter, 152 }, 153 { 154 key: 'identifyLed', 155 label: this.$t('pageInventory.table.identifyLed'), 156 formatter: this.dataFormatter, 157 }, 158 ], 159 expandRowLabel: expandRowLabel, 160 }; 161 }, 162 computed: { 163 chassis() { 164 return this.$store.getters['chassis/chassis']; 165 }, 166 }, 167 created() { 168 this.$store.dispatch('chassis/getChassisInfo').finally(() => { 169 // Emit initial data fetch complete to parent component 170 this.$root.$emit('hardware-status-chassis-complete'); 171 }); 172 }, 173 methods: { 174 toggleIdentifyLedValue(row) { 175 this.$store 176 .dispatch('chassis/updateIdentifyLedValue', { 177 uri: row.uri, 178 identifyLed: row.identifyLed, 179 }) 180 .catch(({ message }) => this.errorToast(message)); 181 }, 182 // TO DO: Remove this method when the LocationIndicatorActive is added from backend. 183 hasIdentifyLed(identifyLed) { 184 return typeof identifyLed === 'boolean'; 185 }, 186 }, 187}; 188</script> 189