xref: /openbmc/webui-vue/src/views/HardwareStatus/Sensors/Sensors.vue (revision 80a87851ab2b1bddb9f42cc494b0ad7799b06012)
1<template>
2  <b-container fluid="xl">
3    <page-title />
4    <b-row class="align-items-end">
5      <b-col sm="6" md="5" xl="4">
6        <search
7          :placeholder="$t('pageSensors.searchForSensors')"
8          data-test-id="sensors-input-searchForSensors"
9          @change-search="onChangeSearchInput"
10          @clear-search="onClearSearchInput"
11        />
12      </b-col>
13      <b-col sm="3" md="3" xl="2">
14        <table-cell-count
15          :filtered-items-count="filteredRows"
16          :total-number-of-cells="allSensors.length"
17        ></table-cell-count>
18      </b-col>
19      <b-col sm="3" md="4" xl="6" class="text-right">
20        <table-filter :filters="tableFilters" @filter-change="onFilterChange" />
21      </b-col>
22    </b-row>
23    <b-row>
24      <b-col xl="12">
25        <table-toolbar
26          ref="toolbar"
27          :selected-items-count="selectedRows.length"
28          @clear-selected="clearSelectedRows($refs.table)"
29        >
30          <template #toolbar-buttons>
31            <table-toolbar-export
32              :data="selectedRows"
33              :file-name="exportFileNameByDate()"
34            />
35          </template>
36        </table-toolbar>
37        <b-table
38          ref="table"
39          responsive="md"
40          selectable
41          no-select-on-click
42          sort-icon-left
43          hover
44          no-sort-reset
45          sticky-header="75vh"
46          sort-by="status"
47          show-empty
48          :no-border-collapse="true"
49          :items="filteredSensors"
50          :fields="fields"
51          :sort-desc="true"
52          :sort-compare="sortCompare"
53          :filter="searchFilter"
54          :empty-text="$t('global.table.emptyMessage')"
55          :empty-filtered-text="$t('global.table.emptySearchMessage')"
56          :busy="isBusy"
57          @filtered="onFiltered"
58          @row-selected="onRowSelected($event, filteredSensors.length)"
59        >
60          <!-- Checkbox column -->
61          <template #head(checkbox)>
62            <b-form-checkbox
63              v-model="tableHeaderCheckboxModel"
64              :indeterminate="tableHeaderCheckboxIndeterminate"
65              @change="onChangeHeaderCheckbox($refs.table)"
66            >
67              <span class="sr-only">{{ $t('global.table.selectAll') }}</span>
68            </b-form-checkbox>
69          </template>
70          <template #cell(checkbox)="row">
71            <b-form-checkbox
72              v-model="row.rowSelected"
73              @change="toggleSelectRow($refs.table, row.index)"
74            >
75              <span class="sr-only">{{ $t('global.table.selectItem') }}</span>
76            </b-form-checkbox>
77          </template>
78
79          <template #cell(status)="{ value }">
80            <status-icon :status="statusIcon(value)" /> {{ value }}
81          </template>
82          <template #cell(currentValue)="data">
83            {{ data.value }} {{ data.item.units }}
84          </template>
85          <template #cell(lowerCaution)="data">
86            {{ data.value }} {{ data.item.units }}
87          </template>
88          <template #cell(upperCaution)="data">
89            {{ data.value }} {{ data.item.units }}
90          </template>
91          <template #cell(lowerCritical)="data">
92            {{ data.value }} {{ data.item.units }}
93          </template>
94          <template #cell(upperCritical)="data">
95            {{ data.value }} {{ data.item.units }}
96          </template>
97        </b-table>
98      </b-col>
99    </b-row>
100  </b-container>
101</template>
102
103<script>
104import PageTitle from '@/components/Global/PageTitle';
105import Search from '@/components/Global/Search';
106import StatusIcon from '@/components/Global/StatusIcon';
107import TableFilter from '@/components/Global/TableFilter';
108import TableToolbar from '@/components/Global/TableToolbar';
109import TableToolbarExport from '@/components/Global/TableToolbarExport';
110import TableCellCount from '@/components/Global/TableCellCount';
111
112import BVTableSelectableMixin, {
113  selectedRows,
114  tableHeaderCheckboxModel,
115  tableHeaderCheckboxIndeterminate,
116} from '@/components/Mixins/BVTableSelectableMixin';
117import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
118import TableFilterMixin from '@/components/Mixins/TableFilterMixin';
119import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
120import TableSortMixin from '@/components/Mixins/TableSortMixin';
121import SearchFilterMixin, {
122  searchFilter,
123} from '@/components/Mixins/SearchFilterMixin';
124
125export default {
126  name: 'Sensors',
127  components: {
128    PageTitle,
129    Search,
130    StatusIcon,
131    TableCellCount,
132    TableFilter,
133    TableToolbar,
134    TableToolbarExport,
135  },
136  mixins: [
137    TableFilterMixin,
138    BVTableSelectableMixin,
139    LoadingBarMixin,
140    DataFormatterMixin,
141    TableSortMixin,
142    SearchFilterMixin,
143  ],
144  beforeRouteLeave(to, from, next) {
145    this.hideLoader();
146    next();
147  },
148  data() {
149    return {
150      isBusy: true,
151      fields: [
152        {
153          key: 'checkbox',
154          sortable: false,
155          label: '',
156        },
157        {
158          key: 'name',
159          sortable: true,
160          label: this.$t('pageSensors.table.name'),
161        },
162        {
163          key: 'status',
164          sortable: true,
165          label: this.$t('pageSensors.table.status'),
166          tdClass: 'text-nowrap',
167        },
168        {
169          key: 'lowerCritical',
170          formatter: this.dataFormatter,
171          label: this.$t('pageSensors.table.lowerCritical'),
172        },
173        {
174          key: 'lowerCaution',
175          formatter: this.dataFormatter,
176          label: this.$t('pageSensors.table.lowerWarning'),
177        },
178
179        {
180          key: 'currentValue',
181          formatter: this.dataFormatter,
182          label: this.$t('pageSensors.table.currentValue'),
183        },
184        {
185          key: 'upperCaution',
186          formatter: this.dataFormatter,
187          label: this.$t('pageSensors.table.upperWarning'),
188        },
189        {
190          key: 'upperCritical',
191          formatter: this.dataFormatter,
192          label: this.$t('pageSensors.table.upperCritical'),
193        },
194      ],
195      tableFilters: [
196        {
197          key: 'status',
198          label: this.$t('pageSensors.table.status'),
199          values: ['OK', 'Warning', 'Critical'],
200        },
201      ],
202      activeFilters: [],
203      searchFilter: searchFilter,
204      searchTotalFilteredRows: 0,
205      selectedRows: selectedRows,
206      tableHeaderCheckboxModel: tableHeaderCheckboxModel,
207      tableHeaderCheckboxIndeterminate: tableHeaderCheckboxIndeterminate,
208    };
209  },
210  computed: {
211    allSensors() {
212      return this.$store.getters['sensors/sensors'];
213    },
214    filteredRows() {
215      return this.searchFilter
216        ? this.searchTotalFilteredRows
217        : this.filteredSensors.length;
218    },
219    filteredSensors() {
220      return this.getFilteredTableData(this.allSensors, this.activeFilters);
221    },
222  },
223  created() {
224    this.startLoader();
225    this.$store.dispatch('sensors/getAllSensors').finally(() => {
226      this.endLoader();
227      this.isBusy = false;
228    });
229  },
230  methods: {
231    sortCompare(a, b, key) {
232      if (key === 'status') {
233        return this.sortStatus(a, b, key);
234      }
235    },
236    onFilterChange({ activeFilters }) {
237      this.activeFilters = activeFilters;
238    },
239    onFiltered(filteredItems) {
240      this.searchTotalFilteredRows = filteredItems.length;
241    },
242    onChangeSearchInput(event) {
243      this.searchFilter = event;
244    },
245    exportFileNameByDate() {
246      // Create export file name based on date
247      let date = new Date();
248      date =
249        date.toISOString().slice(0, 10) +
250        '_' +
251        date.toString().split(':').join('-').split(' ')[4];
252      return this.$t('pageSensors.exportFilePrefix') + date;
253    },
254  },
255};
256</script>
257