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

219 lines
5.6 KiB
JavaScript
Executable File

var _ = require('underscore');
var $ = require('jquery');
var Backbone = require('backbone');
var CoreView = require('backbone/core-view');
var EditorWidgetView = require('./widget-view');
var IconView = require('builder/components/icon/icon-view');
var template = require('./widgets-view.tpl');
var widgetPlaceholderTemplate = require('./widgets-placeholder.tpl');
var widgetsErrorTemplate = require('./widgets-content-error.tpl');
var widgetsNotReadyTemplate = require('./widgets-content-not-ready.tpl');
var checkAndBuildOpts = require('builder/helpers/required-opts');
var AddWidgetsView = require('builder/components/modals/add-widgets/add-widgets-view');
var TipsyTooltipView = require('builder/components/tipsy-tooltip-view');
require('jquery-ui');
var STATES = {
loading: 'loading',
ready: 'ready'
};
var REQUIRED_OPTS = [
'userActions',
'analysisDefinitionNodesCollection',
'layerDefinitionsCollection',
'widgetDefinitionsCollection',
'userModel',
'stackLayoutModel',
'configModel',
'modals'
];
/**
* View to render widgets definitions overview
*/
module.exports = CoreView.extend({
module: 'editor:widgets:widgets-view',
events: {
'click .js-add': '_addWidget'
},
initialize: function (opts) {
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
this.viewModel = new Backbone.Model({
state: STATES.loading
});
this._initViewState();
this._initBinds();
var callback = this._onAllQueryGeometryLoaded.bind(this);
this._layerDefinitionsCollection.loadAllQueryGeometryModels(callback);
},
render: function () {
this._destroySortable();
this.clearSubViews();
this.$el.empty();
this._initViews();
return this;
},
_initViewState: function () {
this._viewState = new Backbone.Model({
anyGeometryData: true
});
this._setViewState();
},
_initViews: function () {
if (this._isLoading()) {
this.$el.append(widgetsNotReadyTemplate());
return;
}
if (!this._viewState.get('anyGeometryData')) {
this._showNoGeometryData();
return;
}
if (this._widgetDefinitionsCollection.size() > 0) {
this.$el.append(template);
_.each(this._widgetDefinitionsCollection.sortBy('order'), this._addWidgetItem, this);
this._initSortable();
this._addTooltip();
this._renderPlusIcon();
return;
}
this.$el.append(widgetPlaceholderTemplate());
this._addTooltip();
this._renderPlusIcon();
},
_renderPlusIcon: function () {
var plusIcon = new IconView({
placeholder: this.$el.find('.js-plus-icon'),
icon: 'plus'
});
plusIcon.render();
this.addView(plusIcon);
},
_initBinds: function () {
this.listenTo(this._widgetDefinitionsCollection, 'destroy successAdd', this.render, this);
this.listenTo(this.viewModel, 'change:state', this.render, this);
this.listenTo(this._viewState, 'change', this.render);
},
_showNoGeometryData: function () {
this.$el.append(
widgetsErrorTemplate({
body: _t('editor.widgets.no-geometry-data')
})
);
},
_onAllQueryGeometryLoaded: function () {
this.viewModel.set('state', STATES.ready);
},
_addTooltip: function () {
var tooltip = new TipsyTooltipView({
el: this.$('.js-add'),
gravity: 'w',
title: function () {
return _t('editor.widgets.add-widget.tooltip');
},
offset: 8
});
this.addView(tooltip);
},
_isLoading: function () {
return this.viewModel.get('state') === STATES.loading;
},
_isReady: function () {
return this.viewModel.get('state') === STATES.ready;
},
_setViewState: function () {
this._layerDefinitionsCollection.isThereAnyGeometryData()
.then(function (anyGeometry) {
this._viewState.set('anyGeometryData', anyGeometry);
}.bind(this));
},
_initSortable: function () {
this.$('.js-widgets').sortable({
axis: 'y',
items: '> li.BlockList-item',
opacity: 0.8,
update: this._onSortableFinish.bind(this),
forcePlaceholderSize: false
}).disableSelection();
},
_destroySortable: function () {
if (this.$('.js-widgets').data('ui-sortable')) {
this.$('.js-widgets').sortable('destroy');
}
},
_onSortableFinish: function () {
var self = this;
this.$('.js-widgets > .js-widgetItem').each(function (index, item) {
var modelCid = $(item).data('model-cid');
var widgetDefModel = self._widgetDefinitionsCollection.get(modelCid);
widgetDefModel.set('order', index);
self._userActions.saveWidget(widgetDefModel);
});
},
_addWidget: function () {
if (this.$('.js-add').hasClass('is-disabled')) return;
var self = this;
this._modals.create(function (modalModel) {
return new AddWidgetsView({
modalModel: modalModel,
userModel: self._userModel,
userActions: self._userActions,
configModel: self._configModel,
analysisDefinitionNodesCollection: self._analysisDefinitionNodesCollection,
layerDefinitionsCollection: self._layerDefinitionsCollection,
widgetDefinitionsCollection: self._widgetDefinitionsCollection
});
}, {
breadcrumbsEnabled: true
});
},
_addWidgetItem: function (model) {
var view = new EditorWidgetView({
model: model,
layer: this._layerDefinitionsCollection.get(model.get('layer_id')),
modals: this._modals,
userActions: this._userActions,
stackLayoutModel: this._stackLayoutModel
});
this.addView(view);
this.$('.js-widgets').append(view.render().el);
},
clean: function () {
this._destroySortable();
CoreView.prototype.clean.apply(this);
}
});