cartodb/lib/assets/javascripts/builder/components/modals/add-widgets/add-widgets-view.js
2020-06-15 10:58:47 +08:00

178 lines
5.3 KiB
JavaScript
Executable File

var _ = require('underscore');
var $ = require('jquery');
var Backbone = require('backbone');
var CoreView = require('backbone/core-view');
var createTuplesItems = require('./create-tuples-items');
var widgetsTypes = require('./widgets-types');
var BodyView = require('./body-view');
var template = require('./add-widgets.tpl');
var renderLoading = require('builder/components/loading/render-loading');
var TableStats = require('./tablestats.js');
var ENTER_KEY_CODE = 13;
/**
* View to add new widgets.
* Expected to be rendered in a modal.
*/
module.exports = CoreView.extend({
module: 'components/modals/add-widgets/add-widgets-view',
className: 'Dialog-content Dialog-content--expanded',
events: {
'click .js-continue': '_onContinue'
},
initialize: function (opts) {
if (!opts.userActions) throw new Error('userActions is required');
if (!opts.modalModel) throw new Error('modalModel is required');
if (!opts.layerDefinitionsCollection) throw new Error('layerDefinitionsCollection is required');
if (!opts.widgetDefinitionsCollection) throw new Error('widgetDefinitionsCollection is required');
if (!opts.analysisDefinitionNodesCollection) throw new Error('analysisDefinitionNodesCollection is required');
this._userActions = opts.userActions;
this._modalModel = opts.modalModel;
this._layerDefinitionsCollection = opts.layerDefinitionsCollection;
this._widgetDefinitionsCollection = opts.widgetDefinitionsCollection;
this._analysisDefinitionNodesCollection = opts.analysisDefinitionNodesCollection;
this._optionsCollection = new Backbone.Collection();
this.tableStats = new TableStats({
configModel: opts.configModel,
userModel: opts.userModel
});
this._analysisDefinitionNodesCollection.each(function (analysisDefinitionNode) {
analysisDefinitionNode = analysisDefinitionNode.querySchemaModel;
analysisDefinitionNode.on('change', this._onQuerySchemaChange, this);
this.add_related_model(analysisDefinitionNode);
analysisDefinitionNode.fetch();
}, this);
this.listenTo(this._optionsCollection, 'change:selected', this._updateContinueButtonState);
this.add_related_model(this._optionsCollection);
this._onKeyDown = this._onKeyDown.bind(this);
this._initBinds();
},
render: function () {
this.clearSubViews();
this.$el.html(template());
if (this._hasFetchedAllQuerySchemas()) {
this._renderBodyView();
} else {
this._renderLoadingView();
}
this._updateContinueButtonState();
return this;
},
_initBinds: function () {
$(document).bind('keydown', this._onKeyDown);
},
_disableBinds: function () {
$(document).unbind('keydown', this._onKeyDown);
},
_onKeyDown: function (event) {
event.preventDefault();
if (event.which === ENTER_KEY_CODE) {
this._onContinue();
}
},
_onQuerySchemaChange: function () {
if (this._hasFetchedAllQuerySchemas()) {
this.render();
}
},
_hasFetchedAllQuerySchemas: function () {
return this._analysisDefinitionNodesCollection.all(function (analysisDefinitionNode) {
return analysisDefinitionNode.querySchemaModel.get('status') !== 'fetching';
});
},
_onContinue: function () {
var self = this;
var selectedOptionModels = this._optionsCollection.filter(this._isSelected);
if (selectedOptionModels.length > 0) {
this._saveSelectedWidgets(selectedOptionModels)
.then(function (widgets) {
self._userActions.goToEditWidget(widgets);
self._userActions.updateWidgetsOrder(selectedOptionModels);
})
.catch(function () {
self._userActions.updateWidgetsOrder(selectedOptionModels);
});
this._modalModel.destroy();
}
},
_saveSelectedWidgets: function (selectedOptionModels) {
var saveWidgetOptionsPromises = [];
_.map(selectedOptionModels, function (selectedOptionModel) {
saveWidgetOptionsPromises.push(this._userActions.saveWidgetOption(selectedOptionModel));
}, this);
return Promise.all(saveWidgetOptionsPromises);
},
_renderBodyView: function () {
this._createOptionsModels();
var view = new BodyView({
el: this._$body(),
optionsCollection: this._optionsCollection,
widgetsTypes: widgetsTypes
});
this.addView(view.render());
},
_renderLoadingView: function () {
this._$body().html(
renderLoading({
title: _t('components.modals.add-widgets.loading-title')
})
);
},
_$body: function () {
return this.$('.js-body');
},
_updateContinueButtonState: function () {
this.$('.js-continue').toggleClass('is-disabled', !this._optionsCollection.any(this._isSelected));
},
_isSelected: function (model) {
return !!model.get('selected');
},
_createOptionsModels: function () {
var self = this;
this._optionsCollection.reset();
var tuplesItems = createTuplesItems(this._analysisDefinitionNodesCollection, this._layerDefinitionsCollection);
_.each(widgetsTypes, function (widgetType) {
var models = widgetType.createOptionModels(tuplesItems, this._widgetDefinitionsCollection);
models = models.map(function (model) { model.stats = self.tableStats; return model; });
this._optionsCollection.add(models);
}, this);
},
clean: function () {
this._disableBinds();
CoreView.prototype.clean.apply(this);
}
});