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,89 @@
var _ = require('underscore');
var ContextMenuView = require('builder/components/context-menu/context-menu-view');
var CustomListCollection = require('builder/components/custom-list/custom-list-collection');
var REQUIRED_OPTS = [
'ev',
'isTableOwner',
'isSync',
'isCustomQuery',
'triggerElementID',
'canCreateDatasets'
];
module.exports = function (opts) {
var data = {};
_.each(REQUIRED_OPTS, function (item) {
if (opts[item] === undefined) throw new Error(item + ' is required');
data['_' + item] = opts[item];
});
var position = { x: data._ev.clientX, y: data._ev.clientY };
var menuItems = [
{
label: _t('dataset.duplicate.' + (data._isCustomQuery ? 'customOption' : 'option')),
val: 'duplicate',
action: function () {
this.trigger('duplicate');
},
disabled: !data._canCreateDatasets
}
];
if (data._isTableOwner) {
if (!data._isSync) {
menuItems.push({
label: _t('dataset.rename.option'),
val: 'rename',
action: function () {
this.trigger('rename');
}
});
}
menuItems = menuItems.concat([
{
label: _t('dataset.metadata.option'),
val: 'metadata',
action: function () {
this.trigger('metadata');
}
}, {
label: _t('dataset.lock.option'),
val: 'lock',
action: function () {
this.trigger('lock');
}
}, {
label: _t('dataset.delete.option'),
val: 'delete',
destructive: true,
action: function () {
this.trigger('delete');
}
}
]);
}
var collection = new CustomListCollection(menuItems);
var view = new ContextMenuView({
collection: collection,
triggerElementID: data._triggerElementID,
position: position
});
collection.bind('change:selected', function (menuItem) {
var action = menuItem.get('action');
action && action.bind(view)(menuItem);
}, view);
view.model.bind('change:visible', function (model, isContextMenuVisible) {
if (view && !isContextMenuVisible) {
collection.unbind(null, null, view);
view.model.unbind(null, null, view);
view.remove();
}
}, view);
return view;
};
@@ -0,0 +1,378 @@
var CoreView = require('backbone/core-view');
var template = require('./dataset-header.tpl');
var moment = require('moment');
var InlineEditorView = require('builder/components/inline-editor/inline-editor-view');
var TipsyTooltipView = require('builder/components/tipsy-tooltip-view');
var renameTableOperation = require('builder/dataset/operations/table-rename-operation');
var templateInlineEditor = require('./inline-editor.tpl');
var ConfirmationModalView = require('builder/components/modals/confirmation/modal-confirmation-view');
var RemoveDatasetModalView = require('builder/components/modals/remove-dataset/remove-dataset-view');
var PublishView = require('builder/components/modals/publish/publish-view');
var PrivacyDropdown = require('builder/components/privacy-dropdown/privacy-dropdown-view');
var PrivacyCollection = require('builder/components/modals/publish/privacy-collection');
var CreatePrivacyOptions = require('builder/components/modals/publish/create-privacy-options');
var ShareWith = require('builder/components/modals/publish/share-with-view');
var CreationModalView = require('builder/components/modals/creation/modal-creation-view');
var EditMetadataView = require('builder/components/modals/dataset-metadata/dataset-metadata-view');
var VisTableModel = require('builder/data/visualization-table-model');
var templateConfirmation = require('./rename-confirmation-modal.tpl');
var createContextMenu = require('./create-context-menu');
var tableDuplicationOperation = require('builder/dataset/operations/table-duplication-operation');
var checkAndBuildOpts = require('builder/helpers/required-opts');
var TITLE_SUFFIX = ' | 快点';
var PRIVACY_MAP = {
public: 'green',
link: 'orange',
private: 'red'
};
var REQUIRED_OPTS = [
'analysisDefinitionNodeModel',
'configModel',
'layerDefinitionModel',
'modals',
'router',
'userModel',
'visModel'
];
module.exports = CoreView.extend({
className: 'Editor-HeaderInfoEditor',
events: {
'click .js-options': '_showContextMenu'
},
initialize: function (opts) {
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
var privacyOptions = CreatePrivacyOptions(this._visModel, this._userModel);
this._querySchemaModel = this._analysisDefinitionNodeModel.querySchemaModel;
this._tableModel = this._analysisDefinitionNodeModel.getTableModel();
this._syncModel = this._tableModel.getSyncModel();
this._privacyCollection = new PrivacyCollection(privacyOptions);
this._setDocumentTitle();
this._initBinds();
},
render: function () {
this.clearSubViews();
var privacy = this._visModel.get('privacy');
this.$el.html(
template({
title: this._tableModel.getUnqualifiedName(),
privacy: privacy,
isOwner: this._isDatasetOwner(),
isCustomQueryApplied: this._isCustomQueryApplied(),
isSync: this._tableModel.isSync(),
syncState: this._syncModel.get('state'),
cssClass: PRIVACY_MAP[privacy.toLowerCase()],
ago: moment(this._visModel.get('updated_at')).fromNow(),
avatar: this._userModel.get('avatar_url'),
isInsideOrg: this._userModel.isInsideOrg(),
hasWriteAccess: this._hasWriteAccess()
})
);
this._initViews();
return this;
},
_hasWriteAccess: function () {
var permissionModel = this._tableModel._permissionModel;
return permissionModel.isOwner(this._userModel) || permissionModel.hasWriteAccess(this._userModel);
},
_initBinds: function () {
this.listenTo(this._syncModel, 'change:state change:interval destroy', this.render);
this.listenTo(this._visModel, 'change:name', this._onChangeName);
this.listenTo(this._visModel, 'change:privacy change:name', this.render);
this.listenTo(this._querySchemaModel, 'change:query', this.render);
},
_initViews: function () {
var isDatasetOwner = this._isDatasetOwner();
var toggleMenuTooltip = new TipsyTooltipView({
el: this.$('.js-toggle'),
gravity: 'w',
title: function () {
return this._isHidden() ? _t('editor.layers.options.show') : _t('editor.layers.options.hide');
}.bind(this)
});
this.addView(toggleMenuTooltip);
if (isDatasetOwner) {
if (this._tableModel.isSync()) {
var syncTooltip = new TipsyTooltipView({
el: this.$('.js-syncState'),
gravity: 'n',
title: function () {
return this._getSyncInfo();
}.bind(this)
});
this.addView(syncTooltip);
} else {
this._inlineEditor = new InlineEditorView({
template: templateInlineEditor,
renderOptions: {
name: this._tableModel.getUnqualifiedName()
},
onEdit: this._onRenameTable.bind(this)
});
this.$('.js-name').html(this._inlineEditor.render().el);
this.addView(this._inlineEditor);
}
if (this._userModel.isInsideOrg()) {
var shareWith = new ShareWith({
visDefinitionModel: this._visModel,
userModel: this._userModel,
separationClass: 'u-rSpace--m',
clickPrivacyAction: this._clickPrivacy.bind(this)
});
this.$('.js-share-users').append(shareWith.render().el);
this.addView(shareWith);
}
}
var privacyDropdown = new PrivacyDropdown({
privacyCollection: this._privacyCollection,
visDefinitionModel: this._visModel,
userModel: this._userModel,
configModel: this._configModel,
isOwner: isDatasetOwner,
ownerName: !isDatasetOwner && this._tableModel.getOwnerName()
});
this.$('.js-dropdown').append(privacyDropdown.render().el);
this.addView(privacyDropdown);
},
_showContextMenu: function (ev) {
var isSync = this._tableModel.isSync();
var triggerElementID = 'context-menu-trigger-' + this._tableModel.cid;
this.$('.js-options').attr('id', triggerElementID);
if (this._menuView && this._menuView.isVisible()) {
this._menuView.hide();
this._menuView.clean();
delete this._menuView;
return;
}
this._menuView = createContextMenu({
ev: ev,
isTableOwner: this._isDatasetOwner(),
isCustomQuery: this._isCustomQueryApplied(),
isSync: isSync,
triggerElementID: triggerElementID,
canCreateDatasets: this._userModel.canCreateDatasets()
});
this._menuView.bind('rename', function () {
this._inlineEditor && this._inlineEditor.edit();
}, this);
this._menuView.bind('delete', this._deleteDataset, this);
this._menuView.bind('duplicate', this._duplicateDataset, this);
this._menuView.bind('lock', this._lockDataset, this);
this._menuView.bind('metadata', this._metadataDataset, this);
this._menuView.show();
this.addView(this._menuView);
},
_deleteDataset: function () {
var self = this;
this._modals.create(function (modalModel) {
return new RemoveDatasetModalView({
modalModel: modalModel,
userModel: self._userModel,
visModel: self._visModel,
tableModel: self._tableModel,
configModel: self._configModel
});
});
},
_duplicateDataset: function () {
var self = this;
var tableName = this._tableModel.getUnquotedName();
var name = this._isCustomQueryApplied() ? _t('dataset.duplicate.query') : tableName;
this._modals.create(function (modalModel) {
return new CreationModalView({
modalModel: modalModel,
loadingTitle: _t('dataset.duplicate.loading', { name: name }),
errorTitle: _t('dataset.duplicate.error', { name: name }),
runAction: function (opts) {
tableDuplicationOperation({
query: self._querySchemaModel.get('query'),
tableModel: self._tableModel,
configModel: self._configModel,
onSuccess: function (importModel) {
var tableName = importModel.get('table_name');
var visTableModel = new VisTableModel({
id: tableName,
table: {
name: tableName
}
}, {
configModel: self._configModel
});
window.location = visTableModel.datasetURL();
},
onError: function (importModel) {
var error = importModel.get('get_error_text');
var errorMessage = error && error.title;
opts.error && opts.error(errorMessage);
}
});
}
});
}, {
escapeOptionsDisabled: true
});
},
_lockDataset: function () {
var self = this;
var tableName = this._tableModel.getUnquotedName();
this._modals.create(function (modalModel) {
return new CreationModalView({
modalModel: modalModel,
loadingTitle: _t('dataset.lock.loading', { tableName: tableName }),
errorTitle: _t('dataset.lock.error', { tableName: tableName }),
runAction: function (opts) {
self._visModel.save({
locked: true
}, {
wait: true,
success: function () {
window.location = self._configModel.get('base_url') + '/dashboard/datasets';
},
error: function () {
opts.error && opts.error();
}
});
}
});
});
},
_metadataDataset: function () {
var isLocked = this._tableModel.isSync();
var self = this;
this._modals.create(function (modalModel) {
return new EditMetadataView({
modalModel: modalModel,
visDefinitionModel: self._visModel,
configModel: self._configModel,
isLocked: isLocked
});
});
},
_onRenameTable: function (newName) {
var self = this;
this._inlineEditor.hide();
if (newName === this._visModel.get('name')) {
return;
}
this._modals.create(function (modalModel) {
return new ConfirmationModalView({
modalModel: modalModel,
template: templateConfirmation,
renderOpts: {
tableName: self._visModel.get('name')
},
runAction: function () {
modalModel.destroy();
renameTableOperation({
visModel: self._visModel,
newName: newName,
onError: self._onRenameFailed.bind(self)
});
}
});
});
},
_onRenameFailed: function () {
this._visModel.set('name', this._visModel.previous('name'), { silent: true });
this.render();
},
_onChangeName: function () {
var name = this._visModel.get('name');
this._analysisDefinitionNodeModel.setTableName(name);
this._setDocumentTitle();
this._layerDefinitionModel.save({
sql: this._analysisDefinitionNodeModel.getDefaultQuery()
});
this._router.navigate(name, {
replace: true
});
},
_getSyncInfo: function () {
var state = this._syncModel.get('state');
if (state === 'success') {
return _t('dataset.sync.synced', { ranAt: moment(this._syncModel.get('ran_at') || new Date()).fromNow() });
} else if (state === 'failure') {
var errorCode = this._syncModel.get('error_code');
var errorMessage = this._syncModel.get('error_message');
return _t('dataset.sync.error-code', { errorCode: errorCode }) + ':' + errorMessage;
} else {
return _t('dataset.sync.syncing');
}
},
_clickPrivacy: function () {
var self = this;
this._modals.create(function (modalModel) {
return new PublishView({
mapcapsCollection: self._mapcapsCollection,
modalModel: modalModel,
visDefinitionModel: self._visModel,
privacyCollection: self._privacyCollection,
userModel: self._userModel,
configModel: self._configModel,
mode: 'share',
isOwner: self._isDatasetOwner()
});
});
},
_setDocumentTitle: function () {
document.title = this._tableModel.get('name') + TITLE_SUFFIX;
},
_isCustomQueryApplied: function () {
return this._analysisDefinitionNodeModel.isCustomQueryApplied();
},
_isEditable: function () {
return !this._analysisDefinitionNodeModel.isReadOnly();
},
_isDatasetOwner: function () {
return this._tableModel.isOwner(this._userModel);
}
});
@@ -0,0 +1,39 @@
<div class="Editor-HeaderInfo-inner">
<div class="Editor-HeaderInfo-title u-bSpace--m u-flex u-alignCenter">
<% if (isSync && isOwner) { %>
<div class="Editor-HeaderInfo-actions">
<span class="SyncInfo-state SyncInfo-state--<%- syncState %> u-rSpace--m js-syncState"></span>
</div>
<% } %>
<div class="Editor-HeaderInfo-titleText is-larger js-name">
<h2 class="u-ellipsis CDB-Text CDB-Size-huge is-light"><%- title %></h2>
</div>
<div class="Editor-HeaderInfo-details u-lSpace">
<% if (!hasWriteAccess) { %>
<span class="Tag CDB-Text CDB-Size-small u-rSpace u-upperCase js-readPermissionTag"><%- _t('dataset.read') %></span>
<% } %>
<% if (isCustomQueryApplied) { %>
<span class="Tag Tag--outline Tag-outline--dark CDB-Text CDB-Size-small u-secondaryTextColor u-rSpace"><%- _t('dataset.sql') %></span>
<% } %>
<button class="CDB-Shape js-options">
<div class="CDB-Shape-threePoints is-blue is-small">
<div class="CDB-Shape-threePointsItem"></div>
<div class="CDB-Shape-threePointsItem"></div>
<div class="CDB-Shape-threePointsItem"></div>
</div>
</button>
</div>
</div>
<div class="u-bSpace--xl u-flex u-alignCenter">
<div class="js-dropdown u-rSpace--m"></div>
<% if (isOwner && isInsideOrg) { %>
<div class="js-share-users"></div>
<% } %>
<span class="CDB-Text CDB-Size-medium u-altTextColor"><%- _t('dataset.updated', { ago: ago }) %></span>
</div>
</div>
@@ -0,0 +1,4 @@
<div class="Inline-editor" title="<%- name %>">
<h2 class="CDB-Text CDB-Size-huge is-light u-ellipsis js-title Inline-editor-text is-larger"><%- name %></h2>
<input type="text" name="text" class="Inline-editor-input Inline-editor-input--small CDB-Text CDB-InputText js-input" value="<%- name %>" readonly>
</div>
@@ -0,0 +1,31 @@
<div class="u-flex u-justifyCenter">
<div class="Modal-inner Modal-inner--grid u-flex u-justifyCenter">
<div class="Modal-icon">
<svg width="12px" height="23px" viewBox="0 0 12 23" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M3.85948829,15.9093411 L3.85948829,15.113874 C3.85948829,13.9648603 4.03625698,13.0196388 4.38979966,12.2781813 C4.74334234,11.5367237 5.40131468,10.7535402 6.36373642,9.92860729 C7.6993421,8.79923484 8.54144849,7.94976308 8.89008086,7.38016654 C9.23871322,6.81057 9.41302679,6.12313622 9.41302679,5.31784456 C9.41302679,4.3161403 9.09140598,3.54277728 8.44815472,2.99773232 C7.80490345,2.45268735 6.87932296,2.18016896 5.67138547,2.18016896 C4.8955557,2.18016896 4.13937853,2.27100842 3.40283128,2.45269008 C2.66628403,2.63437173 1.82172252,2.96581302 0.869121409,3.44702389 L0,1.45835626 C1.85609907,0.486113893 3.7956444,0 5.81869418,0 C7.69443451,0 9.15277619,0.461562686 10.193763,1.38470191 C11.2347497,2.30784113 11.7552353,3.60905508 11.7552353,5.28838281 C11.7552353,6.0052888 11.6594856,6.63625482 11.4679833,7.18129978 C11.2764811,7.72634475 10.9941422,8.24192009 10.6209582,8.72804127 C10.2477743,9.21416246 9.44249472,9.99734595 8.20509534,11.0776153 C7.21321171,11.9221894 6.55769449,12.6243539 6.23852401,13.1841299 C5.91935354,13.7439058 5.7597707,14.4902624 5.7597707,15.4232223 L5.7597707,15.9093411 L3.85948829,15.9093411 Z M2.95990869,20.3988536 C2.95990869,19.3235103 3.49337277,18.7858468 4.56031694,18.7858468 C5.07600662,18.7858468 5.47388191,18.9242161 5.75395476,19.2009588 C6.0340276,19.4777016 6.17406192,19.8769958 6.17406192,20.3988536 C6.17406192,20.9048974 6.03180483,21.2982616 5.74728639,21.5789578 C5.46276794,21.859654 5.06711542,22 4.56031694,22 C4.09797446,22 3.71565854,21.8754676 3.41335769,21.6263992 C3.11105685,21.3773307 2.95990869,20.9681529 2.95990869,20.3988536 Z" stroke="none" fill="#FEB100" fill-rule="evenodd" opacity="1"></path>
</svg>
</div>
<div>
<h2 class=" CDB-Text CDB-Size-huge is-light u-bSpace--xl">
<%- _t('dataset.rename.title', { tableName: tableName }) %>
</h2>
<p class="CDB-Text CDB-Size-large u-altTextColor"><%- _t('dataset.rename.desc') %></p>
<ul class="Modal-listActions u-flex u-alignCenter">
<li class="Modal-listActionsitem">
<button class="CDB-Button CDB-Button--secondary CDB-Button--big js-cancel">
<span class="CDB-Button-Text CDB-Text is-semibold CDB-Size-medium u-upperCase">
<%- _t('dataset.rename.cancel') %>
</span>
</button>
</li>
<li class="Modal-listActionsitem">
<button class="CDB-Button CDB-Button--primary CDB-Button--big js-confirm">
<span class="CDB-Button-Text CDB-Text is-semibold CDB-Size-medium u-upperCase">
<%- _t('dataset.rename.confirm') %>
</span>
</button>
</li>
</ul>
</div>
</div>
</div>