Make Buefy grids use proper Vue.js component structure

at least, better than before...this lets each page have the final say about the
app logic etc.
This commit is contained in:
Lance Edgar 2019-05-23 12:10:11 -05:00
parent 6c3722737d
commit 7b1947914e
4 changed files with 340 additions and 317 deletions

View file

@ -0,0 +1,168 @@
const GridFilter = {
template: '#grid-filter-template',
props: {
filter: Object
},
methods: {
changeVerb() {
// set focus to value input, "as quickly as we can"
this.$nextTick(function() {
this.focusValue()
})
},
focusValue: function() {
this.$refs.valueInput.focus()
// this.$refs.valueInput.select()
}
}
}
Vue.component('grid-filter', GridFilter)
let TailboneGrid = {
template: '#tailbone-grid-template',
methods: {
getRowClass(row, index) {
return this.rowStatusMap[index]
},
loadAsyncData(params) {
if (params === undefined) {
params = [
'partial=true',
`sortkey=${this.sortField}`,
`sortdir=${this.sortOrder}`,
`pagesize=${this.perPage}`,
`page=${this.page}`
].join('&')
}
this.loading = true
this.$http.get(`?${params}`).then(({ data }) => {
this.data = data.data
this.rowStatusMap = data.row_status_map
this.total = data.total_items
this.firstItem = data.first_item
this.lastItem = data.last_item
this.loading = false
})
.catch((error) => {
this.data = []
this.total = 0
this.loading = false
throw error
})
},
onPageChange(page) {
this.page = page
this.loadAsyncData()
},
onSort(field, order) {
this.sortField = field
this.sortOrder = order
// always reset to first page when changing sort options
// TODO: i mean..right? would we ever not want that?
this.page = 1
this.loadAsyncData()
},
resetView() {
this.loading = true
location.href = '?reset-to-default-filters=true'
},
addFilter(filter_key) {
// reset dropdown so user again sees "Add Filter" placeholder
this.$nextTick(function() {
this.selectedFilter = null
})
// show corresponding grid filter
this.filters[filter_key].visible = true
this.filters[filter_key].active = true
// track down the component
var gridFilter = null
for (var gf of this.$refs.gridFilters) {
if (gf.filter.key == filter_key) {
gridFilter = gf
break
}
}
// tell component to focus the value field, ASAP
this.$nextTick(function() {
gridFilter.focusValue()
})
},
applyFilters(params) {
if (params === undefined) {
params = []
}
params.push('partial=true')
params.push('filter=true')
for (var key in this.filters) {
var filter = this.filters[key]
if (filter.active) {
params.push(key + '=' + encodeURIComponent(filter.value))
params.push(key + '.verb=' + encodeURIComponent(filter.verb))
} else {
filter.visible = false
}
}
this.loadAsyncData(params.join('&'))
},
clearFilters() {
// explicitly deactivate all filters
for (var key in this.filters) {
this.filters[key].active = false
}
// then just "apply" as normal
this.applyFilters()
},
saveDefaults() {
// apply current filters as normal, but add special directive
const params = ['save-current-filters-as-defaults=true']
this.applyFilters(params)
},
deleteResults(event) {
// submit form if user confirms
// TODO: how/where to get/show "plural model title" here?
// if (confirm("You are about to delete " + this.total + " ${grid.model_title_plural}.\n\nAre you sure?")) {
if (confirm("You are about to delete " + this.total + " objects.\n\nAre you sure?")) {
event.target.form.submit()
}
},
checkedRowUUIDs() {
var uuids = [];
for (var row of this.$data.checkedRows) {
uuids.push(row.uuid)
}
return uuids
}
}
}

View file

@ -1,24 +0,0 @@
const GridFilter = {
template: '#grid-filter-template',
props: {
filter: Object
},
methods: {
changeVerb() {
// set focus to value input, "as quickly as we can"
this.$nextTick(function() {
this.focusValue()
})
},
focusValue: function() {
this.$refs.valueInput.focus()
// this.$refs.valueInput.select()
}
}
}
Vue.component('grid-filter', GridFilter)