191 lines
6.2 KiB
JavaScript
191 lines
6.2 KiB
JavaScript
|
var _ = require('underscore');
|
||
|
var checkAndBuildOpts = require('builder/helpers/required-opts');
|
||
|
var AnalysisOnboardingLauncher = require('builder/components/onboardings/analysis/analysis-launcher');
|
||
|
var AnalysisNotifications = require('builder/editor/layers/analysis-views/analysis-notifications');
|
||
|
|
||
|
var REQUIRED_OPTS = [
|
||
|
'diDashboardHelpers',
|
||
|
'analysisDefinitionsCollection',
|
||
|
'analysisDefinitionNodesCollection',
|
||
|
'layerDefinitionsCollection',
|
||
|
'onboardings',
|
||
|
'userModel',
|
||
|
'visDefinitionModel'
|
||
|
];
|
||
|
|
||
|
/**
|
||
|
* Only manage **ANALYSIS NODES** and **ANALYSIS DEFINITION** actions between
|
||
|
* Deep-Insights (CARTO.js) and Builder
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
module.exports = {
|
||
|
|
||
|
track: function (options) {
|
||
|
checkAndBuildOpts(options, REQUIRED_OPTS, this);
|
||
|
|
||
|
this._analysisDefinitionNodesCollection.each(function (analysisDefinitionNode) {
|
||
|
analysisDefinitionNode.queryRowsCollection.on('remove', this._invalidateMap, this);
|
||
|
}, this);
|
||
|
|
||
|
this._analysisDefinitionNodesCollection.on('add', this._onAnalysisDefinitionNodeAdded, this);
|
||
|
this._analysisDefinitionNodesCollection.on('change', this._onAnalysisDefinitionNodeChanged, this);
|
||
|
this._analysisDefinitionNodesCollection.on('change:id', this._onAnalysisDefinitionNodeIdChanged, this);
|
||
|
this._analysisDefinitionNodesCollection.on('remove', this._onAnalysisDefinitionNodeRemoved, this);
|
||
|
|
||
|
this._analysisDefinitionsCollection.on('add', this._onAnalysisDefinitionAdded, this);
|
||
|
this._analysisDefinitionsCollection.on('sync', this._onAnalysisDefinitionSync, this);
|
||
|
|
||
|
this._analysisDefinitionsCollection.each(this._analyseDefinition, this);
|
||
|
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
_onAnalysisDefinitionNodeAdded: function (node) {
|
||
|
node.queryRowsCollection.on('remove', this._invalidateMap, this);
|
||
|
this.analyseDefinitionNode(node);
|
||
|
},
|
||
|
|
||
|
_onAnalysisDefinitionNodeChanged: function (node) {
|
||
|
if (!this._hasUpdatedOnlyNodeAnalysisStatus(node)) {
|
||
|
// Only call analyse if there is a non-only-status change
|
||
|
this.analyseDefinitionNode(node);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_onAnalysisDefinitionNodeIdChanged: function (node) {
|
||
|
if (this._hasUpdatedOnlyNodeAnalysisId(node)) {
|
||
|
var analysis = this._diDashboardHelpers.getAnalysisByNodeId(node.previous('id'));
|
||
|
if (analysis) {
|
||
|
analysis.set('id', node.id);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_onAnalysisDefinitionNodeRemoved: function (node) {
|
||
|
node.queryRowsCollection.off('remove', this._invalidateMap, this);
|
||
|
var analysis = this._diDashboardHelpers.getAnalysisByNodeId(node.previous('id'));
|
||
|
if (analysis) {
|
||
|
analysis.set({avoidNotification: (node && !!node.get('avoidNotification'))}, {silent: true});
|
||
|
analysis.remove();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_onAnalysisDefinitionAdded: function (definition) {
|
||
|
this._analyseDefinition(definition);
|
||
|
},
|
||
|
|
||
|
_onAnalysisDefinitionSync: function (definition) {
|
||
|
this._analyseDefinition(definition);
|
||
|
},
|
||
|
|
||
|
_analyseDefinition: function (definition) {
|
||
|
var id = definition.get('node_id');
|
||
|
var node = this._analysisDefinitionNodesCollection.get(id);
|
||
|
this.analyseDefinitionNode(node);
|
||
|
},
|
||
|
|
||
|
analyseDefinitionNode: function (node) {
|
||
|
if (!this._hasUpdatedOnlyNodeAnalysisId(node)) {
|
||
|
var attrs = node.toJSON({ skipOptions: true });
|
||
|
this._diDashboardHelpers.analyse(attrs);
|
||
|
|
||
|
this._tryToSetupDefinitionNodesSync();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_hasUpdatedOnlyNodeAnalysisStatus: function (node) {
|
||
|
return node.hasChanged('status') && _.size(node.changed) === 1;
|
||
|
},
|
||
|
|
||
|
_hasUpdatedOnlyNodeAnalysisId: function (node) {
|
||
|
return node.hasChanged('id') && _.size(node.changed) === 1;
|
||
|
},
|
||
|
|
||
|
_tryToSetupDefinitionNodesSync: function () {
|
||
|
// Unfortunately have to try to setup sync until this point, since a node doesn't exist until after analyse call
|
||
|
this._analysisDefinitionNodesCollection.each(this._tryToSetupDefinitionNodeSync, this);
|
||
|
},
|
||
|
|
||
|
_tryToSetupDefinitionNodeSync: function (node) {
|
||
|
var isCachedAnalysis = this._isCachedAnalysis(node);
|
||
|
if (node.__syncSetup && !isCachedAnalysis) return; // only setup once
|
||
|
|
||
|
var analysis = this._diDashboardHelpers.getAnalysisByNodeId(node.id);
|
||
|
var layerDefinition = this._layerDefinitionsCollection.findOwnerOfAnalysisNode(node);
|
||
|
if (!analysis) return; // might not exist when method is called, so do nothing to allow retries
|
||
|
|
||
|
node.__syncSetup = true;
|
||
|
node.__initialization = true;
|
||
|
|
||
|
if (isCachedAnalysis) {
|
||
|
AnalysisOnboardingLauncher.launch(analysis.get('type'), node);
|
||
|
node.USER_SAVED = false;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Don't need to sync source nodes
|
||
|
if (analysis.get('type') !== 'source') {
|
||
|
AnalysisNotifications.track(analysis, layerDefinition);
|
||
|
|
||
|
var updateAnalysisQuerySchema = function () {
|
||
|
var query = analysis.get('query');
|
||
|
var status = analysis.get('status');
|
||
|
var error = analysis.get('error');
|
||
|
|
||
|
node.querySchemaModel.set({
|
||
|
status: 'unfetched',
|
||
|
query: query,
|
||
|
ready: status === 'ready'
|
||
|
});
|
||
|
node.queryGeometryModel.set({
|
||
|
status: 'unfetched',
|
||
|
query: query,
|
||
|
ready: status === 'ready'
|
||
|
});
|
||
|
|
||
|
node.set({
|
||
|
status: status,
|
||
|
error: error
|
||
|
});
|
||
|
|
||
|
if (status === 'ready') {
|
||
|
if (!node.__initialization) {
|
||
|
node.trigger('queryObjectsUpdated', node);
|
||
|
}
|
||
|
|
||
|
node.__initialization = false;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
AnalysisOnboardingLauncher.init({
|
||
|
onboardings: this._onboardings,
|
||
|
userModel: this._userModel,
|
||
|
visDefinitionModel: this._visDefinitionModel
|
||
|
});
|
||
|
|
||
|
node.listenTo(analysis, 'change:status', function (model, status) {
|
||
|
if (status === 'ready' && node.USER_SAVED) {
|
||
|
AnalysisOnboardingLauncher.launch(analysis.get('type'), model);
|
||
|
node.USER_SAVED = false;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
updateAnalysisQuerySchema();
|
||
|
|
||
|
node.listenTo(analysis, 'change:query change:status change:error', updateAnalysisQuerySchema);
|
||
|
node.listenToOnce(analysis, 'destroy', node.stopListening);
|
||
|
} else {
|
||
|
node.listenTo(node.querySchemaModel, 'resetDueToAlteredData', this._invalidateMap.bind(this));
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_isCachedAnalysis: function (node) {
|
||
|
return node.hasChanged('status') && node.get('status') === 'ready' && node.previous('status') === 'launched';
|
||
|
},
|
||
|
|
||
|
_invalidateMap: function () {
|
||
|
this._diDashboardHelpers.invalidateMap();
|
||
|
}
|
||
|
};
|