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

Max
  • 6,821
  • 3
  • 43
  • 59
  • 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 '19 at 17:34
  • The column has 'html buttons', how can I add that to tabledata? – Vibhu Sharma Oct 15 '19 at 15:05
  • Try using the [VueTableFieldMixin](https://www.vuetable.com/api/field/mixin.html#properties) into the ActionColumn – Max Oct 15 '19 at 17:09

0 Answers0