Initial commit

This commit is contained in:
zhongjin
2020-06-15 10:58:47 +08:00
commit 4f1dfe7564
8590 changed files with 1516878 additions and 0 deletions
@@ -0,0 +1,51 @@
var CoreView = require('backbone/core-view');
var template = require('./password-dialog.tpl');
var _ = require('underscore');
var REQUIRED_OPTS = [
'onBack',
'onEdit'
];
var ESCAPE_KEY_CODE = 27;
var ENTER_KEY_CODE = 13;
module.exports = CoreView.extend({
className: 'Editor-boxModal Editor-PrivacyDialog',
events: {
'click .js-back': '_onClickBack',
'keyup .js-input': '_onKeyUpInput'
},
initialize: function (opts) {
_.each(REQUIRED_OPTS, function (item) {
if (opts[item] === undefined) throw new Error(item + ' is required');
this['_' + item] = opts[item];
}, this);
},
render: function () {
this.$el.empty();
this.$el.html(template());
return this;
},
_onKeyUpInput: function (e) {
if (e.which === ESCAPE_KEY_CODE) {
this._onBack();
}
if (e.which === ENTER_KEY_CODE) {
this._onEdit && this._onEdit(this.getValue());
}
},
_onClickBack: function () {
this._onBack();
},
getValue: function () {
return this.$('.js-input').val();
}
});
@@ -0,0 +1,17 @@
<div class="CDB-Box-modalHeader">
<ul class="CDB-Box-modalHeaderItem CDB-Box-modalHeaderItem--block CDB-Box-modalHeaderItem--paddingHorizontal">
<li class="CDB-ListDecoration-item CDB-ListDecoration-itemPadding--vertical">
<button class="u-actionTextColor js-back CDB-Size-medium u-rSpace">
<i class="CDB-IconFont CDB-IconFont-arrowPrev"></i>
</button>
<span class="CDB-Text CDB-Size-medium">
<%- _t('components.modals.publish.privacy.password.title') %>
</span>
</li>
</ul>
</div>
<ul class="CustomList-list js-customList">
<li class="Privacy-passwordField CustomList-item">
<input type="password" class="CDB-Text CDB-InputText js-input" placeholder="<%- _t('components.modals.publish.privacy.password.placeholder') %>">
</li>
</ul>
@@ -0,0 +1,13 @@
<div class="Privacy-cta u-flex">
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M10.0946667,4.4109223 C10.8886667,4.1368747 11.6846667,3.80147316 12.0073333,3.4715253 C12.7866667,2.67392407 12.7866667,1.37662907 12.0073333,0.579027844 C11.2513333,-0.193350099 9.934,-0.192668389 9.17866667,0.579027844 C8.74133333,1.0262299 8.29266667,2.36033726 8,3.37608583 C7.70666667,2.36033726 7.25866667,1.0262299 6.82133333,0.579027844 C6.066,-0.193350099 4.748,-0.192668389 3.99266667,0.579027844 C3.21266667,1.37662907 3.21266667,2.67392407 3.99266667,3.4715253 C4.316,3.80147316 5.11133333,4.1368747 5.90533333,4.4109223 L0.333333333,4.4109223 C0.149333333,4.4109223 0,4.56362544 0,4.75177753 L0,7.47861934 C0,7.66677142 0.149333333,7.81947456 0.333333333,7.81947456 L0.666666667,7.81947456 L0.666666667,15.6591448 C0.666666667,15.8472969 0.816,16 1,16 L15,16 C15.184,16 15.3333333,15.8472969 15.3333333,15.6591448 L15.3333333,7.81947456 L15.6666667,7.81947456 C15.8506667,7.81947456 16,7.66677142 16,7.47861934 L16,4.75177753 C16,4.56362544 15.8506667,4.4109223 15.6666667,4.4109223 L10.0946667,4.4109223 Z M6,6.95652174 L6,4.86956522 L10,4.86956522 L10,6.95652174 L6,6.95652174 L6,6.95652174 Z M10,7.65217391 L10,15.3043478 L6,15.3043478 L6,7.65217391 L10,7.65217391 L10,7.65217391 Z M9.80833133,1.08822938 C10.0510474,0.834996985 10.3727426,0.695652174 10.7169115,0.695652174 C11.0597961,0.695652174 11.3821334,0.834996985 11.6248495,1.08755946 C12.1250502,1.6101025 12.1250502,2.46023983 11.6248495,2.98278288 C11.2729754,3.34990286 9.79227867,3.85636766 8.66666667,4.17391304 C8.97102496,2.99953105 9.45581507,1.45534937 9.80833133,1.08822938 L9.80833133,1.08822938 Z M4.37515049,1.08822938 C4.6178666,0.834996985 4.94020387,0.695652174 5.28373064,0.695652174 C5.6266153,0.695652174 5.94895256,0.834996985 6.19166867,1.08755946 C6.54354282,1.45467944 7.02833293,2.99886112 7.33333333,4.17391304 C6.20707922,3.85569773 4.72638253,3.34990286 4.37515049,2.98278288 C3.87494984,2.46090976 3.87494984,1.61077243 4.37515049,1.08822938 L4.37515049,1.08822938 Z M0.666666667,4.86956522 L5.33333333,4.86956522 L5.33333333,6.95652174 L1,6.95652174 L0.666666667,6.95652174 L0.666666667,4.86956522 L0.666666667,4.86956522 Z M1.33333333,7.65217391 L5.33333333,7.65217391 L5.33333333,15.3043478 L1.33333333,15.3043478 L1.33333333,7.65217391 L1.33333333,7.65217391 Z M14.6666667,15.3043478 L10.6666667,15.3043478 L10.6666667,7.65217391 L14.6666667,7.65217391 L14.6666667,15.3043478 L14.6666667,15.3043478 Z M15.3333333,6.95652174 L15,6.95652174 L10.6666667,6.95652174 L10.6666667,4.86956522 L15.3333333,4.86956522 L15.3333333,6.95652174 L15.3333333,6.95652174 Z" id="Shape" fill="#9BC63B"></path>
</g>
</svg>
<div class="CDB-Text CDB-Size CDB-Size-small u-lSpace--xl">
<h3 class="u-secondaryTextColor"><%- _t('components.modals.publish.privacy.cta.title') %></h3>
<a href="<%- upgradeURL %>">
<%- _t( 'components.modals.publish.privacy.cta.desc-' + (showTrial ? 'trial' : 'notrial') ) %>
</a>
</div>
</div>
@@ -0,0 +1,53 @@
var CoreView = require('backbone/core-view');
var CustomListView = require('builder/components/custom-list/custom-list-view');
var CustomListItemView = require('builder/components/custom-list/custom-list-item-view');
var privacyCTATemplate = require('./privacy-cta.tpl');
var _ = require('underscore');
var REQUIRED_OPTS = [
'model',
'collection',
'userModel',
'configModel'
];
module.exports = CoreView.extend({
className: 'Editor-boxModal Privacy-dialog',
initialize: function (opts) {
_.each(REQUIRED_OPTS, function (item) {
if (opts[item] === undefined) throw new Error(item + ' is required');
this['_' + item] = opts[item];
}, this);
},
render: function () {
this.$el.empty();
this.clearSubViews();
this._renderList();
return this;
},
_renderList: function () {
var disabledOptions = this._collection.where({ disabled: true });
var customInstall = this._configModel.get('cartodb_com_hosted');
var upgradeURL = this._configModel.get('upgrade_url');
var listView = new CustomListView({
model: this._model,
collection: this._collection,
itemView: CustomListItemView
});
this.$el.append(listView.render().el);
this.addView(listView);
if (disabledOptions.length > 0 && !customInstall && upgradeURL) {
this.$el.append(
privacyCTATemplate({
upgradeURL: upgradeURL,
showTrial: this._userModel.canStartTrial()
})
);
}
}
});
@@ -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);
}
});
@@ -0,0 +1,15 @@
<div class="Privacy-dropdown">
<button class="Privacy-dropdownTrigger Tag Tag-fill Tag-fill--<%- cssClass %> CDB-Text CDB-Size-small u-upperCase js-tooltip <% if (isOwner && canChangePrivacy) { %>js-toggle<% } else { %>is-disabled<% } %>">
<% if (isLoading) { %>
<div class="CDB-LoaderIcon CDB-LoaderIcon--small u-flex">
<svg class="CDB-LoaderIcon-spinner" viewBox="0 0 50 50">
<circle class="CDB-LoaderIcon-path" cx="25" cy="25" r="20" fill="none"></circle>
</svg>
</div>
<% } else { %>
<%- privacy %>
<% } %>
</button>
<div class="js-dialog"></div>
</div>
@@ -0,0 +1 @@
<div class="Tab-paneContent js-content"></div>