Initial commit
This commit is contained in:
+362
@@ -0,0 +1,362 @@
|
||||
var $ = require('jquery');
|
||||
var Backbone = require('backbone');
|
||||
var CoreView = require('backbone/core-view');
|
||||
var PrivacyDialogView = require('./privacy-dialog-view');
|
||||
var PrivacyWarningView = require('builder/components/modals/privacy-warning/privacy-warning-view');
|
||||
var PasswordDialogView = require('./password-dialog-view');
|
||||
var TabPaneView = require('builder/components/tab-pane/tab-pane-view');
|
||||
var TabPaneCollection = require('builder/components/tab-pane/tab-pane-collection');
|
||||
var CustomListCollection = require('builder/components/custom-list/custom-list-collection');
|
||||
var ModalsServiceModel = require('builder/components/modals/modals-service-model');
|
||||
var template = require('./privacy-dropdown.tpl');
|
||||
var templateTabPane = require('./tab-pane.tpl');
|
||||
var TipsyTooltipView = require('builder/components/tipsy-tooltip-view');
|
||||
var VisDefinitionModel = require('builder/data/vis-definition-model');
|
||||
var checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
var ErrorDetailsView = require('builder/components/background-importer/error-details-view');
|
||||
|
||||
var ESCAPE_KEY_CODE = 27;
|
||||
|
||||
var REQUIRED_OPTS = [
|
||||
'visDefinitionModel',
|
||||
'userModel',
|
||||
'privacyCollection',
|
||||
'configModel',
|
||||
'isOwner'
|
||||
];
|
||||
|
||||
var PRIVACY_MAP = {
|
||||
public: 'green',
|
||||
link: 'orange',
|
||||
password: 'orange-dark',
|
||||
private: 'red'
|
||||
};
|
||||
|
||||
module.exports = CoreView.extend({
|
||||
|
||||
events: {
|
||||
'click .js-toggle': '_onToggleDialogClicked'
|
||||
},
|
||||
|
||||
initialize: function (opts) {
|
||||
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
|
||||
|
||||
if (this._visDefinitionModel.isVisualization() && !this.options.mapcapsCollection) {
|
||||
throw new Error('mapcapsCollection is required for visualizations');
|
||||
}
|
||||
|
||||
this._triggerElementID = 'toggle' + this.cid;
|
||||
|
||||
this._modals = new ModalsServiceModel();
|
||||
this.model = new Backbone.Model({
|
||||
privacy: opts.visDefinitionModel.get('privacy'),
|
||||
state: 'show'
|
||||
});
|
||||
|
||||
this._onEscapePressed = this._onEscapePressed.bind(this);
|
||||
this._onDocumentElementClicked = this._onDocumentElementClicked.bind(this);
|
||||
|
||||
if (this.options.ownerName) {
|
||||
this._ownerName = this.options.ownerName;
|
||||
}
|
||||
|
||||
if (this.options.mapcapsCollection) {
|
||||
this._mapcapsCollection = this.options.mapcapsCollection;
|
||||
}
|
||||
|
||||
this._configPrivacyCollection();
|
||||
this._configPanes();
|
||||
this._initBinds();
|
||||
},
|
||||
|
||||
render: function () {
|
||||
var privacy = this.model.get('privacy');
|
||||
if (this.model.get('state') === 'error') {
|
||||
privacy = this.options.visDefinitionModel.get('privacy');
|
||||
}
|
||||
var cssClass = PRIVACY_MAP[privacy.toLowerCase()];
|
||||
var canChangePrivacy = this._canChangePrivacy(privacy);
|
||||
|
||||
this.clearSubViews();
|
||||
this._hideDialog();
|
||||
this.$el.html(template({
|
||||
privacy: privacy,
|
||||
cssClass: cssClass,
|
||||
isLoading: this.model.get('state') === 'loading',
|
||||
isOwner: this._isOwner,
|
||||
canChangePrivacy: canChangePrivacy
|
||||
}));
|
||||
this._initViews();
|
||||
return this;
|
||||
},
|
||||
|
||||
_canChangePrivacy: function (privacy) {
|
||||
var isIndividualUser = this.options.userModel.isIndividualUser();
|
||||
var isMap = this.options.visDefinitionModel.isVisualization();
|
||||
var hasRemainingPublicMaps = this.options.userModel.hasRemainingPublicMaps();
|
||||
if (isIndividualUser && isMap && !hasRemainingPublicMaps && privacy === 'PRIVATE') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
_initBinds: function () {
|
||||
this._customCollection.on('change:selected', function (menuItem) {
|
||||
if (menuItem.get('disabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (menuItem.get('val') === 'password') {
|
||||
this._showPasswordDialog();
|
||||
} else {
|
||||
this._onToggleDialogClicked();
|
||||
this._setPrivacy(menuItem.get('val'));
|
||||
}
|
||||
}, this);
|
||||
|
||||
this.add_related_model(this._customCollection);
|
||||
|
||||
this.model.on('change:state', this.render, this);
|
||||
this.add_related_model(this.model); // explicit
|
||||
},
|
||||
|
||||
_makePrivacyDialog: function () {
|
||||
return new PrivacyDialogView({
|
||||
model: this.model,
|
||||
collection: this._customCollection,
|
||||
userModel: this._userModel,
|
||||
configModel: this._configModel
|
||||
});
|
||||
},
|
||||
|
||||
_makePasswordDialog: function () {
|
||||
return new PasswordDialogView({
|
||||
onBack: this._showPrivacyDialog.bind(this),
|
||||
onEdit: this._setPassword.bind(this)
|
||||
});
|
||||
},
|
||||
|
||||
_setPassword: function (password) {
|
||||
if (password !== '') {
|
||||
this._privacyCollection.passwordOption().set({
|
||||
password: password
|
||||
});
|
||||
|
||||
this.model.set({ password: password });
|
||||
this._setPrivacy('password');
|
||||
}
|
||||
},
|
||||
|
||||
_setPrivacy: function (privacyStatus) {
|
||||
var newPrivacyStatus = privacyStatus.toUpperCase();
|
||||
|
||||
this.model.set(
|
||||
{ privacy: newPrivacyStatus },
|
||||
{ silent: true }
|
||||
);
|
||||
|
||||
if (this._shouldShowPrivacyWarning(newPrivacyStatus)) {
|
||||
this._checkPrivacyChange(
|
||||
newPrivacyStatus,
|
||||
this._savePrivacy.bind(this),
|
||||
this._discardPrivacyChange.bind(this)
|
||||
);
|
||||
} else {
|
||||
this._savePrivacy();
|
||||
}
|
||||
},
|
||||
|
||||
_savePrivacy: function () {
|
||||
var self = this;
|
||||
var vis = this._visDefinitionModel;
|
||||
|
||||
this.model.set({ state: 'loading' });
|
||||
|
||||
this._privacyCollection.searchByPrivacy(this.model.get('privacy'))
|
||||
.saveToVis(vis, {
|
||||
success: function () {
|
||||
self.model.set({state: 'show'});
|
||||
},
|
||||
error: function (req, resp) {
|
||||
if (resp.responseText.indexOf('over account public map quota') !== -1) {
|
||||
self._modals.create(function () {
|
||||
return new ErrorDetailsView({
|
||||
error: { errorCode: 8007 },
|
||||
userModel: self._userModel,
|
||||
configModel: self._configModel
|
||||
});
|
||||
});
|
||||
}
|
||||
self.model.set({state: 'error'});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_checkPrivacyChange: function (newPrivacyStatus, confirmCallback, dismissCallback) {
|
||||
var self = this;
|
||||
|
||||
this._modals.create(function (modalModel) {
|
||||
return new PrivacyWarningView({
|
||||
modalModel: modalModel,
|
||||
privacyType: newPrivacyStatus,
|
||||
type: self._visDefinitionModel.isVisualization() ? 'visualization' : 'dataset',
|
||||
onConfirm: confirmCallback,
|
||||
onDismiss: dismissCallback
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_discardPrivacyChange: function () {
|
||||
var previousPrivacy = this.model.previous('privacy');
|
||||
|
||||
this.model.set('privacy', previousPrivacy, { silent: true });
|
||||
this.model.set('state', 'show');
|
||||
},
|
||||
|
||||
_shouldShowPrivacyWarning: function (privacyStatus) {
|
||||
if (!this._userModel.canSelectPremiumOptions(this._visDefinitionModel)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var isPubliclyAvailable = VisDefinitionModel.isPubliclyAvailable(privacyStatus);
|
||||
|
||||
if (this._visDefinitionModel.isVisualization()) {
|
||||
return !!this._mapcapsCollection.length && isPubliclyAvailable;
|
||||
}
|
||||
|
||||
return isPubliclyAvailable;
|
||||
},
|
||||
|
||||
_transformPrivacyOptions: function () {
|
||||
return this._privacyCollection.map(function (item) {
|
||||
return {
|
||||
label: item.get('title'),
|
||||
val: item.get('privacy').toLowerCase(),
|
||||
disabled: item.get('disabled'),
|
||||
selected: item.get('selected'),
|
||||
renderOptions: {
|
||||
cssClass: item.get('cssClass')
|
||||
}
|
||||
};
|
||||
}).filter(Boolean);
|
||||
},
|
||||
|
||||
_configPrivacyCollection: function () {
|
||||
var models = this._transformPrivacyOptions();
|
||||
this._customCollection = new CustomListCollection(models);
|
||||
},
|
||||
|
||||
_configPanes: function () {
|
||||
var self = this;
|
||||
var tabPaneTabs = [{
|
||||
createContentView: self._showNoneDialog
|
||||
}, {
|
||||
createContentView: self._makePrivacyDialog.bind(self)
|
||||
}, {
|
||||
createContentView: self._makePasswordDialog.bind(self)
|
||||
}];
|
||||
|
||||
this._collectionPane = new TabPaneCollection(tabPaneTabs);
|
||||
},
|
||||
|
||||
_showNoneDialog: function () {
|
||||
return false;
|
||||
},
|
||||
|
||||
_showPasswordDialog: function () {
|
||||
this._collectionPane.at(2).set({selected: true});
|
||||
},
|
||||
|
||||
_showPrivacyDialog: function () {
|
||||
this._customCollection.each(function (m) {
|
||||
m.set({selected: false}, {silent: true});
|
||||
});
|
||||
|
||||
this._collectionPane.at(1).set({selected: true});
|
||||
},
|
||||
|
||||
_onToggleDialogClicked: function () {
|
||||
if (this._isDialogVisible()) {
|
||||
this._hideDialog();
|
||||
} else {
|
||||
this._onMouseClick();
|
||||
this._initDocumentBinds();
|
||||
this._showPrivacyDialog();
|
||||
}
|
||||
},
|
||||
|
||||
_isDialogVisible: function () {
|
||||
return this._collectionPane.at(0).get('selected') === false;
|
||||
},
|
||||
|
||||
_hideDialog: function () {
|
||||
this._destroyDocumentBinds();
|
||||
this._collectionPane.at(0).set({selected: true});
|
||||
},
|
||||
|
||||
_showDialog: function () {
|
||||
this._showPrivacyDialog();
|
||||
},
|
||||
|
||||
_initViews: function () {
|
||||
var view = new TabPaneView({
|
||||
collection: this._collectionPane,
|
||||
template: templateTabPane,
|
||||
mouseOverAction: this._onMouseClick.bind(this)
|
||||
});
|
||||
this.$('.js-dialog').append(view.render().$el);
|
||||
this.addView(view);
|
||||
|
||||
this._privacyTooltip = new TipsyTooltipView({
|
||||
el: this.$('.js-tooltip'),
|
||||
gravity: 'w',
|
||||
html: true,
|
||||
title: function () {
|
||||
return this._getPrivacyInfo();
|
||||
}.bind(this)
|
||||
});
|
||||
this.addView(this._privacyTooltip);
|
||||
},
|
||||
|
||||
_getPrivacyInfo: function () {
|
||||
var privacyInfo = _t('change-privacy');
|
||||
|
||||
if (this._ownerName) {
|
||||
privacyInfo = _t('dataset.privacy.info', { name: this._ownerName });
|
||||
}
|
||||
|
||||
return privacyInfo;
|
||||
},
|
||||
|
||||
_initDocumentBinds: function () {
|
||||
$(document).on('keydown', this._onEscapePressed);
|
||||
$(document).on('mousedown', this._onDocumentElementClicked);
|
||||
},
|
||||
|
||||
_destroyDocumentBinds: function () {
|
||||
$(document).off('keydown', this._onEscapePressed);
|
||||
$(document).off('mousedown', this._onDocumentElementClicked);
|
||||
},
|
||||
|
||||
_onEscapePressed: function (ev) {
|
||||
if (ev.which === ESCAPE_KEY_CODE) {
|
||||
this._hideDialog();
|
||||
}
|
||||
},
|
||||
|
||||
_onDocumentElementClicked: function (ev) {
|
||||
var $el = $(ev.target);
|
||||
if ($el.closest(this.$el).length === 0 && $el.closest($('#' + this._triggerElementID)).length === 0) {
|
||||
this._hideDialog();
|
||||
}
|
||||
},
|
||||
|
||||
_onMouseClick: function () {
|
||||
this._privacyTooltip.hideTipsy();
|
||||
},
|
||||
|
||||
clean: function () {
|
||||
this._destroyDocumentBinds();
|
||||
CoreView.prototype.clean.apply(this);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user