Add "most of" Buefy support for grid filters

still a couple of details to wrap up yet, but this is most of it!
This commit is contained in:
Lance Edgar 2019-04-15 18:36:14 -05:00
parent 23c38e33d4
commit a0cd1f4cd0
8 changed files with 313 additions and 96 deletions

View file

@ -1,6 +1,80 @@
## -*- coding: utf-8; -*-
<div id="buefy-table-app">
<script type="text/x-template" id="grid-filter-template">
<div class="level filter" v-show="filter.visible">
<div class="level-left">
<div class="level-item">
<b-field>
<b-checkbox-button v-model="filter.active" native-value="IGNORED">
<b-icon pack="fas" icon="check" v-show="filter.active"></b-icon>
<span>{{ filter.label }}</span>
</b-checkbox-button>
</b-field>
</div>
<b-field grouped v-show="filter.active" custom-class="level-item">
<b-select v-model="filter.verb"
@input="focusValue()">
<option v-for="verb in filter.verbs"
:key="verb"
:value="verb">
{{ filter.verb_labels[verb] }}
</option>
</b-select>
<b-input v-model="filter.value"
v-show="! (filter.valueless_verbs && filter.valueless_verbs.includes(filter.verb))"
ref="valueInput">
</b-input>
</b-field>
</div><!-- level-left -->
</div><!-- level -->
</script>
<div id="buefy-grid-app">
<div style="display: flex; justify-content: space-between; margin-bottom: 0.5em;">
<div class="filters">
% if grid.filterable:
## TODO: stop using |n filter
${grid.render_filters(allow_save_defaults=allow_save_defaults)|n}
% endif
</div>
<div style="display: flex; flex-direction: column; justify-content: space-between;">
<div class="context-menu">
% if context_menu:
<ul id="context-menu">
## TODO: stop using |n filter
${context_menu|n}
</ul>
% endif
</div>
<div class="grid-tools-wrapper">
% if tools:
<div class="grid-tools">
## TODO: stop using |n filter
${tools|n}
</div>
% endif
</div>
</div>
</div>
<b-table
:data="data"
:columns="columns"
@ -76,7 +150,7 @@
<script type="text/javascript">
new Vue({
el: '#buefy-table-app',
el: '#buefy-grid-app',
data() {
return {
data: ${json.dumps(grid_data['data'])|n},
@ -84,6 +158,7 @@
sortField: '${grid.sortkey}',
sortOrder: '${grid.sortdir}',
rowStatusMap: ${json.dumps(grid_data['row_status_map'])|n},
% if grid.pageable:
% if static_data:
total: ${len(grid_data['data'])},
@ -92,8 +167,14 @@
% endif
perPage: ${grid.pagesize},
page: ${grid.page},
firstItem: ${grid_data['first_item']},
lastItem: ${grid_data['last_item']},
firstItem: ${json.dumps(grid_data['first_item'])|n},
lastItem: ${json.dumps(grid_data['last_item'])|n},
% endif
% if grid.filterable:
filters: ${json.dumps(filters_data)|n},
filtersSequence: ${json.dumps(filters_sequence)|n},
selectedFilter: null,
% endif
}
},
@ -103,15 +184,17 @@
return this.rowStatusMap[index]
},
loadAsyncData() {
loadAsyncData(params) {
const params = [
'partial=true',
`sortkey=${'$'}{this.sortField}`,
`sortdir=${'$'}{this.sortOrder}`,
`pagesize=${'$'}{this.perPage}`,
`page=${'$'}{this.page}`
].join('&')
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(`${request.current_route_url(_query=None)}?${'$'}{params}`).then(({ data }) => {
@ -142,6 +225,77 @@
// 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)
}
}