Add "direct link" support for master grids
This commit is contained in:
parent
cd466a64e5
commit
8264a69cec
|
@ -189,6 +189,7 @@ class Grid(object):
|
||||||
clicking_row_checks_box=False, click_handlers=None,
|
clicking_row_checks_box=False, click_handlers=None,
|
||||||
main_actions=[], more_actions=[], delete_speedbump=False,
|
main_actions=[], more_actions=[], delete_speedbump=False,
|
||||||
ajax_data_url=None, component='tailbone-grid',
|
ajax_data_url=None, component='tailbone-grid',
|
||||||
|
expose_direct_link=False,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
|
|
||||||
self.key = key
|
self.key = key
|
||||||
|
@ -256,11 +257,12 @@ class Grid(object):
|
||||||
if ajax_data_url:
|
if ajax_data_url:
|
||||||
self.ajax_data_url = ajax_data_url
|
self.ajax_data_url = ajax_data_url
|
||||||
elif self.request:
|
elif self.request:
|
||||||
self.ajax_data_url = self.request.current_route_url()
|
self.ajax_data_url = self.request.current_route_url(_query=None)
|
||||||
else:
|
else:
|
||||||
self.ajax_data_url = ''
|
self.ajax_data_url = ''
|
||||||
|
|
||||||
self.component = component
|
self.component = component
|
||||||
|
self.expose_direct_link = expose_direct_link
|
||||||
self._whgrid_kwargs = kwargs
|
self._whgrid_kwargs = kwargs
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -289,9 +289,22 @@
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<div style="display: flex; justify-content: space-between;">
|
||||||
|
|
||||||
|
% if grid.expose_direct_link:
|
||||||
|
<b-button type="is-primary"
|
||||||
|
size="is-small"
|
||||||
|
@click="copyDirectLink()"
|
||||||
|
title="Copy link to clipboard">
|
||||||
|
<span><i class="fa fa-share-alt"></i></span>
|
||||||
|
</b-button>
|
||||||
|
% else:
|
||||||
|
<div></div>
|
||||||
|
% endif
|
||||||
|
|
||||||
% if grid.pageable:
|
% if grid.pageable:
|
||||||
<template slot="footer">
|
<b-field grouped
|
||||||
<b-field grouped position="is-right"
|
|
||||||
v-if="firstItem">
|
v-if="firstItem">
|
||||||
<span class="control">
|
<span class="control">
|
||||||
showing {{ firstItem.toLocaleString('en') }} - {{ lastItem.toLocaleString('en') }} of {{ total.toLocaleString('en') }} results;
|
showing {{ firstItem.toLocaleString('en') }} - {{ lastItem.toLocaleString('en') }} of {{ total.toLocaleString('en') }} results;
|
||||||
|
@ -307,9 +320,11 @@
|
||||||
per page
|
per page
|
||||||
</span>
|
</span>
|
||||||
</b-field>
|
</b-field>
|
||||||
</template>
|
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
</b-table>
|
</b-table>
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
@ -368,10 +383,24 @@
|
||||||
visibleData() {
|
visibleData() {
|
||||||
return this.data
|
return this.data
|
||||||
},
|
},
|
||||||
|
|
||||||
|
directLink() {
|
||||||
|
let params = new URLSearchParams(this.getAllParams())
|
||||||
|
return `${request.current_route_url(_query=None)}?${'$'}{params}`
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
|
copyDirectLink() {
|
||||||
|
navigator.clipboard.writeText(this.directLink)
|
||||||
|
this.$buefy.toast.open({
|
||||||
|
message: "Link was copied to clipboard",
|
||||||
|
type: 'is-info',
|
||||||
|
duration: 2000, // 2 seconds
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
addRowClass(index, className) {
|
addRowClass(index, className) {
|
||||||
|
|
||||||
// TODO: this may add duplicated name to class string
|
// TODO: this may add duplicated name to class string
|
||||||
|
@ -388,16 +417,45 @@
|
||||||
return this.rowStatusMap[index]
|
return this.rowStatusMap[index]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getBasicParams() {
|
||||||
|
let params = {}
|
||||||
|
% if grid.sortable:
|
||||||
|
params.sortkey = this.sortField
|
||||||
|
params.sortdir = this.sortOrder
|
||||||
|
% endif
|
||||||
|
% if grid.pageable:
|
||||||
|
params.pagesize = this.perPage
|
||||||
|
params.page = this.currentPage
|
||||||
|
% endif
|
||||||
|
return params
|
||||||
|
},
|
||||||
|
|
||||||
|
getFilterParams() {
|
||||||
|
let params = {}
|
||||||
|
for (var key in this.filters) {
|
||||||
|
var filter = this.filters[key]
|
||||||
|
if (filter.active) {
|
||||||
|
params[key] = filter.value
|
||||||
|
params[key+'.verb'] = filter.verb
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Object.keys(params).length) {
|
||||||
|
params.filter = true
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
},
|
||||||
|
|
||||||
|
getAllParams() {
|
||||||
|
return {...this.getBasicParams(),
|
||||||
|
...this.getFilterParams()}
|
||||||
|
},
|
||||||
|
|
||||||
loadAsyncData(params, callback) {
|
loadAsyncData(params, callback) {
|
||||||
|
|
||||||
if (params === undefined || params === null) {
|
if (params === undefined || params === null) {
|
||||||
params = [
|
params = new URLSearchParams(this.getBasicParams())
|
||||||
'partial=true',
|
params.append('partial', true)
|
||||||
`sortkey=${'$'}{this.sortField}`,
|
params = params.toString()
|
||||||
`sortdir=${'$'}{this.sortOrder}`,
|
|
||||||
`pagesize=${'$'}{this.perPage}`,
|
|
||||||
`page=${'$'}{this.currentPage}`
|
|
||||||
].join('&')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loading = true
|
this.loading = true
|
||||||
|
@ -482,23 +540,27 @@
|
||||||
|
|
||||||
applyFilters(params) {
|
applyFilters(params) {
|
||||||
if (params === undefined) {
|
if (params === undefined) {
|
||||||
params = []
|
params = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
params.push('partial=true')
|
// merge in actual filter params
|
||||||
params.push('filter=true')
|
// cf. https://stackoverflow.com/a/171256
|
||||||
|
params = {...params, ...this.getFilterParams()}
|
||||||
|
|
||||||
|
// hide inactive filters
|
||||||
for (var key in this.filters) {
|
for (var key in this.filters) {
|
||||||
var filter = this.filters[key]
|
var filter = this.filters[key]
|
||||||
if (filter.active) {
|
if (!filter.active) {
|
||||||
params.push(key + '=' + encodeURIComponent(filter.value))
|
|
||||||
params.push(key + '.verb=' + encodeURIComponent(filter.verb))
|
|
||||||
} else {
|
|
||||||
filter.visible = false
|
filter.visible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadAsyncData(params.join('&'))
|
// set some explicit params
|
||||||
|
params.partial = true
|
||||||
|
params.filter = true
|
||||||
|
|
||||||
|
params = new URLSearchParams(params)
|
||||||
|
this.loadAsyncData(params)
|
||||||
},
|
},
|
||||||
|
|
||||||
clearFilters() {
|
clearFilters() {
|
||||||
|
@ -550,8 +612,7 @@
|
||||||
saveDefaults() {
|
saveDefaults() {
|
||||||
|
|
||||||
// apply current filters as normal, but add special directive
|
// apply current filters as normal, but add special directive
|
||||||
const params = ['save-current-filters-as-defaults=true']
|
this.applyFilters({'save-current-filters-as-defaults': true})
|
||||||
this.applyFilters(params)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteObject(event) {
|
deleteObject(event) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
## -*- coding: utf-8; -*-
|
## -*- coding: utf-8; -*-
|
||||||
|
|
||||||
<form action="${form.action_url}" method="GET" v-on:submit.prevent="applyFilters()">
|
<form action="${form.action_url}" method="GET" @submit.prevent="applyFilters()">
|
||||||
|
|
||||||
<grid-filter v-for="key in filtersSequence"
|
<grid-filter v-for="key in filtersSequence"
|
||||||
:key="key"
|
:key="key"
|
||||||
|
|
|
@ -455,6 +455,10 @@ class MasterView(View):
|
||||||
'clicking_row_checks_box': self.clicking_row_checks_box,
|
'clicking_row_checks_box': self.clicking_row_checks_box,
|
||||||
'assume_local_times': self.has_local_times,
|
'assume_local_times': self.has_local_times,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.sortable or self.pageable or self.filterable:
|
||||||
|
defaults['expose_direct_link'] = True
|
||||||
|
|
||||||
if 'main_actions' not in kwargs and 'more_actions' not in kwargs:
|
if 'main_actions' not in kwargs and 'more_actions' not in kwargs:
|
||||||
main, more = self.get_grid_actions()
|
main, more = self.get_grid_actions()
|
||||||
defaults['main_actions'] = main
|
defaults['main_actions'] = main
|
||||||
|
|
Loading…
Reference in a new issue