Initial commit
This commit is contained in:
+87
@@ -0,0 +1,87 @@
|
||||
var CoreView = require('backbone/core-view');
|
||||
var ModalExportDataView = require('builder/components/modals/export-data/modal-export-data-view');
|
||||
var SyncInfoView = require('./dataset-content-sync-view');
|
||||
var template = require('./dataset-content-options.tpl');
|
||||
var checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
|
||||
var REQUIRED_OPTS = [
|
||||
'analysisDefinitionNodeModel',
|
||||
'configModel',
|
||||
'modals',
|
||||
'userModel'
|
||||
];
|
||||
|
||||
module.exports = CoreView.extend({
|
||||
|
||||
className: 'Dataset-viewOptions u-flex u-justifySpace u-alignCenter',
|
||||
|
||||
events: {
|
||||
'click .js-addRow': '_onAddRowClick',
|
||||
'click .js-addColumn': '_onAddColumnClick',
|
||||
'click .js-export': '_onExportClick'
|
||||
},
|
||||
|
||||
initialize: function (opts) {
|
||||
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
|
||||
|
||||
this._tableModel = this._analysisDefinitionNodeModel.getTableModel();
|
||||
this._querySchemaModel = this._analysisDefinitionNodeModel.querySchemaModel;
|
||||
this._queryGeometryModel = this._analysisDefinitionNodeModel.queryGeometryModel;
|
||||
this._syncModel = this._tableModel.getSyncModel();
|
||||
|
||||
this._initBinds();
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.clearSubViews();
|
||||
this.$el.html(
|
||||
template({
|
||||
isEditable: !this._analysisDefinitionNodeModel.isReadOnly(),
|
||||
isCustomQueryApplied: this._analysisDefinitionNodeModel.isCustomQueryApplied()
|
||||
})
|
||||
);
|
||||
this._initViews();
|
||||
return this;
|
||||
},
|
||||
|
||||
_initBinds: function () {
|
||||
this.listenTo(this._querySchemaModel, 'change:query', this.render);
|
||||
this.listenTo(this._syncModel, 'destroy', this.render);
|
||||
},
|
||||
|
||||
_initViews: function () {
|
||||
if (this._tableModel.isSync() && this._tableModel.isOwner(this._userModel)) {
|
||||
var syncInfo = new SyncInfoView({
|
||||
modals: this._modals,
|
||||
syncModel: this._syncModel,
|
||||
tableModel: this._tableModel,
|
||||
querySchemaModel: this._querySchemaModel
|
||||
});
|
||||
|
||||
this.$('.js-sync').html(syncInfo.render().el);
|
||||
this.addView(syncInfo);
|
||||
}
|
||||
},
|
||||
|
||||
_onExportClick: function () {
|
||||
this._modals.create(function (modalModel) {
|
||||
return new ModalExportDataView({
|
||||
modalModel: modalModel,
|
||||
fromView: 'dataset',
|
||||
configModel: this._configModel,
|
||||
filename: this._tableModel.getUnquotedName(),
|
||||
queryGeometryModel: this._queryGeometryModel,
|
||||
querySchemaModel: this._querySchemaModel,
|
||||
canHideColumns: false
|
||||
});
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
_onAddRowClick: function () {
|
||||
this.trigger('addRow', this);
|
||||
},
|
||||
|
||||
_onAddColumnClick: function () {
|
||||
this.trigger('addColumn', this);
|
||||
}
|
||||
});
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
<div class="js-sync"></div>
|
||||
<div class="js-dataset">
|
||||
<ul class="u-flex u-justifySpace">
|
||||
<% if (isEditable) { %>
|
||||
<li>
|
||||
<button class="CDB-Text CDB-Size-small is-semibold u-actionTextColor u-upperCase js-addRow">
|
||||
<div class="u-flex u-alignCenter">
|
||||
<svg width="16px" height="18px" viewBox="0 0 16 6" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<path d="M4,3 L4,0 L3,0 L3,3 L0,3 L0,4 L3,4 L3,7 L4,7 L4,4 L7,4 L7,3 L4,3 Z" id="path-1"></path>
|
||||
<mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="7" height="7" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
</defs>
|
||||
<g id="Add-Row" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<use id="Combined-Shape" stroke="#1181FB" mask="url(#mask-2)" stroke-width="2" xlink:href="#path-1"></use>
|
||||
<path d="M16,0 L16,3 L9,3 L9,0 L16,0 Z M10.0020142,1 L10.000989,2.01795972 L14.9926249,2.00301586 L14.9962966,1.00580263 L10.0020142,1 Z" id="Combined-Shape" fill="#1181FB"></path>
|
||||
<path d="M16,4 L16,7 L9,7 L9,4 L16,4 Z M10.0020142,5 L10.000989,6.01795972 L14.9926249,6.00301586 L14.9962966,5.00580263 L10.0020142,5 Z" id="Combined-Shape-Copy" fill="#1181FB"></path>
|
||||
</g>
|
||||
</svg>
|
||||
<span class="u-lSpace">
|
||||
<%- _t('dataset.options.add-row') %>
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
</li>
|
||||
<li class="u-lSpace--xl">
|
||||
<button class="CDB-Text CDB-Size-small is-semibold u-actionTextColor u-upperCase js-addColumn">
|
||||
<div class="u-flex u-alignCenter">
|
||||
<svg width="16px" height="18px" viewBox="0 4 16 6" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="Add-Column" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" transform="translate(0.000000, 4.000000)">
|
||||
<path d="M4,3 L4,0 L3,0 L3,3 L0,3 L0,4 L3,4 L3,7 L4,7 L4,4 L7,4 L7,3 L4,3 Z" id="Combined-Shape" fill="#1181FB"></path>
|
||||
<path d="M9,0 L12,0 L12,7 L9,7 L9,0 Z M10,1 L11,1 L11,6 L10,6 L10,1 Z" id="Combined-Shape" fill="#1181FB"></path>
|
||||
<path d="M13,0 L16,0 L16,7 L13,7 L13,0 Z M14,1 L15,1 L15,6 L14,6 L14,1 Z" id="Combined-Shape-Copy-2" fill="#1181FB"></path>
|
||||
</g>
|
||||
</svg>
|
||||
<span class="u-lSpace">
|
||||
<%- _t('dataset.options.add-column') %>
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
</li>
|
||||
<% } %>
|
||||
<li class="u-lSpace--xl">
|
||||
<button class="CDB-Text CDB-Size-small is-semibold u-actionTextColor u-upperCase is-disabled js-export">
|
||||
<div class="u-flex u-alignCenter">
|
||||
<svg width="11px" height="18px" viewBox="-1 2 11 10" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="Esport" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" transform="translate(0.000000, 3.000000)" stroke-linecap="square">
|
||||
<path d="M4.5,0.5 L4.5,6.5" id="Line" stroke="#1181FB"></path>
|
||||
<path d="M4.5,7.5 L8.5,3.5" id="Line" stroke="#1181FB"></path>
|
||||
<path d="M4.5,7.5 L0.5,3.5" id="Line" stroke="#1181FB"></path>
|
||||
</g>
|
||||
</svg>
|
||||
<span class="u-lSpace">
|
||||
<%- _t('dataset.options.export') %>
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
var CoreView = require('backbone/core-view');
|
||||
var TipsyTooltipView = require('builder/components/tipsy-tooltip-view');
|
||||
var CreationModalView = require('builder/components/modals/creation/modal-creation-view');
|
||||
var SyncOptionsModalView = require('builder/components/modals/sync-options/sync-options-modal-view');
|
||||
var SyncModel = require('builder/data/synchronization-model');
|
||||
var template = require('./dataset-content-sync.tpl');
|
||||
var moment = require('moment');
|
||||
var checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
|
||||
var REQUIRED_OPTS = [
|
||||
'syncModel',
|
||||
'tableModel',
|
||||
'querySchemaModel',
|
||||
'modals'
|
||||
];
|
||||
|
||||
module.exports = CoreView.extend({
|
||||
tagName: 'div',
|
||||
className: 'SyncInfo',
|
||||
|
||||
events: {
|
||||
'click .js-options': '_onClickOptions',
|
||||
'click .js-syncNow': '_onClickSyncNow'
|
||||
},
|
||||
|
||||
initialize: function (opts) {
|
||||
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
|
||||
this._startSync = this._startSync.bind(this);
|
||||
|
||||
this._initBinds();
|
||||
|
||||
// Check sync now button
|
||||
if (this._syncModel.isSyncing()) {
|
||||
this._showSyncNowModal();
|
||||
}
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.clearSubViews();
|
||||
var runAt = this._syncModel.get('run_at');
|
||||
|
||||
var d = {
|
||||
canSyncNow: this._syncModel.canSyncNow(),
|
||||
fromExternalSource: this._syncModel.get('from_external_source'),
|
||||
ranAt: moment(this._syncModel.get('ran_at') || new Date()).fromNow(),
|
||||
runAt: moment(runAt).fromNow(),
|
||||
state: this._syncModel.get('state'),
|
||||
errorCode: this._syncModel.get('error_code'),
|
||||
errorMessage: this._syncModel.get('error_message')
|
||||
};
|
||||
|
||||
// Due to the time we need to polling, we have to display to the user
|
||||
// that the sync will be in a moment
|
||||
if (!runAt || (new Date(runAt) <= new Date())) {
|
||||
d.runAt = _t('dataset.sync.in-a-moment');
|
||||
}
|
||||
|
||||
this.$el
|
||||
.html(template(d))
|
||||
.removeClass()
|
||||
.addClass(this.className + ' ' + 'is-' + d.state);
|
||||
|
||||
// Tipsy
|
||||
var tooltip = new TipsyTooltipView({
|
||||
el: this.$('.js-syncNowDisabled'),
|
||||
title: function () {
|
||||
return _t('dataset.sync.disabled', {
|
||||
gap: SyncModel.SYNC_GAP / (1000 * 60)
|
||||
});
|
||||
}
|
||||
});
|
||||
this.addView(tooltip);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_initBinds: function () {
|
||||
// Unbind in clean method
|
||||
this._syncModel.bind('change', this.render, this);
|
||||
},
|
||||
|
||||
_bindChangeSyncEvent: function () {
|
||||
this._syncModel.bind('change:state', this._finishSync, this);
|
||||
},
|
||||
|
||||
_unbindChangeSyncEvent: function () {
|
||||
this._syncModel.unbind(null, null, this);
|
||||
},
|
||||
|
||||
_onClickSyncNow: function (e) {
|
||||
if (e) this.killEvent(e);
|
||||
|
||||
if (this._syncModel.canSyncNow()) {
|
||||
this._showSyncNowModal();
|
||||
}
|
||||
},
|
||||
|
||||
_onClickOptions: function (e) {
|
||||
var self = this;
|
||||
var tableName = this._tableModel.getUnqualifiedName();
|
||||
|
||||
this._modals.create(function (modalModel) {
|
||||
return new SyncOptionsModalView({
|
||||
modalModel: modalModel,
|
||||
syncModel: self._syncModel,
|
||||
tableName: tableName
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_startSync: function () {
|
||||
this.render();
|
||||
this._bindChangeSyncEvent();
|
||||
this._syncModel.pollCheck();
|
||||
},
|
||||
|
||||
_finishSync: function () {
|
||||
if (!this._syncModel.isSyncing()) {
|
||||
this._unbindChangeSyncEvent();
|
||||
this._syncModel.destroyCheck();
|
||||
|
||||
// Reload table
|
||||
this._querySchemaModel.set({
|
||||
status: 'unfetched',
|
||||
query: 'SELECT * FROM ' + this._tableModel.getUnquotedName()
|
||||
});
|
||||
|
||||
this.render();
|
||||
}
|
||||
},
|
||||
|
||||
_showSyncNowModal: function (e) {
|
||||
var self = this;
|
||||
var tableName = this._tableModel.getUnqualifiedName();
|
||||
|
||||
this._modals.create(function (modalModel) {
|
||||
return new CreationModalView({
|
||||
modalModel: modalModel,
|
||||
loadingTitle: _t('dataset.sync.loading', { tableName: tableName }),
|
||||
errorTitle: _t('dataset.sync.error', { tableName: tableName }),
|
||||
runAction: function (opts) {
|
||||
self._syncModel.set({
|
||||
state: 'syncing',
|
||||
error_code: '',
|
||||
error_message: ''
|
||||
});
|
||||
|
||||
self._syncModel.bind('change:state', function () {
|
||||
if (!self._syncModel.isSyncing()) {
|
||||
modalModel.destroy();
|
||||
}
|
||||
}, self);
|
||||
|
||||
self._syncModel.syncNow(self._startSync);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
clean: function () {
|
||||
this._unbindChangeSyncEvent();
|
||||
CoreView.prototype.clean.apply(this);
|
||||
}
|
||||
|
||||
});
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
<p class="CDB-Text CDB-Size-small u-secondaryTextColor">
|
||||
<span class="SyncInfo-state SyncInfo-state--small SyncInfo-state--<%- state %> u-rSpace--s"></span>
|
||||
<span class="u-upperCase">
|
||||
<% if (state === "success") { %>
|
||||
<%- _t('dataset.sync.synced', { ranAt: ranAt }) %>.
|
||||
<% } else if (state === "syncing") { %>
|
||||
<%- _t('dataset.sync.syncing') %>...
|
||||
<% } else if (state === "failure") { %>
|
||||
<%- _t('dataset.sync.sync-failed') %>.
|
||||
<% } %>
|
||||
</span>
|
||||
|
||||
<% if (state === "success") { %>
|
||||
<%- _t('dataset.sync.next', { runAt: runAt }) %>.
|
||||
<% } else if (state === "syncing") { %>
|
||||
<% /* There's no need to add extra text in this case. */ %>
|
||||
<% } else if (errorCode || errorMessage) { %>
|
||||
<%- _t('dataset.sync.error-code', { errorCode: errorCode }) %>: <%- errorMessage %>.
|
||||
<% } %>
|
||||
|
||||
<% if (!fromExternalSource) { %>
|
||||
<% if (state !== "syncing") { %>
|
||||
<button class="<% if (canSyncNow) { %>u-actionTextColor js-syncNow<% } else { %>is-disabled js-syncNowDisabled<% } %>"><%- _t('dataset.sync.sync-now') %></button>.
|
||||
<% } %>
|
||||
<% } %>
|
||||
|
||||
<% if (state !== "syncing") { %>
|
||||
<button class="js-options u-actionTextColor"><%- _t('dataset.sync.view-options') %></button>.
|
||||
<% } %>
|
||||
</p>
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
var CoreView = require('backbone/core-view');
|
||||
var TableManager = require('builder/components/table/table-manager');
|
||||
var DatasetContentOptionsView = require('./dataset-content-options-view');
|
||||
var checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
|
||||
var REQUIRED_OPTS = [
|
||||
'analysisDefinitionNodeModel',
|
||||
'configModel',
|
||||
'modals',
|
||||
'userModel',
|
||||
'visModel'
|
||||
];
|
||||
|
||||
module.exports = CoreView.extend({
|
||||
|
||||
initialize: function (opts) {
|
||||
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
|
||||
this.listenTo(this._visModel, 'change:name', this._onChangeTableVisName);
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.clearSubViews();
|
||||
this._initViews();
|
||||
return this;
|
||||
},
|
||||
|
||||
_initViews: function () {
|
||||
this._tableView = TableManager.create({
|
||||
relativePositionated: true,
|
||||
analysisDefinitionNodeModel: this._analysisDefinitionNodeModel,
|
||||
configModel: this._configModel,
|
||||
modals: this._modals,
|
||||
userModel: this._userModel
|
||||
});
|
||||
this.addView(this._tableView);
|
||||
this.$el.append(this._tableView.render().el);
|
||||
|
||||
var datasetContentOptionsView = new DatasetContentOptionsView({
|
||||
modals: this._modals,
|
||||
userModel: this._userModel,
|
||||
analysisDefinitionNodeModel: this._analysisDefinitionNodeModel,
|
||||
configModel: this._configModel
|
||||
});
|
||||
datasetContentOptionsView.bind('addColumn', function () {
|
||||
this._tableView.addColumn();
|
||||
}, this);
|
||||
datasetContentOptionsView.bind('addRow', function () {
|
||||
this._tableView.addRow();
|
||||
}, this);
|
||||
|
||||
this.addView(datasetContentOptionsView);
|
||||
this.$el.prepend(datasetContentOptionsView.render().el);
|
||||
},
|
||||
|
||||
_onChangeTableVisName: function () {
|
||||
// Although all operations related with table rename are managed in the analysis-definition-source-node-model
|
||||
// this columnsCollection doesn't belong to it and we need to take from it is generated.
|
||||
this._tableView && this._tableView.getColumnsCollection().setTableName(this._visModel.get('name'));
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user