840 lines
24 KiB
JavaScript
840 lines
24 KiB
JavaScript
|
|
||
|
/**
|
||
|
* Layer panel view added in the right menu
|
||
|
*
|
||
|
* - It needs at least layer, visualization and user models.
|
||
|
* Globalerror to show connection or fetching errors.
|
||
|
*
|
||
|
* var layer_view = new cdb.admin.LayerPanelView({
|
||
|
* model: layer_model,
|
||
|
* vis: vis_model,
|
||
|
* user: user_model,
|
||
|
* globalError: globalError_obj
|
||
|
* });
|
||
|
*/
|
||
|
|
||
|
|
||
|
cdb.admin.LayerPanelView = cdb.admin.RightMenu.extend({
|
||
|
|
||
|
_TEXTS: {
|
||
|
error: {
|
||
|
default: _t('Something went wrong, try again later')
|
||
|
},
|
||
|
visible: _t('This layer is hidden, changes won\'t be shown \
|
||
|
until you make it visible'),
|
||
|
dblclick: _t('Double click will allow you to rename it')
|
||
|
},
|
||
|
|
||
|
MODULES: ['infowindow', 'legends'],
|
||
|
className: "layer_panel",
|
||
|
|
||
|
events: {
|
||
|
'dblclick span.name': '_editAlias',
|
||
|
'click .name_info a': '_goToLayer',
|
||
|
'click .info': '_switchTo',
|
||
|
'click a.visibility': '_switchVisibility',
|
||
|
'click a.remove': '_removeLayer',
|
||
|
'keyup input.alias': '_changeAlias',
|
||
|
'click input.alias': 'killEvent',
|
||
|
'click': 'setPanelStatus'
|
||
|
},
|
||
|
|
||
|
initialize: function() {
|
||
|
|
||
|
cdb.admin.RightMenu.prototype.initialize.call(this);
|
||
|
|
||
|
_.bindAll(this, '_editAlias');
|
||
|
|
||
|
// Set internal vars
|
||
|
this.table = this.model.table;
|
||
|
this.sqlView = new cdb.admin.SQLViewData();
|
||
|
this.map = this.options.vis.map;
|
||
|
this.globalError = this.options.globalError;
|
||
|
this.user = this.options.user;
|
||
|
this.vis = this.options.vis;
|
||
|
|
||
|
// Set status view model
|
||
|
this.view_model = new cdb.core.Model({ state:'idle' })
|
||
|
|
||
|
this.render();
|
||
|
|
||
|
// Set current panel view and data layer
|
||
|
this.activeWorkView = 'table';
|
||
|
this.setDataLayer(this.model);
|
||
|
|
||
|
// New added layers need to wait to get model id
|
||
|
this.model.bind('change:id', function(m) {
|
||
|
this.vis.save('active_layer_id', this.dataLayer.id);
|
||
|
this.$el.attr('model-id', this.model.id);
|
||
|
}, this);
|
||
|
this.model.bind('change:type', this._setLayerType, this);
|
||
|
// Show message when layer is not visible
|
||
|
this.model.bind('change:visible', this.setVisibleMsg, this);
|
||
|
this.model.bind('destroy', function() {
|
||
|
this.trigger('destroy', this.dataLayer.cid);
|
||
|
}, this);
|
||
|
|
||
|
// When status change binding
|
||
|
this.view_model.bind('change:state', this._onChangeStatus, this);
|
||
|
this.add_related_model(this.view_model);
|
||
|
|
||
|
// Bind when panel is closed
|
||
|
cdb.god.bind("panel_action", this.setPanelStatus, this);
|
||
|
|
||
|
this.add_related_model(cdb.god);
|
||
|
|
||
|
this.$el.attr('model-id', this.model.id);
|
||
|
this._setLayerType();
|
||
|
},
|
||
|
|
||
|
/* Layer events functions */
|
||
|
|
||
|
// Set active this tab
|
||
|
_switchTo: function(e) {
|
||
|
if (e) e.preventDefault();
|
||
|
var isActive = this.vis.get('active_layer_id') == this.dataLayer.id;
|
||
|
|
||
|
// Preventing problem with double click
|
||
|
// over span.name
|
||
|
if (isActive && $(e.target).prop("tagName").toLowerCase() == "span"
|
||
|
&& $(e.target).prop("className") == "name") {
|
||
|
|
||
|
// Preventing display the tooltip when user is
|
||
|
// double clicking! :(
|
||
|
var self = this;
|
||
|
setTimeout(function() {
|
||
|
if (!self._dblClick) self.$('.layer-info .info .name').tipsy("show");
|
||
|
delete self._dblClick;
|
||
|
}, 150);
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
this.trigger('switchTo', this);
|
||
|
this.view_model.set('state', 'idle');
|
||
|
this.filters._addFilters();
|
||
|
|
||
|
return false;
|
||
|
},
|
||
|
|
||
|
_goToLayer: function(ev) {
|
||
|
if (ev) {
|
||
|
ev.stopPropagation();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
// Change view model to show table
|
||
|
// name alias input
|
||
|
_editAlias: function(e) {
|
||
|
e.preventDefault();
|
||
|
e.stopPropagation();
|
||
|
|
||
|
if (this.vis.isVisualization()) {
|
||
|
this._dblClick = true;
|
||
|
|
||
|
this.view_model.set('state',
|
||
|
this.view_model.get('state') == 'idle' ? 'editing' : 'idle'
|
||
|
);
|
||
|
} else {
|
||
|
this.trigger('switchTo', this);
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
},
|
||
|
|
||
|
// Change layer state when input is ready
|
||
|
_changeAlias: function(e) {
|
||
|
var value = $(e.target).val();
|
||
|
|
||
|
// If form is submitted, go out!
|
||
|
if (e && e.keyCode == 13) {
|
||
|
this.view_model.set({ state: 'idle' });
|
||
|
return false;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
setPanelStatus: function() {
|
||
|
this.view_model.set('state', 'idle');
|
||
|
},
|
||
|
|
||
|
_onChangeStatus: function() {
|
||
|
var $el = this.$('.layer-info div.left');
|
||
|
if (this.view_model.get('state') == "idle") {
|
||
|
var alias = $el.find('input').val();
|
||
|
$el.find('input').hide();
|
||
|
$el.find('span.name').show();
|
||
|
$el.find('.name_info').show();
|
||
|
|
||
|
if (alias != this.view_model.get('table_name_alias')) {
|
||
|
// Set new changes in model
|
||
|
if (alias == "" || alias == " ") {
|
||
|
this.dataLayer.unset('table_name_alias')
|
||
|
} else {
|
||
|
this.dataLayer.set({ table_name_alias: alias })
|
||
|
}
|
||
|
this.dataLayer.save();
|
||
|
this.setLayerName(this.dataLayer);
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
$el.find('span.name').hide();
|
||
|
$el.find('.name_info').hide();
|
||
|
$el.find('input')
|
||
|
.val(this.dataLayer.get('table_name_alias') || this.dataLayer.get('table_name').replace(/_/g,' '))
|
||
|
.show()
|
||
|
.focus();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_setLayerType: function() {
|
||
|
this.$el.attr('layer-type', this.model.get('type').toLowerCase());
|
||
|
},
|
||
|
|
||
|
activated: function() {
|
||
|
// remove layer-info
|
||
|
this.deactivated();
|
||
|
this.$el.html('');
|
||
|
this.render();
|
||
|
|
||
|
// Set data layer
|
||
|
this.setDataLayer(this.model);
|
||
|
|
||
|
// Set previous active layer
|
||
|
this.setActivePanelView();
|
||
|
|
||
|
this.panels.bind('tabEnabled', this.saveActivePanelView, this);
|
||
|
},
|
||
|
|
||
|
deactivated: function() {
|
||
|
this.clearSubViews();
|
||
|
this._removeButtons();
|
||
|
this.view_model.set('state', 'idle');
|
||
|
},
|
||
|
|
||
|
// Set visibility of the map layer
|
||
|
_switchVisibility: function(e) {
|
||
|
e.preventDefault();
|
||
|
|
||
|
if (!this.vis.isVisualization()) {
|
||
|
cdb.log.info("You can't toggle the layer visibility in a table view");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Hide infowindow if it is open
|
||
|
this.model.infowindow && this.model.infowindow.set('visibility', false);
|
||
|
|
||
|
this.model.save({ 'visible': !this.model.get('visible') });
|
||
|
},
|
||
|
|
||
|
// Remove this view and the map layer
|
||
|
_removeLayer: function(e) {
|
||
|
e.preventDefault();
|
||
|
|
||
|
// Check if the visualization is devired type and not table
|
||
|
if (!this.vis.isVisualization()) {
|
||
|
cdb.log.info("You can't remove a layer in a table view");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
this.trigger('delete', this);
|
||
|
},
|
||
|
|
||
|
|
||
|
/* Layer info functions (order, options, name, ...) */
|
||
|
|
||
|
_setLayerInfo: function(layer) {
|
||
|
this.setLayerName(layer);
|
||
|
this.setLayerOptions(layer);
|
||
|
this.setLayerOrder(layer);
|
||
|
this.setVisibility(layer);
|
||
|
this.setVisibleMsg(layer);
|
||
|
this.setView(layer);
|
||
|
},
|
||
|
|
||
|
// Set view options
|
||
|
setView: function(layer) {
|
||
|
this.$el[ this.vis.isVisualization() ? 'addClass' : 'removeClass' ]('vis')
|
||
|
},
|
||
|
|
||
|
setVisibleMsg: function() {
|
||
|
var editors = ['sql_mod', 'cartocss_mod'];
|
||
|
|
||
|
// Remove message
|
||
|
this.$('.layer-views div.info.warning').remove()
|
||
|
|
||
|
// Add message if it is necessary
|
||
|
if (!this.model.get('visible')) {
|
||
|
var $div = $('<div>')
|
||
|
.addClass('info warning')
|
||
|
.append('<p>' + this._TEXTS.visible + '</p>');
|
||
|
|
||
|
var isEditor = _.contains(editors, this.currentPanelView);
|
||
|
$div[ isEditor ? 'addClass' : 'removeClass' ]('editor');
|
||
|
this.$('.layer-views').append($div);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
// Layer name
|
||
|
setLayerName: function(layer) {
|
||
|
if (this.vis.isVisualization()) {
|
||
|
|
||
|
// table name
|
||
|
this.$('.layer-info .info .name')
|
||
|
.text(layer.get('table_name_alias') || layer.get('table_name').replace(/_/g,' '));
|
||
|
|
||
|
// table name alias
|
||
|
var layerUrl = layer.table && layer.table.viewUrl();
|
||
|
this.$('.layer-info .info .name_info')
|
||
|
.html('view of ')
|
||
|
.append($('<a>').attr('href', layerUrl).text(layer.get('table_name')));
|
||
|
|
||
|
// table synced?
|
||
|
if (this.table.isSync()) {
|
||
|
this.$('.layer-info .info .name')
|
||
|
.append($('<i>').addClass('synced'));
|
||
|
} else {
|
||
|
this.$('.layer-info i.synced').remove();
|
||
|
}
|
||
|
|
||
|
// Set tipsy bind
|
||
|
this._setLayerTooltip();
|
||
|
} else {
|
||
|
// Unset tipsy bind
|
||
|
this._unsetLayerTooltip();
|
||
|
this.$('.layer-info .info .name').text(layer.get('table_name'));
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_setLayerTooltip: function() {
|
||
|
var self = this;
|
||
|
this.$('.layer-info .info .name').tipsy({
|
||
|
trigger: 'manual',
|
||
|
fade: true,
|
||
|
gravity: 's',
|
||
|
title: function() {
|
||
|
return self._TEXTS.dblclick
|
||
|
}
|
||
|
})
|
||
|
.bind('mouseleave', function() {
|
||
|
$(this).tipsy('hide');
|
||
|
});
|
||
|
},
|
||
|
|
||
|
_unsetLayerTooltip: function() {
|
||
|
var $name = this.$('.layer-info .info .name');
|
||
|
// Remove tipsy
|
||
|
if ($name.data('tipsy')) {
|
||
|
$name.unbind('mouseenter mouseleave');
|
||
|
$name.data('tipsy').remove();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
// Layer options
|
||
|
setLayerOptions: function(layer) {
|
||
|
// Layer options buttons
|
||
|
if (this.vis && !this.vis.isVisualization()) {
|
||
|
this.$('.layer-info div.right').hide();
|
||
|
} else {
|
||
|
this.$('.layer-info div.right').show();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
setVisibility: function(layer) {
|
||
|
this._maybeHideVisibilitySwitch();
|
||
|
|
||
|
var isVisible = layer.get('visible');
|
||
|
this.$(".layer-info div.right a.switch")
|
||
|
.toggleClass('enabled', !!isVisible)
|
||
|
.toggleClass('disabled', !isVisible);
|
||
|
},
|
||
|
|
||
|
_maybeHideVisibilitySwitch: function() {
|
||
|
var sw = this.$(".layer-info div.right a.switch");
|
||
|
var close = this.$(".layer-info div.right a.remove");
|
||
|
var dataLayers = this.vis.map.layers.getDataLayers();
|
||
|
if (dataLayers.length === 1) {
|
||
|
sw.hide();
|
||
|
close.hide();
|
||
|
} else {
|
||
|
sw.css('display', 'inline-block');
|
||
|
close.css('display', 'inline-block');
|
||
|
}
|
||
|
},
|
||
|
|
||
|
// Layer order
|
||
|
setLayerOrder: function(layer) {
|
||
|
var order = '1';
|
||
|
if(this.vis.isVisualization()) {
|
||
|
order = layer.collection.indexOf(layer);
|
||
|
}
|
||
|
|
||
|
this.$('.layer-info .info .order').text(order);
|
||
|
},
|
||
|
|
||
|
|
||
|
/* Set data of the layer (bindings, errors, modules, ...) */
|
||
|
setDataLayer: function(dataLayer) {
|
||
|
var self = this;
|
||
|
this.add_related_model(dataLayer);
|
||
|
var enabledModulesInit = self.MODULES;
|
||
|
|
||
|
if (!self.dataLayer) {
|
||
|
self.dataLayer = dataLayer;
|
||
|
this._initDataLayer(dataLayer);
|
||
|
}
|
||
|
|
||
|
// Set layer info
|
||
|
this._setLayerInfo(dataLayer);
|
||
|
|
||
|
/* SQL */
|
||
|
var sql = new cdb.admin.mod.SQL({
|
||
|
model: self.dataLayer,
|
||
|
user: self.user,
|
||
|
className: "sql_panel editor"
|
||
|
});
|
||
|
|
||
|
/* Filters */
|
||
|
this.filters = new cdb.admin.mod.Filters({
|
||
|
table: self.table,
|
||
|
sqlView: self.sqlView,
|
||
|
dataLayer: self.dataLayer
|
||
|
});
|
||
|
|
||
|
// load the scroll when the panel is open
|
||
|
cdb.god.bind("end_narrow", function() {
|
||
|
self.filters.loadScroll()
|
||
|
}, this);
|
||
|
|
||
|
/* Wizards */
|
||
|
var activeWizards = {
|
||
|
polygon: "SimpleWizard",
|
||
|
cluster: "ClusterWizard",
|
||
|
intensity: "IntensityWizard",
|
||
|
bubble: "BubbleWizard",
|
||
|
choropleth: "ChoroplethWizard",
|
||
|
color: "CategoryWizard",
|
||
|
category: "CategoryWizard",
|
||
|
density: "DensityWizard",
|
||
|
torque: "TorqueWizard",
|
||
|
torque_cat: "TorqueCategoryWizard",
|
||
|
torque_heat: "TorqueHeatWizard"
|
||
|
};
|
||
|
|
||
|
|
||
|
var wizards = new cdb.admin.mod.CartoCSSWizard({
|
||
|
user: this.user,
|
||
|
model: this.dataLayer,
|
||
|
table: this.table,
|
||
|
map: this.map,
|
||
|
className: "wizards_panel",
|
||
|
wizards: activeWizards
|
||
|
}).bind('modules', function(enabledModules) {
|
||
|
enabledModulesInit = enabledModules;
|
||
|
this.enableModules(enabledModules);
|
||
|
}, this).bind('activeWizard', function(type) {
|
||
|
// Close infowindow if it exists.
|
||
|
this.dataLayer.infowindow && this.dataLayer.infowindow.set('visibility', false);
|
||
|
}, this);
|
||
|
|
||
|
/* Infowindow */
|
||
|
var infowindow = this.infowindow = new cdb.admin.mod.InfoWindow({
|
||
|
table: this.table,
|
||
|
user: this.user,
|
||
|
dataLayer: dataLayer
|
||
|
});
|
||
|
infowindow.bind('tabChanged', this._onModuleTabChanged, this);
|
||
|
|
||
|
/* CartoCSS editor */
|
||
|
var editorPanel = new cdb.admin.mod.CartoCSSEditor({
|
||
|
model: this.dataLayer,
|
||
|
table: this.table,
|
||
|
user: this.user,
|
||
|
className: "csseditor_panel editor"
|
||
|
}).bind('hasErrors', function() {
|
||
|
self.addClassToButton('cartocss_mod', 'has_errors');
|
||
|
}).bind('clearError', function() {
|
||
|
self.removeClassFromButton('cartocss_mod', 'has_errors');
|
||
|
});
|
||
|
|
||
|
/* Legends */
|
||
|
var legends = new cdb.admin.mod.LegendEditor({
|
||
|
model: dataLayer.legend,
|
||
|
dataLayer: dataLayer,
|
||
|
className: "legends_panel",
|
||
|
availableLegends: [
|
||
|
{ name: "none", enabled: true },
|
||
|
{ name: "custom", enabled: true },
|
||
|
{ name: "color", enabled: false },
|
||
|
{ name: "category", enabled: false },
|
||
|
{ name: "bubble", enabled: false },
|
||
|
{ name: "choropleth", enabled: false },
|
||
|
{ name: "intensity", enabled: false },
|
||
|
{ name: "density", enabled: false },
|
||
|
{ name: "torque_cat", enabled: false }
|
||
|
],
|
||
|
}).bind('modules', function(enabledModules) {
|
||
|
enabledModulesInit = enabledModules;
|
||
|
self.enableModules(enabledModules);
|
||
|
}).bind('tabChanged', this._onModuleTabChanged, this);
|
||
|
|
||
|
if (!this.user.featureEnabled('disabled_ui_sql')) {
|
||
|
self.addModule(sql.render(), ['table', 'tableLite', 'map', 'mapLite']);
|
||
|
}
|
||
|
self.addModule(wizards.render(), ['map', 'mapLite']);
|
||
|
self.addModule(infowindow.render(), ['map', 'mapLite']);
|
||
|
if (!this.user.featureEnabled('disabled_ui_cartocss')) {
|
||
|
self.addModule(editorPanel.render(), ['map', 'mapLite']);
|
||
|
}
|
||
|
self.addModule(legends.render(), ['map', 'mapLite']);
|
||
|
self.addModule(this.filters.render(), ['table', 'tableLite', 'map', 'mapLite']);
|
||
|
|
||
|
/* Lateral menu modules */
|
||
|
var mergeTables = self.addToolButton("merge_datasets", 'table');
|
||
|
var addRow = self.addToolButton('add_row', 'table');
|
||
|
var addColumn = self.addToolButton('add_column', 'table');
|
||
|
var addGeom = self.addToolButton('add_feature', 'map');
|
||
|
|
||
|
addRow.bind('click', this._addRow, this);
|
||
|
addColumn.bind('click', this.trigger.bind(this, 'addColumn', this));
|
||
|
mergeTables.bind('click', this._mergeTables, this);
|
||
|
addGeom.bind('click', this._addFeature, this);
|
||
|
|
||
|
this.enableModules(enabledModulesInit);
|
||
|
this._bindDataLayer();
|
||
|
},
|
||
|
|
||
|
// set initial parameters to the layer
|
||
|
_initDataLayer: function(layer) {
|
||
|
layer.bind('change:table_name', this.setLayerName, this);
|
||
|
layer.bind('change:order', this.setLayerOrder, this);
|
||
|
layer.bind('change:visible', this.setVisibility, this);
|
||
|
|
||
|
layer.collection.bind('add remove', this._maybeHideVisibilitySwitch, this);
|
||
|
this.add_related_model(layer.collection);
|
||
|
|
||
|
layer.set({
|
||
|
stat_tag: this.vis.get('id'),
|
||
|
user_name: this.user.get("username"),
|
||
|
maps_api_template: cdb.config.get('maps_api_template'),
|
||
|
cartodb_logo: false,
|
||
|
no_cdn: false,
|
||
|
force_cors: true // use CORS to control error management in a better way
|
||
|
});
|
||
|
|
||
|
// set api key
|
||
|
var e = layer.get('extra_params') || {};
|
||
|
e.api_key = e.map_key = this.user.get('api_key');
|
||
|
layer.set('extra_params', e);
|
||
|
layer.invalidate();
|
||
|
},
|
||
|
|
||
|
// bind related ui changed to datalayer
|
||
|
_bindDataLayer: function() {
|
||
|
var self = this;
|
||
|
this.dataLayer.bindSQLView(this.sqlView);
|
||
|
this.dataLayer
|
||
|
.bind('parseError', function() {
|
||
|
if(self.activeWorkView === 'map') {
|
||
|
self.globalError.showError('There is a problem with the map tiles. Please, check your CartoCSS style.', 'error', 0, 'tiles');
|
||
|
}
|
||
|
}, this)
|
||
|
.bind('sqlNoMercator', function() {
|
||
|
if(self.activeWorkView === 'map') {
|
||
|
// don't show this error, the warning is shown in the sql bar
|
||
|
//self.globalError.showError(_t('the_geom_webmercator column should be selected'), 'warn', 0, 'tiles');
|
||
|
}
|
||
|
}, this)
|
||
|
.bind('error', function(model, resp) {
|
||
|
var aborted = resp && resp.statusText === 'abort';
|
||
|
if(self.activeWorkView === 'map' && !aborted) {
|
||
|
self.globalError.showError('There is a problem with your connection', 'error', 0, 'tiles');
|
||
|
}
|
||
|
}, this)
|
||
|
.bind('tileOk', function() {
|
||
|
self.globalError.hide('tiles');
|
||
|
}, this);
|
||
|
|
||
|
this.table.bind('columnRename columnDelete columnAdded geolocated', function() {
|
||
|
self.dataLayer.invalidate();
|
||
|
}, this);
|
||
|
|
||
|
this.table.bind('change:geometry_types', function() {
|
||
|
if(this.table.get('geometry_types').length) {
|
||
|
this._enableGeometryRelatedWizards();
|
||
|
} else {
|
||
|
this._disableGeometryRelatedWizards();
|
||
|
}
|
||
|
}, this);
|
||
|
|
||
|
// Need to check buttons when permission changes
|
||
|
this.table.bind('change:permission', this._checkButtons, this);
|
||
|
this.table.bind('change:readOnly', this._checkButtons, this);
|
||
|
this.table.bind('change:synchronization', this._checkButtons, this);
|
||
|
this.table.bind('change:isSync', this._checkButtons, this);
|
||
|
|
||
|
this.vis.bind('change:type', function() {
|
||
|
this.setLayerOptions()
|
||
|
this.setLayerName(this.model)
|
||
|
}, this);
|
||
|
|
||
|
this.model.bind('applySQLView errorSQLView clearSQLView', this._checkButtons, this);
|
||
|
|
||
|
// this.model.bind('clearSQLView', this._onResetSQL, this);
|
||
|
// this.model.bind('applySQLView', this._onApplySQL, this);
|
||
|
// this.model.bind('errorSQLView', this._onErrorSQL, this);
|
||
|
|
||
|
this.model.unbind('applyFilter', this._applyFilter, this);
|
||
|
this.model.bind('applyFilter', this._applyFilter, this);
|
||
|
|
||
|
// Add related models to be cleaned when view is destroyed
|
||
|
this.add_related_model(this.vis);
|
||
|
this.add_related_model(this.table);
|
||
|
|
||
|
this._checkButtons();
|
||
|
},
|
||
|
|
||
|
enableModules: function(enabledModules) {
|
||
|
|
||
|
var self = this;
|
||
|
|
||
|
_(self.MODULES).each(function(m) {
|
||
|
|
||
|
if (m === "infowindow" && !self.model.wizard_properties.supportsInteractivity()) {
|
||
|
self.disableModule("infowindow_mod");
|
||
|
} else {
|
||
|
|
||
|
if (_.contains(enabledModules, m)) {
|
||
|
self.enableModule(m + "_mod");
|
||
|
} else {
|
||
|
self.disableModule(m + "_mod");
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
},
|
||
|
|
||
|
SQL_WIZARDS: ['cartocss_mod', 'wizards_mod', 'infowindow_mod', 'legends_mod'],
|
||
|
|
||
|
_disableGeometryRelatedWizards: function() {
|
||
|
var self = this;
|
||
|
_(this.SQL_WIZARDS).each(function(m) {
|
||
|
self.disableModule(m);
|
||
|
});
|
||
|
},
|
||
|
|
||
|
_enableGeometryRelatedWizards: function() {
|
||
|
var self = this;
|
||
|
|
||
|
_(this.SQL_WIZARDS).each(function(m) {
|
||
|
|
||
|
if (m == 'infowindow_mod' && !self.model.wizard_properties.supportsInteractivity()) {
|
||
|
self.disableModule(m);
|
||
|
} else {
|
||
|
self.enableModule(m);
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
},
|
||
|
|
||
|
_addRow: function() {
|
||
|
this.table.data().addRow({ at: 0});
|
||
|
this.trigger('createRow');
|
||
|
cdb.god.trigger("closeDialogs");
|
||
|
},
|
||
|
|
||
|
_mergeTables: function() {
|
||
|
var user = this.user;
|
||
|
var view = new cdb.editor.MergeDatasetsView({
|
||
|
table: this.table,
|
||
|
user: user
|
||
|
});
|
||
|
view.appendToBody();
|
||
|
cdb.god.trigger("closeDialogs");
|
||
|
},
|
||
|
|
||
|
_addFeature: function(mod) {
|
||
|
if (this.map.get('provider') === 'leaflet') {
|
||
|
this.map.clamp();
|
||
|
}
|
||
|
if (this.table.isGeoreferenced()) {
|
||
|
this._addGeometry();
|
||
|
} else {
|
||
|
this._showScratchDialog();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_showScratchDialog: function() {
|
||
|
var view = new cdb.editor.ScratchView({
|
||
|
clean_on_hide: true,
|
||
|
enter_to_confirm: true,
|
||
|
table: this.table,
|
||
|
skipDisabled: true
|
||
|
});
|
||
|
view.bind("newGeometry", this._addGeometry, this);
|
||
|
view.appendToBody();
|
||
|
},
|
||
|
|
||
|
_addGeometry: function(type) {
|
||
|
// row is saved by geometry editor if it is needed
|
||
|
type = type || this.table.geomColumnTypes()[0];
|
||
|
this.dataLayer.trigger("startEdition", type);
|
||
|
},
|
||
|
|
||
|
/* Module functions */
|
||
|
|
||
|
// When a tab is activated within a sub-module.
|
||
|
// It could be the indowindow view, filters view, etc.
|
||
|
_onModuleTabChanged: function(action) {
|
||
|
this.trigger('tabChanged', action);
|
||
|
},
|
||
|
|
||
|
// check buttons if they should be enabled or not
|
||
|
_checkButtons: function() {
|
||
|
var self = this;
|
||
|
var gt = this.table.get('geometry_types');
|
||
|
|
||
|
// Changes over the SQL button
|
||
|
var sql_button_changes = {
|
||
|
applied: 'remove',
|
||
|
has_errors: 'remove'
|
||
|
};
|
||
|
|
||
|
// *Table with read permissions* //
|
||
|
if (this.table.isReadOnly()) {
|
||
|
|
||
|
// Data layer has a query applied?
|
||
|
if (this.table.isInSQLView()) {
|
||
|
if(this.model.getCurrentState() === 'error') {
|
||
|
sql_button_changes = {
|
||
|
applied: 'add',
|
||
|
has_errors: 'add'
|
||
|
}
|
||
|
} else {
|
||
|
sql_button_changes.applied = 'add';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Check if there is any geometry
|
||
|
if (gt && gt.length === 0) {
|
||
|
this._disableGeometryRelatedWizards();
|
||
|
} else {
|
||
|
this._enableGeometryRelatedWizards();
|
||
|
}
|
||
|
|
||
|
this._readOnlyTableButtons();
|
||
|
} else {
|
||
|
// *Table with write permissions* //
|
||
|
|
||
|
// Check if there is any geometry
|
||
|
if(gt && gt.length === 0) {
|
||
|
this._disableGeometryRelatedWizards();
|
||
|
} else {
|
||
|
this._enableGeometryRelatedWizards();
|
||
|
}
|
||
|
|
||
|
// Enable writable buttons
|
||
|
this._writableTableButtons();
|
||
|
}
|
||
|
|
||
|
// Set title changes (as in name, sync info,...)
|
||
|
this.setLayerName(this.dataLayer);
|
||
|
|
||
|
// Set sql button changes
|
||
|
_.each(sql_button_changes, function(value, key) {
|
||
|
self[ value === "remove" ? 'removeClassFromButton' : 'addClassToButton' ]('sql_mod', key);
|
||
|
});
|
||
|
},
|
||
|
|
||
|
_removeButtons: function() {
|
||
|
this.buttons = [];
|
||
|
this.panels.unbind('tabEnabled', this.saveActivePanelView, this);
|
||
|
this.panels.clean();
|
||
|
this.tabs.clean();
|
||
|
},
|
||
|
|
||
|
// Enable the correct buttons depending on
|
||
|
// if the layer is in query mode or not
|
||
|
setActiveWorkView: function(workView) {
|
||
|
this.activeWorkView = workView;
|
||
|
this._checkButtons();
|
||
|
this.setActivePanelView(true);
|
||
|
},
|
||
|
|
||
|
saveActivePanelView: function(name) {
|
||
|
this.currentPanelView = name;
|
||
|
this.setVisibleMsg();
|
||
|
},
|
||
|
|
||
|
setActivePanelView: function(work_view) {
|
||
|
if (work_view || !this.currentPanelView) {
|
||
|
if (this.activeWorkView === 'map') {
|
||
|
var gt = this.table.get('geometry_types');
|
||
|
if(this.model.getCurrentState() !== 'error' && (gt && gt.length > 0)) {
|
||
|
this.active('wizards_mod');
|
||
|
}
|
||
|
} else {
|
||
|
this.active('sql_mod');
|
||
|
}
|
||
|
} else {
|
||
|
this.active(this.currentPanelView);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_readOnlyTableButtons: function() {
|
||
|
if(this.activeWorkView === 'map') {
|
||
|
this.showTools('mapLite', true);
|
||
|
} else {
|
||
|
this.showTools('tableLite', true);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_writableTableButtons: function() {
|
||
|
if(this.activeWorkView === 'map') {
|
||
|
this.showTools('map', true);
|
||
|
} else {
|
||
|
this.showTools('table', true);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_applyFilter: function(column_name) {
|
||
|
|
||
|
var col = { column: column_name };
|
||
|
|
||
|
var exists = this.filters.filters.find(function(a) {
|
||
|
return a.get("column") == col.column
|
||
|
});
|
||
|
|
||
|
if (!exists) this.filters.filters.add(col);
|
||
|
|
||
|
},
|
||
|
|
||
|
|
||
|
/* View visibility functions */
|
||
|
|
||
|
hide: function() {
|
||
|
this.$('.layer-sidebar').hide();
|
||
|
this.$('.layer-views').hide();
|
||
|
},
|
||
|
|
||
|
show: function() {
|
||
|
this.$('.layer-sidebar').show();
|
||
|
this.$('.layer-views').show();
|
||
|
},
|
||
|
|
||
|
showModule: function(modName, modTab) {
|
||
|
// Set tab in the module
|
||
|
if (modTab && this[modName]) this[modName].setActiveTab(modTab);
|
||
|
// Show module
|
||
|
this.trigger('show', modName + "_mod", this);
|
||
|
},
|
||
|
|
||
|
clean: function() {
|
||
|
this._unsetLayerTooltip();
|
||
|
this._removeButtons();
|
||
|
this.elder('clean');
|
||
|
}
|
||
|
});
|