diff options
author | Yoshie Muranaka <yoshiemuranaka@gmail.com> | 2020-06-08 18:18:23 +0300 |
---|---|---|
committer | Derick Montague <derick.montague@ibm.com> | 2020-06-17 23:46:47 +0300 |
commit | 5918b48a0530a43a4dd9ee1a3f134846c948011e (patch) | |
tree | 6728686c82fa9cd31d1a8777d8acb65cd144f855 | |
parent | c687f101324f301de04e326b2937953a395a5fed (diff) | |
download | webui-vue-5918b48a0530a43a4dd9ee1a3f134846c948011e.tar.xz |
Add power supplies table to hardware status page
Adds items at /redfish/v1/Chassis/chassis/Power endpoint in
Power supplies table. Table is sortable and has a row expansion
to view details.
- Table sort mixin to reuse sort method for status values
Signed-off-by: Yoshie Muranaka <yoshiemuranaka@gmail.com>
Change-Id: Ib2953ad06be3fa25e9dbbbed34e37d09154431f5
-rw-r--r-- | src/components/Mixins/TableSortMixin.js | 11 | ||||
-rw-r--r-- | src/locales/en-US.json | 12 | ||||
-rw-r--r-- | src/store/index.js | 2 | ||||
-rw-r--r-- | src/store/modules/Health/PowerSupplyStore.js | 52 | ||||
-rw-r--r-- | src/views/Health/HardwareStatus/HardwareStatus.vue | 15 | ||||
-rw-r--r-- | src/views/Health/HardwareStatus/HardwareStatusTablePowerSupplies.vue | 131 |
6 files changed, 217 insertions, 6 deletions
diff --git a/src/components/Mixins/TableSortMixin.js b/src/components/Mixins/TableSortMixin.js new file mode 100644 index 00000000..7e988503 --- /dev/null +++ b/src/components/Mixins/TableSortMixin.js @@ -0,0 +1,11 @@ +const STATUS = ['OK', 'Warning', 'Critical']; + +const TableSortMixin = { + methods: { + sortStatus(a, b, key) { + return STATUS.indexOf(a[key]) - STATUS.indexOf(b[key]); + } + } +}; + +export default TableSortMixin; diff --git a/src/locales/en-US.json b/src/locales/en-US.json index 8072770f..1ccc330e 100644 --- a/src/locales/en-US.json +++ b/src/locales/en-US.json @@ -125,17 +125,21 @@ } }, "pageHardwareStatus": { + "powerSupplies": "Power supplies", "system": "System", "table": { - "id": "ID", - "health": "Health", - "partNumber": "Part number", - "serialNumber": "Serial number", "assetTag": "Asset tag", "description": "Description", + "efficiencyPercent": "Efficiency percent", + "firmwareVersion": "Firmware version", + "health": "Health", + "id": "ID", "indicatorLed": "Indicator LED", "model": "Model", + "partNumber": "Part number", + "powerInputWatts": "Power input watts", "powerState": "Power state", + "serialNumber": "Serial number", "statusHealthRollup": "Status (Health rollup)", "statusState": "Status (State)", "systemType": "System type" diff --git a/src/store/index.js b/src/store/index.js index 44b8ded6..8479a27b 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -15,6 +15,7 @@ import EventLogStore from './modules/Health/EventLogStore'; import SensorsStore from './modules/Health/SensorsStore'; import ServerLedStore from './modules/Control/ServerLedStore'; import SystemStore from './modules/Health/SystemStore'; +import PowerSupplyStore from './modules/Health/PowerSupplyStore'; import WebSocketPlugin from './plugins/WebSocketPlugin'; @@ -33,6 +34,7 @@ export default new Vuex.Store({ hostBootSettings: BootSettingsStore, controls: ControlStore, powerControl: PowerControlStore, + powerSupply: PowerSupplyStore, networkSettings: NetworkSettingStore, eventLog: EventLogStore, sensors: SensorsStore, diff --git a/src/store/modules/Health/PowerSupplyStore.js b/src/store/modules/Health/PowerSupplyStore.js new file mode 100644 index 00000000..4e3d5fef --- /dev/null +++ b/src/store/modules/Health/PowerSupplyStore.js @@ -0,0 +1,52 @@ +import api from '@/store/api'; + +const PowerSupplyStore = { + namespaced: true, + state: { + powerSupplies: [] + }, + getters: { + powerSupplies: state => state.powerSupplies + }, + mutations: { + setPowerSupply: (state, data) => { + state.powerSupplies = data.map(powerSupply => { + const { + EfficiencyPercent, + FirmwareVersion, + IndicatorLED, + MemberId, + Model, + PartNumber, + PowerInputWatts, + SerialNumber, + Status + } = powerSupply; + return { + id: MemberId, + health: Status.Health, + partNumber: PartNumber, + serialNumber: SerialNumber, + efficiencyPercent: EfficiencyPercent, + firmwareVersion: FirmwareVersion, + indicatorLed: IndicatorLED, + model: Model, + powerInputWatts: PowerInputWatts, + statusState: Status.State + }; + }); + } + }, + actions: { + async getPowerSupply({ commit }) { + return await api + .get('/redfish/v1/Chassis/chassis/Power') + .then(({ data: { PowerSupplies } }) => + commit('setPowerSupply', PowerSupplies) + ) + .catch(error => console.log(error)); + } + } +}; + +export default PowerSupplyStore; diff --git a/src/views/Health/HardwareStatus/HardwareStatus.vue b/src/views/Health/HardwareStatus/HardwareStatus.vue index 9f34b534..2860e599 100644 --- a/src/views/Health/HardwareStatus/HardwareStatus.vue +++ b/src/views/Health/HardwareStatus/HardwareStatus.vue @@ -4,25 +4,36 @@ <!-- System table --> <table-system /> + + <!-- Power supplies table --> + <table-power-supplies /> </b-container> </template> <script> import PageTitle from '@/components/Global/PageTitle'; import TableSystem from './HardwareStatusTableStystem'; +import TablePowerSupplies from './HardwareStatusTablePowerSupplies'; import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin'; export default { - components: { PageTitle, TableSystem }, + components: { PageTitle, TablePowerSupplies, TableSystem }, mixins: [LoadingBarMixin], created() { this.startLoader(); const systemTablePromise = new Promise(resolve => { this.$root.$on('hardwareStatus::system::complete', () => resolve()); }); + const powerSuppliesTablePromise = new Promise(resolve => { + this.$root.$on('hardwareStatus::powerSupplies::complete', () => + resolve() + ); + }); // Combine all child component Promises to indicate // when page data load complete - Promise.all([systemTablePromise]).finally(() => this.endLoader()); + Promise.all([systemTablePromise, powerSuppliesTablePromise]).finally(() => + this.endLoader() + ); }, beforeRouteLeave(to, from, next) { // Hide loader if user navigates away from page diff --git a/src/views/Health/HardwareStatus/HardwareStatusTablePowerSupplies.vue b/src/views/Health/HardwareStatus/HardwareStatusTablePowerSupplies.vue new file mode 100644 index 00000000..3e066b73 --- /dev/null +++ b/src/views/Health/HardwareStatus/HardwareStatusTablePowerSupplies.vue @@ -0,0 +1,131 @@ +<template> + <page-section :section-title="$t('pageHardwareStatus.powerSupplies')"> + <b-table + sort-icon-left + no-sort-reset + sort-by="health" + :items="powerSupplies" + :fields="fields" + :sort-desc="true" + :sort-compare="sortCompare" + > + <!-- Expand chevron icon --> + <template v-slot:cell(expandRow)="row"> + <b-button variant="link" @click="row.toggleDetails"> + <icon-chevron /> + </b-button> + </template> + + <!-- Health --> + <template v-slot:cell(health)="{ value }"> + <status-icon :status="statusIcon(value)" /> + {{ value }} + </template> + + <template v-slot:row-details="{ item }"> + <b-container fluid> + <b-row> + <b-col sm="6" xl="4"> + <dl> + <!-- Efficiency percent --> + <dt>{{ $t('pageHardwareStatus.table.efficiencyPercent') }}:</dt> + <dd>{{ tableFormatter(item.efficiencyPercent) }}</dd> + <br /> + <!-- Firmware version --> + <dt>{{ $t('pageHardwareStatus.table.firmwareVersion') }}:</dt> + <dd>{{ tableFormatter(item.firmwareVersion) }}</dd> + <br /> + <!-- Indicator LED --> + <dt>{{ $t('pageHardwareStatus.table.indicatorLed') }}:</dt> + <dd>{{ tableFormatter(item.indicatorLed) }}</dd> + </dl> + </b-col> + <b-col sm="6" xl="4"> + <dl> + <!-- Model --> + <dt>{{ $t('pageHardwareStatus.table.model') }}:</dt> + <dd>{{ tableFormatter(item.model) }}</dd> + <br /> + <!-- Power input watts --> + <dt>{{ $t('pageHardwareStatus.table.powerInputWatts') }}:</dt> + <dd>{{ tableFormatter(item.powerInputWatts) }}</dd> + <br /> + <!-- Status state --> + <dt>{{ $t('pageHardwareStatus.table.statusState') }}:</dt> + <dd>{{ tableFormatter(item.statusState) }}</dd> + </dl> + </b-col> + </b-row> + </b-container> + </template> + </b-table> + </page-section> +</template> + +<script> +import PageSection from '@/components/Global/PageSection'; +import IconChevron from '@carbon/icons-vue/es/chevron--down/20'; + +import StatusIcon from '@/components/Global/StatusIcon'; +import TableDataFormatter from '@/components/Mixins/TableDataFormatter'; +import TableSortMixin from '@/components/Mixins/TableSortMixin'; + +export default { + components: { IconChevron, PageSection, StatusIcon }, + mixins: [TableDataFormatter, TableSortMixin], + data() { + return { + fields: [ + { + key: 'expandRow', + label: '', + tdClass: 'table-row-expand', + sortable: false + }, + { + key: 'id', + label: this.$t('pageHardwareStatus.table.id'), + formatter: this.tableFormatter, + sortable: true + }, + { + key: 'health', + label: this.$t('pageHardwareStatus.table.health'), + formatter: this.tableFormatter, + sortable: true + }, + { + key: 'partNumber', + label: this.$t('pageHardwareStatus.table.partNumber'), + formatter: this.tableFormatter, + sortable: true + }, + { + key: 'serialNumber', + label: this.$t('pageHardwareStatus.table.serialNumber'), + formatter: this.tableFormatter, + sortable: true + } + ] + }; + }, + computed: { + powerSupplies() { + return this.$store.getters['powerSupply/powerSupplies']; + } + }, + created() { + this.$store.dispatch('powerSupply/getPowerSupply').finally(() => { + // Emit intial data fetch complete to parent component + this.$root.$emit('hardwareStatus::powerSupplies::complete'); + }); + }, + methods: { + sortCompare(a, b, key) { + if (key === 'health') { + return this.sortStatus(a, b, key); + } + } + } +}; +</script> |