Source

components/location/LocationEvents/LocationEventsTable.vue

<template lang="pug">

.vehicle_events_table(ref="root")
  PicturesGallery(v-show="pictures.length > 0" :pictures="pictures" @close="pictures=[]")
  .table_toolbar
    TableModesToolbar(
      :mode="mode"
      @switchToListMode="switchToListMode({mapComponent:'LocationEventsMap',selectedSubMenuTab:'events'})"
      @switchToTablePlusMapMode="switchToTablePlusMapMode({top: 'LocationEventsMap', bottom: 'LocationEventsTable'})"
      @switchToTableMode="switchToTableMode({component: 'LocationEventsTable'})"
    )
  
  DataTable(
    v-if="table"
    class="table_theme_1"
    ref="datatable",
    :ssrPaging="false",
    :ssrShowMultiColumnFilter="false",
    :searching="true",
    :paging="true",
    name="locationEvents",
    rowId="id",
    scrollY="250px",
    :columns="columns",
    :columnDefs="columnDefs",
    :language="$translations.datatable",
    :extraOptions="extraOptions || {}",
    :select="select",
    :defaultSortingColumn="2"
    @select="onSelect"
    @deselect="onDeselect"
    :autoHeight="true"
    :autoHeightOffset="mode==='table'?0:0"
  )
</template>
<script>
import DataTable, {
  createComponentRender,
} from '@/components/shared/DataTable/DataTable.vue'
import { mapGetters } from 'vuex'
import moment from 'moment'
import $ from 'jquery'
import datatableMixin from '@/mixins/datatable.js'
import TableModesToolbar from '@c/shared/TableModesToolbar/TableModesToolbar.vue'
import locationLayoutModesMixin from '@c/location/mixins/location-layout-modes.js'
import PicturesGallery from '@/components/shared/PicturesGallery/PicturesGallery.vue'
import { createSortableColumnDefinition } from '@/utils/datatable.js'
const R = require('ramda')

/**
 * @todo Refactor/Extract
 */
function sortableColumn(sortBy, display, title) {
  return {
    data: {
      _: sortBy,
      filter: display, //Filter using what user see
      display,
      sort: sortBy,
    },
    title,
  }
}

/**
 * Table feature
 * @namespace components
 * @category components
 * @subcategory location/events
 * @module LocationEventsTable
 **/
export default {
  name: 'LocationEventsTable',
  components: {
    DataTable,
    TableModesToolbar,
    PicturesGallery,
  },
  mixins: [datatableMixin, locationLayoutModesMixin],
  props: {
    mode: {
      type: String,
      default: 'table+map',
      enum: ['table', 'table+map'],
    },
    showRoundColumns: {
      type: Boolean,
      default: false,
    },
    showBinColumns: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    var self = this

    return {
      pictures: [],
      table: false,
      select: {
        items: 'row',
        style: 'single',
        info: false,
      },
      columns: this.buildColumnsArray(),
      columnDefs: [
        {
          targets: 0,
          orderable: false,
          render: createComponentRender({
            name: 'ZoomActionButton',
            template: `<em @click="handleZoom" class="fas fa-search" style="cursor:pointer;"></em>`,
            methods: {
              handleZoom(e) {
                e.stopPropagation()
                self.$mitt.emit('SIMPLICITI_MAP_FIT_TO_BOUNDS', [
                  [this.row.lat, this.row.lng],
                ])
                self.$mitt.emit('SIMPLICITI_MAP_OPEN_MARKER_POPUP', {
                  groupName: 'vehicle_events',
                  layerId: this.row.id,
                })
              },
            },
          }),
        },
        {
          targets: 1,
          orderable: false,
          render: createComponentRender({
            name: 'PhotoActionButton',
            template: `<em @click="openPhotoGallery" class="fas fa-camera" :style="iconStyle"></em>`,
            computed: {
              iconStyle() {
                return this.row.photos !== undefined &&
                  this.row.photos.length > 0
                  ? `cursor: pointer;`
                  : `color: rgb(82 77 77 / 53%); cursor: not-allowed;`
              },
            },
            methods: {
              openPhotoGallery(e) {
                e.stopPropagation()
                self.pictures = this.row.photos
                if (self.$api.areFixturesEnabled) {
                  self.pictures = self.pictures.concat([
                    `https://via.placeholder.com/1920x1080`,
                    `https://via.placeholder.com/1400x1080`,
                    `https://via.placeholder.com/1600x1200`,
                  ])
                }
              },
            },
          }),
        },
      ],
      extraOptions: this.buildExtraOptions(),
    }
  },
  computed: {
    ...mapGetters({
      results: 'location_module/getEvents',
      selectedItem: 'location_module/selectedItem',
    }),
    isAggregateEventGroupBinEnabled() {
      let result = this.$store.getters['settings/getParameter'](
        'isAggregateEventGroupBinEnabled'
      )

      return result
    },
    isAggregateEventGroupRoundEnabled() {
      let result = this.$store.getters['settings/getParameter'](
        'isAggregateEventGroupRoundEnabled'
      )

      return result
    },
  },
  watch: {
    isAggregateEventGroupBinEnabled() {
      this.forceTableReload()
    },
    isAggregateEventGroupRoundEnabled() {
      this.forceTableReload()
    },
    results() {
      this.updateTable()
    },
  },
  mounted() {
    $.fn.dataTable.moment(this.$date.getDatetimePattern())
    this.updateTable()

    this.$store.dispatch('app/changeLayout', {
      currentLayoutName: 'LOCATION_EVENTS_TABLE',
      menu_full_collapse: true,
    })

    setTimeout(() => (this.table = true), 500)
  },
  destroyed() {
    if (this.$store.state.search_module.view !== 'selection') {
      this.$store.dispatch('app/changeLayout', {
        currentLayoutName: 'LOCATION_EVENTS_DETAILS',
        menu_collapsed: this.$store.getters['app/layout'].isMenuCollapsed,
        menu_full_collapse: false,
        sub_menu: true,
      })
    }
  },
  methods: {
    onDeselect() {},
    onSelect({ item }) {},
    updateTable() {
      this.$store.dispatch('datatable/setTableItems', {
        name: 'locationEvents',
        items: this.results,
      })
    },
    forceTableReload() {
      if (this.table) {
        this.table = false
        this.columns = this.buildColumnsArray()
        this.extraOptions = this.buildExtraOptions()
        setInterval(() => {
          this.table = true
        }, 250)
      }
    },
    buildColumnsArray() {
      let columns = [
        {
          data: 'zoomIcon',
          title: '',
        },
        {
          data: 'galleryIcon',
          title: '',
        },
        sortableColumn(
          `timestamp`,
          `formattedDate`,
          this.$t('location_module.events.date')
        ),
        sortableColumn(
          `timestamp`,
          `formattedTime`,
          this.$t('location_module.events.time')
        ),
        sortableColumn(
          `vehicleName`,
          `vehicleName`,
          this.$t('location_module.events.vehicle')
        ),
        sortableColumn(
          `label`,
          `label`,
          this.$t('location_module.events.name')
        ),
        sortableColumn(
          `address`,
          `address`,
          this.$t('location_module.events.address')
        ),
        sortableColumn(`city`, `city`, this.$t('location_module.events.city')),
        sortableColumn(
          `comment`,
          `comment`,
          this.$t('location_module.events.comment')
        ),
      ]

      if (
        this.$store.getters['settings/getParameter'](
          'isAggregateEventGroupRoundEnabled'
        )
      ) {
        columns.push(
          createSortableColumnDefinition(
            `circuitName`,
            `circuitName`,
            this.$t('events.table_column.circuit_name')
          )
        )
      }

      if (
        this.$store.getters['settings/getParameter'](
          'isAggregateEventGroupBinEnabled'
        )
      ) {
        columns.push(
          createSortableColumnDefinition(
            `puceNumber`,
            `puceNumber`,
            this.$t('events.table_column.puce_number')
          )
        )

        columns.push(
          createSortableColumnDefinition(
            `binCollectionSideLabel`,
            `binCollectionSideLabel`,
            this.$t('events.table_column.side')
          )
        )
      }

      return columns
    },
    buildExtraOptions() {
      return {
        ...this.configureColumnsFilters((filters) => {
          let columnFilters = []
          this.columns.forEach((def, index) => {
            if ([0, 1].includes(index)) {
              columnFilters.push(null)
            } else {
              columnFilters.push(filters.createTextFilter({ column: index }))
            }
          })

          return columnFilters
        }),
        ...this.configureExportButtons(),
        dom: 'rtip',
        pageLength: 20,
        info: true,
      }
    },
  },
}
</script>
<style lang="scss" scoped>
.title {
  padding: 5px 10px 0px 10px;
  margin-bottom: 0px;
  flex-shrink: 0;
}
.title,
.title span,
.title strong {
  font-size: 12px;
}
.vehicle_events_table {
  height: 100%;
  height: -moz-available; /* WebKit-based browsers will ignore this. */
  height: -webkit-fill-available; /* Mozilla-based browsers will ignore this. */
  height: fill-available;
}
.table_toolbar {
  display: flex;
  align-items: center;
}
.fas.fa-camera {
  color: #8c8c8c;
  cursor: not-allowed;
}
.fas.fa-camera.active {
  cursor: pointer;
}
</style>