Initial commit
This commit is contained in:
253
lib/assets/javascripts/dashboard/data/visualization-model.js
Normal file
253
lib/assets/javascripts/dashboard/data/visualization-model.js
Normal file
@@ -0,0 +1,253 @@
|
||||
const Backbone = require('backbone');
|
||||
const _ = require('underscore');
|
||||
const LikeModel = require('dashboard/data/like-model');
|
||||
const UserModel = require('dashboard/data/user-model');
|
||||
const PermissionModel = require('dashboard/data/permission-model');
|
||||
const MapModel = require('dashboard/data/map-model');
|
||||
const VisualizationOrderModel = require('dashboard/data/visualization-order-model');
|
||||
const SlideTransition = require('dashboard/data/slide-transition-model');
|
||||
const MapUrlModel = require('dashboard/data/map-url-model');
|
||||
const DatasetUrlModel = require('dashboard/data/dataset-url-model');
|
||||
const CartoTableMetadata = require('dashboard/views/public-dataset/carto-table-metadata');
|
||||
const checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
|
||||
const REQUIRED_OPTS = [
|
||||
'configModel'
|
||||
];
|
||||
|
||||
const PRIVACY_OPTIONS = {
|
||||
public: 'PUBLIC',
|
||||
link: 'LINK',
|
||||
private: 'PRIVATE',
|
||||
password: 'PASSWORD'
|
||||
};
|
||||
|
||||
const VisualizationModel = Backbone.Model.extend({
|
||||
|
||||
defaults: {
|
||||
bindMap: true
|
||||
},
|
||||
|
||||
INHERIT_TABLE_ATTRIBUTES: [
|
||||
'name', 'description', 'privacy'
|
||||
],
|
||||
|
||||
initialize: function (attrs, opts) {
|
||||
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
|
||||
|
||||
this.map = new MapModel({ configModel: this._configModel });
|
||||
this.permission = new PermissionModel(this.get('permission'), { configModel: this._configModel });
|
||||
this.order = new VisualizationOrderModel({ visualization: this });
|
||||
this.transition = new SlideTransition(this.get('transition_options'), { parse: true });
|
||||
|
||||
this.like = LikeModel.newByVisData({
|
||||
vis_id: this.id,
|
||||
liked: this.get('liked'),
|
||||
likes: this.get('likes'),
|
||||
config: this._configModel
|
||||
});
|
||||
|
||||
if (this.get('bindMap')) this._bindMap();
|
||||
|
||||
this._initBinds();
|
||||
},
|
||||
|
||||
_initBinds: function () {
|
||||
this.permission.acl.bind('reset', function () {
|
||||
// Sync the local permission object w/ the raw data, so vis.save don't accidentally overwrites permissions changes
|
||||
this.set('permission', this.permission.attributes, { silent: true });
|
||||
this.trigger('change:permission', this);
|
||||
}, this);
|
||||
|
||||
// Keep permission model in sync, e.g. on vis.save
|
||||
this.bind('change:permission', function () {
|
||||
this.permission.set(this.get('permission'));
|
||||
}, this);
|
||||
},
|
||||
|
||||
_bindMap: function () {
|
||||
this.on('change:map_id', this._fetchMap, this);
|
||||
|
||||
this.map.bind('change:id', function () {
|
||||
this.set('map_id', this.map.id);
|
||||
}, this);
|
||||
|
||||
this.map.set('id', this.get('map_id'));
|
||||
},
|
||||
|
||||
url: function (method) {
|
||||
var version = this._configModel.urlVersion('visualization', method);
|
||||
var base = '/api/' + version + '/viz';
|
||||
if (this.isNew()) {
|
||||
return base;
|
||||
}
|
||||
return base + '/' + this.id;
|
||||
},
|
||||
|
||||
parse: function (data) {
|
||||
if (this.transition && data.transition_options) {
|
||||
this.transition.set(this.transition.parse(data.transition_options));
|
||||
}
|
||||
|
||||
if (this.like) {
|
||||
this.like.set({
|
||||
vis_id: this.id,
|
||||
likes: this.get('likes'),
|
||||
liked: this.get('liked')
|
||||
});
|
||||
}
|
||||
|
||||
if (this.owner) {
|
||||
this.owner = new UserModel(this.owner);
|
||||
}
|
||||
|
||||
return data;
|
||||
},
|
||||
|
||||
toJSON: function () {
|
||||
var attr = _.clone(this.attributes);
|
||||
|
||||
delete attr.bindMap;
|
||||
delete attr.stats;
|
||||
delete attr.related_tables;
|
||||
delete attr.children;
|
||||
|
||||
attr.transition_options = this.transition.toJSON();
|
||||
|
||||
return attr;
|
||||
},
|
||||
|
||||
getLikesModel: function () {
|
||||
return this.like;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a copy of the visualization model
|
||||
*/
|
||||
copy: function (attrs, options) {
|
||||
attrs = attrs || {};
|
||||
options = options || {};
|
||||
var vis = new VisualizationModel(
|
||||
_.extend({
|
||||
source_visualization_id: this.id
|
||||
},
|
||||
attrs
|
||||
),
|
||||
{ configModel: this._configModel }
|
||||
);
|
||||
vis.save(null, options);
|
||||
return vis;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch map information
|
||||
*/
|
||||
_fetchMap: function () {
|
||||
this.map
|
||||
.set('id', this.get('map_id'))
|
||||
.fetch();
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the URL for current instance.
|
||||
* @param {Object} currentUser (Optional) Get the URL from the perspective of the current user, necessary to
|
||||
* correctly setup URLs to tables.
|
||||
* @return {Object} instance of cdb.common.Url
|
||||
*/
|
||||
viewUrl: function (currentUser) {
|
||||
const owner = this.permission.owner;
|
||||
let userUrl = this.permission.owner.viewUrl();
|
||||
|
||||
// the undefined check is required for backward compability, in some cases (e.g. dependant visualizations) the type
|
||||
// is not available on the attrs, if so assume the old behavior (e.g. it's a visualization/derived/map).
|
||||
if (this.isVisualization() || _.isUndefined(this.get('type'))) {
|
||||
let id = this.get('id');
|
||||
|
||||
if (currentUser && currentUser.id !== owner.id && this.permission.hasAccess(currentUser)) {
|
||||
userUrl = currentUser.viewUrl();
|
||||
id = owner.get('username') + '.' + id;
|
||||
}
|
||||
|
||||
return new MapUrlModel({
|
||||
base_url: userUrl.urlToPath('viz', id)
|
||||
});
|
||||
} else {
|
||||
if (currentUser && this.permission.hasAccess(currentUser)) {
|
||||
userUrl = currentUser.viewUrl();
|
||||
}
|
||||
return new DatasetUrlModel({
|
||||
base_url: userUrl.urlToPath('tables', this.tableMetadata().getUnquotedName())
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// return: Array of entities (user or organizations) this vis is shared with
|
||||
sharedWithEntities: function () {
|
||||
return _.map((this.permission.acl.toArray() || []), function (aclItem) {
|
||||
return aclItem.get('entity');
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Is this model a true visualization?
|
||||
*/
|
||||
isVisualization: function () {
|
||||
return this.get('type') === 'derived' || this.get('type') === 'slide';
|
||||
},
|
||||
|
||||
/**
|
||||
* Get table metadata related to this vis.
|
||||
* Note that you might need to do a {metadata.fetch()} to get full data.
|
||||
*
|
||||
* @returns {CartoTableMetadata} if this vis represents a table
|
||||
* TODO: when and when isn't it required to do a fetch really?
|
||||
*/
|
||||
tableMetadata: function () {
|
||||
if (!this._metadata) {
|
||||
this._metadata = new CartoTableMetadata(this.get('table'), { configModel: this._configModel });
|
||||
}
|
||||
return this._metadata;
|
||||
},
|
||||
|
||||
getTableModel: function () {
|
||||
if (!this._metadata) {
|
||||
this._metadata = new CartoTableMetadata(this.get('table'), { configModel: this._configModel });
|
||||
}
|
||||
return this._metadata;
|
||||
},
|
||||
|
||||
privacyOptions: function () {
|
||||
const privacyOptions = _.values(PRIVACY_OPTIONS);
|
||||
|
||||
if (this.isVisualization()) {
|
||||
return privacyOptions;
|
||||
} else {
|
||||
return _.filter(privacyOptions, option => option !== 'PASSWORD');
|
||||
}
|
||||
},
|
||||
|
||||
isRaster: function () {
|
||||
return this.get('kind') === 'raster';
|
||||
},
|
||||
|
||||
getPermissionModel: function () {
|
||||
return this.permission;
|
||||
},
|
||||
|
||||
getSynchronizationModel: function () {
|
||||
return this._synchronizationModel;
|
||||
},
|
||||
|
||||
mapcapsURL: function () {
|
||||
var baseUrl = this._configModel.get('base_url');
|
||||
return baseUrl + '/api/v3/viz/' + this.id + '/mapcaps';
|
||||
}
|
||||
}, {
|
||||
isPubliclyAvailable: function (privacyStatus) {
|
||||
return privacyStatus === PRIVACY_OPTIONS.password ||
|
||||
privacyStatus === PRIVACY_OPTIONS.link ||
|
||||
privacyStatus === PRIVACY_OPTIONS.public;
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = VisualizationModel;
|
||||
Reference in New Issue
Block a user