Initial commit
This commit is contained in:
220
lib/assets/javascripts/builder/data/widget-definitions-collection.js
Executable file
220
lib/assets/javascripts/builder/data/widget-definitions-collection.js
Executable file
@@ -0,0 +1,220 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var WidgetDefinitionModel = require('./widget-definition-model');
|
||||
var checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
|
||||
var REQUIRED_OPTS = [
|
||||
'configModel',
|
||||
'mapId',
|
||||
'layerDefinitionsCollection',
|
||||
'analysisDefinitionNodesCollection'
|
||||
];
|
||||
|
||||
/**
|
||||
* Collection of widget definitions, synhronizes the internal definitions and the widget models.
|
||||
*/
|
||||
module.exports = Backbone.Collection.extend({
|
||||
comparator: 'order',
|
||||
|
||||
model: function (attrs, opts) {
|
||||
var self = opts.collection;
|
||||
attrs.order = !_.isUndefined(attrs.order) ? attrs.order : 0;
|
||||
var model = new WidgetDefinitionModel(attrs, {
|
||||
parse: true, // make sure data is structured as expected
|
||||
collection: self,
|
||||
configModel: self._configModel,
|
||||
mapId: self._mapId
|
||||
});
|
||||
return model;
|
||||
},
|
||||
|
||||
initialize: function (models, opts) {
|
||||
var self = this;
|
||||
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
|
||||
|
||||
this._bindLayerStyleChanges();
|
||||
|
||||
this._attrsForThisTypeMap = {
|
||||
formula: function (model) {
|
||||
return {
|
||||
column: model.get('column'),
|
||||
operation: model.get('operation') || 'max'
|
||||
};
|
||||
},
|
||||
category: function (model) {
|
||||
var columnName = model.get('column');
|
||||
return {
|
||||
aggregation: model.get('aggregation') || 'count',
|
||||
aggregation_column: model.get('aggregation_column') || columnName,
|
||||
column: columnName,
|
||||
widget_style_definition: model.get('widget_style_definition') || WidgetDefinitionModel.getDefaultWidgetStyle('category'),
|
||||
auto_style_definition: undefined
|
||||
};
|
||||
},
|
||||
histogram: function (model) {
|
||||
return {
|
||||
column: model.get('column'),
|
||||
bins: model.get('bins') || 10,
|
||||
column_type: 'number',
|
||||
widget_style_definition: model.get('widget_style_definition') || WidgetDefinitionModel.getDefaultWidgetStyle('histogram'),
|
||||
auto_style_definition: undefined
|
||||
};
|
||||
},
|
||||
'time-series': function (model) {
|
||||
return {
|
||||
column: model.get('column'),
|
||||
bins: model.get('bins') || 256,
|
||||
aggregation: model.get('aggregation'),
|
||||
column_type: self.getColumnType(model.get('column'), model.get('source')),
|
||||
widget_style_definition: model.get('widget_style_definition') || WidgetDefinitionModel.getDefaultWidgetStyle('time-series')
|
||||
};
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
url: function () {
|
||||
var baseUrl = this._configModel.get('base_url');
|
||||
return baseUrl + '/api/v3/maps/' + this._mapId + '/widgets';
|
||||
},
|
||||
|
||||
parse: function (response) {
|
||||
return response && response.widgets
|
||||
? response.widgets
|
||||
: [];
|
||||
},
|
||||
|
||||
_bindLayerStyleChanges: function () {
|
||||
this._layerDefinitionsCollection.bind('change:style_properties', this._onLayerStyleChanged, this);
|
||||
},
|
||||
|
||||
_onLayerStyleChanged: function (layerDefModel) {
|
||||
var styleModel = layerDefModel.styleModel;
|
||||
var isAllowed = styleModel && styleModel.canApplyAutoStyle();
|
||||
var affectedWidgets = this.where({ layer_id: layerDefModel.id });
|
||||
|
||||
_.each(affectedWidgets, function (widgetDefModel) {
|
||||
var isNowAllowed = widgetDefModel.get('auto_style_allowed');
|
||||
var willBeAllowed = isAllowed;
|
||||
var attrs = {
|
||||
auto_style_allowed: willBeAllowed
|
||||
};
|
||||
|
||||
if (isNowAllowed !== willBeAllowed) {
|
||||
// if autostyle is not allow, we should clean auto_style_definition
|
||||
if (willBeAllowed === false) {
|
||||
attrs = _.extend(attrs, { auto_style_definition: '' });
|
||||
}
|
||||
widgetDefModel.save(attrs);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
addWidget: function (widgetModel, attrs) {
|
||||
var self = this;
|
||||
var ORDER_NUMBER_TO_APPEAR_ON_TOP = -1;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
_.extend(attrs, { order: ORDER_NUMBER_TO_APPEAR_ON_TOP });
|
||||
|
||||
self.create(attrs, {
|
||||
wait: true,
|
||||
success: function (model) {
|
||||
resolve(model);
|
||||
},
|
||||
error: function (response, error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
updateWidgetsOrder: function (numberOfWidgets) {
|
||||
this.each(function (widgetDefinitionModel, index) {
|
||||
widgetDefinitionModel.set({ order: index });
|
||||
});
|
||||
|
||||
return this.saveAsync(numberOfWidgets);
|
||||
},
|
||||
|
||||
saveAsync: function (updatedWidgets) {
|
||||
var self = this;
|
||||
|
||||
this.trigger('loading', updatedWidgets);
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
self.save({
|
||||
wait: true,
|
||||
success: function (collection) {
|
||||
self.trigger('successAdd', updatedWidgets);
|
||||
resolve(collection);
|
||||
},
|
||||
error: function (response, error) {
|
||||
self.trigger('errorAdd', response);
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
save: function (options) {
|
||||
options = options || {};
|
||||
Backbone.sync('update', this, options);
|
||||
},
|
||||
|
||||
attrsForThisType: function (newType, m) {
|
||||
return this._attrsForThisTypeMap[newType](m);
|
||||
},
|
||||
|
||||
resetableAttrsForTypeMap: function (type) {
|
||||
switch (type) {
|
||||
case 'formula':
|
||||
return [];
|
||||
case 'category':
|
||||
return ['aggregation'];
|
||||
case 'histogram':
|
||||
return ['bins', 'column_type'];
|
||||
case 'time-series':
|
||||
return ['bins', 'aggregation', 'column_type'];
|
||||
}
|
||||
},
|
||||
|
||||
isThereTimeSeries: function (opts) {
|
||||
opts = opts || {};
|
||||
|
||||
var timeSeries = opts.animated ? this.findWhere({ type: 'time-series', animated: opts.animated }) : this.findWhere({ type: 'time-series' });
|
||||
return !!timeSeries;
|
||||
},
|
||||
|
||||
isThereOtherWidgets: function () {
|
||||
return !!this.find(function (widgetModel) {
|
||||
return widgetModel.get('type') !== 'time-series';
|
||||
});
|
||||
},
|
||||
|
||||
_getNextOrder: function () {
|
||||
if (this.isEmpty()) {
|
||||
return 0;
|
||||
} else {
|
||||
var lastItemByOrder = this.max(function (mdl) {
|
||||
return mdl.get('order');
|
||||
});
|
||||
return lastItemByOrder.get('order') + 1;
|
||||
}
|
||||
},
|
||||
|
||||
widgetsOwnedByLayer: function (layerId) {
|
||||
var widgets = this.where({ layer_id: layerId });
|
||||
|
||||
return widgets.length;
|
||||
},
|
||||
|
||||
getColumnType: function (columnName, source) {
|
||||
var column;
|
||||
var node = this._analysisDefinitionNodesCollection.get(source);
|
||||
var schemaModel = node && node.querySchemaModel;
|
||||
if (schemaModel && schemaModel.get('status') === 'fetched') {
|
||||
column = schemaModel.columnsCollection.findWhere({ name: columnName });
|
||||
}
|
||||
return column && column.get('type');
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user