Migrate to Bootstrap 5 and remove Vue compat plugin
Complete migration from Bootstrap 4 (bootstrap-vue) to Bootstrap 5
(bootstrap-vue-next) and remove the @vue/compat plugin to finalize
the Vue 3 migration.
Bundle size impact:
- Before (Bootstrap 4 + bootstrap-vue): 535 KiB gzipped
- After (Bootstrap 5 + bootstrap-vue-next): 511 KiB gzipped
- Reduction: 24 KiB (4.5% smaller)
Package updates:
- Update bootstrap 4.6.2 -> 5.3.8
- Update bootstrap-vue 2.23.1 -> bootstrap-vue-next 0.40.8
- Remove @vue/compat plugin
- Update vue 3.4.29 -> 3.5.24 and related packages
- Add mitt 3.0.1 for global event bus
- Add vue-demi 0.14.10 for library compatibility
Bootstrap 5 CSS updates:
- Replace directional classes: ml/mr/pl/pr -> ms/me/ps/pe
- Replace text-left/right -> text-start/end
- Replace sr-only -> visually-hidden / visually-hidden-focusable
- Update media breakpoint xs -> sm (Bootstrap 5 removed xs)
- Update color functions: gray("700") -> $gray-700
- Add form-switch border-radius for curved toggles
- Update alert, table, toast, form, and button styles
Bootstrap-Vue-Next API changes:
- Use createBootstrap() for plugin registration
- Update modal footer slots: #modal-footer -> #footer
- Fix form select events: @change -> @update:model-value
- Add v-model bindings to modals instead of manual show()/hide()
- Update toast system with custom plugin wrapping useToast()
- Register components and directives explicitly
Vue 3 specific updates:
- Replace $root.$emit with mitt event bus (eventBus.js)
- Update render function from h(App) to createApp(App)
- Add emits option to components
- Use h() instead of $createElement in mixins
- Add Vue 3 compile-time feature flags with documentation
- Update event listeners: $on/$off to eventBus methods
- Add beforeUnmount cleanup for event listeners
New components and significant additions:
- src/plugins/toast.js - Custom toast plugin wrapping useToast() for
Options API compatibility
- src/components/Global/ConfirmModal.vue - Global confirmation dialog
shim to replace Bootstrap 4's removed bvModal.msgBoxConfirm
- src/eventBus.js - mitt-based event bus with Vue 2-compatible API
- Navigation state preservation on page refresh implemented
Critical fixes:
- Add global API interceptor to strip Vue reactivity from payloads
- Preserve binary data (File, Blob, FormData) in API requests
- Fix Generate CSR modal v-model binding for proper open/close
- Remove debug logging and fix jest configuration
- Fix responsive text visibility in AppHeader
- Update BVTableSelectableMixin for proper row selection
- Fix BVToastMixin VNode rendering for Vue 3
Vue 3 modal fixes (lazy-loaded components):
- Add v-model support to network modals (ModalIpv4, ModalIpv6, ModalDns,
ModalHostname, ModalMacAddress, ModalDefaultGateway) by adding
modelValue prop, watcher on modelValue that triggers show(), and
update:modelValue emit in resetForm
- Remove lazy loading from TableIpv4, TableIpv6, TableDns to ensure
modal component refs are available when v-model triggers
- Fix modal title accessibility by adding title prop to modals
(ModalAddDestination, ModalUser, ModalAddRoleGroup, etc.)
i18n fixes (computed properties):
- Fix computed properties using i18n translations in ModalAddRoleGroup,
ModalUser, and ModalUploadCertificate
- Move useI18n() call from data() to setup() and return i18n object
- Use i18n.t() instead of $t in computed properties and templates
- Prevents "this.$t is not a function" and "_ctx.$t is not a function"
errors in Vue 3
Toast notification fixes:
- Fix toast progress bar visibility by setting progressProps to
undefined (documented way to opt-out) instead of false
- Change modelValue prop to interval for auto-dismiss timing
- Remove temporary CSS display:none hack from _toasts.scss
Network settings fixes:
- Fix checkbox @change event sending Vue reactive proxy object instead
of boolean by casting with !! operator in changeDomainNameState and
related methods in NetworkGlobalSettings.vue
- Ensures API receives plain boolean values in PATCH requests
Navigation fixes:
- Fix nav-link styling for navigation items without children by
replacing b-nav-item with router-link in AppNavigation.vue
- Prevents blue font color from .nav-link CSS class
Configuration updates:
- Remove vue-compat webpack configuration
- Add Vue 3 feature flags (__VUE_OPTIONS_API__, etc.)
- Add .cursor to .gitignore
Accessibility improvements:
- Add autocomplete attributes to password and credential inputs
- Add modal title props for screen reader support
Build completes successfully and UI behavior matches pre-migration.
Extracted features (to be submitted in follow-up PRs):
The following features were removed from this migration PR to keep it
focused on the Bootstrap 5 upgrade. They will be submitted separately:
1. UnresponsiveModal - Server connectivity watchdog with auto-retry
2. Auth token persistence - sessionStorage support for X-Auth-Token
3. Hardware store error handling - try/catch, dynamic discovery
4. Login page connecting indicator - Backend polling with spinner
5. Test updates - Jest setup and snapshot updates for
Bootstrap-Vue-Next
6. Documentation updates - Vue 3 and Vue I18n v9+ API documentation
7. Enhanced ConfirmModal - Feature-rich confirmation dialog with
custom actions
Change-Id: Ib76a58f324b3c926cf536e6e4626e4271639de38
Signed-off-by: Jason Westover <jwestover@nvidia.com>
diff --git a/src/views/HardwareStatus/Inventory/Inventory.vue b/src/views/HardwareStatus/Inventory/Inventory.vue
index a3f4d23..d99a792 100644
--- a/src/views/HardwareStatus/Inventory/Inventory.vue
+++ b/src/views/HardwareStatus/Inventory/Inventory.vue
@@ -153,33 +153,56 @@
created() {
this.startLoader();
const bmcManagerTablePromise = new Promise((resolve) => {
- this.$root.$on('hardware-status-bmc-manager-complete', () => resolve());
+ require('@/eventBus').default.$on(
+ 'hardware-status-bmc-manager-complete',
+ () => resolve(),
+ );
});
const chassisTablePromise = new Promise((resolve) => {
- this.$root.$on('hardware-status-chassis-complete', () => resolve());
+ require('@/eventBus').default.$on(
+ 'hardware-status-chassis-complete',
+ () => resolve(),
+ );
});
const dimmSlotTablePromise = new Promise((resolve) => {
- this.$root.$on('hardware-status-dimm-slot-complete', () => resolve());
+ require('@/eventBus').default.$on(
+ 'hardware-status-dimm-slot-complete',
+ () => resolve(),
+ );
});
const fansTablePromise = new Promise((resolve) => {
- this.$root.$on('hardware-status-fans-complete', () => resolve());
- });
- const powerSuppliesTablePromise = new Promise((resolve) => {
- this.$root.$on('hardware-status-power-supplies-complete', () =>
+ require('@/eventBus').default.$on('hardware-status-fans-complete', () =>
resolve(),
);
});
+ const powerSuppliesTablePromise = new Promise((resolve) => {
+ require('@/eventBus').default.$on(
+ 'hardware-status-power-supplies-complete',
+ () => resolve(),
+ );
+ });
const processorsTablePromise = new Promise((resolve) => {
- this.$root.$on('hardware-status-processors-complete', () => resolve());
+ require('@/eventBus').default.$on(
+ 'hardware-status-processors-complete',
+ () => resolve(),
+ );
});
const serviceIndicatorPromise = new Promise((resolve) => {
- this.$root.$on('hardware-status-service-complete', () => resolve());
+ require('@/eventBus').default.$on(
+ 'hardware-status-service-complete',
+ () => resolve(),
+ );
});
const systemTablePromise = new Promise((resolve) => {
- this.$root.$on('hardware-status-system-complete', () => resolve());
+ require('@/eventBus').default.$on('hardware-status-system-complete', () =>
+ resolve(),
+ );
});
const assemblyTablePromise = new Promise((resolve) => {
- this.$root.$on('hardware-status-assembly-complete', () => resolve());
+ require('@/eventBus').default.$on(
+ 'hardware-status-assembly-complete',
+ () => resolve(),
+ );
});
// Combine all child component Promises to indicate
// when page data load complete
diff --git a/src/views/HardwareStatus/Inventory/InventoryServiceIndicator.vue b/src/views/HardwareStatus/Inventory/InventoryServiceIndicator.vue
index 5b19b42..0a1a84b 100644
--- a/src/views/HardwareStatus/Inventory/InventoryServiceIndicator.vue
+++ b/src/views/HardwareStatus/Inventory/InventoryServiceIndicator.vue
@@ -2,11 +2,13 @@
<page-section
:section-title="$t('pageInventory.systemIndicator.sectionTitle')"
>
- <div class="form-background pl-4 pt-4 pb-1">
+ <div class="form-background ps-4 pt-4 pb-1">
<b-row>
<b-col sm="6" md="3">
<dl>
- <dt>{{ $t('pageInventory.systemIndicator.powerStatus') }}</dt>
+ <dt>
+ {{ $t('pageInventory.systemIndicator.powerStatus') }}
+ </dt>
<dd>
{{ $t(powerStatus) }}
</dd>
@@ -68,7 +70,7 @@
created() {
this.$store.dispatch('system/getSystem').finally(() => {
// Emit initial data fetch complete to parent component
- this.$root.$emit('hardware-status-service-complete');
+ require('@/eventBus').default.$emit('hardware-status-service-complete');
});
},
methods: {
diff --git a/src/views/HardwareStatus/Inventory/InventoryTableAssembly.vue b/src/views/HardwareStatus/Inventory/InventoryTableAssembly.vue
index 68bee05..e267f7f 100644
--- a/src/views/HardwareStatus/Inventory/InventoryTableAssembly.vue
+++ b/src/views/HardwareStatus/Inventory/InventoryTableAssembly.vue
@@ -2,9 +2,10 @@
<page-section :section-title="$t('pageInventory.assemblies')">
<b-table
sort-icon-left
- no-sort-reset
+ must-sort
hover
responsive="md"
+ thead-class="table-light"
:items="items"
:fields="fields"
show-empty
@@ -18,10 +19,11 @@
data-test-id="hardwareStatus-button-expandAssembly"
:title="expandRowLabel"
class="btn-icon-only"
+ :class="{ collapsed: !row.detailsShowing }"
@click="toggleRowDetails(row)"
>
<icon-chevron />
- <span class="sr-only">{{ expandRowLabel }}</span>
+ <span class="visually-hidden">{{ expandRowLabel }}</span>
</b-button>
</template>
@@ -134,7 +136,7 @@
created() {
this.$store.dispatch('assemblies/getAssemblyInfo').finally(() => {
// Emit initial data fetch complete to parent component
- this.$root.$emit('hardware-status-assembly-complete');
+ require('@/eventBus').default.$emit('hardware-status-assembly-complete');
this.isBusy = false;
});
},
diff --git a/src/views/HardwareStatus/Inventory/InventoryTableBmcManager.vue b/src/views/HardwareStatus/Inventory/InventoryTableBmcManager.vue
index 4ee4eba..8a0671e 100644
--- a/src/views/HardwareStatus/Inventory/InventoryTableBmcManager.vue
+++ b/src/views/HardwareStatus/Inventory/InventoryTableBmcManager.vue
@@ -3,6 +3,7 @@
<b-table
responsive="md"
hover
+ thead-class="table-light"
:items="items"
:fields="fields"
show-empty
@@ -16,10 +17,11 @@
data-test-id="hardwareStatus-button-expandBmc"
:title="expandRowLabel"
class="btn-icon-only"
+ :class="{ collapsed: !row.detailsShowing }"
@click="toggleRowDetails(row)"
>
<icon-chevron />
- <span class="sr-only">{{ expandRowLabel }}</span>
+ <span class="visually-hidden">{{ expandRowLabel }}</span>
</b-button>
</template>
@@ -62,7 +64,9 @@
<dd>{{ dataFormatter(item.serialNumber) }}</dd>
<!-- Spare part number -->
<dt>{{ $t('pageInventory.table.sparePartNumber') }}:</dt>
- <dd>{{ dataFormatter(item.sparePartNumber) }}</dd>
+ <dd>
+ {{ dataFormatter(item.sparePartNumber) }}
+ </dd>
<!-- Model -->
<dt>{{ $t('pageInventory.table.model') }}:</dt>
<dd>{{ dataFormatter(item.model) }}</dd>
@@ -71,7 +75,9 @@
<dd>{{ dataFormatter(item.uuid) }}</dd>
<!-- Service entry point UUID -->
<dt>{{ $t('pageInventory.table.serviceEntryPointUuid') }}:</dt>
- <dd>{{ dataFormatter(item.serviceEntryPointUuid) }}</dd>
+ <dd>
+ {{ dataFormatter(item.serviceEntryPointUuid) }}
+ </dd>
</dl>
</b-col>
<b-col class="mt-2" sm="6" xl="6">
@@ -125,7 +131,7 @@
<p class="mt-1 mb-2 h6 float-none m-0">
{{ $t('pageInventory.table.graphicalConsole') }}
</p>
- <dl class="ml-4">
+ <dl class="ms-4">
<dt>{{ $t('pageInventory.table.connectTypesSupported') }}:</dt>
<dd>
{{ dataFormatterArray(item.graphicalConsoleConnectTypes) }}
@@ -211,7 +217,9 @@
created() {
this.$store.dispatch('bmc/getBmcInfo').finally(() => {
// Emit initial data fetch complete to parent component
- this.$root.$emit('hardware-status-bmc-manager-complete');
+ require('@/eventBus').default.$emit(
+ 'hardware-status-bmc-manager-complete',
+ );
this.isBusy = false;
});
},
diff --git a/src/views/HardwareStatus/Inventory/InventoryTableChassis.vue b/src/views/HardwareStatus/Inventory/InventoryTableChassis.vue
index 4458e33..8278e52 100644
--- a/src/views/HardwareStatus/Inventory/InventoryTableChassis.vue
+++ b/src/views/HardwareStatus/Inventory/InventoryTableChassis.vue
@@ -3,6 +3,7 @@
<b-table
responsive="md"
hover
+ thead-class="table-light"
:items="chassis"
:fields="fields"
show-empty
@@ -16,10 +17,11 @@
data-test-id="hardwareStatus-button-expandChassis"
:title="expandRowLabel"
class="btn-icon-only"
+ :class="{ collapsed: !row.detailsShowing }"
@click="toggleRowDetails(row)"
>
<icon-chevron />
- <span class="sr-only">{{ expandRowLabel }}</span>
+ <span class="visually-hidden">{{ expandRowLabel }}</span>
</b-button>
</template>
@@ -178,7 +180,7 @@
created() {
this.$store.dispatch('chassis/getChassisInfo').finally(() => {
// Emit initial data fetch complete to parent component
- this.$root.$emit('hardware-status-chassis-complete');
+ require('@/eventBus').default.$emit('hardware-status-chassis-complete');
this.isBusy = false;
});
},
diff --git a/src/views/HardwareStatus/Inventory/InventoryTableDimmSlot.vue b/src/views/HardwareStatus/Inventory/InventoryTableDimmSlot.vue
index f4a850b..c767726 100644
--- a/src/views/HardwareStatus/Inventory/InventoryTableDimmSlot.vue
+++ b/src/views/HardwareStatus/Inventory/InventoryTableDimmSlot.vue
@@ -16,15 +16,15 @@
</b-row>
<b-table
sort-icon-left
- no-sort-reset
+ must-sort
hover
- sort-by="health"
+ thead-class="table-light"
+ :sort-by="['health']"
responsive="md"
show-empty
:items="dimms"
:fields="fields"
- :sort-desc="true"
- :sort-compare="sortCompare"
+ :sort-desc="[true]"
:filter="searchFilter"
:empty-text="$t('global.table.emptyMessage')"
:empty-filtered-text="$t('global.table.emptySearchMessage')"
@@ -35,13 +35,14 @@
<template #cell(expandRow)="row">
<b-button
variant="link"
- data-test-id="hardwareStatus-button-expandDimms"
+ data-test-id="hardwareStatus-button-expandDimmSlot"
:title="expandRowLabel"
class="btn-icon-only"
+ :class="{ collapsed: !row.detailsShowing }"
@click="toggleRowDetails(row)"
>
<icon-chevron />
- <span class="sr-only">{{ expandRowLabel }}</span>
+ <span class="visually-hidden">{{ expandRowLabel }}</span>
</b-button>
</template>
@@ -95,7 +96,9 @@
<dl>
<!-- Spare Part Number -->
<dt>{{ $t('pageInventory.table.sparePartNumber') }}:</dt>
- <dd>{{ dataFormatter(item.sparePartNumber) }}</dd>
+ <dd>
+ {{ dataFormatter(item.sparePartNumber) }}
+ </dd>
</dl>
<dl>
<!-- Model -->
@@ -145,7 +148,9 @@
<dl>
<!-- Base Module Type -->
<dt>{{ $t('pageInventory.table.baseModuleType') }}:</dt>
- <dd>{{ dataFormatter(item.baseModuleType) }}</dd>
+ <dd>
+ {{ dataFormatter(item.baseModuleType) }}
+ </dd>
</dl>
</b-col>
<b-col sm="6" xl="6">
@@ -176,7 +181,9 @@
<dl>
<!-- Error Correction -->
<dt>{{ $t('pageInventory.table.errorCorrection') }}:</dt>
- <dd>{{ dataFormatter(item.errorCorrection) }}</dd>
+ <dd>
+ {{ dataFormatter(item.errorCorrection) }}
+ </dd>
</dl>
</b-col>
</b-row>
@@ -207,7 +214,13 @@
import i18n from '@/i18n';
export default {
- components: { IconChevron, PageSection, StatusIcon, Search, TableCellCount },
+ components: {
+ IconChevron,
+ PageSection,
+ StatusIcon,
+ Search,
+ TableCellCount,
+ },
mixins: [
BVToastMixin,
TableRowExpandMixin,
@@ -271,7 +284,7 @@
created() {
this.$store.dispatch('memory/getDimms').finally(() => {
// Emit initial data fetch complete to parent component
- this.$root.$emit('hardware-status-dimm-slot-complete');
+ require('@/eventBus').default.$emit('hardware-status-dimm-slot-complete');
this.isBusy = false;
});
},
diff --git a/src/views/HardwareStatus/Inventory/InventoryTableFans.vue b/src/views/HardwareStatus/Inventory/InventoryTableFans.vue
index 4a540e0..9f4dffa 100644
--- a/src/views/HardwareStatus/Inventory/InventoryTableFans.vue
+++ b/src/views/HardwareStatus/Inventory/InventoryTableFans.vue
@@ -16,15 +16,15 @@
</b-row>
<b-table
sort-icon-left
- no-sort-reset
+ must-sort
hover
responsive="md"
- sort-by="health"
+ thead-class="table-light"
+ :sort-by="['health']"
show-empty
:items="fans"
:fields="fields"
- :sort-desc="true"
- :sort-compare="sortCompare"
+ :sort-desc="[true]"
:filter="searchFilter"
:empty-text="$t('global.table.emptyMessage')"
:empty-filtered-text="$t('global.table.emptySearchMessage')"
@@ -38,10 +38,11 @@
data-test-id="hardwareStatus-button-expandFans"
:title="expandRowLabel"
class="btn-icon-only"
+ :class="{ collapsed: !row.detailsShowing }"
@click="toggleRowDetails(row)"
>
<icon-chevron />
- <span class="sr-only">{{ expandRowLabel }}</span>
+ <span class="visually-hidden">{{ expandRowLabel }}</span>
</b-button>
</template>
@@ -123,7 +124,13 @@
import i18n from '@/i18n';
export default {
- components: { IconChevron, PageSection, StatusIcon, Search, TableCellCount },
+ components: {
+ IconChevron,
+ PageSection,
+ StatusIcon,
+ Search,
+ TableCellCount,
+ },
mixins: [
TableRowExpandMixin,
DataFormatterMixin,
@@ -190,7 +197,7 @@
created() {
this.$store.dispatch('fan/getFanInfo').finally(() => {
// Emit initial data fetch complete to parent component
- this.$root.$emit('hardware-status-fans-complete');
+ require('@/eventBus').default.$emit('hardware-status-fans-complete');
this.isBusy = false;
});
},
diff --git a/src/views/HardwareStatus/Inventory/InventoryTablePowerSupplies.vue b/src/views/HardwareStatus/Inventory/InventoryTablePowerSupplies.vue
index ddc3333..f494514 100644
--- a/src/views/HardwareStatus/Inventory/InventoryTablePowerSupplies.vue
+++ b/src/views/HardwareStatus/Inventory/InventoryTablePowerSupplies.vue
@@ -16,15 +16,15 @@
</b-row>
<b-table
sort-icon-left
- no-sort-reset
+ must-sort
hover
responsive="md"
- sort-by="health"
+ thead-class="table-light"
+ :sort-by="['health']"
show-empty
:items="powerSupplies"
:fields="fields"
- :sort-desc="true"
- :sort-compare="sortCompare"
+ :sort-desc="[true]"
:filter="searchFilter"
:empty-text="$t('global.table.emptyMessage')"
:empty-filtered-text="$t('global.table.emptySearchMessage')"
@@ -38,10 +38,11 @@
data-test-id="hardwareStatus-button-expandPowerSupplies"
:title="expandRowLabel"
class="btn-icon-only"
+ :class="{ collapsed: !row.detailsShowing }"
@click="toggleRowDetails(row)"
>
<icon-chevron />
- <span class="sr-only">{{ expandRowLabel }}</span>
+ <span class="visually-hidden">{{ expandRowLabel }}</span>
</b-button>
</template>
@@ -73,7 +74,9 @@
<dd>{{ dataFormatter(item.serialNumber) }}</dd>
<!-- Spare part number -->
<dt>{{ $t('pageInventory.table.sparePartNumber') }}:</dt>
- <dd>{{ dataFormatter(item.sparePartNumber) }}</dd>
+ <dd>
+ {{ dataFormatter(item.sparePartNumber) }}
+ </dd>
<!-- Model -->
<dt>{{ $t('pageInventory.table.model') }}:</dt>
<dd>{{ dataFormatter(item.model) }}</dd>
@@ -115,7 +118,9 @@
<dl>
<!-- Firmware version -->
<dt>{{ $t('pageInventory.table.firmwareVersion') }}:</dt>
- <dd>{{ dataFormatter(item.firmwareVersion) }}</dd>
+ <dd>
+ {{ dataFormatter(item.firmwareVersion) }}
+ </dd>
</dl>
</b-col>
</b-row>
@@ -144,7 +149,13 @@
import i18n from '@/i18n';
export default {
- components: { IconChevron, PageSection, StatusIcon, Search, TableCellCount },
+ components: {
+ IconChevron,
+ PageSection,
+ StatusIcon,
+ Search,
+ TableCellCount,
+ },
mixins: [
TableRowExpandMixin,
DataFormatterMixin,
@@ -211,7 +222,9 @@
created() {
this.$store.dispatch('powerSupply/getAllPowerSupplies').finally(() => {
// Emit initial data fetch complete to parent component
- this.$root.$emit('hardware-status-power-supplies-complete');
+ require('@/eventBus').default.$emit(
+ 'hardware-status-power-supplies-complete',
+ );
this.isBusy = false;
});
},
diff --git a/src/views/HardwareStatus/Inventory/InventoryTableProcessors.vue b/src/views/HardwareStatus/Inventory/InventoryTableProcessors.vue
index 4bdff54..5290133 100644
--- a/src/views/HardwareStatus/Inventory/InventoryTableProcessors.vue
+++ b/src/views/HardwareStatus/Inventory/InventoryTableProcessors.vue
@@ -17,13 +17,15 @@
</b-row>
<b-table
sort-icon-left
- no-sort-reset
+ must-sort
hover
responsive="md"
+ thead-class="table-light"
+ :sort-by="['health']"
show-empty
:items="processors"
:fields="fields"
- :sort-desc="true"
+ :sort-desc="[true]"
:filter="searchFilter"
:empty-text="$t('global.table.emptyMessage')"
:empty-filtered-text="$t('global.table.emptySearchMessage')"
@@ -37,10 +39,11 @@
data-test-id="hardwareStatus-button-expandProcessors"
:title="expandRowLabel"
class="btn-icon-only"
+ :class="{ collapsed: !row.detailsShowing }"
@click="toggleRowDetails(row)"
>
<icon-chevron />
- <span class="sr-only">{{ expandRowLabel }}</span>
+ <span class="visually-hidden">{{ expandRowLabel }}</span>
</b-button>
</template>
<!-- Health -->
@@ -87,7 +90,9 @@
<dd>{{ dataFormatter(item.serialNumber) }}</dd>
<!-- Spare Part Number -->
<dt>{{ $t('pageInventory.table.sparePartNumber') }}:</dt>
- <dd>{{ dataFormatter(item.sparePartNumber) }}</dd>
+ <dd>
+ {{ dataFormatter(item.sparePartNumber) }}
+ </dd>
<!-- Model -->
<dt>{{ $t('pageInventory.table.model') }}:</dt>
<dd>{{ dataFormatter(item.model) }}</dd>
@@ -119,10 +124,14 @@
<dd>{{ dataFormatter(item.processorType) }}</dd>
<!-- Processor Architecture -->
<dt>{{ $t('pageInventory.table.processorArchitecture') }}:</dt>
- <dd>{{ dataFormatter(item.processorArchitecture) }}</dd>
+ <dd>
+ {{ dataFormatter(item.processorArchitecture) }}
+ </dd>
<!-- Instruction Set -->
<dt>{{ $t('pageInventory.table.instructionSet') }}:</dt>
- <dd>{{ dataFormatter(item.instructionSet) }}</dd>
+ <dd>
+ {{ dataFormatter(item.instructionSet) }}
+ </dd>
<!-- Version -->
<dt>{{ $t('pageInventory.table.version') }}:</dt>
<dd>{{ dataFormatter(item.version) }}</dd>
@@ -176,7 +185,13 @@
import i18n from '@/i18n';
export default {
- components: { IconChevron, PageSection, StatusIcon, Search, TableCellCount },
+ components: {
+ IconChevron,
+ PageSection,
+ StatusIcon,
+ Search,
+ TableCellCount,
+ },
mixins: [
BVToastMixin,
TableRowExpandMixin,
@@ -246,7 +261,9 @@
created() {
this.$store.dispatch('processors/getProcessorsInfo').finally(() => {
// Emit initial data fetch complete to parent component
- this.$root.$emit('hardware-status-processors-complete');
+ require('@/eventBus').default.$emit(
+ 'hardware-status-processors-complete',
+ );
this.isBusy = false;
});
},
diff --git a/src/views/HardwareStatus/Inventory/InventoryTableSystem.vue b/src/views/HardwareStatus/Inventory/InventoryTableSystem.vue
index 23beb47..a3cb0cf 100644
--- a/src/views/HardwareStatus/Inventory/InventoryTableSystem.vue
+++ b/src/views/HardwareStatus/Inventory/InventoryTableSystem.vue
@@ -4,6 +4,7 @@
responsive="md"
hover
show-empty
+ thead-class="table-light"
:items="systems"
:fields="fields"
:empty-text="$t('global.table.emptyMessage')"
@@ -16,10 +17,11 @@
data-test-id="hardwareStatus-button-expandSystem"
:title="expandRowLabel"
class="btn-icon-only"
+ :class="{ collapsed: !row.detailsShowing }"
@click="toggleRowDetails(row)"
>
<icon-chevron />
- <span class="sr-only">{{ expandRowLabel }}</span>
+ <span class="visually-hidden">{{ expandRowLabel }}</span>
</b-button>
</template>
@@ -103,7 +105,7 @@
<p class="mt-1 mb-2 h6 float-none m-0">
{{ $t('pageInventory.table.memorySummary') }}
</p>
- <dl class="ml-4">
+ <dl class="ms-4">
<!-- Total system memory -->
<dt>{{ $t('pageInventory.table.totalSystemMemoryGiB') }}:</dt>
<dd>
@@ -115,23 +117,31 @@
<p class="mt-1 mb-2 h6 float-none m-0">
{{ $t('pageInventory.table.processorSummary') }}
</p>
- <dl class="ml-4">
+ <dl class="ms-4">
<!-- Count -->
<dt>{{ $t('pageInventory.table.count') }}:</dt>
- <dd>{{ dataFormatter(item.processorSummaryCount) }}</dd>
+ <dd>
+ {{ dataFormatter(item.processorSummaryCount) }}
+ </dd>
<!-- Core Count -->
<dt>{{ $t('pageInventory.table.coreCount') }}:</dt>
- <dd>{{ dataFormatter(item.processorSummaryCoreCount) }}</dd>
+ <dd>
+ {{ dataFormatter(item.processorSummaryCoreCount) }}
+ </dd>
</dl>
<!-- Serial console -->
<p class="mt-1 mb-2 h6 float-none m-0">
{{ $t('pageInventory.table.serialConsole') }}
</p>
- <dl class="ml-4">
+ <dl class="ms-4">
<dt>{{ $t('pageInventory.table.maxConcurrentSessions') }}:</dt>
- <dd>{{ dataFormatter(item.serialConsoleMaxSessions) }}</dd>
+ <dd>
+ {{ dataFormatter(item.serialConsoleMaxSessions) }}
+ </dd>
<dt>{{ $t('pageInventory.table.serviceEnabled') }}:</dt>
- <dd>{{ dataFormatter(item.serialConsoleEnabled) }}</dd>
+ <dd>
+ {{ dataFormatter(item.serialConsoleEnabled) }}
+ </dd>
</dl>
</b-col>
</b-row>
@@ -207,7 +217,7 @@
created() {
this.$store.dispatch('system/getSystem').finally(() => {
// Emit initial data fetch complete to parent component
- this.$root.$emit('hardware-status-system-complete');
+ require('@/eventBus').default.$emit('hardware-status-system-complete');
this.isBusy = false;
});
},