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