cartodb/lib/assets/javascripts/deep-insights/widgets/widget-view.js
2020-06-15 10:58:47 +08:00

150 lines
4.2 KiB
JavaScript

var Backbone = require('backbone');
var _ = require('underscore');
var CoreView = require('backbone/core-view');
var WidgetLoaderView = require('./widget-loader-view');
var WidgetErrorView = require('./widget-error-view');
var errorEnhancer = require('../util/error-enhancer');
var getValue = require('../util/get-object-value');
var Utils = require('builder/helpers/utils');
var PLACEHOLDER_TEMPLATES = {
category: require('./category/list/items-placeholder-template.tpl'),
formula: require('./formula/placeholder.tpl'),
histogram: require('./histogram/placeholder.tpl')
};
var MAX_BUCKETS = 367;
/**
* Default widget view
* The model is a expected to be widget model
*/
module.exports = CoreView.extend({
className: 'CDB-Widget CDB-Widget--light',
options: {
columns_title: []
},
initialize: function () {
this.errorModel = new Backbone.Model({});
var dataviewModel = this.model.dataviewModel;
this.listenTo(this.model, 'destroy', this.clean);
this.listenTo(this.model, 'error', this._onError);
this.listenTo(this.model, 'setDisabled', this._setDisabled);
this.listenTo(dataviewModel, 'statusError', this._onError);
this.listenTo(dataviewModel, 'sync change:data', this._onDataChanged);
},
render: function () {
this.clearSubViews();
this.$el.empty();
this._appendView(new WidgetLoaderView({
model: this.model.dataviewModel
}));
this._appendView(new WidgetErrorView({
title: this.model.get('title'),
errorModel: this.errorModel
}));
this._appendView(this.options.contentView);
return this;
},
_onDataChanged: function (model) {
if (this._noDataAvailable()) {
this.options.contentView.$el.addClass('is-hidden');
return this.errorModel.set({
model: model,
error: errorEnhancer({ type: 'no_data_available' }),
placeholder: this._getPlaceholder()
});
}
if (this._dataHasTooManyBins()) {
this.options.contentView.$el.addClass('is-hidden');
return this.errorModel.set({
model: model,
error: errorEnhancer({ type: 'too_many_bins' }),
placeholder: this._getPlaceholder()
});
}
if (!_.isEmpty(this.errorModel.get('error'))) {
this.errorModel.clear();
this.options.contentView.render();
this.options.contentView.$el.removeClass('is-hidden');
}
},
_onError: function (model, error) {
if (error && error.message === 'abort') {
return;
}
var enhancedError = errorEnhancer(error);
this.options.contentView.$el.addClass('is-hidden');
this.errorModel.set({
model: model,
error: enhancedError,
placeholder: this._getPlaceholder()
});
},
_appendView: function (view) {
this.$el.append(view.render().el);
this.addView(view);
},
_noDataAvailable: function () {
var valueToCheck = this._isHistogram() ? 'totalAmount' : 'data';
var data = this.model.dataviewModel.get(valueToCheck);
return !Utils.hasValue(data) || (_.isArray(data) && _.isEmpty(data));
},
_dataHasTooManyBins: function () {
if (this._isHistogram()) {
var data = this.model.dataviewModel.getUnfilteredData && this.model.dataviewModel.getUnfilteredData();
return !_.isEmpty(data) && _.size(data) > MAX_BUCKETS;
}
return false;
},
_isHistogram: function () {
return this.model.dataviewModel.get('type') === 'histogram';
},
_extractError: function (response) {
// XmlHttpRequest error?
var errors = getValue(response, 'responseJSON.errors_with_context', []);
if (errors.length > 0) {
return errors[0];
} else if (response && response.message) {
response.type = response.type || 'generic';
return response;
}
return {};
},
_getPlaceholder: function () {
var widgetType = this.model.dataviewModel.get('type');
return PLACEHOLDER_TEMPLATES[widgetType];
},
_setDisabled: function (model, selectedWidgetId) {
var differentWidget = model.get('id') !== selectedWidgetId;
if (selectedWidgetId && !differentWidget) {
this.el.scrollIntoView && this.el.scrollIntoView();
}
this.$el.toggleClass('is-disabled', selectedWidgetId !== null && differentWidget);
}
});