Initial commit
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
<div class="CDB-LoaderIcon is-dark">
|
||||
<svg class="CDB-LoaderIcon-spinner" viewbox="0 0 50 50">
|
||||
<circle class="CDB-LoaderIcon-path" cx="25" cy="25" r="20" fill="none"/>
|
||||
</svg>
|
||||
</div>
|
||||
@@ -0,0 +1,132 @@
|
||||
var _ = require('underscore');
|
||||
var CoreView = require('backbone/core-view');
|
||||
var template = require('./table-paginator.tpl');
|
||||
var templateLoader = require('./table-paginator-loader.tpl');
|
||||
var Notifier = require('builder/components/notifier/notifier');
|
||||
var errorParser = require('builder/helpers/error-parser');
|
||||
var QueryUtilsModel = require('builder/helpers/query-utils-model');
|
||||
|
||||
module.exports = CoreView.extend({
|
||||
|
||||
tagName: 'div',
|
||||
className: 'Table-paginator js-tablePaginator',
|
||||
|
||||
events: {
|
||||
'click .js-prev': '_onPrevPage',
|
||||
'click .js-next': '_onNextPage'
|
||||
},
|
||||
|
||||
initialize: function (opts) {
|
||||
if (!opts.rowsCollection) throw new Error('rowsCollection is required');
|
||||
if (!opts.tableViewModel) throw new Error('tableViewModel is required');
|
||||
|
||||
this._tableViewModel = opts.tableViewModel;
|
||||
this._rowsCollection = opts.rowsCollection;
|
||||
this._scrollToBottom = opts.scrollToBottom;
|
||||
this._numRows = -1;
|
||||
|
||||
this._queryUtilsModel = opts.queryUtilsModel || new QueryUtilsModel({
|
||||
subquery: this._rowsCollection._querySchemaModel.get('query'),
|
||||
configModel: this._rowsCollection._configModel
|
||||
});
|
||||
|
||||
this._queryUtilsModel.fetchCount(function (numRows) {
|
||||
// Check total number of rows to evaluate
|
||||
// if there is a next page available
|
||||
this._numRows = numRows;
|
||||
this.render();
|
||||
}.bind(this));
|
||||
|
||||
this._rowsCollection.bind('loading', function (item) {
|
||||
// Don't take into account row model loading triggers
|
||||
if (item.models) {
|
||||
this._isLoading = true;
|
||||
}
|
||||
}, this);
|
||||
this._rowsCollection.bind('add', this._onRowAdded, this);
|
||||
this._rowsCollection.bind('remove', this._onRowRemoved, this);
|
||||
this._tableViewModel.bind('change:page', this._onTablePageChange, this);
|
||||
this.add_related_model(this._tableViewModel);
|
||||
this.add_related_model(this._rowsCollection);
|
||||
},
|
||||
|
||||
render: function () {
|
||||
var rowsSize = this._rowsCollection.size();
|
||||
var page = this._tableViewModel.get('page');
|
||||
var maxRowsPerPage = this._rowsCollection.DEFAULT_FETCH_OPTIONS.rows_per_page;
|
||||
|
||||
this.$el.html(
|
||||
template({
|
||||
page: this._tableViewModel.get('page'),
|
||||
size: rowsSize,
|
||||
isNextAvailable: this._numRows > (page + 1) * maxRowsPerPage,
|
||||
isPrevAvailable: page > 0
|
||||
})
|
||||
);
|
||||
|
||||
this.$el.toggleClass('Table-paginator--relative', !!this._tableViewModel.get('relativePositionated'));
|
||||
return this;
|
||||
},
|
||||
|
||||
_onRowAdded: function () {
|
||||
this._queryUtilsModel.fetchCount(function (numRows) {
|
||||
if (numRows > -1) {
|
||||
// Go to the last page
|
||||
var maxRowsPerPage = this._rowsCollection.DEFAULT_FETCH_OPTIONS.rows_per_page;
|
||||
var lastPage = Math.ceil(numRows / maxRowsPerPage) - 1;
|
||||
if (lastPage !== this._tableViewModel.get('page')) {
|
||||
this._tableViewModel.set('page', lastPage);
|
||||
} else {
|
||||
this.render();
|
||||
}
|
||||
setTimeout(this._scrollToBottom, 200);
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
_onRowRemoved: function () {
|
||||
this._rowsCollection.fetch({
|
||||
data: this._getData()
|
||||
});
|
||||
},
|
||||
|
||||
_onTablePageChange: function () {
|
||||
this._rowsCollection.fetch({
|
||||
data: this._getData(),
|
||||
error: function (mdl, response) {
|
||||
this._isLoading = false;
|
||||
this.render();
|
||||
|
||||
Notifier.addNotification({
|
||||
status: 'error',
|
||||
info: _t('components.table.rows.paginator.error', { error: errorParser(response) }),
|
||||
closable: true
|
||||
});
|
||||
}.bind(this)
|
||||
});
|
||||
},
|
||||
|
||||
_getData: function () {
|
||||
return _.extend(
|
||||
this._tableViewModel.pick('page', 'order_by', 'sort_order'),
|
||||
{
|
||||
exclude: !this._tableViewModel.isCustomQueryApplied() ? ['the_geom_webmercator'] : []
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
_onPrevPage: function (ev) {
|
||||
if (!this._isLoading) {
|
||||
this.$('.js-prev').html(templateLoader());
|
||||
this._tableViewModel.set('page', this._tableViewModel.get('page') - 1);
|
||||
}
|
||||
},
|
||||
|
||||
_onNextPage: function (ev) {
|
||||
if (!this._isLoading) {
|
||||
this.$('.js-next').html(templateLoader());
|
||||
this._tableViewModel.set('page', this._tableViewModel.get('page') + 1);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
<button class="Table-paginatorButton Table-paginatorButton--prev
|
||||
<% if (isPrevAvailable) { %>
|
||||
js-prev
|
||||
is-active
|
||||
<% } %>
|
||||
">
|
||||
<i class="CDB-IconFont is-semibold CDB-IconFont-lArrowLight CDB-Size-small
|
||||
<% if (isPrevAvailable) { %>
|
||||
u-actionTextColor
|
||||
<% } else { %>
|
||||
u-hintTextColor
|
||||
<% } %>
|
||||
"></i>
|
||||
</button>
|
||||
<p class="Table-paginatorText CDB-Text CDB-Size-small is-semibold u-upperCase">
|
||||
<% if (!size) {%>
|
||||
<span class="u-mainTextColor">…</span>
|
||||
<% } else { %>
|
||||
<span class="u-mainTextColor"><%- (page * 40) + 1 %></span>
|
||||
<span class="u-altTextColor u-lSpace u-rSpace"><%- _t('components.table.rows.paginator.to') %></span>
|
||||
<span class="u-mainTextColor"><%- (page * 40) + size %></span>
|
||||
<% } %>
|
||||
</p>
|
||||
<button class="Table-paginatorButton Table-paginatorButton--next
|
||||
<% if (isNextAvailable) { %>
|
||||
js-next
|
||||
is-active
|
||||
<% } %>
|
||||
">
|
||||
<i class="CDB-IconFont is-semibold CDB-IconFont-rArrowLight CDB-Size-small
|
||||
<% if (isNextAvailable) { %>
|
||||
u-actionTextColor
|
||||
<% } else { %>
|
||||
u-hintTextColor
|
||||
<% } %>
|
||||
"></i>
|
||||
</button>
|
||||
Reference in New Issue
Block a user