Add POST code logs page
This page will be included in the Health section of the primary
navigation. The user will be able to export and download POST code
logs.
Signed-off-by: Sandeepa Singh <sandeepa.singh@ibm.com>
Change-Id: I26cf1e01bfdfcf298f24f2c7dd9633ab7d31f1b5
diff --git a/src/views/Health/PostCodeLogs/PostCodeLogs.vue b/src/views/Health/PostCodeLogs/PostCodeLogs.vue
new file mode 100644
index 0000000..1154cbf
--- /dev/null
+++ b/src/views/Health/PostCodeLogs/PostCodeLogs.vue
@@ -0,0 +1,344 @@
+<template>
+ <b-container fluid="xl">
+ <page-title />
+ <b-row class="align-items-start">
+ <b-col sm="8" xl="6" class="d-sm-flex align-items-end mb-4">
+ <search
+ :placeholder="$t('pagePostCodeLogs.table.searchLogs')"
+ @change-search="onChangeSearchInput"
+ @clear-search="onClearSearchInput"
+ />
+ <div class="ml-sm-4">
+ <table-cell-count
+ :filtered-items-count="filteredRows"
+ :total-number-of-cells="allLogs.length"
+ ></table-cell-count>
+ </div>
+ </b-col>
+ <b-col sm="8" md="7" xl="6">
+ <table-date-filter @change="onChangeDateTimeFilter" />
+ </b-col>
+ </b-row>
+ <b-row>
+ <b-col xl="12" class="text-right">
+ <b-button
+ variant="primary"
+ :disabled="allLogs.length === 0"
+ :download="exportFileNameByDate()"
+ :href="href"
+ >
+ <icon-export /> {{ $t('pagePostCodeLogs.button.exportAll') }}
+ </b-button>
+ </b-col>
+ </b-row>
+ <b-row>
+ <b-col>
+ <table-toolbar
+ ref="toolbar"
+ :selected-items-count="selectedRows.length"
+ @clear-selected="clearSelectedRows($refs.table)"
+ >
+ <template #export>
+ <table-toolbar-export
+ :data="batchExportData"
+ :file-name="exportFileNameByDate('export')"
+ />
+ </template>
+ </table-toolbar>
+ <b-table
+ id="table-post-code-logs"
+ ref="table"
+ responsive="md"
+ selectable
+ no-select-on-click
+ sort-icon-left
+ hover
+ no-sort-reset
+ sort-desc
+ show-empty
+ sort-by="id"
+ :fields="fields"
+ :items="filteredLogs"
+ :empty-text="$t('global.table.emptyMessage')"
+ :empty-filtered-text="$t('global.table.emptySearchMessage')"
+ :per-page="perPage"
+ :current-page="currentPage"
+ :filter="searchFilter"
+ @filtered="onFiltered"
+ @row-selected="onRowSelected($event, filteredLogs.length)"
+ >
+ <!-- Checkbox column -->
+ <template #head(checkbox)>
+ <b-form-checkbox
+ v-model="tableHeaderCheckboxModel"
+ data-test-id="postCode-checkbox-selectAll"
+ :indeterminate="tableHeaderCheckboxIndeterminate"
+ @change="onChangeHeaderCheckbox($refs.table)"
+ >
+ <span class="sr-only">{{ $t('global.table.selectAll') }}</span>
+ </b-form-checkbox>
+ </template>
+ <template #cell(checkbox)="row">
+ <b-form-checkbox
+ v-model="row.rowSelected"
+ :data-test-id="`postCode-checkbox-selectRow-${row.index}`"
+ @change="toggleSelectRow($refs.table, row.index)"
+ >
+ <span class="sr-only">{{ $t('global.table.selectItem') }}</span>
+ </b-form-checkbox>
+ </template>
+ <!-- Date column -->
+ <template #cell(date)="{ value }">
+ <p class="mb-0">{{ value | formatDate }}</p>
+ <p class="mb-0">{{ value | formatTime }}</p>
+ </template>
+
+ <!-- Actions column -->
+ <template #cell(actions)="row">
+ <table-row-action
+ v-for="(action, index) in row.item.actions"
+ :key="index"
+ :value="action.value"
+ :title="action.title"
+ :row-data="row.item"
+ :btn-icon-only="true"
+ :export-name="exportFileNameByDate(action.value)"
+ :download-location="row.item.uri"
+ :download-in-new-tab="true"
+ >
+ <template #icon>
+ <icon-export v-if="action.value === 'export'" />
+ <icon-download v-if="action.value === 'download'" />
+ </template>
+ </table-row-action>
+ </template>
+ </b-table>
+ </b-col>
+ </b-row>
+
+ <!-- Table pagination -->
+ <b-row>
+ <b-col sm="6">
+ <b-form-group
+ class="table-pagination-select"
+ :label="$t('global.table.itemsPerPage')"
+ label-for="pagination-items-per-page"
+ >
+ <b-form-select
+ id="pagination-items-per-page"
+ v-model="perPage"
+ :options="itemsPerPageOptions"
+ />
+ </b-form-group>
+ </b-col>
+ <b-col sm="6">
+ <b-pagination
+ v-model="currentPage"
+ first-number
+ last-number
+ :per-page="perPage"
+ :total-rows="getTotalRowCount(filteredLogs.length)"
+ aria-controls="table-post-code-logs"
+ />
+ </b-col>
+ </b-row>
+ </b-container>
+</template>
+
+<script>
+import IconDownload from '@carbon/icons-vue/es/download/20';
+import IconExport from '@carbon/icons-vue/es/document--export/20';
+import { omit } from 'lodash';
+import PageTitle from '@/components/Global/PageTitle';
+import Search from '@/components/Global/Search';
+import TableCellCount from '@/components/Global/TableCellCount';
+import TableDateFilter from '@/components/Global/TableDateFilter';
+import TableRowAction from '@/components/Global/TableRowAction';
+import TableToolbar from '@/components/Global/TableToolbar';
+import TableToolbarExport from '@/components/Global/TableToolbarExport';
+import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
+import TableFilterMixin from '@/components/Mixins/TableFilterMixin';
+import BVPaginationMixin, {
+ currentPage,
+ perPage,
+ itemsPerPageOptions,
+} from '@/components/Mixins/BVPaginationMixin';
+import BVTableSelectableMixin, {
+ selectedRows,
+ tableHeaderCheckboxModel,
+ tableHeaderCheckboxIndeterminate,
+} from '@/components/Mixins/BVTableSelectableMixin';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import TableDataFormatterMixin from '@/components/Mixins/TableDataFormatterMixin';
+import TableSortMixin from '@/components/Mixins/TableSortMixin';
+import TableRowExpandMixin, {
+ expandRowLabel,
+} from '@/components/Mixins/TableRowExpandMixin';
+import SearchFilterMixin, {
+ searchFilter,
+} from '@/components/Mixins/SearchFilterMixin';
+
+export default {
+ components: {
+ IconExport,
+ IconDownload,
+ PageTitle,
+ Search,
+ TableCellCount,
+ TableRowAction,
+ TableToolbar,
+ TableToolbarExport,
+ TableDateFilter,
+ },
+ mixins: [
+ BVPaginationMixin,
+ BVTableSelectableMixin,
+ BVToastMixin,
+ LoadingBarMixin,
+ TableFilterMixin,
+ TableDataFormatterMixin,
+ TableSortMixin,
+ TableRowExpandMixin,
+ SearchFilterMixin,
+ ],
+ beforeRouteLeave(to, from, next) {
+ // Hide loader if the user navigates to another page
+ // before request is fulfilled.
+ this.hideLoader();
+ next();
+ },
+ data() {
+ return {
+ fields: [
+ {
+ key: 'checkbox',
+ sortable: false,
+ },
+ {
+ key: 'date',
+ label: this.$t('pagePostCodeLogs.table.created'),
+ },
+ {
+ key: 'timeStampOffset',
+ label: this.$t('pagePostCodeLogs.table.timeStampOffset'),
+ },
+ {
+ key: 'bootCount',
+ label: this.$t('pagePostCodeLogs.table.bootCount'),
+ },
+ {
+ key: 'postCode',
+ label: this.$t('pagePostCodeLogs.table.postCode'),
+ },
+ {
+ key: 'actions',
+ label: '',
+ tdClass: 'text-right text-nowrap',
+ },
+ ],
+ expandRowLabel,
+ activeFilters: [],
+ currentPage: currentPage,
+ filterStartDate: null,
+ filterEndDate: null,
+ itemsPerPageOptions: itemsPerPageOptions,
+ perPage: perPage,
+ searchFilter: searchFilter,
+ searchTotalFilteredRows: 0,
+ selectedRows: selectedRows,
+ tableHeaderCheckboxModel: tableHeaderCheckboxModel,
+ tableHeaderCheckboxIndeterminate: tableHeaderCheckboxIndeterminate,
+ };
+ },
+ computed: {
+ href() {
+ return `data:text/json;charset=utf-8,${this.exportAllLogsString()}`;
+ },
+ filteredRows() {
+ return this.searchFilter
+ ? this.searchTotalFilteredRows
+ : this.filteredLogs.length;
+ },
+ allLogs() {
+ return this.$store.getters['postCodeLogs/allPostCodes'].map(
+ (postCodes) => {
+ return {
+ ...postCodes,
+ actions: [
+ {
+ value: 'export',
+ title: this.$t('pagePostCodeLogs.action.exportLogs'),
+ },
+ {
+ value: 'download',
+ title: this.$t('pagePostCodeLogs.action.downloadDetails'),
+ },
+ ],
+ };
+ }
+ );
+ },
+ batchExportData() {
+ return this.selectedRows.map((row) => omit(row, 'actions'));
+ },
+ filteredLogsByDate() {
+ return this.getFilteredTableDataByDate(
+ this.allLogs,
+ this.filterStartDate,
+ this.filterEndDate
+ );
+ },
+ filteredLogs() {
+ return this.getFilteredTableData(
+ this.filteredLogsByDate,
+ this.activeFilters
+ );
+ },
+ },
+ created() {
+ this.startLoader();
+ this.$store
+ .dispatch('postCodeLogs/getPostCodesLogData')
+ .finally(() => this.endLoader());
+ },
+ methods: {
+ exportAllLogsString() {
+ {
+ return this.$store.getters['postCodeLogs/allPostCodes'].map(
+ (postCodes) => {
+ const allLogsString = JSON.stringify(postCodes);
+ return allLogsString;
+ }
+ );
+ }
+ },
+ onFilterChange({ activeFilters }) {
+ this.activeFilters = activeFilters;
+ },
+ onChangeDateTimeFilter({ fromDate, toDate }) {
+ this.filterStartDate = fromDate;
+ this.filterEndDate = toDate;
+ },
+ onFiltered(filteredItems) {
+ this.searchTotalFilteredRows = filteredItems.length;
+ },
+ // Create export file name based on date and action
+ exportFileNameByDate(value) {
+ let date = new Date();
+ date =
+ date.toISOString().slice(0, 10) +
+ '_' +
+ date.toString().split(':').join('-').split(' ')[4];
+ let fileName;
+ if (value === 'download') {
+ fileName = this.$t('pagePostCodeLogs.downloadFilePrefix');
+ } else if (value === 'export') {
+ fileName = this.$t('pagePostCodeLogs.exportFilePrefix');
+ } else {
+ fileName = this.$t('pagePostCodeLogs.allExportFilePrefix');
+ }
+ return fileName + date;
+ },
+ },
+};
+</script>