Merge pull request #756 from ONLYOFFICE/feature/pe-history

Feature/pe history
This commit is contained in:
Julia Radzhabova 2021-03-26 11:34:34 +03:00 committed by GitHub
commit e17185db32
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 344 additions and 21 deletions

View file

@ -413,9 +413,11 @@ define([
SetDisabled: function(disable) {
var _btn_save = this.getButton('save'),
_btn_rename = this.getButton('rename');
_btn_rename = this.getButton('rename'),
_btn_protect = this.getButton('protect');
_btn_save[(disable || !this.mode.isEdit)?'hide':'show']();
_btn_protect[(disable || !this.mode.isEdit)?'hide':'show']();
_btn_rename[(disable || !this.mode.canRename || this.mode.isDesktopApp) ?'hide':'show']();
},
@ -440,7 +442,7 @@ define([
} else
if (type == 'rename') {
return this.miRename;
}else
}else
if (type == 'protect') {
return this.miProtect;
}

View file

@ -54,6 +54,8 @@ require.config({
jmousewheel : '../vendor/perfect-scrollbar/src/jquery.mousewheel',
xregexp : '../vendor/xregexp/xregexp-all-min',
sockjs : '../vendor/sockjs/sockjs.min',
jszip : '../vendor/jszip/jszip.min',
jsziputils : '../vendor/jszip-utils/jszip-utils.min',
allfonts : '../../sdkjs/common/AllFonts',
sdk : '../../sdkjs/slide/sdk-all-min',
api : 'api/documents/api',
@ -106,7 +108,9 @@ require.config({
'underscore',
'allfonts',
'xregexp',
'sockjs'
'sockjs',
'jszip',
'jsziputils'
]
},
gateway: {
@ -148,7 +152,8 @@ require([
'RightMenu',
'LeftMenu',
'Main',
'Common.Controllers.Fonts'
'Common.Controllers.Fonts',
'Common.Controllers.History'
/** coauthoring begin **/
, 'Common.Controllers.Chat'
,'Common.Controllers.Comments'
@ -179,7 +184,8 @@ require([
'presentationeditor/main/app/view/SignatureSettings',
'common/main/lib/util/utils',
'common/main/lib/util/LocalStorage',
'common/main/lib/controller/Fonts'
'common/main/lib/controller/Fonts',
'common/main/lib/controller/History'
/** coauthoring begin **/
,'common/main/lib/controller/Comments',
'common/main/lib/controller/Chat',

View file

@ -62,7 +62,11 @@ define([
'hide': _.bind(this.onHideChat, this)
},
'Common.Views.Header': {
'file:settings': _.bind(this.clickToolbarSettings,this)
'file:settings': _.bind(this.clickToolbarSettings,this),
'history:show': function () {
if ( !this.leftMenu.panelHistory.isVisible() )
this.clickMenuFileItem('header', 'history');
}.bind(this)
},
'Common.Views.Plugins': {
'plugin:open': _.bind(this.onPluginOpen, this),
@ -106,6 +110,10 @@ define([
}
});
Common.NotificationCenter.on('leftmenu:change', _.bind(this.onMenuChange, this));
Common.NotificationCenter.on('collaboration:history', _.bind(function () {
if ( !this.leftMenu.panelHistory.isVisible() )
this.clickMenuFileItem(null, 'history');
}, this));
},
onLaunch: function() {
@ -159,6 +167,8 @@ define([
this.api.asc_registerCallback('asc_onCountPages', _.bind(this.onApiCountPages, this));
this.onApiCountPages(this.api.getCountPages());
this.leftMenu.getMenu('file').setApi(api);
if (this.mode.canUseHistory)
this.getApplication().getController('Common.Controllers.History').setApi(this.api).setMode(this.mode);
return this;
},
@ -192,6 +202,9 @@ define([
this.leftMenu.btnChat.hide();
this.leftMenu.btnComments.hide();
}
if (this.mode.canUseHistory)
this.leftMenu.setOptionsPanel('history', this.getApplication().getController('Common.Controllers.History').getView('Common.Views.History'));
(this.mode.trialMode || this.mode.isBeta) && this.leftMenu.setDeveloperMode(this.mode.trialMode, this.mode.isBeta, this.mode.buildVersion);
/** coauthoring end **/
Common.util.Shortcuts.resumeEvents();
@ -237,10 +250,34 @@ define([
}
})).show();
break;
default: close_menu = false;
case 'history':
if (!this.leftMenu.panelHistory.isVisible()) {
if (this.api.isDocumentModified()) {
var me = this;
this.api.asc_stopSaving();
Common.UI.warning({
closable: false,
width: 500,
title: this.notcriticalErrorTitle,
msg: this.leavePageText,
buttons: ['ok', 'cancel'],
primary: 'ok',
callback: function(btn) {
if (btn == 'ok') {
me.api.asc_undoAllChanges();
me.showHistory();
} else
me.api.asc_continueSaving();
}
});
} else
this.showHistory();
}
break;
default: close_menu = false;
}
if (close_menu) {
if (close_menu && menu) {
menu.hide();
}
},
@ -518,7 +555,7 @@ define([
if (panel == 'thumbs') {
this.isThumbsShown = show;
} else {
if (!show && this.isThumbsShown && !this.leftMenu._state.pluginIsRunning) {
if (!show && this.isThumbsShown && !this.leftMenu._state.pluginIsRunning && !this.leftMenu._state.historyIsRunning) {
this.leftMenu.btnThumbs.toggle(true, false);
}
}
@ -713,12 +750,40 @@ define([
}
},
showHistory: function() {
var maincontroller = PE.getController('Main');
if (!maincontroller.loadMask)
maincontroller.loadMask = new Common.UI.LoadMask({owner: $('#viewport')});
maincontroller.loadMask.setTitle(this.textLoadHistory);
maincontroller.loadMask.show();
Common.Gateway.requestHistory();
},
SetDisabled: function(disable, disableFileMenu) {
this.mode.isEdit = !disable;
if (disable) this.leftMenu.close();
/** coauthoring begin **/
this.leftMenu.btnComments.setDisabled(disable);
var comments = this.getApplication().getController('Common.Controllers.Comments');
if (comments)
comments.setPreviewMode(disable);
this.setPreviewMode(disable);
this.leftMenu.btnChat.setDisabled(disable);
/** coauthoring end **/
this.leftMenu.btnPlugins.setDisabled(disable);
this.leftMenu.btnThumbs.setDisabled(disable);
if (disableFileMenu) this.leftMenu.getMenu('file').SetDisabled(disable);
},
textNoTextFound : 'Text not found',
newDocumentTitle : 'Unnamed document',
requestEditRightsText : 'Requesting editing rights...',
notcriticalErrorTitle: 'Warning',
txtUntitled: 'Untitled',
textReplaceSuccess : 'Search has been done. {0} occurrences have been replaced',
textReplaceSkipped : 'The replacement has been made. {0} occurrences were skipped.'
textReplaceSkipped : 'The replacement has been made. {0} occurrences were skipped.',
textLoadHistory : 'Loading version history...',
leavePageText: 'All unsaved changes in this document will be lost.<br> Click \'Cancel\' then \'Save\' to save them. Click \'OK\' to discard all the unsaved changes.'
}, PE.Controllers.LeftMenu || {}));
});

View file

@ -84,7 +84,8 @@ define([
'ShapeGroups',
'SlideLayouts',
'EquationGroups',
'Common.Collections.TextArt'
'Common.Collections.TextArt',
'Common.Collections.HistoryUsers'
],
views: [],
@ -869,6 +870,7 @@ define([
Common.Gateway.on('processmouse', _.bind(me.onProcessMouse, me));
Common.Gateway.on('downloadas', _.bind(me.onDownloadAs, me));
Common.Gateway.on('setfavorite', _.bind(me.onSetFavorite, me));
Common.Gateway.on('refreshhistory', _.bind(me.onRefreshHistory, me));
Common.Gateway.sendInfo({mode:me.appOptions.isEdit?'edit':'view'});
@ -956,9 +958,12 @@ define([
var app = this.getApplication();
if (this.appOptions.canEdit && this.editorConfig.mode !== 'view') {
app.getController('RightMenu').getView('RightMenu').clearSelection();
app.getController('Toolbar').DisableToolbar(disable);
app.getController('RightMenu').SetDisabled(disable, false);
app.getController('Statusbar').getView('Statusbar').SetDisabled(disable);
}
app.getController('LeftMenu').SetDisabled(disable, true);
app.getController('Toolbar').DisableToolbar(disable);
app.getController('Common.Controllers.ReviewChanges').SetDisabled(disable);
},
onOpenDocument: function(progress) {
@ -1025,6 +1030,14 @@ define([
this.appOptions.canHelp = !((typeof (this.editorConfig.customization) == 'object') && this.editorConfig.customization.help===false);
this.appOptions.isRestrictedEdit = !this.appOptions.isEdit && this.appOptions.canComments;
this.appOptions.canUseHistory = this.appOptions.canLicense && this.editorConfig.canUseHistory && this.appOptions.canCoAuthoring && !this.appOptions.isOffline;
this.appOptions.canHistoryClose = this.editorConfig.canHistoryClose;
this.appOptions.canHistoryRestore= this.editorConfig.canHistoryRestore;
if ( this.appOptions.isLightVersion ) {
this.appOptions.canUseHistory = false;
}
this.appOptions.canBranding = params.asc_getCustomization();
if (this.appOptions.canBranding)
appHeader.setBranding(this.editorConfig.customization);
@ -2118,6 +2131,156 @@ define([
this._renameDialog.show(Common.Utils.innerWidth() - this._renameDialog.options.width - 15, 30);
},
onRefreshHistory: function(opts) {
if (!this.appOptions.canUseHistory) return;
this.loadMask && this.loadMask.hide();
if (opts.data.error || !opts.data.history) {
var historyStore = this.getApplication().getCollection('Common.Collections.HistoryVersions');
if (historyStore && historyStore.size()>0) {
historyStore.each(function(item){
item.set('canRestore', false);
});
}
Common.UI.alert({
title: this.notcriticalErrorTitle,
msg: (opts.data.error) ? opts.data.error : this.txtErrorLoadHistory,
iconCls: 'warn',
buttons: ['ok'],
callback: _.bind(function(btn){
this.onEditComplete();
}, this)
});
} else {
this.api.asc_coAuthoringDisconnect();
appHeader.setCanRename(false);
appHeader.getButton('users') && appHeader.getButton('users').hide();
this.getApplication().getController('LeftMenu').getView('LeftMenu').showHistory();
this.disableEditing(true);
var versions = opts.data.history,
historyStore = this.getApplication().getCollection('Common.Collections.HistoryVersions'),
currentVersion = null;
if (historyStore) {
var arrVersions = [], ver, version, group = -1, prev_ver = -1, arrColors = [], docIdPrev = '',
usersStore = this.getApplication().getCollection('Common.Collections.HistoryUsers'), user = null, usersCnt = 0;
for (ver=versions.length-1; ver>=0; ver--) {
version = versions[ver];
if (version.versionGroup===undefined || version.versionGroup===null)
version.versionGroup = version.version;
if (version) {
if (!version.user) version.user = {};
docIdPrev = (ver>0 && versions[ver-1]) ? versions[ver-1].key : version.key + '0';
user = usersStore.findUser(version.user.id);
if (!user) {
user = new Common.Models.User({
id : version.user.id,
username : version.user.name,
colorval : Asc.c_oAscArrUserColors[usersCnt],
color : this.generateUserColor(Asc.c_oAscArrUserColors[usersCnt++])
});
usersStore.add(user);
}
arrVersions.push(new Common.Models.HistoryVersion({
version: version.versionGroup,
revision: version.version,
userid : version.user.id,
username : version.user.name,
usercolor: user.get('color'),
created: version.created,
docId: version.key,
markedAsVersion: (group!==version.versionGroup),
selected: (opts.data.currentVersion == version.version),
canRestore: this.appOptions.canHistoryRestore && (ver < versions.length-1),
isExpanded: true,
serverVersion: version.serverVersion
}));
if (opts.data.currentVersion == version.version) {
currentVersion = arrVersions[arrVersions.length-1];
}
group = version.versionGroup;
if (prev_ver!==version.version) {
prev_ver = version.version;
arrColors.reverse();
for (i=0; i<arrColors.length; i++) {
arrVersions[arrVersions.length-i-2].set('arrColors',arrColors);
}
arrColors = [];
}
arrColors.push(user.get('colorval'));
var changes = version.changes, change, i;
if (changes && changes.length>0) {
arrVersions[arrVersions.length-1].set('docIdPrev', docIdPrev);
if (!_.isEmpty(version.serverVersion) && version.serverVersion == this.appOptions.buildVersion) {
arrVersions[arrVersions.length-1].set('changeid', changes.length-1);
arrVersions[arrVersions.length-1].set('hasChanges', changes.length>1);
for (i=changes.length-2; i>=0; i--) {
change = changes[i];
user = usersStore.findUser(change.user.id);
if (!user) {
user = new Common.Models.User({
id : change.user.id,
username : change.user.name,
colorval : Asc.c_oAscArrUserColors[usersCnt],
color : this.generateUserColor(Asc.c_oAscArrUserColors[usersCnt++])
});
usersStore.add(user);
}
arrVersions.push(new Common.Models.HistoryVersion({
version: version.versionGroup,
revision: version.version,
changeid: i,
userid : change.user.id,
username : change.user.name,
usercolor: user.get('color'),
created: change.created,
docId: version.key,
docIdPrev: docIdPrev,
selected: false,
canRestore: this.appOptions.canHistoryRestore && this.appOptions.canDownload,
isRevision: false,
isVisible: true,
serverVersion: version.serverVersion
}));
arrColors.push(user.get('colorval'));
}
}
} else if (ver==0 && versions.length==1) {
arrVersions[arrVersions.length-1].set('docId', version.key + '1');
}
}
}
if (arrColors.length>0) {
arrColors.reverse();
for (i=0; i<arrColors.length; i++) {
arrVersions[arrVersions.length-i-1].set('arrColors',arrColors);
}
arrColors = [];
}
historyStore.reset(arrVersions);
if (currentVersion===null && historyStore.size()>0) {
currentVersion = historyStore.at(0);
currentVersion.set('selected', true);
}
if (currentVersion)
this.getApplication().getController('Common.Controllers.History').onSelectRevision(null, null, currentVersion);
}
}
},
DisableVersionHistory: function() {
this.editorConfig.canUseHistory = false;
this.appOptions.canUseHistory = false;
},
generateUserColor: function(color) {
return"#"+("000000"+color.toString(16)).substr(-6);
},
// Translation
leavePageText: 'You have unsaved changes in this document. Click \'Stay on this Page\' then \'Save\' to save them. Click \'Leave this Page\' to discard all the unsaved changes.',
criticalErrorTitle: 'Error',
@ -2480,7 +2643,8 @@ define([
textRenameLabel: 'Enter a name to be used for collaboration',
textRenameError: 'User name must not be empty.',
textLongName: 'Enter a name that is less than 128 characters.',
textGuest: 'Guest'
textGuest: 'Guest',
txtErrorLoadHistory: 'Loading history failed'
}
})(), PE.Controllers.Main || {}))
});

View file

@ -146,12 +146,16 @@ define([
Common.NotificationCenter.on('layout:changed', _.bind(this.onLayoutChanged, this));
$(window).on('resize', _.bind(this.onWindowResize, this));
var leftPanel = $('#left-menu');
var leftPanel = $('#left-menu'),
histPanel = $('#left-panel-history');
this.viewport.hlayout.on('layout:resizedrag', function() {
this.api.Resize();
Common.localStorage.setItem('pe-mainmenu-width',leftPanel.width());
Common.localStorage.setItem('pe-mainmenu-width', histPanel.is(':visible') ? (histPanel.width()+SCALE_MIN) : leftPanel.width() );
}, this);
this.boxSdk = $('#editor_sdk');
this.boxSdk.css('border-left', 'none');
this.header.mnuitemFitPage = this.header.fakeMenuItem();
this.header.mnuitemFitWidth = this.header.fakeMenuItem();
@ -327,10 +331,24 @@ define([
case 'rightmenu':
this.viewport.hlayout.doLayout();
break;
case 'history':
var panel = this.viewport.hlayout.items[1];
if (panel.resize.el) {
this.boxSdk.css('border-left', '');
panel.resize.el.show();
}
this.viewport.hlayout.doLayout();
break;
case 'leftmenu':
var panel = this.viewport.hlayout.items[0];
if (panel.resize.el) {
panel.el.width() > 40 ? panel.resize.el.show() : panel.resize.el.hide();
if (panel.el.width() > 40) {
this.boxSdk.css('border-left', '');
panel.resize.el.show();
} else {
panel.resize.el.hide();
this.boxSdk.css('border-left', '0 none');
}
}
this.viewport.hlayout.doLayout();
break;

View file

@ -16,6 +16,7 @@
<li class="devider"></li>
<li id="fm-btn-info" class="fm-btn"></li>
<li id="fm-btn-rights" class="fm-btn"></li>
<li id="fm-btn-history" class="fm-btn"></li>
<li class="devider" class="fm-btn"></li>
<li id="fm-btn-settings" class="fm-btn"></li>
<li class="devider"></li>

View file

@ -12,6 +12,7 @@
<div id="about-menu-panel" class="left-menu-full-ct" style="display:none;"></div>
<div id="editor-container" class="layout-item"><div id="editor_sdk"></div></div>
<div id="right-menu" class="layout-item"></div>
<div id="left-panel-history" class="layout-item"></div>
</div>
</div>
<div id="statusbar" class="layout-item"></div>

View file

@ -180,6 +180,13 @@ define([
canFocused: false
});
this.miHistory = new Common.UI.MenuItem({
el : $markup.elementById('#fm-btn-history'),
action : 'history',
caption : this.btnHistoryCaption,
canFocused: false
});
this.items = [];
this.items.push(
new Common.UI.MenuItem({
@ -205,6 +212,7 @@ define([
canFocused: false
}),
this.miAccess,
this.miHistory,
new Common.UI.MenuItem({
el : $markup.elementById('#fm-btn-settings'),
action : 'opts',
@ -332,6 +340,8 @@ define([
this.panels['help'] = ((new PE.Views.FileMenuPanels.Help({menu: this})).render());
this.panels['help'].setLangConfig(this.mode.lang);
}
this.miHistory[this.mode.canUseHistory&&!this.mode.isDisconnected?'show':'hide']();
},
setMode: function(mode, delay) {
@ -418,6 +428,9 @@ define([
if (type == 'save') {
return this.options.miSave ? this.options.miSave : (this.options.miSave = new Common.UI.MenuItem({}));
} else
if (type == 'rename') {
return this.options.miRename ? this.options.miRename : (this.options.miRename = new Common.UI.MenuItem({}));
} else
if (type == 'protect') {
return this.options.miProtect ? this.options.miProtect : (this.options.miProtect = new Common.UI.MenuItem({}));
}
@ -425,12 +438,25 @@ define([
if (type == 'save') {
return this.miSave;
} else
if (type == 'rename') {
return this.miRename;
} else
if (type == 'protect') {
return this.miProtect;
}
}
},
SetDisabled: function(disable) {
var _btn_save = this.getButton('save'),
_btn_rename = this.getButton('rename'),
_btn_protect = this.getButton('protect');
_btn_save[(disable || !this.mode.isEdit)?'hide':'show']();
_btn_protect[(disable || !this.mode.isEdit)?'hide':'show']();
_btn_rename[(disable || !this.mode.canRename || this.mode.isDesktopApp) ?'hide':'show']();
},
btnSaveCaption : 'Save',
btnDownloadCaption : 'Download as...',
btnInfoCaption : 'Document Info...',
@ -447,6 +473,7 @@ define([
btnRenameCaption : 'Rename...',
btnCloseMenuCaption : 'Close Menu',
btnProtectCaption: 'Protect',
btnSaveCopyAsCaption : 'Save Copy as...'
btnSaveCopyAsCaption : 'Save Copy as...',
btnHistoryCaption : 'Versions History'
}, PE.Views.FileMenu || {}));
});

View file

@ -45,10 +45,10 @@ define([
'backbone',
'common/main/lib/component/Button',
'common/main/lib/view/About',
'common/main/lib/view/About',
/** coauthoring begin **/
'common/main/lib/view/Comments',
'common/main/lib/view/Chat',
'common/main/lib/view/History',
/** coauthoring end **/
'common/main/lib/view/Plugins',
'common/main/lib/view/SearchDialog',
@ -258,6 +258,8 @@ define([
} else /** coauthoring end **/
if (name == 'plugins' && !this.panelPlugins) {
this.panelPlugins = panel.render('#left-panel-plugins');
} else if (name == 'history') {
this.panelHistory = panel.render('#left-panel-history');
}
},
@ -433,6 +435,14 @@ define([
this.limitHint && this.limitHint.css('top', top);
},
showHistory: function() {
this._state.pluginIsRunning = false;
this._state.historyIsRunning = true;
this.panelHistory.show();
this.panelHistory.$el.width((parseInt(Common.localStorage.getItem('pe-mainmenu-width')) || MENU_SCALE_PART) - SCALE_MIN);
Common.NotificationCenter.trigger('layout:changed', 'history');
},
/** coauthoring begin **/
tipComments : 'Comments',
tipChat : 'Chat',

View file

@ -115,7 +115,16 @@ define([
autohide: false,
min: 300,
max: 600
}}, {
}}, { // history versions
el: items[3],
rely: true,
resize: {
hidden: true,
autohide: false,
min: 300,
max: 600
}
}, {
el: items[1],
stretch: true
}, {

View file

@ -54,6 +54,8 @@ require.config({
jmousewheel : '../vendor/perfect-scrollbar/src/jquery.mousewheel',
xregexp : '../vendor/xregexp/xregexp-all-min',
sockjs : '../vendor/sockjs/sockjs.min',
jszip : '../vendor/jszip/jszip.min',
jsziputils : '../vendor/jszip-utils/jszip-utils.min',
api : 'api/documents/api',
core : 'common/main/lib/core/application',
notification : 'common/main/lib/core/NotificationCenter',
@ -119,6 +121,8 @@ require([
'analytics',
'gateway',
'locale',
'jszip',
'jsziputils',
'sockjs',
'xregexp',
'underscore'
@ -139,7 +143,8 @@ require([
'RightMenu',
'LeftMenu',
'Main',
'Common.Controllers.Fonts'
'Common.Controllers.Fonts',
'Common.Controllers.History'
/** coauthoring begin **/
, 'Common.Controllers.Chat'
,'Common.Controllers.Comments'
@ -170,7 +175,8 @@ require([
'presentationeditor/main/app/view/SignatureSettings',
'common/main/lib/util/utils',
'common/main/lib/util/LocalStorage',
'common/main/lib/controller/Fonts'
'common/main/lib/controller/Fonts',
'common/main/lib/controller/History'
/** coauthoring begin **/
,'common/main/lib/controller/Comments',
'common/main/lib/controller/Chat',

View file

@ -118,6 +118,7 @@
@import "../../../../common/main/resources/less/language-dialog.less";
@import "../../../../common/main/resources/less/winxp_fix.less";
@import "../../../../common/main/resources/less/symboltable.less";
@import "../../../../common/main/resources/less/history.less";
// App
// --------------------------------------------------

View file

@ -86,4 +86,11 @@ label {
#editor_sdk {
width: 100%;
height: 100%;
}
#left-panel-history {
left: 40px;
width: 300px;
height: 100%;
display: none;
}

View file

@ -14,6 +14,12 @@
}
}
.left-panel {
#left-panel-history {
height: 100%;
}
}
.left-menu-full-ct {
width: 100%;
height: 100%;