cartodb/lib/assets/javascripts/builder/dataset/dataset-options/dataset-options-view.js
2020-06-15 10:58:47 +08:00

288 lines
8.9 KiB
JavaScript
Executable File

var Backbone = require('backbone');
var $ = require('jquery');
var CoreView = require('backbone/core-view');
var VisDefinitionModel = require('builder/data/vis-definition-model');
var CreationModalView = require('builder/components/modals/creation/modal-creation-view');
var DatasetBaseView = require('builder/components/dataset/dataset-base-view');
var errorParser = require('builder/helpers/error-parser');
var PanelWithOptionsView = require('builder/components/view-options/panel-with-options-view');
var TabPaneView = require('builder/components/tab-pane/tab-pane-view');
var TabPaneCollection = require('builder/components/tab-pane/tab-pane-collection');
var Toggler = require('builder/components/toggler/toggler-view');
var DatasetEditorView = require('./dataset-sql-view');
var ActionView = require('./dataset-actions-view');
var PreviewMapView = require('./preview-map-view');
var ActionViewEdition = require('./dataset-actions-edition-view');
var DataSQLModel = require('builder/dataset/data-sql-model');
var SQLNotifications = require('builder/sql-notifications');
var MetricsTracker = require('builder/components/metrics/metrics-tracker');
var MetricsTypes = require('builder/components/metrics/metrics-types');
var checkAndBuildOpts = require('builder/helpers/required-opts');
var REQUIRED_OPTS = [
'analysisDefinitionNodeModel',
'configModel',
'editorModel',
'layerDefinitionModel',
'modals',
'onToggleEdition',
'router',
'userModel',
'visModel'
];
module.exports = DatasetBaseView.extend({
initialize: function (opts) {
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
this._querySchemaModel = this._analysisDefinitionNodeModel.querySchemaModel;
if (!this._layerDefinitionModel.sqlModel) {
var sqlHistory = this._layerDefinitionModel.options && this._layerDefinitionModel.options.sql_history;
this._layerDefinitionModel.sqlModel = new DataSQLModel({
content: this._querySchemaModel.get('query')
}, {
history: sqlHistory || []
});
}
DatasetBaseView.prototype.initialize.call(this, {
layerDefinitionModel: this._layerDefinitionModel,
editorModel: this._editorModel,
configModel: this._configModel,
querySchemaModel: this._querySchemaModel
});
this._tableModel = this._analysisDefinitionNodeModel.getTableModel();
this._queryGeometryModel = this._analysisDefinitionNodeModel.queryGeometryModel;
this._canCreateMap = this._userModel.hasCreateMapsFeature();
this._parseSQL = this._internalParseSQL.bind(this);
SQLNotifications.track(this);
this._togglerModel = new Backbone.Model({
labels: [_t('dataset.data'), _t('dataset.sql')],
active: this._editorModel.isEditing(),
disabled: this._editorModel.isDisabled()
});
this._configPanes();
this._initBinds();
},
render: function () {
this.clearSubViews();
this.$el.empty();
this._initViews();
this._checkClearButton();
return this;
},
_initBinds: function () {
this.listenTo(this._editorModel, 'change:edition', this._onChangeEdition);
this.listenTo(this._editorModel, 'change:disabled', this._onChangeDisabled);
this.listenTo(this._togglerModel, 'change:active', this._onTogglerChanged);
this.listenTo(this._querySchemaModel, 'change:query_errors', this._showErrors);
this.listenTo(this._visModel, 'change:name', this._onChangeName);
this.listenTo(this._sqlModel, 'undo redo', function () {
this._codemirrorModel.set('content', this._sqlModel.get('content'));
});
},
_onChangeName: function (model, name) {
this._codemirrorModel.set('content', this._analysisDefinitionNodeModel.getDefaultQuery());
},
_initViews: function () {
var self = this;
var panelWithOptionsView = new PanelWithOptionsView({
editorModel: self._editorModel,
createContentView: function () {
return new TabPaneView({
collection: self._collectionPane
});
},
createControlView: function () {
return new Toggler({
model: self._togglerModel
});
},
createActionView: function () {
return new TabPaneView({
collection: self._collectionPane,
createContentKey: 'createActionView'
});
}
});
this.$el.append(panelWithOptionsView.render().el);
this.addView(panelWithOptionsView);
},
_onChangeEdition: function () {
this._onToggleEdition();
var edition = this._editorModel.get('edition');
var index = edition ? 1 : 0;
this._collectionPane.at(index).set({ selected: true });
this._togglerModel.set({ active: edition });
},
_onChangeDisabled: function () {
var disabled = this._editorModel.get('disabled');
this._togglerModel.set({ disabled: disabled });
},
_onTogglerChanged: function () {
var checked = this._togglerModel.get('active');
this._editorModel.set({ edition: checked });
},
_configPanes: function () {
var self = this;
var tabPaneTabs = [{
selected: !this._editorModel.get('edition'),
createContentView: function () {
return new CoreView();
},
createActionView: function () {
var actionViewOptions = {
queryGeometryModel: self._queryGeometryModel,
previewAction: self._previewMap.bind(self)
};
if (self._canCreateMap) {
actionViewOptions.mapAction = self._createMap.bind(self);
}
return new ActionView(actionViewOptions);
}
}, {
selected: this._editorModel.get('edition'),
createContentView: function () {
return new DatasetEditorView({
editorModel: self._editorModel,
codemirrorModel: self._codemirrorModel,
onApplyEvent: self._parseSQL,
layerDefinitionModel: self._layerDefinitionModel,
querySchemaModel: self._querySchemaModel
});
},
createActionView: function () {
var actionViewOptions = {
clearSQLModel: self._clearSQLModel,
trackModel: self._sqlModel,
editorModel: self._editorModel,
queryGeometryModel: self._queryGeometryModel,
querySchemaModel: self._querySchemaModel,
onApply: self._parseSQL,
previewAction: self._previewMap.bind(self),
onClear: self._clearSQL.bind(self),
applyButtonStatusModel: self._applyButtonStatusModel
};
if (self._canCreateMap) {
actionViewOptions.mapAction = self._createMap.bind(self);
}
return new ActionViewEdition(actionViewOptions);
}
}];
this._collectionPane = new TabPaneCollection(tabPaneTabs);
},
_runQuery: function (query, callback) {
this._querySchemaModel.set({
query: query,
status: 'unfetched'
});
this._queryGeometryModel.set({
query: query,
simple_geom: '',
status: 'unfetched'
}, {
silent: true
});
this._querySchemaModel.fetch({
success: callback
});
this._queryGeometryModel.fetch();
},
_saveSQL: function () {
var content = this._codemirrorModel.get('content');
this._sqlModel.set('content', content);
this._querySchemaModel.set('query_errors', []);
if (this._tableModel.hasWriteAccess(this._userModel)) {
this._layerDefinitionModel.save({
sql: content
});
MetricsTracker.track(MetricsTypes.APPLIED_SQL, {
dataset_id: this._tableModel.get('id'),
sql: content
});
}
SQLNotifications.showNotification({
status: 'success',
info: _t('notifications.sql.success'),
closable: true
});
this._checkClearButton();
},
_defaultSQL: function () {
return this._analysisDefinitionNodeModel.getDefaultQuery();
},
_previewMap: function () {
var previewMap = new PreviewMapView({
analysisDefinitionNodeModel: this._analysisDefinitionNodeModel,
configModel: this._configModel,
modals: this._modals,
userModel: this._userModel,
visModel: this._visModel
});
$('body').append(previewMap.render().el);
this.addView(previewMap);
},
_createMap: function () {
var self = this;
var tableName = this._tableModel.getUnquotedName();
this._modals.create(function (modalModel) {
return new CreationModalView({
modalModel: modalModel,
loadingTitle: _t('dataset.create-map.loading', { tableName: tableName }),
errorTitle: _t('dataset.create-map.error', { tableName: tableName }),
runAction: function (opts) {
var newVisModel = new VisDefinitionModel({
name: self._visModel.get('name') + ' ' + _t('editor.map')
}, {
configModel: self._configModel
});
newVisModel.save({
source_visualization_id: self._visModel.get('id')
}, {
success: function (visModel) {
window.location = visModel.builderURL();
},
error: function (mdl, e) {
opts.error && opts.error(errorParser(e));
}
});
}
});
});
}
});