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