From 96e3172b02aebe1eea27e9562f6ff14e8c8bf62f Mon Sep 17 00:00:00 2001 From: Julia Radzhabova Date: Wed, 25 Sep 2024 20:57:38 +0300 Subject: [PATCH 1/7] [PDF] Show version history --- apps/pdfeditor/main/app.js | 2 + .../pdfeditor/main/app/controller/LeftMenu.js | 50 ++++- apps/pdfeditor/main/app/controller/Main.js | 182 +++++++++++++++++- .../pdfeditor/main/app/controller/Viewport.js | 13 +- .../main/app/template/FileMenu.template | 1 + .../main/app/template/Viewport.template | 1 + apps/pdfeditor/main/app/view/FileMenu.js | 35 +++- apps/pdfeditor/main/app/view/LeftMenu.js | 11 ++ apps/pdfeditor/main/app/view/Viewport.js | 12 +- apps/pdfeditor/main/app_dev.js | 2 + apps/pdfeditor/main/locale/en.json | 3 + apps/pdfeditor/main/resources/less/app.less | 1 + .../pdfeditor/main/resources/less/layout.less | 7 + .../main/resources/less/leftmenu.less | 6 + 14 files changed, 319 insertions(+), 7 deletions(-) diff --git a/apps/pdfeditor/main/app.js b/apps/pdfeditor/main/app.js index 9ff95990b5..55936850fa 100644 --- a/apps/pdfeditor/main/app.js +++ b/apps/pdfeditor/main/app.js @@ -146,6 +146,7 @@ require([ 'Search', 'Print', 'Common.Controllers.Fonts', + 'Common.Controllers.History', 'Common.Controllers.Chat', 'Common.Controllers.Comments', 'Common.Controllers.Draw', @@ -180,6 +181,7 @@ require([ 'pdfeditor/main/app/controller/Search', 'pdfeditor/main/app/controller/Print', 'common/main/lib/util/utils', + 'common/main/lib/controller/History', 'common/main/lib/controller/Fonts', 'common/main/lib/controller/Comments', 'common/main/lib/controller/Chat', diff --git a/apps/pdfeditor/main/app/controller/LeftMenu.js b/apps/pdfeditor/main/app/controller/LeftMenu.js index cd05c18e6b..242f5e7e38 100644 --- a/apps/pdfeditor/main/app/controller/LeftMenu.js +++ b/apps/pdfeditor/main/app/controller/LeftMenu.js @@ -115,6 +115,10 @@ define([ Common.NotificationCenter.on('leftmenu:change', _.bind(this.onMenuChange, this)); Common.NotificationCenter.on('app:comment:add', _.bind(this.onAppAddComment, this)); + Common.NotificationCenter.on('collaboration:history', _.bind(function () { + if ( !this.leftMenu.panelHistory.isVisible() ) + this.clickMenuFileItem(null, 'history'); + }, this)); Common.NotificationCenter.on('file:print', _.bind(this.clickToolbarPrint, this)); }, @@ -165,6 +169,8 @@ define([ } /** coauthoring end **/ this.leftMenu.getMenu('file').setApi(api); + if (this.mode.canUseHistory) + this.getApplication().getController('Common.Controllers.History').setApi(this.api).setMode(this.mode); this.getApplication().getController('PageThumbnails').setApi(this.api).setMode(this.mode); this.getApplication().getController('Search').setApi(this.api).setMode(this.mode); this.leftMenu.setOptionsPanel('advancedsearch', this.getApplication().getController('Search').getView('Common.Views.SearchPanel')); @@ -194,6 +200,9 @@ define([ } /** coauthoring end **/ + if (this.mode.canUseHistory) + this.leftMenu.setOptionsPanel('history', this.getApplication().getController('Common.Controllers.History').getView('Common.Views.History')); + if (this.mode.canUseViwerNavigation) { this.leftMenu.setOptionsPanel('navigation', this.getApplication().getController('Navigation').getView('Navigation')); } else { @@ -260,6 +269,31 @@ define([ close_menu = !!isopts; break; case 'close-editor': Common.NotificationCenter.trigger('close'); break; + 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.api.asc_continueSaving(); + me.showHistory(); + } else + me.api.asc_continueSaving(); + } + }); + } else + this.showHistory(); + } + break; default: close_menu = false; } @@ -641,6 +675,8 @@ define([ this.leftMenu.btnChat.setDisabled(disable); if (!options || options.navigation && options.navigation.disable) this.leftMenu.btnNavigation.setDisabled(disable); + if (!options || options.thumbnails && options.thumbnails.disable) + this.leftMenu.btnThumbnails.setDisabled(disable); this.leftMenu.setDisabledPluginButtons(disable); }, @@ -856,6 +892,17 @@ define([ } }, + showHistory: function() { + if (!this.mode.wopi) { + var maincontroller = PDFE.getController('Main'); + if (!maincontroller.loadMask) + maincontroller.loadMask = new Common.UI.LoadMask({owner: $('#viewport')}); + maincontroller.loadMask.setTitle(this.textLoadHistory); + maincontroller.loadMask.show(); + } + Common.Gateway.requestHistory(); + }, + onShowHideChat: function(state) { if (this.mode.canCoAuthoring && this.mode.canChat && !this.mode.isLightVersion) { if (state) { @@ -934,7 +981,8 @@ define([ txtUntitled: 'Untitled', txtCompatible: 'The document will be saved to the new format. It will allow to use all the editor features, but might affect the document layout.
Use the \'Compatibility\' option of the advanced settings if you want to make the files compatible with older MS Word versions.', warnDownloadAsPdf: 'Your {0} will be converted to an editable format. This may take a while. The resulting document will be optimized to allow you to edit the text, so it might not look exactly like the original {0}, especially if the original file contained lots of graphics.', - textSelectPath: 'Enter a new name for saving the file copy' + textSelectPath: 'Enter a new name for saving the file copy', + textLoadHistory : 'Loading version history...' }, PDFE.Controllers.LeftMenu || {})); }); \ No newline at end of file diff --git a/apps/pdfeditor/main/app/controller/Main.js b/apps/pdfeditor/main/app/controller/Main.js index b8774b85f4..e8b56ad9f8 100644 --- a/apps/pdfeditor/main/app/controller/Main.js +++ b/apps/pdfeditor/main/app/controller/Main.js @@ -83,6 +83,7 @@ define([ models: [], collections: [ 'Common.Collections.TextArt', + 'Common.Collections.HistoryUsers', ], views: [], @@ -616,8 +617,9 @@ define([ statusBar: true, rightMenu: {clear: !temp, disable: true}, leftMenu: {disable: true, previewMode: true}, - fileMenu: {protect: true}, + fileMenu: {protect: true, history: temp}, navigation: {disable: !temp, previewMode: true}, + thumbnails: {disable: !temp}, comments: {disable: !temp, previewMode: true}, chat: true, viewport: true, @@ -1128,6 +1130,7 @@ define([ Common.Gateway.on('processsaveresult', _.bind(me.onProcessSaveResult, me)); Common.Gateway.on('processrightschange', _.bind(me.onProcessRightsChange, me)); Common.Gateway.on('processmouse', _.bind(me.onProcessMouse, me)); + Common.Gateway.on('refreshhistory', _.bind(me.onRefreshHistory, me)); Common.Gateway.on('downloadas', _.bind(me.onDownloadAs, me)); Common.Gateway.on('setfavorite', _.bind(me.onSetFavorite, me)); Common.Gateway.on('requestclose', _.bind(me.onRequestClose, me)); @@ -1293,6 +1296,10 @@ define([ this.appOptions.canSwitchMode = this.appOptions.isPDFAnnotate && this.appOptions.canPDFEdit; // switch between View/annotate and pdf edit // this.appOptions.canCoEditing = (this.appOptions.isPDFAnnotate || this.appOptions.isPDFFill) && !(this.appOptions.isDesktopApp && this.appOptions.isOffline); + this.appOptions.canUseHistory = pdfEdit && this.appOptions.canLicense && this.editorConfig.canUseHistory && this.appOptions.canCoAuthoring && !this.appOptions.isOffline; + this.appOptions.canHistoryClose = this.editorConfig.canHistoryClose; + this.appOptions.canHistoryRestore= this.editorConfig.canHistoryRestore; + this.appOptions.canComments = pdfEdit && this.appOptions.canLicense && (this.permissions.comment===undefined ? this.appOptions.isPDFAnnotate : this.permissions.comment) && (this.editorConfig.mode !== 'view'); this.appOptions.canComments = this.appOptions.canComments && !((typeof (this.editorConfig.customization) == 'object') && this.editorConfig.customization.comments===false); this.appOptions.canViewComments = this.appOptions.canComments || pdfEdit && !((typeof (this.editorConfig.customization) == 'object') && this.editorConfig.customization.comments===false); @@ -1628,6 +1635,9 @@ define([ } else if (id == Asc.c_oAscError.ID.CanNotPasteImage) { this.showTips([this.errorCannotPasteImg], {timeout: 7000, hideCloseTip: true}); return; + } else if (id === Asc.c_oAscError.ID.DocumentAndChangeMismatch) { + this.getApplication().getController('Common.Controllers.History').onHashError(); + return; } this.hidePreloader(); @@ -2584,6 +2594,176 @@ define([ artStore.reset(arr); }, + DisableVersionHistory: function() { + this.editorConfig.canUseHistory = false; + this.appOptions.canUseHistory = false; + }, + + 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(); + appHeader.getButton('share') && appHeader.getButton('share').setVisible(false); + this.getApplication().getController('LeftMenu').getView('LeftMenu').showHistory(); + this.disableEditing(true); + this._renameDialog && this._renameDialog.close(); + var versions = opts.data.history, + historyStore = this.getApplication().getCollection('Common.Collections.HistoryVersions'), + currentVersion = null, + arrIds = []; + 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 (var ver=versions.length-1, index = 0; ver>=0; ver--, index++) { + 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) { + var color = Common.UI.ExternalUsers.getColor(version.user.id || version.user.name || this.textAnonymous, true); + user = new Common.Models.User({ + id : version.user.id, + username : version.user.name || this.textAnonymous, + colorval : color, + color : this.generateUserColor(color) + }); + usersStore.add(user); + } + var avatar = Common.UI.ExternalUsers.getImage(version.user.id); + (avatar===undefined) && arrIds.push(version.user.id); + arrVersions.push(new Common.Models.HistoryVersion({ + version: version.versionGroup, + revision: version.version, + userid : version.user.id, + username : version.user.name || this.textAnonymous, + usercolor: user.get('color'), + initials : Common.Utils.getUserInitials(AscCommon.UserInfoParser.getParsedName(version.user.name || this.textAnonymous)), + avatar : avatar, + 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, + fileType: 'docx', + index: index + })); + 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; i0) { + 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('hasSubItems', changes.length>1); + arrVersions[arrVersions.length-1].set('documentSha256', changes[changes.length-1].documentSha256); + for (i=changes.length-2; i>=0; i--, index++) { + change = changes[i]; + + user = usersStore.findUser(change.user.id); + if (!user) { + var color = Common.UI.ExternalUsers.getColor(change.user.id || change.user.name || this.textAnonymous, true); + user = new Common.Models.User({ + id : change.user.id, + username : change.user.name || this.textAnonymous, + colorval : color, + color : this.generateUserColor(color) + }); + usersStore.add(user); + } + avatar = Common.UI.ExternalUsers.getImage(change.user.id); + (avatar===undefined) && arrIds.push(change.user.id); + arrVersions.push(new Common.Models.HistoryVersion({ + version: version.versionGroup, + revision: version.version, + changeid: i, + userid : change.user.id, + username : change.user.name || this.textAnonymous, + usercolor: user.get('color'), + initials : Common.Utils.getUserInitials(AscCommon.UserInfoParser.getParsedName(change.user.name || this.textAnonymous)), + avatar : avatar, + created: change.created, + docId: version.key, + docIdPrev: docIdPrev, + selected: false, + canRestore: this.appOptions.canHistoryRestore && this.appOptions.canDownload, + isRevision: false, + isVisible: true, + serverVersion: version.serverVersion, + documentSha256: change.documentSha256, + fileType: 'docx', + hasParent: true, + index: index, + level: 1 + })); + 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; i0) { + currentVersion = historyStore.at(0); + currentVersion.set('selected', true); + } + // if (currentVersion) + // this.getApplication().getController('Common.Controllers.History').onSelectRevision(null, null, currentVersion); + arrIds.length && Common.UI.ExternalUsers.get('info', arrIds); + } + } + }, + + generateUserColor: function(color) { + return"#"+("000000"+color.toString(16)).substr(-6); + }, + onSaveDocumentBinary: function(data) { Common.Gateway.saveDocument(data); }, diff --git a/apps/pdfeditor/main/app/controller/Viewport.js b/apps/pdfeditor/main/app/controller/Viewport.js index 0ce45d990e..bc6884af46 100644 --- a/apps/pdfeditor/main/app/controller/Viewport.js +++ b/apps/pdfeditor/main/app/controller/Viewport.js @@ -151,10 +151,11 @@ 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('pdfe-mainmenu-width', leftPanel.width() ); + Common.localStorage.setItem('pdfe-mainmenu-width', histPanel.is(':visible') ? (histPanel.width()+SCALE_MIN) : leftPanel.width() ); }, this); this.boxSdk = $('#editor_sdk'); @@ -215,6 +216,14 @@ define([ case 'rightmenu': this.viewport.hlayout.doLayout(); break; + case 'history': + var panel = this.viewport.hlayout.getItem('history'); + 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.getItem('left'); if (panel.resize.el) { diff --git a/apps/pdfeditor/main/app/template/FileMenu.template b/apps/pdfeditor/main/app/template/FileMenu.template index 2c9db50a27..6d8a9df166 100644 --- a/apps/pdfeditor/main/app/template/FileMenu.template +++ b/apps/pdfeditor/main/app/template/FileMenu.template @@ -14,6 +14,7 @@
  • +
  • diff --git a/apps/pdfeditor/main/app/template/Viewport.template b/apps/pdfeditor/main/app/template/Viewport.template index 1d62d20983..02cac83474 100644 --- a/apps/pdfeditor/main/app/template/Viewport.template +++ b/apps/pdfeditor/main/app/template/Viewport.template @@ -11,6 +11,7 @@
    +
    diff --git a/apps/pdfeditor/main/app/view/FileMenu.js b/apps/pdfeditor/main/app/view/FileMenu.js index e64e1429cc..fad84e4aea 100644 --- a/apps/pdfeditor/main/app/view/FileMenu.js +++ b/apps/pdfeditor/main/app/view/FileMenu.js @@ -266,6 +266,21 @@ define([ iconCls: 'menu__icon btn-users-share' }); + this.miHistory = new Common.UI.MenuItem({ + el : $markup.elementById('#fm-btn-history'), + action : 'history', + caption : this.btnHistoryCaption, + canFocused: false, + dataHint: 1, + dataHintDirection: 'left-top', + dataHintOffset: [-2, 22], + iconCls: 'menu__icon btn-version-history' + }); + if ( !!this.options.miHistory ) { + this.miHistory.setDisabled(this.options.miHistory.isDisabled()); + delete this.options.miHistory; + } + this.miSettings = new Common.UI.MenuItem({ el : $markup.elementById('#fm-btn-settings'), action : 'opts', @@ -315,6 +330,7 @@ define([ this.miNew, this.miInfo, this.miAccess, + this.miHistory, this.miSettings, this.miHelp, this.miBack @@ -427,6 +443,12 @@ define([ separatorVisible = separatorVisible || isVisible; this.miAccess[isVisible?'show':'hide'](); + isVisible = this.mode.canUseHistory&&!this.mode.isDisconnected; + separatorVisible = separatorVisible || isVisible; + this.miHistory[isVisible?'show':'hide'](); + this.miHistory.$el.find('+.devider')[separatorVisible?'show':'hide'](); + separatorVisible && (lastSeparator = this.miHistory.$el.find('+.devider')); + isVisible = Common.UI.LayoutManager.isElementVisible('toolbar-file-settings'); this.miSettings[isVisible?'show':'hide'](); this.miSettings.$el.find('+.devider')[isVisible?'show':'hide'](); @@ -607,9 +629,11 @@ define([ }, SetDisabled: function(disable, options) { - var _btn_protect = this.getButton('protect'); + var _btn_protect = this.getButton('protect'), + _btn_history = this.getButton('history'); options && options.protect && _btn_protect.setDisabled(disable); + options && options.history && _btn_history.setDisabled(disable); options && options.info && (this.panels ? this.panels['info'].setPreviewMode(disable) : this._state.infoPreviewMode = disable ); }, @@ -627,6 +651,9 @@ define([ } else if (type == 'protect') { return this.options.miProtect ? this.options.miProtect : (this.options.miProtect = new Common.UI.MenuItem({})); + } else + if (type == 'history') { + return this.options.miHistory ? this.options.miHistory : (this.options.miHistory = new Common.UI.MenuItem({})); } } else { if (type == 'save') { @@ -637,6 +664,9 @@ define([ }else if (type == 'protect') { return this.miProtect; + }else + if (type == 'history') { + return this.miHistory; } } }, @@ -662,6 +692,7 @@ define([ btnExitCaption : 'Exit', btnFileOpenCaption : 'Open...', btnCloseEditor : 'Close File', - ariaFileMenu : 'File menu' + ariaFileMenu : 'File menu', + btnHistoryCaption : 'Versions History' }, PDFE.Views.FileMenu || {})); }); diff --git a/apps/pdfeditor/main/app/view/LeftMenu.js b/apps/pdfeditor/main/app/view/LeftMenu.js index 25449d71f5..d9f5e7fcd7 100644 --- a/apps/pdfeditor/main/app/view/LeftMenu.js +++ b/apps/pdfeditor/main/app/view/LeftMenu.js @@ -48,6 +48,7 @@ define([ 'common/main/lib/view/Comments', 'common/main/lib/view/Chat', /** coauthoring end **/ + 'common/main/lib/view/History', 'common/main/lib/view/Plugins', 'common/main/lib/view/About', 'pdfeditor/main/app/view/FileMenu', @@ -275,6 +276,9 @@ define([ } else if (name == 'advancedsearch') { this.panelSearch = panel.render('#left-panel-search'); + } else /** coauthoring end **/ + if (name == 'history') { + this.panelHistory = panel.render('#left-panel-history'); } }, @@ -408,6 +412,13 @@ define([ return this; }, + showHistory: function() { + this._state.pluginIsRunning = false; + this.panelHistory.show(); + this.panelHistory.$el.width((parseInt(Common.localStorage.getItem('pdfe-mainmenu-width')) || MENU_SCALE_PART) - SCALE_MIN); + Common.NotificationCenter.trigger('layout:changed', 'history'); + }, + setDeveloperMode: function(mode, beta, version) { if ( !this.$el.is(':visible') ) return; diff --git a/apps/pdfeditor/main/app/view/Viewport.js b/apps/pdfeditor/main/app/view/Viewport.js index d72b04aa7c..80b01ebfc6 100644 --- a/apps/pdfeditor/main/app/view/Viewport.js +++ b/apps/pdfeditor/main/app/view/Viewport.js @@ -111,7 +111,17 @@ define([ autohide: false, min: 300, max: 600 - }}, { // sdk + }}, { // history versions + el: items[3], + rely: true, + alias: 'history', + resize: { + hidden: true, + autohide: false, + min: 300, + max: 600 + } + }, { // sdk el: items[1], stretch: true }, { diff --git a/apps/pdfeditor/main/app_dev.js b/apps/pdfeditor/main/app_dev.js index 6e6016ace5..c7c44e8e0c 100644 --- a/apps/pdfeditor/main/app_dev.js +++ b/apps/pdfeditor/main/app_dev.js @@ -136,6 +136,7 @@ require([ 'Search', 'Print', 'Common.Controllers.Fonts' + ,'Common.Controllers.History' ,'Common.Controllers.Chat' ,'Common.Controllers.Comments' ,'Common.Controllers.Draw' @@ -171,6 +172,7 @@ require([ 'pdfeditor/main/app/controller/Print', 'common/main/lib/util/utils', 'common/main/lib/controller/Fonts', + 'common/main/lib/controller/History', 'common/main/lib/controller/Comments' ,'common/main/lib/controller/Chat' ,'common/main/lib/controller/Plugins' diff --git a/apps/pdfeditor/main/locale/en.json b/apps/pdfeditor/main/locale/en.json index 914201154b..b8c137fc2f 100644 --- a/apps/pdfeditor/main/locale/en.json +++ b/apps/pdfeditor/main/locale/en.json @@ -865,6 +865,7 @@ "PDFE.Controllers.LeftMenu.warnDownloadAs": "If you continue saving in this format all features except the text will be lost.
    Are you sure you want to continue?", "PDFE.Controllers.LeftMenu.warnDownloadAsPdf": "Your {0} will be converted to an editable format. This may take a while. The resulting document will be optimized to allow you to edit the text, so it might not look exactly like the original {0}, especially if the original file contained lots of graphics.", "PDFE.Controllers.LeftMenu.warnDownloadAsRTF": "If you continue saving in this format some of the formatting might be lost.
    Are you sure you want to continue?", + "PDFE.Controllers.LeftMenu.textLoadHistory": "Loading version history...", "PDFE.Controllers.Main.applyChangesTextText": "Loading the changes...", "PDFE.Controllers.Main.applyChangesTitleText": "Loading the changes", "PDFE.Controllers.Main.confirmMaxChangesSize": "The size of actions exceeds the limitation set for your server.
    Press \"Undo\" to cancel your last action or press \"Continue\" to keep action locally (you need to download the file or copy its content to make sure nothing is lost).", @@ -1014,6 +1015,7 @@ "PDFE.Controllers.Main.warnNoLicense": "You've reached the limit for simultaneous connections to %1 editors. This document will be opened for viewing only.
    Contact %1 sales team for personal upgrade terms.", "PDFE.Controllers.Main.warnNoLicenseUsers": "You've reached the user limit for %1 editors. Contact %1 sales team for personal upgrade terms.", "PDFE.Controllers.Main.warnProcessRightsChange": "You have been denied the right to edit the file.", + "PDFE.Controllers.Main.txtErrorLoadHistory": "History loading failed", "PDFE.Controllers.Navigation.txtBeginning": "Beginning of document", "PDFE.Controllers.Navigation.txtGotoBeginning": "Go to the beginning of the document", "PDFE.Controllers.Print.textMarginsLast": "Last custom", @@ -1251,6 +1253,7 @@ "PDFE.Views.FileMenu.btnSettingsCaption": "Advanced Settings", "PDFE.Views.FileMenu.btnToEditCaption": "Edit Document", "PDFE.Views.FileMenu.textDownload": "Download", + "PDFE.Views.FileMenu.btnHistoryCaption": "Version History", "PDFE.Views.FileMenuPanels.CreateNew.txtBlank": "Blank Document", "PDFE.Views.FileMenuPanels.CreateNew.txtCreateNew": "Create new", "PDFE.Views.FileMenuPanels.DocumentInfo.okButtonText": "Apply", diff --git a/apps/pdfeditor/main/resources/less/app.less b/apps/pdfeditor/main/resources/less/app.less index 4e0dc11ae3..b4142a62f4 100644 --- a/apps/pdfeditor/main/resources/less/app.less +++ b/apps/pdfeditor/main/resources/less/app.less @@ -95,6 +95,7 @@ @import "../../../../common/main/resources/less/winxp_fix.less"; @import "../../../../common/main/resources/less/symboltable.less"; @import "../../../../common/main/resources/less/hint-manager.less"; +@import "../../../../common/main/resources/less/history.less"; @import "../../../../common/main/resources/less/bigscaling.less"; @import "../../../../common/main/resources/less/updown-picker.less"; @import "../../../../common/main/resources/less/calendar.less"; diff --git a/apps/pdfeditor/main/resources/less/layout.less b/apps/pdfeditor/main/resources/less/layout.less index b8bcca3c3e..2566cde6e2 100644 --- a/apps/pdfeditor/main/resources/less/layout.less +++ b/apps/pdfeditor/main/resources/less/layout.less @@ -71,6 +71,13 @@ label { } } +#left-panel-history { + left: 40px; + width: 300px; + height: 100%; + display: none; +} + #editor_sdk { width: 100%; height: 100%; diff --git a/apps/pdfeditor/main/resources/less/leftmenu.less b/apps/pdfeditor/main/resources/less/leftmenu.less index 04b584cbbd..c3e5ff73cc 100644 --- a/apps/pdfeditor/main/resources/less/leftmenu.less +++ b/apps/pdfeditor/main/resources/less/leftmenu.less @@ -1,3 +1,9 @@ +.left-panel { + #left-panel-history { + height: 100%; + } +} + .left-menu-full-ct { width: 100%; height: 100%; From 5c1d844fb60d6b2354d44ea3ed85227ec7181b29 Mon Sep 17 00:00:00 2001 From: Julia Radzhabova Date: Wed, 25 Sep 2024 23:09:24 +0300 Subject: [PATCH 2/7] [PDF] Show collaboration tab --- apps/common/main/lib/view/ReviewChanges.js | 3 +- apps/pdfeditor/main/app.js | 6 ++-- .../pdfeditor/main/app/controller/LeftMenu.js | 6 ++-- apps/pdfeditor/main/app/controller/Main.js | 23 +++++++------- apps/pdfeditor/main/app/controller/Toolbar.js | 31 +++++++++++++++++++ apps/pdfeditor/main/app_dev.js | 2 ++ apps/pdfeditor/main/locale/en.json | 2 ++ 7 files changed, 56 insertions(+), 17 deletions(-) diff --git a/apps/common/main/lib/view/ReviewChanges.js b/apps/common/main/lib/view/ReviewChanges.js index be6e160b8f..4ff7a2891e 100644 --- a/apps/common/main/lib/view/ReviewChanges.js +++ b/apps/common/main/lib/view/ReviewChanges.js @@ -768,7 +768,8 @@ define([ if ((!me.btnMailRecepients || !Common.UI.LayoutManager.isElementVisible('toolbar-collaboration-mailmerge')) && separator_last) me.$el.find(separator_last).hide(); - Common.NotificationCenter.trigger('tab:visible', 'review', (config.isEdit || config.canViewReview || me.canComments) && Common.UI.LayoutManager.isElementVisible('toolbar-collaboration')); + Common.NotificationCenter.trigger('tab:visible', 'review', (window.PDFE && (config.isPDFAnnotate || config.isPDFEdit) || !window.PDFE && (config.isEdit || config.canViewReview || me.canComments)) + && Common.UI.LayoutManager.isElementVisible('toolbar-collaboration')); setEvents.call(me); }); }, diff --git a/apps/pdfeditor/main/app.js b/apps/pdfeditor/main/app.js index 55936850fa..1cf5116e2b 100644 --- a/apps/pdfeditor/main/app.js +++ b/apps/pdfeditor/main/app.js @@ -153,7 +153,8 @@ require([ 'Common.Controllers.Plugins', // 'Common.Controllers.ExternalDiagramEditor', // 'Common.Controllers.ExternalOleEditor', - 'Common.Controllers.Protection' + 'Common.Controllers.Protection', + 'Common.Controllers.ReviewChanges' ] }); @@ -190,7 +191,8 @@ require([ // 'common/main/lib/controller/ExternalDiagramEditor', // 'common/main/lib/controller/ExternalOleEditor', 'common/main/lib/controller/Draw', - 'common/main/lib/controller/Protection' + 'common/main/lib/controller/Protection', + 'common/main/lib/controller/ReviewChanges' ], function() { app.postLaunchScripts = [ 'pdfeditor/main/code', diff --git a/apps/pdfeditor/main/app/controller/LeftMenu.js b/apps/pdfeditor/main/app/controller/LeftMenu.js index 242f5e7e38..282c83a00d 100644 --- a/apps/pdfeditor/main/app/controller/LeftMenu.js +++ b/apps/pdfeditor/main/app/controller/LeftMenu.js @@ -101,9 +101,9 @@ define([ 'file:close': this.clickToolbarTab.bind(this, 'other'), 'save:disabled': this.changeToolbarSaveState.bind(this) }, - // 'Common.Views.ReviewChanges': { - // 'collaboration:chat': _.bind(this.onShowHideChat, this) - // }, + 'Common.Views.ReviewChanges': { + 'collaboration:chat': _.bind(this.onShowHideChat, this) + }, 'ViewTab': { 'viewtab:navigation': _.bind(this.onShowHideNavigation, this), 'leftmenu:hide': _.bind(this.onLeftMenuHide, this) diff --git a/apps/pdfeditor/main/app/controller/Main.js b/apps/pdfeditor/main/app/controller/Main.js index e8b56ad9f8..199920e232 100644 --- a/apps/pdfeditor/main/app/controller/Main.js +++ b/apps/pdfeditor/main/app/controller/Main.js @@ -92,9 +92,9 @@ define([ 'FileMenu': { 'settings:apply': _.bind(this.applySettings, this) }, - // 'Common.Views.ReviewChanges': { - // 'settings:apply': _.bind(this.applySettings, this) - // } + 'Common.Views.ReviewChanges': { + 'settings:apply': _.bind(this.applySettings, this) + } }); this.translationTable = { @@ -479,7 +479,6 @@ define([ docInfo.asc_putIsEnabledMacroses(!!enable); enable = !this.editorConfig.customization || (this.editorConfig.customization.plugins!==false); docInfo.asc_putIsEnabledPlugins(!!enable); -// docInfo.put_Review(this.permissions.review); var type = /^(?:(djvu|xps|oxps))$/.exec(data.doc.fileType); var coEditMode = (type && typeof type[1] === 'string') ? 'strict' : // offline viewer for djvu|xps|oxps @@ -622,6 +621,7 @@ define([ thumbnails: {disable: !temp}, comments: {disable: !temp, previewMode: true}, chat: true, + review: true, viewport: true, documentHolder: {clear: !temp, disable: true}, toolbar: true, @@ -647,6 +647,9 @@ define([ if (options.statusBar) { app.getController('Statusbar').getView('Statusbar').SetDisabled(disable); } + if (options.review) { + app.getController('Common.Controllers.ReviewChanges').SetDisabled(disable); + } if (options.viewport) { app.getController('Viewport').SetDisabled(disable); } @@ -844,9 +847,6 @@ define([ if (this.appOptions.isEdit && (id==Asc.c_oAscAsyncAction['Save'] || id==Asc.c_oAscAsyncAction['ForceSaveButton']) && (!this._state.fastCoauth || this._state.usersCount<2)) this.synchronizeChanges(); - // else if (this.appOptions.isEdit && (id==Asc.c_oAscAsyncAction['Save'] || id==Asc.c_oAscAsyncAction['ForceSaveButton'] || id == Asc.c_oAscAsyncAction['ApplyChanges']) && - // this._state.fastCoauth) - // this.getApplication().getController('Common.Controllers.ReviewChanges').synchronizeChanges(); if ( id == Asc.c_oAscAsyncAction['Disconnect']) { this._state.timerDisconnect && clearTimeout(this._state.timerDisconnect); @@ -1581,9 +1581,9 @@ define([ applyModeEditorElements: function() { var me = this, - application = this.getApplication(); - // reviewController = application.getController('Common.Controllers.ReviewChanges'); - // reviewController.setMode(me.appOptions).setConfig({config: me.editorConfig}, me.api).loadDocument({doc:me.document}); + application = this.getApplication(), + reviewController = application.getController('Common.Controllers.ReviewChanges'); + reviewController.setMode(me.appOptions).setConfig({config: me.editorConfig}, me.api).loadDocument({doc:me.document}); if (this.appOptions.isEdit) { if (me.appOptions.isSignatureSupport || me.appOptions.isPasswordSupport) @@ -2317,7 +2317,7 @@ define([ // Common.localStorage.setItem("pdfe-settings-showchanges-strict", 'last'); Common.Utils.InternalSettings.set("pdfe-settings-showchanges-strict", 'last'); this.api.SetCollaborativeMarksShowType(Asc.c_oAscCollaborativeMarksShowType.LastChanges); - // this.getApplication().getController('Common.Controllers.ReviewChanges').applySettings(); + this.getApplication().getController('Common.Controllers.ReviewChanges').applySettings(); } this.onEditComplete(); }, this) @@ -2381,6 +2381,7 @@ define([ var filemenu = this.getApplication().getController('LeftMenu').getView('LeftMenu').getMenu('file'); filemenu.loadDocument({doc:this.document}); filemenu.panels && filemenu.panels['info'] && filemenu.panels['info'].updateInfo(this.document); + this.getApplication().getController('Common.Controllers.ReviewChanges').loadDocument({doc:this.document}); Common.Gateway.metaChange(meta); if (this.appOptions.wopi) { diff --git a/apps/pdfeditor/main/app/controller/Toolbar.js b/apps/pdfeditor/main/app/controller/Toolbar.js index 168150c315..d54731c61c 100644 --- a/apps/pdfeditor/main/app/controller/Toolbar.js +++ b/apps/pdfeditor/main/app/controller/Toolbar.js @@ -1268,6 +1268,13 @@ define([ } !config.canComments && me.toolbar.setVisible('comment', false); + + var tab = {action: 'review', caption: me.toolbar.textTabCollaboration, dataHintTitle: 'U', layoutname: 'toolbar-collaboration'}; + var $panel = me.getApplication().getController('Common.Controllers.ReviewChanges').createToolbarPanel(); + if ( $panel ) { + me.toolbar.addTab(tab, $panel, 7); + me.toolbar.setVisible('review', (config.isPDFAnnotate || config.isPDFEdit) && Common.UI.LayoutManager.isElementVisible('toolbar-collaboration') ); // use config.canViewReview in review controller. set visible review tab in view mode only when asc_HaveRevisionsChanges + } } var tab = {caption: me.toolbar.textTabView, action: 'view', extcls: config.isEdit ? 'canedit' : '', layoutname: 'toolbar-view', dataHintTitle: 'W'}; @@ -1368,6 +1375,30 @@ define([ } } config.isEdit && Common.UI.TooltipManager.showTip('editPdf'); + + me.btnsComment = []; + if ( config.canComments ) { + var _set = Common.enumLock; + me.btnsComment = Common.Utils.injectButtons(me.toolbar.$el.find('.slot-comment'), 'tlbtn-addcomment-', 'toolbar__icon btn-big-add-comment', me.toolbar.capBtnComment, [_set.lostConnect], undefined, undefined, undefined, '1', 'bottom', 'small'); + + if ( me.btnsComment.length ) { + var _comments = PDFE.getController('Common.Controllers.Comments').getView(); + me.btnsComment.forEach(function (btn) { + btn.updateHint( _comments.textHintAddComment ); + btn.on('click', function (btn, e) { + Common.NotificationCenter.trigger('app:comment:add', 'toolbar'); + }); + if (btn.cmpEl.closest('#review-changes-panel').length>0) + btn.setCaption(me.toolbar.capBtnAddComment); + }, me); + if (_comments.buttonAddNew) { + _comments.buttonAddNew.options.lock = [ _set.lostConnect ]; + me.btnsComment.add(_comments.buttonAddNew); + } + Array.prototype.push.apply(me.toolbar.lockControls, me.btnsComment); + Array.prototype.push.apply(me.toolbar.toolbarControls, me.btnsComment); + } + } }); }, diff --git a/apps/pdfeditor/main/app_dev.js b/apps/pdfeditor/main/app_dev.js index c7c44e8e0c..81704b65b4 100644 --- a/apps/pdfeditor/main/app_dev.js +++ b/apps/pdfeditor/main/app_dev.js @@ -144,6 +144,7 @@ require([ // ,'Common.Controllers.ExternalDiagramEditor' // ,'Common.Controllers.ExternalOleEditor' ,'Common.Controllers.Protection' + ,'Common.Controllers.ReviewChanges' ] }); @@ -180,6 +181,7 @@ require([ // ,'common/main/lib/controller/ExternalOleEditor' ,'common/main/lib/controller/Draw' ,'common/main/lib/controller/Protection' + ,'common/main/lib/controller/ReviewChanges' ], function() { app.postLaunchScripts = [ 'common/main/lib/controller/ScreenReaderFocus', diff --git a/apps/pdfeditor/main/locale/en.json b/apps/pdfeditor/main/locale/en.json index b8c137fc2f..0d4e52fcc5 100644 --- a/apps/pdfeditor/main/locale/en.json +++ b/apps/pdfeditor/main/locale/en.json @@ -1997,6 +1997,8 @@ "PDFE.Views.Toolbar.txtRotatePageRight": "Rotate page right", "PDFE.Views.Toolbar.txtRotateRight": "Rotate right", "PDFE.Views.Toolbar.txtUngroup": "Ungroup", + "PDFE.Views.Toolbar.textTabCollaboration": "Collaboration", + "PDFE.Views.Toolbar.capBtnAddComment": "Add Comment", "PDFE.Views.ViewTab.textAlwaysShowToolbar": "Always Show Toolbar", "PDFE.Views.ViewTab.textDarkDocument": "Dark Document", "PDFE.Views.ViewTab.textFill": "Fill", From ef4d741b0aaf10d365eaa29e990c21d5b1ad4441 Mon Sep 17 00:00:00 2001 From: Julia Radzhabova Date: Wed, 25 Sep 2024 23:15:18 +0300 Subject: [PATCH 3/7] [PDF] Add translation --- apps/pdfeditor/main/locale/en.json | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/apps/pdfeditor/main/locale/en.json b/apps/pdfeditor/main/locale/en.json index 0d4e52fcc5..ce1dff3d34 100644 --- a/apps/pdfeditor/main/locale/en.json +++ b/apps/pdfeditor/main/locale/en.json @@ -293,6 +293,32 @@ "Common.Views.RecentFiles.txtOpenRecent": "Open Recent", "Common.Views.RenameDialog.textName": "File name", "Common.Views.RenameDialog.txtInvalidName": "The file name cannot contain any of the following characters: ", + "Common.Views.ReviewChanges.strFast": "Fast", + "Common.Views.ReviewChanges.strFastDesc": "Real-time co-editing. All changes are saved automatically.", + "Common.Views.ReviewChanges.strStrict": "Strict", + "Common.Views.ReviewChanges.strStrictDesc": "Use the 'Save' button to sync the changes you and others make.", + "Common.Views.ReviewChanges.tipCoAuthMode": "Set co-editing mode", + "Common.Views.ReviewChanges.tipCommentRem": "Delete comments", + "Common.Views.ReviewChanges.tipCommentRemCurrent": "Delete current comments", + "Common.Views.ReviewChanges.tipCommentResolve": "Resolve comments", + "Common.Views.ReviewChanges.tipCommentResolveCurrent": "Resolve current comments", + "Common.Views.ReviewChanges.tipHistory": "Show version history", + "Common.Views.ReviewChanges.tipSharing": "Manage document access rights", + "Common.Views.ReviewChanges.txtChat": "Chat", + "Common.Views.ReviewChanges.txtClose": "Close", + "Common.Views.ReviewChanges.txtCoAuthMode": "Co-editing Mode", + "Common.Views.ReviewChanges.txtCommentRemAll": "Delete all comments", + "Common.Views.ReviewChanges.txtCommentRemCurrent": "Delete current comments", + "Common.Views.ReviewChanges.txtCommentRemMy": "Delete my comments", + "Common.Views.ReviewChanges.txtCommentRemMyCurrent": "Delete my current comments", + "Common.Views.ReviewChanges.txtCommentRemove": "Delete", + "Common.Views.ReviewChanges.txtCommentResolve": "Resolve", + "Common.Views.ReviewChanges.txtCommentResolveAll": "Resolve all comments", + "Common.Views.ReviewChanges.txtCommentResolveCurrent": "Resolve current comments", + "Common.Views.ReviewChanges.txtCommentResolveMy": "Resolve my comments", + "Common.Views.ReviewChanges.txtCommentResolveMyCurrent": "Resolve my current comments", + "Common.Views.ReviewChanges.txtHistory": "Version history", + "Common.Views.ReviewChanges.txtSharing": "Sharing", "Common.Views.ReviewPopover.textAdd": "Add", "Common.Views.ReviewPopover.textAddReply": "Add Reply", "Common.Views.ReviewPopover.textCancel": "Cancel", From c1cce5d9f9487990aad979afccd5a5a7c2ad2ae0 Mon Sep 17 00:00:00 2001 From: Julia Radzhabova Date: Thu, 26 Sep 2024 12:45:25 +0300 Subject: [PATCH 4/7] [PDF] Open current file version --- apps/pdfeditor/main/app/controller/Main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/pdfeditor/main/app/controller/Main.js b/apps/pdfeditor/main/app/controller/Main.js index 199920e232..68a1cde23a 100644 --- a/apps/pdfeditor/main/app/controller/Main.js +++ b/apps/pdfeditor/main/app/controller/Main.js @@ -2754,8 +2754,8 @@ define([ currentVersion = historyStore.at(0); currentVersion.set('selected', true); } - // if (currentVersion) - // this.getApplication().getController('Common.Controllers.History').onSelectRevision(null, null, currentVersion); + if (currentVersion) + this.getApplication().getController('Common.Controllers.History').onSelectRevision(null, null, currentVersion); arrIds.length && Common.UI.ExternalUsers.get('info', arrIds); } } From 1af11128479b9fe4928d72156061c72267c1b703 Mon Sep 17 00:00:00 2001 From: Julia Radzhabova Date: Fri, 27 Sep 2024 14:13:43 +0300 Subject: [PATCH 5/7] [PDF] Hide changes for history --- apps/pdfeditor/main/app/controller/Main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pdfeditor/main/app/controller/Main.js b/apps/pdfeditor/main/app/controller/Main.js index 68a1cde23a..1df2e1f8c2 100644 --- a/apps/pdfeditor/main/app/controller/Main.js +++ b/apps/pdfeditor/main/app/controller/Main.js @@ -2689,7 +2689,7 @@ define([ arrColors.push(user.get('colorval')); var changes = version.changes, change, i; - if (changes && changes.length>0) { + if (changes && changes.length>0 && false) { // hide changes for pdf 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); From 4f3dc9e1b04a516d102b7f43156f2f8b9ba6d24f Mon Sep 17 00:00:00 2001 From: maxkadushkin Date: Thu, 15 Jan 2026 14:45:35 +0300 Subject: [PATCH 6/7] some description after merge --- apps/common/main/lib/view/ReviewChanges.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/common/main/lib/view/ReviewChanges.js b/apps/common/main/lib/view/ReviewChanges.js index e02cc7da46..cdf67c22fd 100644 --- a/apps/common/main/lib/view/ReviewChanges.js +++ b/apps/common/main/lib/view/ReviewChanges.js @@ -789,6 +789,7 @@ define([ if ((!me.btnMailRecepients || !Common.UI.LayoutManager.isElementVisible('toolbar-collaboration-mailmerge')) && separator_last) me.$el.find(separator_last).hide(); +//! NOTE: conflicted code from branch feature/pdf-history. remove if is not relevant and merge is successful //! Common.NotificationCenter.trigger('tab:visible', 'review', (window.PDFE && (config.isPDFAnnotate || config.isPDFEdit) || !window.PDFE && (config.isEdit || config.canViewReview || me.canComments)) //! && Common.UI.LayoutManager.isElementVisible('toolbar-collaboration')); var visible = (config.isEdit || config.canViewReview || me.canComments) && Common.UI.LayoutManager.isElementVisible('toolbar-collaboration'); From 390078afacdd548e085c9a673a00c15cb1bfb35d Mon Sep 17 00:00:00 2001 From: maxkadushkin Date: Fri, 23 Jan 2026 11:52:05 +0300 Subject: [PATCH 7/7] [PDFE] fix after merge --- apps/pdfeditor/main/app/view/FileMenu.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/pdfeditor/main/app/view/FileMenu.js b/apps/pdfeditor/main/app/view/FileMenu.js index 47e5813cbd..897755303e 100644 --- a/apps/pdfeditor/main/app/view/FileMenu.js +++ b/apps/pdfeditor/main/app/view/FileMenu.js @@ -442,10 +442,10 @@ define([ this.miAccess[isVisible?'show':'hide'](); isVisible = this.mode.canUseHistory&&!this.mode.isDisconnected; - separatorVisible = separatorVisible || isVisible; + // separatorVisible = separatorVisible || isVisible; this.miHistory[isVisible?'show':'hide'](); - this.miHistory.$el.find('+.devider')[separatorVisible?'show':'hide'](); - separatorVisible && (lastSeparator = this.miHistory.$el.find('+.devider')); + // this.miHistory.$el.find('+.devider')[separatorVisible?'show':'hide'](); + // separatorVisible && (lastSeparator = this.miHistory.$el.find('+.devider')); isVisible = Common.UI.LayoutManager.isElementVisible('toolbar-file-settings'); this.miSettings[isVisible?'show':'hide']();