diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/locales/en-US.json | 1 | ||||
-rw-r--r-- | src/store/index.js | 2 | ||||
-rw-r--r-- | src/store/modules/HardwareStatus/AssemblyStore.js | 66 | ||||
-rw-r--r-- | src/views/HardwareStatus/Inventory/Inventory.vue | 15 | ||||
-rw-r--r-- | src/views/HardwareStatus/Inventory/InventoryTableAssembly.vue | 149 |
5 files changed, 233 insertions, 0 deletions
diff --git a/src/locales/en-US.json b/src/locales/en-US.json index 4948c9da..a94d3995 100644 --- a/src/locales/en-US.json +++ b/src/locales/en-US.json @@ -374,6 +374,7 @@ "processors": "Processors", "quicklinkTitle": "Quick links to hardware components", "system": "System", + "assemblies": "Assemblies", "systemIndicator": { "powerStatus": "Power status", "identifyLed": "System identify LED", diff --git a/src/store/index.js b/src/store/index.js index 2408055d..d7c1b22d 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -23,6 +23,7 @@ import FanStore from './modules/HardwareStatus/FanStore'; import ChassisStore from './modules/HardwareStatus/ChassisStore'; import BmcStore from './modules/HardwareStatus/BmcStore'; import ProcessorStore from './modules/HardwareStatus/ProcessorStore'; +import AssemblyStore from './modules/HardwareStatus/AssemblyStore'; import PostCodeLogsStore from './modules/Logs/PostCodeLogsStore'; import PoliciesStore from './modules/SecurityAndAccess/PoliciesStore'; import FactoryResetStore from './modules/Operations/FactoryResetStore'; @@ -61,6 +62,7 @@ export default new Vuex.Store({ chassis: ChassisStore, bmc: BmcStore, processors: ProcessorStore, + assemblies: AssemblyStore, postCodeLogs: PostCodeLogsStore, virtualMedia: VirtualMediaStore, policies: PoliciesStore, diff --git a/src/store/modules/HardwareStatus/AssemblyStore.js b/src/store/modules/HardwareStatus/AssemblyStore.js new file mode 100644 index 00000000..56e5631d --- /dev/null +++ b/src/store/modules/HardwareStatus/AssemblyStore.js @@ -0,0 +1,66 @@ +import api from '@/store/api'; +import i18n from '@/i18n'; + +const AssemblyStore = { + namespaced: true, + state: { + assemblies: null, + }, + getters: { + assemblies: (state) => state.assemblies, + }, + mutations: { + setAssemblyInfo: (state, data) => { + state.assemblies = data.map((assembly) => { + const { + MemberId, + PartNumber, + SerialNumber, + SparePartNumber, + Model, + Name, + Location, + LocationIndicatorActive, + } = assembly; + return { + id: MemberId, + partNumber: PartNumber, + serialNumber: SerialNumber, + sparePartNumber: SparePartNumber, + model: Model, + name: Name, + locationNumber: Location?.PartLocation?.ServiceLabel, + identifyLed: LocationIndicatorActive, + uri: assembly['@odata.id'], + }; + }); + }, + }, + actions: { + async getAssemblyInfo({ commit }) { + return await api + .get('/redfish/v1/Chassis/chassis/Assembly') + .then(({ data }) => commit('setAssemblyInfo', data?.Assemblies)) + .catch((error) => console.log(error)); + }, + async updateIdentifyLedValue({ dispatch }, led) { + const uri = led.uri; + const updatedIdentifyLedValue = { + LocationIndicatorActive: led.identifyLed, + }; + return await api.patch(uri, updatedIdentifyLedValue).catch((error) => { + dispatch('getAssemblyInfo'); + console.log('error', error); + if (led.identifyLed) { + throw new Error(i18n.t('pageInventory.toast.errorEnableIdentifyLed')); + } else { + throw new Error( + i18n.t('pageInventory.toast.errorDisableIdentifyLed') + ); + } + }); + }, + }, +}; + +export default AssemblyStore; diff --git a/src/views/HardwareStatus/Inventory/Inventory.vue b/src/views/HardwareStatus/Inventory/Inventory.vue index a729aaa2..e3a7ea2f 100644 --- a/src/views/HardwareStatus/Inventory/Inventory.vue +++ b/src/views/HardwareStatus/Inventory/Inventory.vue @@ -42,6 +42,9 @@ <!-- Processors table --> <table-processors ref="processors" /> + + <!-- Assembly table --> + <table-assembly ref="assembly" /> </b-container> </template> @@ -55,6 +58,7 @@ import TableFans from './InventoryTableFans'; import TableBmcManager from './InventoryTableBmcManager'; import TableChassis from './InventoryTableChassis'; import TableProcessors from './InventoryTableProcessors'; +import TableAssembly from './InventoryTableAssembly'; import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin'; import PageSection from '@/components/Global/PageSection'; import JumpLink16 from '@carbon/icons-vue/es/jump-link/16'; @@ -72,6 +76,7 @@ export default { TableBmcManager, TableChassis, TableProcessors, + TableAssembly, PageSection, JumpLink: JumpLink16, }, @@ -133,6 +138,12 @@ export default { href: '#system', linkText: this.$t('pageInventory.system'), }, + { + id: 'assembly', + dataRef: 'assembly', + href: '#assembly', + linkText: this.$t('pageInventory.assemblies'), + }, ], }; }, @@ -170,6 +181,9 @@ export default { const systemTablePromise = new Promise((resolve) => { this.$root.$on('hardware-status-system-complete', () => resolve()); }); + const assemblyTablePromise = new Promise((resolve) => { + this.$root.$on('hardware-status-assembly-complete', () => resolve()); + }); // Combine all child component Promises to indicate // when page data load complete Promise.all([ @@ -181,6 +195,7 @@ export default { processorsTablePromise, serviceIndicatorPromise, systemTablePromise, + assemblyTablePromise, ]).finally(() => this.endLoader()); }, }; diff --git a/src/views/HardwareStatus/Inventory/InventoryTableAssembly.vue b/src/views/HardwareStatus/Inventory/InventoryTableAssembly.vue new file mode 100644 index 00000000..df435c84 --- /dev/null +++ b/src/views/HardwareStatus/Inventory/InventoryTableAssembly.vue @@ -0,0 +1,149 @@ +<template> + <page-section :section-title="$t('pageInventory.assemblies')"> + <b-table + sort-icon-left + no-sort-reset + hover + responsive="md" + :items="items" + :fields="fields" + show-empty + :empty-text="$t('global.table.emptyMessage')" + > + <!-- Expand chevron icon --> + <template #cell(expandRow)="row"> + <b-button + variant="link" + data-test-id="hardwareStatus-button-expandAssembly" + :title="expandRowLabel" + class="btn-icon-only" + @click="toggleRowDetails(row)" + > + <icon-chevron /> + <span class="sr-only">{{ expandRowLabel }}</span> + </b-button> + </template> + + <!-- Toggle identify LED --> + <template #cell(identifyLed)="row"> + <b-form-checkbox + v-if="hasIdentifyLed(row.item.identifyLed)" + v-model="row.item.identifyLed" + name="switch" + switch + @change="toggleIdentifyLedValue(row.item)" + > + <span v-if="row.item.identifyLed"> + {{ $t('global.status.on') }} + </span> + <span v-else> {{ $t('global.status.off') }} </span> + </b-form-checkbox> + <div v-else>--</div> + </template> + + <template #row-details="{ item }"> + <b-container fluid> + <b-row> + <b-col class="mt-2" sm="6" xl="6"> + <!-- Nmae --> + <dt>{{ $t('pageInventory.table.name') }}:</dt> + <dd>{{ tableFormatter(item.name) }}</dd> + <!-- Serial number --> + <dt>{{ $t('pageInventory.table.serialNumber') }}:</dt> + <dd>{{ tableFormatter(item.serialNumber) }}</dd> + </b-col> + <b-col class="mt-2" sm="6" xl="6"> + <!-- Model--> + <dt>Model</dt> + <dd>{{ tableFormatter(item.model) }}</dd> + <!-- Spare Part Number --> + <dt>Spare Part Number</dt> + <dd>{{ tableFormatter(item.sparePartNumber) }}</dd> + </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 BVToastMixin from '@/components/Mixins/BVToastMixin'; +import TableRowExpandMixin, { + expandRowLabel, +} from '@/components/Mixins/TableRowExpandMixin'; +import TableDataFormatterMixin from '@/components/Mixins/TableDataFormatterMixin'; + +export default { + components: { IconChevron, PageSection }, + mixins: [BVToastMixin, TableRowExpandMixin, TableDataFormatterMixin], + data() { + return { + fields: [ + { + key: 'expandRow', + label: '', + tdClass: 'table-row-expand', + }, + { + key: 'id', + label: this.$t('pageInventory.table.id'), + formatter: this.tableFormatter, + sortable: true, + }, + { + key: 'partNumber', + label: this.$t('pageInventory.table.partNumber'), + formatter: this.tableFormatter, + sortable: true, + }, + { + key: 'locationNumber', + label: this.$t('pageInventory.table.locationNumber'), + formatter: this.tableFormatter, + sortable: true, + }, + { + key: 'identifyLed', + label: this.$t('pageInventory.table.identifyLed'), + formatter: this.tableFormatter, + }, + ], + expandRowLabel: expandRowLabel, + }; + }, + computed: { + assemblies() { + return this.$store.getters['assemblies/assemblies']; + }, + items() { + if (this.assemblies) { + return this.assemblies; + } else { + return []; + } + }, + }, + created() { + this.$store.dispatch('assemblies/getAssemblyInfo').finally(() => { + // Emit initial data fetch complete to parent component + this.$root.$emit('hardware-status-assembly-complete'); + }); + }, + methods: { + toggleIdentifyLedValue(row) { + this.$store + .dispatch('assemblies/updateIdentifyLedValue', { + uri: row.uri, + identifyLed: row.identifyLed, + }) + .catch(({ message }) => this.errorToast(message)); + }, + hasIdentifyLed(identifyLed) { + return typeof identifyLed === 'boolean'; + }, + }, +}; +</script> |