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
tabledata
computed method and threat it as a data column.