Initial commit
This commit is contained in:
@@ -0,0 +1,304 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var CoreView = require('backbone/core-view');
|
||||
|
||||
var StyleFormView = require('./style-form/style-form-view');
|
||||
var StylesFactory = require('./styles-factory');
|
||||
var CarouselFormView = require('builder/components/carousel-form-view');
|
||||
var CarouselCollection = require('builder/components/custom-carousel/custom-carousel-collection');
|
||||
var Notifier = require('builder/components/notifier/notifier');
|
||||
var MetricsTracker = require('builder/components/metrics/metrics-tracker');
|
||||
var MetricsTypes = require('builder/components/metrics/metrics-types');
|
||||
|
||||
var StyleConstants = require('builder/components/form-components/_constants/_style');
|
||||
|
||||
var styleSQLErrorTemplate = require('./style-content-sql-error.tpl');
|
||||
var actionErrorTemplate = require('builder/editor/layers/sql-error-action.tpl');
|
||||
var layerTabMessageTemplate = require('builder/editor/layers/layer-tab-message.tpl');
|
||||
|
||||
var checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
|
||||
var EXTRA_STYLE_PROPERTIES = [
|
||||
'fillSize',
|
||||
'fillColor',
|
||||
'strokeSize',
|
||||
'strokeColor'
|
||||
];
|
||||
|
||||
var EXTRA_LABELS_STYLE_PROPERTIES = [
|
||||
'fillSize',
|
||||
'fillColor',
|
||||
'haloSize',
|
||||
'haloColor'
|
||||
];
|
||||
|
||||
var REQUIRED_OPTS = [
|
||||
'configModel',
|
||||
'layerDefinitionsCollection',
|
||||
'userModel',
|
||||
'layerDefinitionModel',
|
||||
'userActions',
|
||||
'styleModel',
|
||||
'overlayModel',
|
||||
'queryGeometryModel',
|
||||
'querySchemaModel',
|
||||
'freezeTorgeAggregation',
|
||||
'editorModel',
|
||||
'modals',
|
||||
'layerContentModel'
|
||||
];
|
||||
|
||||
module.exports = CoreView.extend({
|
||||
module: 'editor/style/style-content-view',
|
||||
|
||||
className: 'Editor-styleContent',
|
||||
|
||||
initialize: function (opts) {
|
||||
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
|
||||
|
||||
this._initViewState();
|
||||
this._buildAggregationCarouselCollection();
|
||||
this._initBinds();
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.clearSubViews();
|
||||
this.$el.empty();
|
||||
|
||||
if (this._isErrored()) {
|
||||
this._renderError();
|
||||
} else if (this._viewState.get('isDataFiltered')) {
|
||||
this._renderFilteredData();
|
||||
} else {
|
||||
this._initViews();
|
||||
}
|
||||
|
||||
this._toggleOverlay();
|
||||
return this;
|
||||
},
|
||||
|
||||
_initViewState: function () {
|
||||
this._viewState = new Backbone.Model({
|
||||
isDataFiltered: false
|
||||
});
|
||||
|
||||
this._setViewValues();
|
||||
},
|
||||
|
||||
_buildAggregationCarouselCollection: function () {
|
||||
if (this._carouselCollection) {
|
||||
this.stopListening(this._carouselCollection, 'change:selected');
|
||||
}
|
||||
this._carouselCollection = new CarouselCollection(
|
||||
_.map(StylesFactory.getStyleTypes(this._styleModel.get('type'), this._queryGeometryModel.get('simple_geom')), function (type) {
|
||||
return {
|
||||
selected: this._styleModel.get('type') === type.value,
|
||||
val: type.value,
|
||||
label: type.label,
|
||||
template: function () {
|
||||
return (type.iconTemplate && type.iconTemplate()) || type.value;
|
||||
},
|
||||
tooltip: type.tooltip
|
||||
};
|
||||
}, this)
|
||||
);
|
||||
this.listenTo(this._carouselCollection, 'change:selected', this._onSelectAggregation);
|
||||
|
||||
return this._carouselCollection;
|
||||
},
|
||||
|
||||
_initBinds: function () {
|
||||
this.listenTo(this._layerDefinitionModel, 'change:autoStyle', this._onAutoStyleChanged);
|
||||
this.listenTo(this._layerDefinitionModel, 'change', this._onStyleChanged);
|
||||
this.listenTo(this._styleModel, 'change:fill', this._onStyleChanged);
|
||||
this.listenTo(this._styleModel, 'change:labels', this._onStyleLabelChanged);
|
||||
this.listenTo(this._styleModel, 'undo redo', this.render);
|
||||
this.listenTo(this._layerContentModel, 'change:state', this._setViewValues);
|
||||
this.listenTo(this._layerContentModel, 'change:state', this._checkEditorModel);
|
||||
this.listenTo(this._overlayModel, 'change:visible', this._toggleOverlay);
|
||||
this.listenTo(this._viewState, 'change:isDataFiltered', this.render);
|
||||
},
|
||||
|
||||
_initViews: function () {
|
||||
if (this._queryGeometryModel.get('simple_geom') === 'point') {
|
||||
this._renderCarousel();
|
||||
}
|
||||
|
||||
this._renderForm();
|
||||
},
|
||||
|
||||
_toggleOverlay: function () {
|
||||
var isDisabled = this._overlayModel.get('visible');
|
||||
this.$el.toggleClass('is-disabled', isDisabled);
|
||||
},
|
||||
|
||||
_isErrored: function () {
|
||||
return this._layerContentModel.isErrored();
|
||||
},
|
||||
|
||||
_onAutoStyleChanged: function (layerDefModel) {
|
||||
var isAutoStyleApplied = layerDefModel.get('autoStyle');
|
||||
|
||||
if (!isAutoStyleApplied) {
|
||||
this.render();
|
||||
} else {
|
||||
this._styleModel.unbind('change', this._onStyleChanged, this);
|
||||
this._styleModel.once('change', function () {
|
||||
this.render();
|
||||
this._styleModel.bind('change', this._onStyleChanged, this);
|
||||
}, this);
|
||||
}
|
||||
},
|
||||
|
||||
_checkEditorModel: function () {
|
||||
this._queryGeometryModel.hasValueAsync()
|
||||
.then(function (hasGeometry) {
|
||||
this._editorModel.set({ disabled: this._isErrored() || !hasGeometry });
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
_renderError: function () {
|
||||
this.$el.append(
|
||||
styleSQLErrorTemplate({
|
||||
body: _t('editor.error-query.body', {
|
||||
action: actionErrorTemplate({
|
||||
label: _t('editor.error-query.label')
|
||||
})
|
||||
})
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
_renderFilteredData: function () {
|
||||
this.$el.append(
|
||||
layerTabMessageTemplate({
|
||||
message: _t('editor.layers.warnings.no-data.message'),
|
||||
action: _t('editor.layers.warnings.no-data.action-message')
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
_renderCarousel: function () {
|
||||
var view = new CarouselFormView({
|
||||
collection: this._buildAggregationCarouselCollection(),
|
||||
template: require('./style-form-types.tpl')
|
||||
});
|
||||
this.addView(view);
|
||||
this.$el.append(view.render().el);
|
||||
},
|
||||
|
||||
_onSelectAggregation: function (model) {
|
||||
var alreadyTorqueLayer = this._layerDefinitionsCollection.isThereAnyTorqueLayer();
|
||||
var isTorqueLayer = this._layerDefinitionModel.get('type') === 'torque';
|
||||
|
||||
var styleType;
|
||||
var isTorqueType;
|
||||
var currentGeometryType;
|
||||
|
||||
if (model.get('selected')) {
|
||||
styleType = model.getValue();
|
||||
currentGeometryType = this._queryGeometryModel.get('simple_geom');
|
||||
|
||||
isTorqueType = (styleType === StyleConstants.Type.HEATMAP || styleType === StyleConstants.Type.ANIMATION);
|
||||
|
||||
if (alreadyTorqueLayer && !isTorqueLayer && isTorqueType) {
|
||||
this._freezeTorgeAggregation(styleType, currentGeometryType);
|
||||
} else {
|
||||
// If an animated or a heatmap style is selected, we should move the layer to the
|
||||
// top, but if it is in the most high position, we shouldn't do anything
|
||||
if (isTorqueType && !this._layerDefinitionsCollection.isDataLayerOnTop(this._layerDefinitionModel)) {
|
||||
this._moveTorqueLayerToTop(function () {
|
||||
this._setDefaultProperties(styleType, currentGeometryType);
|
||||
}.bind(this));
|
||||
} else {
|
||||
this._setDefaultProperties(styleType, currentGeometryType, false /* silently */);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_setDefaultProperties: function (styleType, currentGeometryType, silently) {
|
||||
var previousType = this._styleModel.get('type');
|
||||
this._styleModel.setDefaultPropertiesByType(styleType, currentGeometryType, silently);
|
||||
|
||||
MetricsTracker.track(MetricsTypes.AGGREGATED_GEOMETRIES, {
|
||||
previous_agg_type: previousType,
|
||||
agg_type: styleType
|
||||
});
|
||||
},
|
||||
|
||||
_moveTorqueLayerToTop: function (callback) {
|
||||
var notification = Notifier.addNotification({
|
||||
status: 'loading',
|
||||
info: _t('editor.layers.moveTorqueLayer.loading'),
|
||||
closable: true
|
||||
});
|
||||
|
||||
this._layerDefinitionsCollection.once('layerMoved', function () {
|
||||
if (callback) { callback(); }
|
||||
|
||||
notification.set({
|
||||
status: 'success',
|
||||
info: _t('editor.layers.moveTorqueLayer.success'),
|
||||
delay: Notifier.DEFAULT_DELAY
|
||||
});
|
||||
}, this);
|
||||
|
||||
this._userActions.moveLayer({
|
||||
from: this._layerDefinitionModel.get('order'),
|
||||
to: this._layerDefinitionsCollection.getTopDataLayerIndex()
|
||||
});
|
||||
},
|
||||
|
||||
_renderForm: function () {
|
||||
if (this._querySchemaModel.get('query')) {
|
||||
var view = new StyleFormView({
|
||||
layerDefinitionsCollection: this._layerDefinitionsCollection,
|
||||
layerDefinitionModel: this._layerDefinitionModel,
|
||||
styleModel: this._styleModel,
|
||||
configModel: this._configModel,
|
||||
userModel: this._userModel,
|
||||
queryGeometryModel: this._queryGeometryModel,
|
||||
querySchemaModel: this._querySchemaModel,
|
||||
modals: this._modals
|
||||
});
|
||||
this.$el.append(view.render().el);
|
||||
this.addView(view);
|
||||
}
|
||||
},
|
||||
|
||||
_onStyleChanged: function () {
|
||||
this._styleModel.set('autogenerated', false);
|
||||
this._unsetExtraStyleProperties();
|
||||
this._layerDefinitionModel.save();
|
||||
|
||||
MetricsTracker.track(MetricsTypes.MODIFIED_STYLE_FORM, {
|
||||
layer_id: this._layerDefinitionModel.get('id'),
|
||||
cartocss: this._layerDefinitionModel.get('cartocss'),
|
||||
style_properties: this._layerDefinitionModel.get('style_properties')
|
||||
});
|
||||
},
|
||||
|
||||
_unsetExtraStyleProperties: function () {
|
||||
EXTRA_STYLE_PROPERTIES.forEach(function (property) {
|
||||
this._styleModel.unset(property, { silent: true });
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
_onStyleLabelChanged: function () {
|
||||
var labels = this._styleModel.get('labels');
|
||||
|
||||
EXTRA_LABELS_STYLE_PROPERTIES.forEach(function (property) {
|
||||
delete labels[property];
|
||||
});
|
||||
|
||||
this._styleModel.set('labels', labels, { silent: true });
|
||||
},
|
||||
|
||||
_setViewValues: function () {
|
||||
this._layerDefinitionModel.isDataFiltered()
|
||||
.then(function (isDataFiltered) {
|
||||
this._viewState.set('isDataFiltered', isDataFiltered);
|
||||
}.bind(this));
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user