diff --git a/tailbone/grids/core.py b/tailbone/grids/core.py index 2593ed4c..60934879 100644 --- a/tailbone/grids/core.py +++ b/tailbone/grids/core.py @@ -75,7 +75,7 @@ class Grid(object): pageable=False, default_pagesize=20, default_page=1, checkboxes=False, checked=None, check_handler=None, check_all_handler=None, main_actions=[], more_actions=[], delete_speedbump=False, - ajax_data_url=None, + ajax_data_url=None, component='tailbone-grid', **kwargs): self.key = key @@ -139,8 +139,14 @@ class Grid(object): else: self.ajax_data_url = '' + self.component = component self._whgrid_kwargs = kwargs + @property + def component_studly(self): + words = self.component.split('-') + return ''.join([word.capitalize() for word in words]) + def make_columns(self): """ Return a default list of columns, based on :attr:`model_class`. @@ -1237,8 +1243,9 @@ class Grid(object): results['checked_rows'] = checked # TODO: this seems a bit hacky, but is required for now to # initialize things on the client side... + var = '{}CurrentData'.format(self.component_studly) results['checked_rows_code'] = '[{}]'.format( - ', '.join(['TailboneGridCurrentData[{}]'.format(i) for i in checked])) + ', '.join(['{}[{}]'.format(var, i) for i in checked])) if self.pageable and self.pager is not None: results['total_items'] = self.pager.item_count diff --git a/tailbone/static/js/tailbone.buefy.grid.js b/tailbone/static/js/tailbone.buefy.grid.js index 45f6581d..f4ebf170 100644 --- a/tailbone/static/js/tailbone.buefy.grid.js +++ b/tailbone/static/js/tailbone.buefy.grid.js @@ -88,176 +88,3 @@ const GridFilter = { } Vue.component('grid-filter', GridFilter) - - -let TailboneGrid = { - template: '#tailbone-grid-template', - - props: { - csrftoken: String, - }, - - computed: { - // note, can use this with v-model for hidden 'uuids' fields - selected_uuids: function() { - return this.checkedRowUUIDs().join(',') - }, - }, - - 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(`${this.ajaxDataUrl}?${params}`).then(({ data }) => { - TailboneGridCurrentData = data.data - this.data = TailboneGridCurrentData - this.rowStatusMap = data.row_status_map - this.total = data.total_items - this.firstItem = data.first_item - this.lastItem = data.last_item - this.loading = false - this.checkedRows = this.locateCheckedRows(data.checked_rows) - }) - .catch((error) => { - this.data = [] - this.total = 0 - this.loading = false - throw error - }) - }, - - locateCheckedRows(checked) { - let rows = [] - if (checked) { - for (let i = 0; i < this.data.length; i++) { - if (checked.includes(i)) { - rows.push(this.data[i]) - } - } - } - return rows - }, - - 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) - }, - - deleteObject(event) { - // we let parent component/app deal with this, in whatever way makes sense... - // TODO: should we ever provide anything besides the URL for this? - this.$emit('deleteActionClicked', event.target.href) - }, - - checkedRowUUIDs() { - let uuids = [] - for (let row of this.$data.checkedRows) { - uuids.push(row.uuid) - } - return uuids - }, - - allRowUUIDs() { - let uuids = [] - for (let row of this.data) { - uuids.push(row.uuid) - } - return uuids - }, - } -} diff --git a/tailbone/templates/grids/buefy.mako b/tailbone/templates/grids/buefy.mako index 1d47310b..f1bfadf1 100644 --- a/tailbone/templates/grids/buefy.mako +++ b/tailbone/templates/grids/buefy.mako @@ -85,7 +85,7 @@ - diff --git a/tailbone/templates/master/index.mako b/tailbone/templates/master/index.mako index cae42362..8826c096 100644 --- a/tailbone/templates/master/index.mako +++ b/tailbone/templates/master/index.mako @@ -256,12 +256,12 @@ <%def name="page_content()"> - - + % if master.deletable and request.has_perm('{}.delete'.format(permission_prefix)) and master.delete_confirm == 'simple': ${h.form('#', ref='deleteObjectForm')} ${h.csrf_token(request)} @@ -273,9 +273,9 @@ ${parent.make_this_page_component()} @@ -309,10 +309,10 @@ ## enable / disable selected objects % if master.supports_set_enabled_toggle and master.has_perm('enable_disable_set'): - TailboneGridData.enableSelectedSubmitting = false - TailboneGridData.enableSelectedText = "Enable Selected" + ${grid.component_studly}Data.enableSelectedSubmitting = false + ${grid.component_studly}Data.enableSelectedText = "Enable Selected" - TailboneGrid.computed.enableSelectedDisabled = function() { + ${grid.component_studly}.computed.enableSelectedDisabled = function() { if (this.enableSelectedSubmitting) { return true } @@ -322,7 +322,7 @@ return false } - TailboneGrid.methods.enableSelectedSubmit = function() { + ${grid.component_studly}.methods.enableSelectedSubmit = function() { let uuids = this.checkedRowUUIDs() if (!uuids.length) { alert("You must first select one or more objects to disable.") @@ -337,10 +337,10 @@ this.$refs.enable_selected_form.submit() } - TailboneGridData.disableSelectedSubmitting = false - TailboneGridData.disableSelectedText = "Disable Selected" + ${grid.component_studly}Data.disableSelectedSubmitting = false + ${grid.component_studly}Data.disableSelectedText = "Disable Selected" - TailboneGrid.computed.disableSelectedDisabled = function() { + ${grid.component_studly}.computed.disableSelectedDisabled = function() { if (this.disableSelectedSubmitting) { return true } @@ -350,7 +350,7 @@ return false } - TailboneGrid.methods.disableSelectedSubmit = function() { + ${grid.component_studly}.methods.disableSelectedSubmit = function() { let uuids = this.checkedRowUUIDs() if (!uuids.length) { alert("You must first select one or more objects to disable.") @@ -370,10 +370,10 @@ ## delete selected objects % if master.set_deletable and master.has_perm('delete_set'): - TailboneGridData.deleteSelectedSubmitting = false - TailboneGridData.deleteSelectedText = "Delete Selected" + ${grid.component_studly}Data.deleteSelectedSubmitting = false + ${grid.component_studly}Data.deleteSelectedText = "Delete Selected" - TailboneGrid.computed.deleteSelectedDisabled = function() { + ${grid.component_studly}.computed.deleteSelectedDisabled = function() { if (this.deleteSelectedSubmitting) { return true } @@ -383,7 +383,7 @@ return false } - TailboneGrid.methods.deleteSelectedSubmit = function() { + ${grid.component_studly}.methods.deleteSelectedSubmit = function() { let uuids = this.checkedRowUUIDs() if (!uuids.length) { alert("You must first select one or more objects to disable.") @@ -401,10 +401,10 @@ % if master.bulk_deletable and master.has_perm('bulk_delete'): - TailboneGridData.deleteResultsSubmitting = false - TailboneGridData.deleteResultsText = "Delete Results" + ${grid.component_studly}Data.deleteResultsSubmitting = false + ${grid.component_studly}Data.deleteResultsText = "Delete Results" - TailboneGrid.computed.deleteResultsDisabled = function() { + ${grid.component_studly}.computed.deleteResultsDisabled = function() { if (this.deleteResultsSubmitting) { return true } @@ -414,7 +414,7 @@ return false } - TailboneGrid.methods.deleteResultsSubmit = function() { + ${grid.component_studly}.methods.deleteResultsSubmit = function() { // TODO: show "plural model title" here? if (!confirm("You are about to delete " + this.total.toLocaleString('en') + " objects.\n\nAre you sure?")) { return @@ -429,10 +429,10 @@ % if master.mergeable and master.has_perm('merge'): - TailboneGridData.mergeFormButtonText = "Merge 2 ${model_title_plural}" - TailboneGridData.mergeFormSubmitting = false + ${grid.component_studly}Data.mergeFormButtonText = "Merge 2 ${model_title_plural}" + ${grid.component_studly}Data.mergeFormSubmitting = false - TailboneGrid.methods.submitMergeForm = function() { + ${grid.component_studly}.methods.submitMergeForm = function() { this.mergeFormSubmitting = true this.mergeFormButtonText = "Working, please wait..." } diff --git a/tailbone/templates/master/view.mako b/tailbone/templates/master/view.mako index 1f4b59ee..d07e1cc9 100644 --- a/tailbone/templates/master/view.mako +++ b/tailbone/templates/master/view.mako @@ -102,6 +102,7 @@ <%def name="make_this_page_component()"> + % if master.has_rows: + % endif ${parent.make_this_page_component()}