1<template>
2  <page-section :section-title="$t('pageInventory.dimmSlot')">
3    <b-row class="align-items-end">
4      <b-col sm="6" md="5" xl="4">
5        <search
6          @change-search="onChangeSearchInput"
7          @clear-search="onClearSearchInput"
8        />
9      </b-col>
10      <b-col sm="6" md="3" xl="2">
11        <table-cell-count
12          :filtered-items-count="filteredRows"
13          :total-number-of-cells="dimms.length"
14        ></table-cell-count>
15      </b-col>
16    </b-row>
17    <b-table
18      sort-icon-left
19      no-sort-reset
20      hover
21      sort-by="health"
22      responsive="md"
23      show-empty
24      :items="dimms"
25      :fields="fields"
26      :sort-desc="true"
27      :sort-compare="sortCompare"
28      :filter="searchFilter"
29      :empty-text="$t('global.table.emptyMessage')"
30      :empty-filtered-text="$t('global.table.emptySearchMessage')"
31      :busy="isBusy"
32      @filtered="onFiltered"
33    >
34      <!-- Expand chevron icon -->
35      <template #cell(expandRow)="row">
36        <b-button
37          variant="link"
38          data-test-id="hardwareStatus-button-expandDimms"
39          :title="expandRowLabel"
40          class="btn-icon-only"
41          @click="toggleRowDetails(row)"
42        >
43          <icon-chevron />
44          <span class="sr-only">{{ expandRowLabel }}</span>
45        </b-button>
46      </template>
47
48      <!-- Health -->
49      <template #cell(health)="{ value }">
50        <status-icon :status="statusIcon(value)" />
51        {{ value }}
52      </template>
53      <!-- Toggle identify LED -->
54      <template #cell(identifyLed)="row">
55        <b-form-checkbox
56          v-if="hasIdentifyLed(row.item.identifyLed)"
57          v-model="row.item.identifyLed"
58          name="switch"
59          switch
60          @change="toggleIdentifyLedValue(row.item)"
61        >
62          <span v-if="row.item.identifyLed">
63            {{ $t('global.status.on') }}
64          </span>
65          <span v-else> {{ $t('global.status.off') }} </span>
66        </b-form-checkbox>
67        <div v-else>--</div>
68      </template>
69      <template #row-details="{ item }">
70        <b-container fluid>
71          <b-row>
72            <b-col sm="6" xl="6">
73              <dl>
74                <!-- Part Number -->
75                <dt>{{ $t('pageInventory.table.partNumber') }}:</dt>
76                <dd>{{ dataFormatter(item.partNumber) }}</dd>
77              </dl>
78              <dl>
79                <!-- Serial Number -->
80                <dt>{{ $t('pageInventory.table.serialNumber') }}:</dt>
81                <dd>{{ dataFormatter(item.serialNumber) }}</dd>
82              </dl>
83              <dl>
84                <!-- Spare Part Number -->
85                <dt>{{ $t('pageInventory.table.sparePartNumber') }}:</dt>
86                <dd>{{ dataFormatter(item.sparePartNumber) }}</dd>
87              </dl>
88              <dl>
89                <!-- Model -->
90                <dt>{{ $t('pageInventory.table.model') }}:</dt>
91                <dd>{{ dataFormatter(item.model) }}</dd>
92              </dl>
93            </b-col>
94            <b-col sm="6" xl="6">
95              <dl>
96                <!-- Memory Size in kb -->
97                <dt>{{ $t('pageInventory.table.memorySize') }}:</dt>
98                <dd>{{ dataFormatter(item.memorySize) }} KB</dd>
99              </dl>
100              <dl>
101                <!-- Status-->
102                <dt>{{ $t('pageInventory.table.statusState') }}:</dt>
103                <dd>{{ dataFormatter(item.statusState) }}</dd>
104              </dl>
105              <dl>
106                <!-- Enabled-->
107                <dt>{{ $t('pageInventory.table.enabled') }}:</dt>
108                <dd>{{ dataFormatter(item.enabled) }}</dd>
109              </dl>
110            </b-col>
111          </b-row>
112          <div class="section-divider mb-3 mt-3"></div>
113          <b-row>
114            <b-col sm="6" xl="6">
115              <dl>
116                <!-- Description -->
117                <dt>{{ $t('pageInventory.table.description') }}:</dt>
118                <dd>{{ dataFormatter(item.description) }}</dd>
119              </dl>
120              <dl>
121                <!-- Memory Type -->
122                <dt>{{ $t('pageInventory.table.memoryType') }}:</dt>
123                <dd>{{ dataFormatter(item.memoryType) }}</dd>
124              </dl>
125              <dl>
126                <!-- Base Module Type -->
127                <dt>{{ $t('pageInventory.table.baseModuleType') }}:</dt>
128                <dd>{{ dataFormatter(item.baseModuleType) }}</dd>
129              </dl>
130              <dl>
131                <!-- Capacity MiB -->
132                <dt>{{ $t('pageInventory.table.capacityMiB') }}:</dt>
133                <dd>{{ dataFormatter(item.capacityMiB) }}</dd>
134              </dl>
135            </b-col>
136            <b-col sm="6" xl="6">
137              <dl>
138                <!-- Bus Width Bits -->
139                <dt>{{ $t('pageInventory.table.busWidthBits') }}:</dt>
140                <dd>{{ dataFormatter(item.busWidthBits) }}</dd>
141              </dl>
142              <dl>
143                <!-- Data Width Bits -->
144                <dt>{{ $t('pageInventory.table.dataWidthBits') }}:</dt>
145                <dd>{{ dataFormatter(item.dataWidthBits) }}</dd>
146              </dl>
147              <dl>
148                <!-- Operating Speed Mhz -->
149                <dt>{{ $t('pageInventory.table.operatingSpeedMhz') }}:</dt>
150                <dd>{{ dataFormatter(item.operatingSpeedMhz) }} MHz</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';
163
164import StatusIcon from '@/components/Global/StatusIcon';
165import TableCellCount from '@/components/Global/TableCellCount';
166
167import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
168import TableSortMixin from '@/components/Mixins/TableSortMixin';
169import Search from '@/components/Global/Search';
170import SearchFilterMixin, {
171  searchFilter,
172} from '@/components/Mixins/SearchFilterMixin';
173import TableRowExpandMixin, {
174  expandRowLabel,
175} from '@/components/Mixins/TableRowExpandMixin';
176
177export default {
178  components: { IconChevron, PageSection, StatusIcon, Search, TableCellCount },
179  mixins: [
180    TableRowExpandMixin,
181    DataFormatterMixin,
182    TableSortMixin,
183    SearchFilterMixin,
184  ],
185  data() {
186    return {
187      isBusy: true,
188      fields: [
189        {
190          key: 'expandRow',
191          label: '',
192          tdClass: 'table-row-expand',
193        },
194        {
195          key: 'id',
196          label: this.$t('pageInventory.table.id'),
197          formatter: this.dataFormatter,
198        },
199        {
200          key: 'health',
201          label: this.$t('pageInventory.table.health'),
202          formatter: this.dataFormatter,
203          tdClass: 'text-nowrap',
204        },
205        {
206          key: 'locationNumber',
207          label: this.$t('pageInventory.table.locationNumber'),
208          formatter: this.dataFormatter,
209        },
210        {
211          key: 'identifyLed',
212          label: this.$t('pageInventory.table.identifyLed'),
213          formatter: this.dataFormatter,
214        },
215      ],
216      searchFilter: searchFilter,
217      searchTotalFilteredRows: 0,
218      expandRowLabel: expandRowLabel,
219    };
220  },
221  computed: {
222    filteredRows() {
223      return this.searchFilter
224        ? this.searchTotalFilteredRows
225        : this.dimms.length;
226    },
227    dimms() {
228      return this.$store.getters['memory/dimms'];
229    },
230  },
231  created() {
232    this.$store.dispatch('memory/getDimms').finally(() => {
233      // Emit initial data fetch complete to parent component
234      this.$root.$emit('hardware-status-dimm-slot-complete');
235      this.isBusy = false;
236    });
237  },
238  methods: {
239    sortCompare(a, b, key) {
240      if (key === 'health') {
241        return this.sortStatus(a, b, key);
242      }
243    },
244    onFiltered(filteredItems) {
245      this.searchTotalFilteredRows = filteredItems.length;
246    },
247    toggleIdentifyLedValue(row) {
248      this.$store
249        .dispatch('memory/updateIdentifyLedValue', {
250          uri: row.uri,
251          identifyLed: row.identifyLed,
252        })
253        .catch(({ message }) => this.errorToast(message));
254    },
255    hasIdentifyLed(identifyLed) {
256      return typeof identifyLed === 'boolean';
257    },
258  },
259};
260</script>
261