xref: /openbmc/webui-vue/src/views/HardwareStatus/Inventory/InventoryTableProcessors.vue (revision ce7db82c9582c4dac04ac81d9af6b557ae7965e3)
1<template>
2  <page-section :section-title="$t('pageInventory.processors')">
3    <!-- Search -->
4    <b-row class="align-items-end">
5      <b-col sm="6" md="5" xl="4">
6        <search
7          @change-search="onChangeSearchInput"
8          @clear-search="onClearSearchInput"
9        />
10      </b-col>
11      <b-col sm="6" md="3" xl="2">
12        <table-cell-count
13          :filtered-items-count="filteredRows"
14          :total-number-of-cells="processors.length"
15        ></table-cell-count>
16      </b-col>
17    </b-row>
18    <b-table
19      sort-icon-left
20      no-sort-reset
21      hover
22      responsive="md"
23      show-empty
24      :items="processors"
25      :fields="fields"
26      :sort-desc="true"
27      :filter="searchFilter"
28      :empty-text="$t('global.table.emptyMessage')"
29      :empty-filtered-text="$t('global.table.emptySearchMessage')"
30      :busy="isBusy"
31      @filtered="onFiltered"
32    >
33      <!-- Expand button -->
34      <template #cell(expandRow)="row">
35        <b-button
36          variant="link"
37          data-test-id="hardwareStatus-button-expandProcessors"
38          :title="expandRowLabel"
39          class="btn-icon-only"
40          @click="toggleRowDetails(row)"
41        >
42          <icon-chevron />
43          <span class="sr-only">{{ expandRowLabel }}</span>
44        </b-button>
45      </template>
46      <!-- Health -->
47      <template #cell(health)="{ value }">
48        <status-icon :status="statusIcon(value)" />
49        {{ value }}
50      </template>
51      <!-- StatusState -->
52      <template #cell(statusState)="{ value }">
53        <status-icon :status="statusStateIcon(value)" />
54        {{ value }}
55      </template>
56
57      <!-- Toggle identify LED -->
58      <template #cell(identifyLed)="row">
59        <b-form-checkbox
60          v-if="hasIdentifyLed(row.item.identifyLed)"
61          v-model="row.item.identifyLed"
62          name="switch"
63          switch
64          @change="toggleIdentifyLedValue(row.item)"
65        >
66          <span v-if="row.item.identifyLed">
67            {{ $t('global.status.on') }}
68          </span>
69          <span v-else> {{ $t('global.status.off') }} </span>
70        </b-form-checkbox>
71        <div v-else>--</div>
72      </template>
73
74      <template #row-details="{ item }">
75        <b-container fluid>
76          <b-row>
77            <b-col class="mt-2" sm="6" xl="6">
78              <dl>
79                <!-- Name -->
80                <dt>{{ $t('pageInventory.table.name') }}:</dt>
81                <dd>{{ dataFormatter(item.name) }}</dd>
82                <!-- Part Number -->
83                <dt>{{ $t('pageInventory.table.partNumber') }}:</dt>
84                <dd>{{ dataFormatter(item.partNumber) }}</dd>
85                <!-- Serial Number -->
86                <dt>{{ $t('pageInventory.table.serialNumber') }}:</dt>
87                <dd>{{ dataFormatter(item.serialNumber) }}</dd>
88                <!-- Spare Part Number -->
89                <dt>{{ $t('pageInventory.table.sparePartNumber') }}:</dt>
90                <dd>{{ dataFormatter(item.sparePartNumber) }}</dd>
91                <!-- Model -->
92                <dt>{{ $t('pageInventory.table.model') }}:</dt>
93                <dd>{{ dataFormatter(item.model) }}</dd>
94                <!-- Asset Tag -->
95                <dt>{{ $t('pageInventory.table.assetTag') }}:</dt>
96                <dd>{{ dataFormatter(item.assetTag) }}</dd>
97              </dl>
98            </b-col>
99            <b-col class="mt-2" sm="6" xl="6">
100              <dl>
101                <!-- Status state -->
102                <dt>{{ $t('pageInventory.table.statusState') }}:</dt>
103                <dd>{{ dataFormatter(item.statusState) }}</dd>
104                <!-- Health Rollup -->
105                <dt>{{ $t('pageInventory.table.healthRollup') }}:</dt>
106                <dd>{{ dataFormatter(item.healthRollup) }}</dd>
107              </dl>
108            </b-col>
109          </b-row>
110          <div class="section-divider mb-3 mt-3"></div>
111          <b-row>
112            <b-col class="mt-1" sm="6" xl="6">
113              <dl>
114                <!-- Manufacturer -->
115                <dt>{{ $t('pageInventory.table.manufacturer') }}:</dt>
116                <dd>{{ dataFormatter(item.manufacturer) }}</dd>
117                <!-- Processor Type -->
118                <dt>{{ $t('pageInventory.table.processorType') }}:</dt>
119                <dd>{{ dataFormatter(item.processorType) }}</dd>
120                <!-- Processor Architecture -->
121                <dt>{{ $t('pageInventory.table.processorArchitecture') }}:</dt>
122                <dd>{{ dataFormatter(item.processorArchitecture) }}</dd>
123                <!-- Instruction Set -->
124                <dt>{{ $t('pageInventory.table.instructionSet') }}:</dt>
125                <dd>{{ dataFormatter(item.instructionSet) }}</dd>
126                <!-- Version -->
127                <dt>{{ $t('pageInventory.table.version') }}:</dt>
128                <dd>{{ dataFormatter(item.version) }}</dd>
129              </dl>
130            </b-col>
131            <b-col class="mt-1" sm="6" xl="6">
132              <dl>
133                <!-- Min Speed MHz -->
134                <dt>{{ $t('pageInventory.table.minSpeedMHz') }}:</dt>
135                <dd>
136                  {{ dataFormatter(item.minSpeedMHz) }}
137                  {{ $t('unit.MHz') }}
138                </dd>
139                <!-- Max Speed MHz -->
140                <dt>{{ $t('pageInventory.table.maxSpeedMHz') }}:</dt>
141                <dd>
142                  {{ dataFormatter(item.maxSpeedMHz) }}
143                  {{ $t('unit.MHz') }}
144                </dd>
145                <!-- Total Cores -->
146                <dt>{{ $t('pageInventory.table.totalCores') }}:</dt>
147                <dd>{{ dataFormatter(item.totalCores) }}</dd>
148                <!-- Total Threads -->
149                <dt>{{ $t('pageInventory.table.totalThreads') }}:</dt>
150                <dd>{{ dataFormatter(item.totalThreads) }}</dd>
151              </dl>
152            </b-col>
153          </b-row>
154        </b-container>
155      </template>
156    </b-table>
157  </page-section>
158</template>
159
160<script>
161import PageSection from '@/components/Global/PageSection';
162import IconChevron from '@carbon/icons-vue/es/chevron--down/20';
163import StatusIcon from '@/components/Global/StatusIcon';
164import TableCellCount from '@/components/Global/TableCellCount';
165import BVToastMixin from '@/components/Mixins/BVToastMixin';
166import TableSortMixin from '@/components/Mixins/TableSortMixin';
167import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
168import Search from '@/components/Global/Search';
169import SearchFilterMixin, {
170  searchFilter,
171} from '@/components/Mixins/SearchFilterMixin';
172import TableRowExpandMixin, {
173  expandRowLabel,
174} from '@/components/Mixins/TableRowExpandMixin';
175import { useI18n } from 'vue-i18n';
176import i18n from '@/i18n';
177
178export default {
179  components: { IconChevron, PageSection, StatusIcon, Search, TableCellCount },
180  mixins: [
181    BVToastMixin,
182    TableRowExpandMixin,
183    DataFormatterMixin,
184    TableSortMixin,
185    SearchFilterMixin,
186  ],
187  data() {
188    return {
189      $t: useI18n().t,
190      isBusy: true,
191      fields: [
192        {
193          key: 'expandRow',
194          label: '',
195          tdClass: 'table-row-expand',
196          sortable: false,
197        },
198        {
199          key: 'id',
200          label: i18n.global.t('pageInventory.table.id'),
201          formatter: this.dataFormatter,
202          sortable: true,
203        },
204        {
205          key: 'health',
206          label: i18n.global.t('pageInventory.table.health'),
207          formatter: this.dataFormatter,
208          sortable: true,
209          tdClass: 'text-nowrap',
210        },
211        {
212          key: 'statusState',
213          label: i18n.global.t('pageInventory.table.state'),
214          formatter: this.dataFormatter,
215          sortable: true,
216          tdClass: 'text-nowrap',
217        },
218        {
219          key: 'locationNumber',
220          label: i18n.global.t('pageInventory.table.locationNumber'),
221          formatter: this.dataFormatter,
222          sortable: true,
223        },
224        {
225          key: 'identifyLed',
226          label: i18n.global.t('pageInventory.table.identifyLed'),
227          formatter: this.dataFormatter,
228          sortable: false,
229        },
230      ],
231      searchFilter: searchFilter,
232      searchTotalFilteredRows: 0,
233      expandRowLabel: expandRowLabel,
234    };
235  },
236  computed: {
237    filteredRows() {
238      return this.searchFilter
239        ? this.searchTotalFilteredRows
240        : this.processors.length;
241    },
242    processors() {
243      return this.$store.getters['processors/processors'];
244    },
245  },
246  created() {
247    this.$store.dispatch('processors/getProcessorsInfo').finally(() => {
248      // Emit initial data fetch complete to parent component
249      this.$root.$emit('hardware-status-processors-complete');
250      this.isBusy = false;
251    });
252  },
253  methods: {
254    onFiltered(filteredItems) {
255      this.searchTotalFilteredRows = filteredItems.length;
256    },
257    toggleIdentifyLedValue(row) {
258      this.$store
259        .dispatch('processors/updateIdentifyLedValue', {
260          uri: row.uri,
261          identifyLed: row.identifyLed,
262        })
263        .then((message) => this.successToast(message))
264        .catch(({ message }) => this.errorToast(message));
265    },
266    // TO DO: remove hasIdentifyLed when the following is merged:
267    // https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/37045
268    hasIdentifyLed(identifyLed) {
269      return typeof identifyLed === 'boolean';
270    },
271    statusStateIcon(status) {
272      switch (status) {
273        case 'Enabled':
274          return 'success';
275        case 'Absent':
276          return 'warning';
277        default:
278          return '';
279      }
280    },
281  },
282};
283</script>
284