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                <!-- Capacity MiB -->
97                <dt>{{ $t('pageInventory.table.capacityMiB') }}:</dt>
98                <dd>{{ dataFormatter(item.capacityMiB) }}</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            </b-col>
131            <b-col sm="6" xl="6">
132              <dl>
133                <!-- Bus Width Bits -->
134                <dt>{{ $t('pageInventory.table.busWidthBits') }}:</dt>
135                <dd>{{ dataFormatter(item.busWidthBits) }}</dd>
136              </dl>
137              <dl>
138                <!-- Data Width Bits -->
139                <dt>{{ $t('pageInventory.table.dataWidthBits') }}:</dt>
140                <dd>{{ dataFormatter(item.dataWidthBits) }}</dd>
141              </dl>
142              <dl>
143                <!-- Operating Speed Mhz -->
144                <dt>{{ $t('pageInventory.table.operatingSpeedMhz') }}:</dt>
145                <dd>{{ dataFormatter(item.operatingSpeedMhz) }} MHz</dd>
146              </dl>
147            </b-col>
148          </b-row>
149        </b-container>
150      </template>
151    </b-table>
152  </page-section>
153</template>
154
155<script>
156import PageSection from '@/components/Global/PageSection';
157import IconChevron from '@carbon/icons-vue/es/chevron--down/20';
158
159import StatusIcon from '@/components/Global/StatusIcon';
160import TableCellCount from '@/components/Global/TableCellCount';
161
162import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
163import TableSortMixin from '@/components/Mixins/TableSortMixin';
164import Search from '@/components/Global/Search';
165import SearchFilterMixin, {
166  searchFilter,
167} from '@/components/Mixins/SearchFilterMixin';
168import TableRowExpandMixin, {
169  expandRowLabel,
170} from '@/components/Mixins/TableRowExpandMixin';
171
172export default {
173  components: { IconChevron, PageSection, StatusIcon, Search, TableCellCount },
174  mixins: [
175    TableRowExpandMixin,
176    DataFormatterMixin,
177    TableSortMixin,
178    SearchFilterMixin,
179  ],
180  data() {
181    return {
182      isBusy: true,
183      fields: [
184        {
185          key: 'expandRow',
186          label: '',
187          tdClass: 'table-row-expand',
188        },
189        {
190          key: 'id',
191          label: this.$t('pageInventory.table.id'),
192          formatter: this.dataFormatter,
193        },
194        {
195          key: 'health',
196          label: this.$t('pageInventory.table.health'),
197          formatter: this.dataFormatter,
198          tdClass: 'text-nowrap',
199        },
200        {
201          key: 'locationNumber',
202          label: this.$t('pageInventory.table.locationNumber'),
203          formatter: this.dataFormatter,
204        },
205        {
206          key: 'identifyLed',
207          label: this.$t('pageInventory.table.identifyLed'),
208          formatter: this.dataFormatter,
209        },
210      ],
211      searchFilter: searchFilter,
212      searchTotalFilteredRows: 0,
213      expandRowLabel: expandRowLabel,
214    };
215  },
216  computed: {
217    filteredRows() {
218      return this.searchFilter
219        ? this.searchTotalFilteredRows
220        : this.dimms.length;
221    },
222    dimms() {
223      return this.$store.getters['memory/dimms'];
224    },
225  },
226  created() {
227    this.$store.dispatch('memory/getDimms').finally(() => {
228      // Emit initial data fetch complete to parent component
229      this.$root.$emit('hardware-status-dimm-slot-complete');
230      this.isBusy = false;
231    });
232  },
233  methods: {
234    sortCompare(a, b, key) {
235      if (key === 'health') {
236        return this.sortStatus(a, b, key);
237      }
238    },
239    onFiltered(filteredItems) {
240      this.searchTotalFilteredRows = filteredItems.length;
241    },
242    toggleIdentifyLedValue(row) {
243      this.$store
244        .dispatch('memory/updateIdentifyLedValue', {
245          uri: row.uri,
246          identifyLed: row.identifyLed,
247        })
248        .catch(({ message }) => this.errorToast(message));
249    },
250    hasIdentifyLed(identifyLed) {
251      return typeof identifyLed === 'boolean';
252    },
253  },
254};
255</script>
256