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: [
200            this.$t('global.action.ok'),
201            this.$t('global.action.warning'),
202            this.$t('global.action.critical'),
203          ],
204        },
205      ],
206      activeFilters: [],
207      searchFilter: searchFilter,
208      searchTotalFilteredRows: 0,
209      selectedRows: selectedRows,
210      tableHeaderCheckboxModel: tableHeaderCheckboxModel,
211      tableHeaderCheckboxIndeterminate: tableHeaderCheckboxIndeterminate,
212    };
213  },
214  computed: {
215    allSensors() {
216      return this.$store.getters['sensors/sensors'];
217    },
218    filteredRows() {
219      return this.searchFilter
220        ? this.searchTotalFilteredRows
221        : this.filteredSensors.length;
222    },
223    filteredSensors() {
224      return this.getFilteredTableData(this.allSensors, this.activeFilters);
225    },
226  },
227  created() {
228    this.startLoader();
229    this.$store.dispatch('sensors/getAllSensors').finally(() => {
230      this.endLoader();
231      this.isBusy = false;
232    });
233  },
234  methods: {
235    sortCompare(a, b, key) {
236      if (key === 'status') {
237        return this.sortStatus(a, b, key);
238      }
239    },
240    onFilterChange({ activeFilters }) {
241      this.activeFilters = activeFilters;
242    },
243    onFiltered(filteredItems) {
244      this.searchTotalFilteredRows = filteredItems.length;
245    },
246    onChangeSearchInput(event) {
247      this.searchFilter = event;
248    },
249    exportFileNameByDate() {
250      // Create export file name based on date
251      let date = new Date();
252      date =
253        date.toISOString().slice(0, 10) +
254        '_' +
255        date.toString().split(':').join('-').split(' ')[4];
256      return this.$t('pageSensors.exportFilePrefix') + date;
257    },
258  },
259};
260</script>
261