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)); } }); } }); }); } });