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                <!-- Manufacturer -->
75                <dt>{{ $t('pageInventory.table.manufacturer') }}:</dt>
76                <dd>{{ dataFormatter(item.manufacturer) }}</dd>
77              </dl>
78              <dl>
79                <!-- Part Number -->
80                <dt>{{ $t('pageInventory.table.partNumber') }}:</dt>
81                <dd>{{ dataFormatter(item.partNumber) }}</dd>
82              </dl>
83              <dl>
84                <!-- Serial Number -->
85                <dt>{{ $t('pageInventory.table.serialNumber') }}:</dt>
86                <dd>{{ dataFormatter(item.serialNumber) }}</dd>
87              </dl>
88              <dl>
89                <!-- Spare Part Number -->
90                <dt>{{ $t('pageInventory.table.sparePartNumber') }}:</dt>
91                <dd>{{ dataFormatter(item.sparePartNumber) }}</dd>
92              </dl>
93              <dl>
94                <!-- Model -->
95                <dt>{{ $t('pageInventory.table.model') }}:</dt>
96                <dd>{{ dataFormatter(item.model) }}</dd>
97              </dl>
98            </b-col>
99            <b-col sm="6" xl="6">
100              <dl>
101                <!-- Capacity MiB -->
102                <dt>{{ $t('pageInventory.table.capacityMiB') }}:</dt>
103                <dd>
104                  {{ dataFormatter(item.capacityMiB) }}
105                  {{ $t('unit.MiB') }}
106                </dd>
107              </dl>
108              <dl>
109                <!-- Rank Count -->
110                <dt>{{ $t('pageInventory.table.rankCount') }}:</dt>
111                <dd>{{ dataFormatter(item.rankCount) }}</dd>
112              </dl>
113              <dl>
114                <!-- Status-->
115                <dt>{{ $t('pageInventory.table.statusState') }}:</dt>
116                <dd>{{ dataFormatter(item.statusState) }}</dd>
117              </dl>
118              <dl>
119                <!-- Enabled-->
120                <dt>{{ $t('pageInventory.table.enabled') }}:</dt>
121                <dd>{{ dataFormatter(item.enabled) }}</dd>
122              </dl>
123            </b-col>
124          </b-row>
125          <div class="section-divider mb-3 mt-3"></div>
126          <b-row>
127            <b-col sm="6" xl="6">
128              <dl>
129                <!-- Description -->
130                <dt>{{ $t('pageInventory.table.description') }}:</dt>
131                <dd>{{ dataFormatter(item.description) }}</dd>
132              </dl>
133              <dl>
134                <!-- Memory Type -->
135                <dt>{{ $t('pageInventory.table.memoryType') }}:</dt>
136                <dd>{{ dataFormatter(item.memoryType) }}</dd>
137              </dl>
138              <dl>
139                <!-- Base Module Type -->
140                <dt>{{ $t('pageInventory.table.baseModuleType') }}:</dt>
141                <dd>{{ dataFormatter(item.baseModuleType) }}</dd>
142              </dl>
143            </b-col>
144            <b-col sm="6" xl="6">
145              <dl>
146                <!-- Bus Width Bits -->
147                <dt>{{ $t('pageInventory.table.busWidthBits') }}:</dt>
148                <dd>
149                  {{ dataFormatter(item.busWidthBits) }}
150                  {{ $t('unit.bit') }}
151                </dd>
152              </dl>
153              <dl>
154                <!-- Data Width Bits -->
155                <dt>{{ $t('pageInventory.table.dataWidthBits') }}:</dt>
156                <dd>
157                  {{ dataFormatter(item.dataWidthBits) }}
158                  {{ $t('unit.bit') }}
159                </dd>
160              </dl>
161              <dl>
162                <!-- Operating Speed Mhz -->
163                <dt>{{ $t('pageInventory.table.operatingSpeedMhz') }}:</dt>
164                <dd>
165                  {{ dataFormatter(item.operatingSpeedMhz) }}
166                  {{ $t('unit.MHz') }}
167                </dd>
168              </dl>
169              <dl>
170                <!-- Error Correction -->
171                <dt>{{ $t('pageInventory.table.errorCorrection') }}:</dt>
172                <dd>{{ dataFormatter(item.errorCorrection) }}</dd>
173              </dl>
174            </b-col>
175          </b-row>
176        </b-container>
177      </template>
178    </b-table>
179  </page-section>
180</template>
181
182<script>
183import PageSection from '@/components/Global/PageSection';
184import IconChevron from '@carbon/icons-vue/es/chevron--down/20';
185
186import StatusIcon from '@/components/Global/StatusIcon';
187import TableCellCount from '@/components/Global/TableCellCount';
188
189import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
190import TableSortMixin from '@/components/Mixins/TableSortMixin';
191import Search from '@/components/Global/Search';
192import SearchFilterMixin, {
193  searchFilter,
194} from '@/components/Mixins/SearchFilterMixin';
195import TableRowExpandMixin, {
196  expandRowLabel,
197} from '@/components/Mixins/TableRowExpandMixin';
198
199export default {
200  components: { IconChevron, PageSection, StatusIcon, Search, TableCellCount },
201  mixins: [
202    TableRowExpandMixin,
203    DataFormatterMixin,
204    TableSortMixin,
205    SearchFilterMixin,
206  ],
207  data() {
208    return {
209      isBusy: true,
210      fields: [
211        {
212          key: 'expandRow',
213          label: '',
214          tdClass: 'table-row-expand',
215        },
216        {
217          key: 'id',
218          label: this.$t('pageInventory.table.id'),
219          formatter: this.dataFormatter,
220        },
221        {
222          key: 'health',
223          label: this.$t('pageInventory.table.health'),
224          formatter: this.dataFormatter,
225          tdClass: 'text-nowrap',
226        },
227        {
228          key: 'locationNumber',
229          label: this.$t('pageInventory.table.locationNumber'),
230          formatter: this.dataFormatter,
231        },
232        {
233          key: 'identifyLed',
234          label: this.$t('pageInventory.table.identifyLed'),
235          formatter: this.dataFormatter,
236        },
237      ],
238      searchFilter: searchFilter,
239      searchTotalFilteredRows: 0,
240      expandRowLabel: expandRowLabel,
241    };
242  },
243  computed: {
244    filteredRows() {
245      return this.searchFilter
246        ? this.searchTotalFilteredRows
247        : this.dimms.length;
248    },
249    dimms() {
250      return this.$store.getters['memory/dimms'];
251    },
252  },
253  created() {
254    this.$store.dispatch('memory/getDimms').finally(() => {
255      // Emit initial data fetch complete to parent component
256      this.$root.$emit('hardware-status-dimm-slot-complete');
257      this.isBusy = false;
258    });
259  },
260  methods: {
261    sortCompare(a, b, key) {
262      if (key === 'health') {
263        return this.sortStatus(a, b, key);
264      }
265    },
266    onFiltered(filteredItems) {
267      this.searchTotalFilteredRows = filteredItems.length;
268    },
269    toggleIdentifyLedValue(row) {
270      this.$store
271        .dispatch('memory/updateIdentifyLedValue', {
272          uri: row.uri,
273          identifyLed: row.identifyLed,
274        })
275        .catch(({ message }) => this.errorToast(message));
276    },
277    hasIdentifyLed(identifyLed) {
278      return typeof identifyLed === 'boolean';
279    },
280  },
281};
282</script>
283