2

I have a vuestic data table having 7 columns.

The first 6 columns are table fields coming from a table stored in database.

The last column is a vuetable action column which is a combination of two buttons - 'Details' and 'Delete'.

Depending on the data coming from table in DB, some rows have delete buttons and other rows do not have it.

Also, I am using sorting on first 6 columns of vuetable. But my problem is that when I sort the vuetable with one column, say for e.g., 'Lines Read', all other columns gets sorted as well but the action column (the last column) does not change at all and displays the buttons in the same order.

I want the buttons to change also as the row data is changed on sorting. How can I do that?

TransactionImports.vue

<template>
  <div class="va-row">
    <div class="flex md12 xs12">
      <vuestic-widget headerText="Transaction Imports">
        <div style="float: right; margin-right: 20px;">
          <filter-bar
            @input="onFilterSet"
            label="Search"
            v-model="searchText"
          />
        </div>
        <div v-show="loading" class="data-table-loading">
          <slot name="loading">
            <spring-spinner
              slot="loading"
              :animation-duration="2500"
              :size="70"
              color="#007755"
            />
          </slot>
        </div>
        <vuestic-data-table
          ref="vuestictable"
          v-show="!loading"
          :apiMode="false"
          :tableData="tableData"
          :tableFields="tableFields"
          :defaultPerPage="defaultPerPage"
          :sortFunctions="sortFunctions"
          :paginationPath="paginationPath"
          :queryParams="queryParams"
        />
      </vuestic-widget>
    </div>
  </div>
</template>

<script>
import Vue from 'vue'
import moment from 'moment'
import FilterBar from '../comps/FilterBar'
import { SpringSpinner } from 'epic-spinners'
import ActionColumn from './ActionColumn'
import { getAllTransactionImports } from '../../services/api'

Vue.component('action-column', ActionColumn)
export default {
  name: 'transaction-imports',
  components: {
    FilterBar,
    SpringSpinner
  },
  props: {
    filterablefields: {
      type: Array,
      default: () => [
        'collection',
        'linesRead',
        'outputFilename',
        'totalInserts'
        // 'accountNumbers'
      ]
    }
  },
  data () {
    return {
      loading: false,
      searchText: '',
      imports: [],
      tableFields: [
        {
          name: 'importedOn',
          title: 'Imported On',
          sortField: 'importedOn',
          width: '10%',
          callback: this.formatDate
        },
        {
          name: 'collection',
          title: 'Collection',
          sortField: 'collection',
          width: '20%'
        },
        {
          name: 'linesRead',
          title: 'Lines Read',
          sortField: 'linesRead',
          width: '10%'
        },
        {
          name: 'totalInserts',
          title: 'Total Inserts',
          sortField: 'totalInserts',
          width: '10%'
        },
        {
          name: 'rowsParsed',
          title: 'Rows Parsed',
          sortField: 'rowsParsed',
          width: '10%'
        },
        { 
          name: 'outputFilename',
          title: 'Output',
          sortField: 'outputFilename',
          width: '25%'
        },
        {
          name: '__component:action-column',
          title: '',
          width: '15%'
        }
      ],
      defaultPerPage: 30,
      queryParams: {
        sort: 'sort',
        page: 'page',
        perPage: 'per_page'
      },
      paginationPath: '',
      sortFunctions: {
        'achIncrements': this.sortFunc,
        'collection': this.sortFunc,
        'importedOn': this.sortFunc,
        'linesRead': this.sortFunc,
        'outputFilename': this.sortFunc,
        'rowsParsed': this.sortFunc,
        'totalInserts': this.sortFunc,
      }
    }
  },
  created() {
    this.loadTransImport()
  },
  computed: {
    tableData: {
      get () {
        const txt = new RegExp(this.searchText, 'i')
          let list = this.imports.slice()
          list = list.filter(item => {
            return this.filterablefields.some(field => {
              const val = item[field] + ''
              return val.search(txt) >= 0
            })
          })
          list = {data: list}
          return list
      },
      set () {}
    },
  },
  methods: {
    loadTransImport () {
      let self = this
      self.loading = true
      getAllTransactionImports().then(res => {
        self.$log.debug(res.data)
        self.imports = res.data.sort((item1, item2) => item1.importedOn >= item2.importedOn ? -1 : 1)
        self.tableData = self.imports
        Vue.nextTick(() => self.$refs.vuestictable.$refs.vuetable.refresh())
        self.loading = false
      }).catch(e => {
        self.$log.error(e)
        self.loading = false
      })
    },
    // list filter and pagination
    onFilterSet () {
      const txt = new RegExp(this.searchText, 'i')
      this.tableData = this.imports.slice()
      this.tableData = this.imports.filter(item => {
        return this.filterablefields.some(field => {
          const val = item[field] + ''
          console.log(val.search(txt) >= 0)
          return val.search(txt) >= 0
        })
      })
      Vue.nextTick(() => this.$refs.vuestictable.$refs.vuetable.refresh())
    },
    sortFunc (item1, item2) {
      return item1 >= item2 ? 1 : -1
    },
    formatDate (value) {
      return moment(value).format('MM/DD/YYYY HH:mm')
    }
  }
}
</script>

ActionColumn.vue

<template>
  <div style="height: 100%">
    <button 
      class="btn btn-primary btn-micro"
      @click="importDetails"
    >
      Details
    </button>
    <span v-if="profile.role === 'clerk'" style="margin-left:80px;"></span>
    <button v-if="locked && profile.role === 'admin' || profile.role === 'manager'"
        class="btn btn-danger btn-micro"
        @click="openDeleteModal"
      >
        <span class="fa fa-trash-o"></span>
    </button>
    <vuestic-modal
      ref="deleteModal"
      okText="Delete"
      okClass="btn btn-danger btn-micro"
      cancelClass="btn btn-pale btn-micro"
      @ok="deleteImport"
    >
      <p slot="title">Delete the Import</p>
      <p>This can't be undone</p>
    </vuestic-modal>
  </div>
</template>

<script>
import { deleteTransactionImport } from '../../services/api'

export default {
  name: 'action-column',
  props: {
    rowData: {
      type: Object,
      required: true
    },
    rowIndex: {
      type: Number
    }
  },
  created () {
    this.loadProfile()
  },
  methods: {
    loadProfile () {
      console.log(this.rowData)
      this.locked = this.rowData.isLocked
      this.profile = this.$store.getters.getProfile
    },
    importDetails () {
      this.$router.push({name: 'transaction-list', params: {importDate: this.rowData.importedOn}})
    },
    openDeleteModal () {
      this.$refs.deleteModal.open()
    },
    deleteImport () {
      // too dangerous to try
      let importID = this.rowData.collection
      deleteTransactionImport(importID).then(res => {
        this.$log.info('deleted')
      })
    }
  }
}
</script>

<style scoped>
/* .circle {
  width: .75rem;
  height: .75rem;
  border-radius: 50%;
  display: inline-block
} */
</style>

This is the table Screenshot

enter image description here

3
  • Disclaimer: I don't know the vuetable. You must add the column in the tabledata computed method and threat it as a data column.
    – Max
    Oct 14, 2019 at 17:34
  • The column has 'html buttons', how can I add that to tabledata? Oct 15, 2019 at 15:05
  • Try using the VueTableFieldMixin into the ActionColumn
    – Max
    Oct 15, 2019 at 17:09

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.