diff --git a/apps/api/documents/api.js b/apps/api/documents/api.js index 9d3fbabdf8..934d4da318 100644 --- a/apps/api/documents/api.js +++ b/apps/api/documents/api.js @@ -132,7 +132,11 @@ url: 'http://...', text: 'Go to London', blank: true, - requestClose: false // if true - goback send onRequestClose event instead opening url + requestClose: false // if true - goback send onRequestClose event instead opening url, deprecated, use customization.close instead + }, + close: { + visible: false, + text: 'Close file' }, reviewPermissions: { "Group1": ["Group2"], // users from Group1 can accept/reject review changes made by users from Group2 diff --git a/apps/common/main/lib/view/Header.js b/apps/common/main/lib/view/Header.js index 9a5d3b72ea..2152728c54 100644 --- a/apps/common/main/lib/view/Header.js +++ b/apps/common/main/lib/view/Header.js @@ -127,6 +127,7 @@ define([ '
' + '' + '' + + '
' + '' + '' + ''; @@ -158,6 +159,7 @@ define([ '
' + '' + '' + + '
' + '' + ''; @@ -312,6 +314,13 @@ define([ Common.NotificationCenter.trigger('goback'); }); + if (me.btnClose) { + me.btnClose.on('click', function (e) { + Common.NotificationCenter.trigger('close'); + }); + me.btnClose.updateHint(appConfig.customization.close.text || me.textClose); + } + me.btnFavorite.on('click', function (e) { // wait for setFavorite method // me.options.favorite = !me.options.favorite; @@ -729,6 +738,9 @@ define([ } $btnUserName = $html.find('.color-user-name'); me.setUserName(me.options.userName); + + if ( config.canCloseEditor ) + me.btnClose = createTitleButton('toolbar__icon icon--inverse btn-close', $html.findById('#slot-btn-close'), false, 'bottom', 'big'); } if (!_readonlyRights && config && (config.sharingSettingsUrl && config.sharingSettingsUrl.length || config.canRequestSharingSettings)) { @@ -808,6 +820,9 @@ define([ $btnUserName = $html.find('.color-user-name'); me.setUserName(me.options.userName); + if ( config.canCloseEditor ) + me.btnClose = createTitleButton('toolbar__icon icon--inverse btn-close', $html.findById('#slot-btn-close'), false, 'left', '10, 10'); + if ( config.canPrint && (config.isEdit || isPDFEditor && config.isRestrictedEdit) ) { me.btnPrint = createTitleButton('toolbar__icon icon--inverse btn-print', $html.findById('#slot-btn-dt-print'), true, undefined, undefined, 'P'); } @@ -1113,7 +1128,8 @@ define([ tipDocEdit: 'Editing', textReview: 'Reviewing', textReviewDesc: 'Suggest changes', - tipReview: 'Reviewing' + tipReview: 'Reviewing', + textClose: 'Close file' } }(), Common.Views.Header || {})) }); diff --git a/apps/common/mobile/resources/less/common.less b/apps/common/mobile/resources/less/common.less index 20e3a1046b..ea0e96bec5 100644 --- a/apps/common/mobile/resources/less/common.less +++ b/apps/common/mobile/resources/less/common.less @@ -1200,6 +1200,17 @@ input[type="number"]::-webkit-inner-spin-button { border-radius: 4px; } +// Close editor button +.close-editor-btn { + .item-inner { + padding-left: 36px; + } + + .item-title { + color: @text-error; + } +} + diff --git a/apps/documenteditor/embed/index.html b/apps/documenteditor/embed/index.html index cb5f9eb8d2..8325c4c732 100644 --- a/apps/documenteditor/embed/index.html +++ b/apps/documenteditor/embed/index.html @@ -243,6 +243,7 @@ + diff --git a/apps/documenteditor/embed/index.html.deploy b/apps/documenteditor/embed/index.html.deploy index 84e3f43954..4a6461957e 100644 --- a/apps/documenteditor/embed/index.html.deploy +++ b/apps/documenteditor/embed/index.html.deploy @@ -234,6 +234,7 @@ + diff --git a/apps/documenteditor/embed/index_loader.html b/apps/documenteditor/embed/index_loader.html index b972da3666..561f102f5c 100644 --- a/apps/documenteditor/embed/index_loader.html +++ b/apps/documenteditor/embed/index_loader.html @@ -304,6 +304,7 @@ + diff --git a/apps/documenteditor/embed/index_loader.html.deploy b/apps/documenteditor/embed/index_loader.html.deploy index 7844bb22e3..80faf7d237 100644 --- a/apps/documenteditor/embed/index_loader.html.deploy +++ b/apps/documenteditor/embed/index_loader.html.deploy @@ -296,6 +296,7 @@ + diff --git a/apps/documenteditor/embed/js/ApplicationController.js b/apps/documenteditor/embed/js/ApplicationController.js index 6e29108ed2..33da757178 100644 --- a/apps/documenteditor/embed/js/ApplicationController.js +++ b/apps/documenteditor/embed/js/ApplicationController.js @@ -89,8 +89,21 @@ DE.ApplicationController = new(function(){ ttOffset[1] = 40; } - config.canBackToFolder = (config.canBackToFolder!==false) && config.customization && config.customization.goback && - (config.customization.goback.url || config.customization.goback.requestClose && config.canRequestClose); + config.canCloseEditor = false; + var _canback = false; + if (typeof config.customization === 'object') { + if (typeof config.customization.goback == 'object' && config.canBackToFolder!==false) { + _canback = config.customization.close===undefined ? + config.customization.goback.url || config.customization.goback.requestClose && config.canRequestClose : + config.customization.goback.url && !config.customization.goback.requestClose; + + if (config.customization.goback.requestClose) + console.log("Obsolete: The 'requestClose' parameter of the 'customization.goback' section is deprecated. Please use 'close' parameter in the 'customization' section instead."); + } + if (typeof config.customization.close === 'object') + config.canCloseEditor = !!config.customization.close.visible && config.canRequestClose && !config.isDesktopApp; + } + config.canBackToFolder = !!_canback; } function loadDocument(data) { @@ -428,6 +441,10 @@ DE.ApplicationController = new(function(){ text && (typeof text == 'string') && $('#idt-close .caption').text(text); } + if (config.canCloseEditor) { + $('#id-btn-close-editor').removeClass('hidden'); + } + if (itemsCount < 7) { $(dividers[0]).hide(); $(dividers[1]).hide(); @@ -508,6 +525,10 @@ DE.ApplicationController = new(function(){ } }); + $('#id-btn-close-editor').on('click', function(){ + config.canRequestClose && Common.Gateway.requestClose(); + }); + var downloadAs = function(format){ api.asc_DownloadAs(new Asc.asc_CDownloadOptions(format)); Common.Analytics.trackEvent('Save'); diff --git a/apps/documenteditor/main/app/controller/LeftMenu.js b/apps/documenteditor/main/app/controller/LeftMenu.js index 61cf5dbb97..21403fc162 100644 --- a/apps/documenteditor/main/app/controller/LeftMenu.js +++ b/apps/documenteditor/main/app/controller/LeftMenu.js @@ -305,6 +305,7 @@ define([ case 'external-help': close_menu = !!isopts; break; + case 'close-editor': Common.NotificationCenter.trigger('close'); break; default: close_menu = false; } diff --git a/apps/documenteditor/main/app/controller/Main.js b/apps/documenteditor/main/app/controller/Main.js index 6763f5bcb4..5df5a0e36d 100644 --- a/apps/documenteditor/main/app/controller/Main.js +++ b/apps/documenteditor/main/app/controller/Main.js @@ -236,6 +236,7 @@ define([ Common.NotificationCenter.on('api:disconnect', _.bind(this.onCoAuthoringDisconnect, this)); Common.NotificationCenter.on('goback', _.bind(this.goBack, this)); + Common.NotificationCenter.on('close', _.bind(this.closeEditor, this)); Common.NotificationCenter.on('markfavorite', _.bind(this.markFavorite, this)); Common.NotificationCenter.on('download:advanced', _.bind(this.onAdvancedOptions, this)); Common.NotificationCenter.on('showmessage', _.bind(this.onExternalMessage, this)); @@ -443,10 +444,6 @@ define([ this.appOptions.mergeFolderUrl = this.editorConfig.mergeFolderUrl; this.appOptions.saveAsUrl = this.editorConfig.saveAsUrl; this.appOptions.canAnalytics = false; - this.appOptions.canRequestClose = this.editorConfig.canRequestClose; - this.appOptions.canBackToFolder = (this.editorConfig.canBackToFolder!==false) && (typeof (this.editorConfig.customization) == 'object') && (typeof (this.editorConfig.customization.goback) == 'object') - && (!_.isEmpty(this.editorConfig.customization.goback.url) || this.editorConfig.customization.goback.requestClose && this.appOptions.canRequestClose); - this.appOptions.canBack = this.appOptions.canBackToFolder === true; this.appOptions.canPlugins = false; this.appOptions.canMakeActionLink = this.editorConfig.canMakeActionLink; this.appOptions.canRequestUsers = this.editorConfig.canRequestUsers; @@ -468,8 +465,26 @@ define([ this.appOptions.user.guest && this.appOptions.canRenameAnonymous && Common.NotificationCenter.on('user:rename', _.bind(this.showRenameUserDialog, this)); + this.appOptions.canRequestClose = this.editorConfig.canRequestClose; + this.appOptions.canCloseEditor = false; + + var _canback = false; + if (typeof this.appOptions.customization === 'object') { + if (typeof this.appOptions.customization.goback == 'object' && this.editorConfig.canBackToFolder!==false) { + _canback = this.appOptions.customization.close===undefined ? + !_.isEmpty(this.editorConfig.customization.goback.url) || this.editorConfig.customization.goback.requestClose && this.appOptions.canRequestClose : + !_.isEmpty(this.editorConfig.customization.goback.url) && !this.editorConfig.customization.goback.requestClose; + + if (this.appOptions.customization.goback.requestClose) + console.log("Obsolete: The 'requestClose' parameter of the 'customization.goback' section is deprecated. Please use 'close' parameter in the 'customization' section instead."); + } + if (typeof this.appOptions.customization.close === 'object') + this.appOptions.canCloseEditor = !!this.appOptions.customization.close.visible && this.appOptions.canRequestClose && !this.appOptions.isDesktopApp; + } + this.appOptions.canBack = this.appOptions.canBackToFolder = !!_canback; + appHeader = this.getApplication().getController('Viewport').getView('Common.Views.Header'); - appHeader.setCanBack(this.appOptions.canBackToFolder === true, (this.appOptions.canBackToFolder) ? this.editorConfig.customization.goback.text : ''); + appHeader.setCanBack(this.appOptions.canBack, this.appOptions.canBack ? this.appOptions.customization.goback.text : ''); if (this.editorConfig.lang) this.api.asc_setLocale(this.editorConfig.lang); @@ -966,6 +981,10 @@ define([ } }, + closeEditor: function() { + this.appOptions.canRequestClose && this.onRequestClose(); + }, + markFavorite: function(favorite) { if ( !Common.Controllers.Desktop.process('markfavorite') ) { Common.Gateway.metaChange({ diff --git a/apps/documenteditor/main/app/view/FileMenu.js b/apps/documenteditor/main/app/view/FileMenu.js index 23347bd1de..9d113fe30c 100644 --- a/apps/documenteditor/main/app/view/FileMenu.js +++ b/apps/documenteditor/main/app/view/FileMenu.js @@ -518,6 +518,19 @@ define([ dataHintDirection: 'left-top', dataHintOffset: [2, 14] })); + } else if (this.mode.canCloseEditor) { + $('
  • ' + + '
  • ').insertAfter($('#fm-btn-back', this.$el)); + this.items.push( + new Common.UI.MenuItem({ + el : $('#fm-btn-close', this.$el), + action : 'close-editor', + caption : this.mode.customization.close.text || this.btnCloseEditor, + canFocused: false, + dataHint: 1, + dataHintDirection: 'left-top', + dataHintOffset: [2, 14] + })); } }, @@ -655,6 +668,7 @@ define([ btnProtectCaption: 'Protect', btnSaveCopyAsCaption : 'Save Copy as...', btnExitCaption : 'Exit', - btnFileOpenCaption : 'Open...' + btnFileOpenCaption : 'Open...', + btnCloseEditor : 'Close File' }, DE.Views.FileMenu || {})); }); diff --git a/apps/documenteditor/main/locale/en.json b/apps/documenteditor/main/locale/en.json index e7b208eec4..e54d9b91fa 100644 --- a/apps/documenteditor/main/locale/en.json +++ b/apps/documenteditor/main/locale/en.json @@ -552,6 +552,7 @@ "Common.Views.Header.tipViewUsers": "View users and manage document access rights", "Common.Views.Header.txtAccessRights": "Change access rights", "Common.Views.Header.txtRename": "Rename", + "Common.Views.Header.textClose": "Close file", "Common.Views.History.textCloseHistory": "Close History", "Common.Views.History.textHide": "Collapse", "Common.Views.History.textHideAll": "Hide detailed changes", @@ -2055,6 +2056,7 @@ "DE.Views.FileMenu.btnSettingsCaption": "Advanced Settings", "DE.Views.FileMenu.btnToEditCaption": "Edit Document", "DE.Views.FileMenu.textDownload": "Download", + "DE.Views.FileMenu.btnCloseEditor": "Close File", "DE.Views.FileMenuPanels.CreateNew.txtBlank": "Blank document", "DE.Views.FileMenuPanels.CreateNew.txtCreateNew": "Create New", "DE.Views.FileMenuPanels.DocumentInfo.okButtonText": "Apply", diff --git a/apps/documenteditor/mobile/locale/en.json b/apps/documenteditor/mobile/locale/en.json index 85f0060085..96f892a93b 100644 --- a/apps/documenteditor/mobile/locale/en.json +++ b/apps/documenteditor/mobile/locale/en.json @@ -784,7 +784,8 @@ "txtScheme6": "Concourse", "txtScheme7": "Equity", "txtScheme8": "Flow", - "txtScheme9": "Foundry" + "txtScheme9": "Foundry", + "textClose": "Close" }, "Toolbar": { "dlgLeaveMsgText": "You have unsaved changes. Click 'Stay on this Page' to wait for autosave. Click 'Leave this Page' to discard all the unsaved changes.", diff --git a/apps/documenteditor/mobile/src/controller/Toolbar.jsx b/apps/documenteditor/mobile/src/controller/Toolbar.jsx index d9d042ad33..01c63eb42a 100644 --- a/apps/documenteditor/mobile/src/controller/Toolbar.jsx +++ b/apps/documenteditor/mobile/src/controller/Toolbar.jsx @@ -52,6 +52,7 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeReview', 'sto Common.Notifications.on('toolbar:activatecontrols', activateControls); Common.Notifications.on('toolbar:deactivateeditcontrols', deactivateEditControls); Common.Notifications.on('goback', goBack); + Common.Notifications.on('close', onRequestClose); if (isDisconnected) { f7.popover.close(); @@ -63,6 +64,7 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeReview', 'sto Common.Notifications.off('toolbar:activatecontrols', activateControls); Common.Notifications.off('toolbar:deactivateeditcontrols', deactivateEditControls); Common.Notifications.off('goback', goBack); + Common.Notifications.off('close', onRequestClose); } }, []); @@ -120,11 +122,11 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeReview', 'sto // Back button const [isShowBack, setShowBack] = useState(appOptions.canBackToFolder); const loadConfig = (data) => { - if (data && data.config && data.config.canBackToFolder !== false && - data.config.customization && data.config.customization.goback && - (data.config.customization.goback.url || data.config.customization.goback.requestClose && data.config.canRequestClose)) - { - setShowBack(true); + if (data && data.config && data.config?.canBackToFolder !== false && data.config?.customization && data.config?.customization.goback) { + const canback = data.config.customization.close === undefined ? + data.config.customization.goback.url || data.config.customization.goback.requestClose && data.config.canRequestClose : + data.config.customization.goback.url && !data.config.customization.goback.requestClose; + canback && setShowBack(true); } }; diff --git a/apps/documenteditor/mobile/src/store/appOptions.js b/apps/documenteditor/mobile/src/store/appOptions.js index 23226ac7db..8e9d2c108e 100644 --- a/apps/documenteditor/mobile/src/store/appOptions.js +++ b/apps/documenteditor/mobile/src/store/appOptions.js @@ -128,9 +128,30 @@ export class storeAppOptions { this.saveAsUrl = config.saveAsUrl; this.canAnalytics = false; this.canRequestClose = config.canRequestClose; - this.canBackToFolder = (config.canBackToFolder!==false) && (typeof (config.customization) == 'object') && (typeof (config.customization.goback) == 'object') - && (!!(config.customization.goback.url) || config.customization.goback.requestClose && this.canRequestClose); - this.canBack = this.canBackToFolder === true; + this.canCloseEditor = false; + + let canBack = false; + + if (typeof config.customization === 'object' && config.customization !== null) { + const { goback, close } = config.customization; + + if (typeof goback === 'object' && config.canBackToFolder !== false) { + const hasUrl = !!goback.url; + const requestClose = goback.requestClose && this.canRequestClose; + + canBack = close === undefined ? hasUrl || requestClose : hasUrl && !goback.requestClose; + + if (goback.requestClose) { + console.log("Obsolete: The 'requestClose' parameter of the 'customization.goback' section is deprecated. Please use 'close' parameter in the 'customization' section instead."); + } + } + + if (typeof close === 'object' && close !== null) { + this.canCloseEditor = !!close.visible && this.canRequestClose && !this.isDesktopApp; + } + } + + this.canBack = this.canBackToFolder = canBack; this.canRequestSaveAs = config.canRequestSaveAs; this.canPlugins = false; this.canFeatureForms = !!Common.EditorApi.get().asc_isSupportFeature("forms"); diff --git a/apps/documenteditor/mobile/src/view/settings/SettingsPage.jsx b/apps/documenteditor/mobile/src/view/settings/SettingsPage.jsx index d3e9f01626..da3fe7f49a 100644 --- a/apps/documenteditor/mobile/src/view/settings/SettingsPage.jsx +++ b/apps/documenteditor/mobile/src/view/settings/SettingsPage.jsx @@ -38,8 +38,10 @@ const SettingsPage = inject("storeAppOptions", "storeReview", "storeDocumentInfo const canFillForms = appOptions.canFillForms; const isEditableForms = isForm && canFillForms; const canSubmitForms = appOptions.canSubmitForms; + const canCloseEditor = appOptions.canCloseEditor; + const closeButtonText = canCloseEditor && appOptions.customization.close.text; const canUseHistory = appOptions.canUseHistory; - + let _isEdit = false, _canDownload = false, _canDownloadOrigin = false, @@ -186,6 +188,9 @@ const SettingsPage = inject("storeAppOptions", "storeReview", "storeDocumentInfo } + {canCloseEditor && + Common.Notifications.trigger('close')}> + } ) diff --git a/apps/pdfeditor/main/app/controller/LeftMenu.js b/apps/pdfeditor/main/app/controller/LeftMenu.js index 2336f31944..c6b615fa8f 100644 --- a/apps/pdfeditor/main/app/controller/LeftMenu.js +++ b/apps/pdfeditor/main/app/controller/LeftMenu.js @@ -261,6 +261,7 @@ define([ case 'external-help': close_menu = !!isopts; break; + case 'close-editor': Common.NotificationCenter.trigger('close'); break; default: close_menu = false; } diff --git a/apps/pdfeditor/main/app/controller/Main.js b/apps/pdfeditor/main/app/controller/Main.js index d309368296..3766b45dbd 100644 --- a/apps/pdfeditor/main/app/controller/Main.js +++ b/apps/pdfeditor/main/app/controller/Main.js @@ -186,6 +186,7 @@ define([ Common.NotificationCenter.on('api:disconnect', _.bind(this.onCoAuthoringDisconnect, this)); Common.NotificationCenter.on('goback', _.bind(this.goBack, this)); + Common.NotificationCenter.on('close', _.bind(this.closeEditor, this)); Common.NotificationCenter.on('markfavorite', _.bind(this.markFavorite, this)); Common.NotificationCenter.on('download:advanced', _.bind(this.onAdvancedOptions, this)); Common.NotificationCenter.on('showmessage', _.bind(this.onExternalMessage, this)); @@ -389,10 +390,6 @@ define([ this.appOptions.fileChoiceUrl = this.editorConfig.fileChoiceUrl; this.appOptions.saveAsUrl = this.editorConfig.saveAsUrl; this.appOptions.canAnalytics = false; - this.appOptions.canRequestClose = this.editorConfig.canRequestClose; - this.appOptions.canBackToFolder = (this.editorConfig.canBackToFolder!==false) && (typeof (this.editorConfig.customization) == 'object') && (typeof (this.editorConfig.customization.goback) == 'object') - && (!_.isEmpty(this.editorConfig.customization.goback.url) || this.editorConfig.customization.goback.requestClose && this.appOptions.canRequestClose); - this.appOptions.canBack = this.appOptions.canBackToFolder === true; this.appOptions.canPlugins = false; this.appOptions.canMakeActionLink = this.editorConfig.canMakeActionLink; this.appOptions.canRequestUsers = this.editorConfig.canRequestUsers; @@ -407,8 +404,26 @@ define([ this.appOptions.user.guest && this.appOptions.canRenameAnonymous && Common.NotificationCenter.on('user:rename', _.bind(this.showRenameUserDialog, this)); + this.appOptions.canRequestClose = this.editorConfig.canRequestClose; + this.appOptions.canCloseEditor = false; + + var _canback = false; + if (typeof this.appOptions.customization === 'object') { + if (typeof this.appOptions.customization.goback == 'object' && this.editorConfig.canBackToFolder!==false) { + _canback = this.appOptions.customization.close===undefined ? + !_.isEmpty(this.editorConfig.customization.goback.url) || this.editorConfig.customization.goback.requestClose && this.appOptions.canRequestClose : + !_.isEmpty(this.editorConfig.customization.goback.url) && !this.editorConfig.customization.goback.requestClose; + + if (this.appOptions.customization.goback.requestClose) + console.log("Obsolete: The 'requestClose' parameter of the 'customization.goback' section is deprecated. Please use 'close' parameter in the 'customization' section instead."); + } + if (typeof this.appOptions.customization.close === 'object') + this.appOptions.canCloseEditor = !!this.appOptions.customization.close.visible && this.appOptions.canRequestClose && !this.appOptions.isDesktopApp; + } + this.appOptions.canBack = this.appOptions.canBackToFolder = !!_canback; + appHeader = this.getApplication().getController('Viewport').getView('Common.Views.Header'); - appHeader.setCanBack(this.appOptions.canBackToFolder === true, (this.appOptions.canBackToFolder) ? this.editorConfig.customization.goback.text : ''); + appHeader.setCanBack(this.appOptions.canBack, this.appOptions.canBack ? this.editorConfig.customization.goback.text : ''); if (this.editorConfig.lang) this.api.asc_setLocale(this.editorConfig.lang); @@ -698,6 +713,10 @@ define([ } }, + closeEditor: function() { + this.appOptions.canRequestClose && this.onRequestClose(); + }, + markFavorite: function(favorite) { if ( !Common.Controllers.Desktop.process('markfavorite') ) { Common.Gateway.metaChange({ diff --git a/apps/pdfeditor/main/app/view/FileMenu.js b/apps/pdfeditor/main/app/view/FileMenu.js index 440d913337..80f18492cb 100644 --- a/apps/pdfeditor/main/app/view/FileMenu.js +++ b/apps/pdfeditor/main/app/view/FileMenu.js @@ -497,6 +497,19 @@ define([ dataHintDirection: 'left-top', dataHintOffset: [2, 14] })); + } else if (this.mode.canCloseEditor) { + $('
  • ' + + '
  • ').insertAfter($('#fm-btn-back', this.$el)); + this.items.push( + new Common.UI.MenuItem({ + el : $('#fm-btn-close', this.$el), + action : 'close-editor', + caption : this.mode.customization.close.text || this.btnCloseEditor, + canFocused: false, + dataHint: 1, + dataHintDirection: 'left-top', + dataHintOffset: [2, 14] + })); } }, @@ -625,6 +638,7 @@ define([ btnProtectCaption: 'Protect', btnSaveCopyAsCaption : 'Save Copy as...', btnExitCaption : 'Exit', - btnFileOpenCaption : 'Open...' + btnFileOpenCaption : 'Open...', + btnCloseEditor : 'Close File' }, PDFE.Views.FileMenu || {})); }); diff --git a/apps/pdfeditor/main/locale/en.json b/apps/pdfeditor/main/locale/en.json index 5666f5092e..91ea2bd713 100644 --- a/apps/pdfeditor/main/locale/en.json +++ b/apps/pdfeditor/main/locale/en.json @@ -223,6 +223,7 @@ "Common.Views.Header.tipViewUsers": "View users and manage document access rights", "Common.Views.Header.txtAccessRights": "Change access rights", "Common.Views.Header.txtRename": "Rename", + "Common.Views.Header.textClose": "Close file", "Common.Views.ImageFromUrlDialog.textUrl": "Paste an image URL:", "Common.Views.ImageFromUrlDialog.txtEmpty": "This field is required", "Common.Views.ImageFromUrlDialog.txtNotUrl": "This field should be a URL in the \"http://www.example.com\" format", @@ -516,6 +517,7 @@ "PDFE.Views.FileMenu.btnSettingsCaption": "Advanced Settings", "PDFE.Views.FileMenu.btnToEditCaption": "Edit Document", "PDFE.Views.FileMenu.textDownload": "Download", + "PDFE.Views.FileMenu.btnCloseEditor": "Close File", "PDFE.Views.FileMenuPanels.CreateNew.txtBlank": "Blank Document", "PDFE.Views.FileMenuPanels.CreateNew.txtCreateNew": "Create new", "PDFE.Views.FileMenuPanels.DocumentInfo.okButtonText": "Apply", diff --git a/apps/presentationeditor/embed/index.html b/apps/presentationeditor/embed/index.html index 9fbb09d470..6e3e2c178e 100644 --- a/apps/presentationeditor/embed/index.html +++ b/apps/presentationeditor/embed/index.html @@ -263,6 +263,7 @@ + diff --git a/apps/presentationeditor/embed/index.html.deploy b/apps/presentationeditor/embed/index.html.deploy index 4cbe880236..1649530816 100644 --- a/apps/presentationeditor/embed/index.html.deploy +++ b/apps/presentationeditor/embed/index.html.deploy @@ -257,6 +257,7 @@ + diff --git a/apps/presentationeditor/embed/index_loader.html b/apps/presentationeditor/embed/index_loader.html index 513204c119..96c171ea99 100644 --- a/apps/presentationeditor/embed/index_loader.html +++ b/apps/presentationeditor/embed/index_loader.html @@ -302,6 +302,7 @@ + diff --git a/apps/presentationeditor/embed/index_loader.html.deploy b/apps/presentationeditor/embed/index_loader.html.deploy index f1bfc2be1d..2a4f1dbc52 100644 --- a/apps/presentationeditor/embed/index_loader.html.deploy +++ b/apps/presentationeditor/embed/index_loader.html.deploy @@ -295,6 +295,7 @@ + diff --git a/apps/presentationeditor/embed/js/ApplicationController.js b/apps/presentationeditor/embed/js/ApplicationController.js index 08afd5d0bf..5261cdb45b 100644 --- a/apps/presentationeditor/embed/js/ApplicationController.js +++ b/apps/presentationeditor/embed/js/ApplicationController.js @@ -86,8 +86,21 @@ PE.ApplicationController = new(function(){ $('#box-preview').addClass('top'); } - config.canBackToFolder = (config.canBackToFolder!==false) && config.customization && config.customization.goback && - (config.customization.goback.url || config.customization.goback.requestClose && config.canRequestClose); + config.canCloseEditor = false; + var _canback = false; + if (typeof config.customization === 'object') { + if (typeof config.customization.goback == 'object' && config.canBackToFolder!==false) { + _canback = config.customization.close===undefined ? + config.customization.goback.url || config.customization.goback.requestClose && config.canRequestClose : + config.customization.goback.url && !config.customization.goback.requestClose; + + if (config.customization.goback.requestClose) + console.log("Obsolete: The 'requestClose' parameter of the 'customization.goback' section is deprecated. Please use 'close' parameter in the 'customization' section instead."); + } + if (typeof config.customization.close === 'object') + config.canCloseEditor = !!config.customization.close.visible && config.canRequestClose && !config.isDesktopApp; + } + config.canBackToFolder = !!_canback; } function loadDocument(data) { @@ -294,6 +307,10 @@ PE.ApplicationController = new(function(){ text && (typeof text == 'string') && $('#idt-close .caption').text(text); } + if (config.canCloseEditor) { + $('#id-btn-close-editor').removeClass('hidden'); + } + if (itemsCount < 7) { $(dividers[0]).hide(); $(dividers[1]).hide(); @@ -372,6 +389,10 @@ PE.ApplicationController = new(function(){ } }); + $('#id-btn-close-editor').on('click', function(){ + config.canRequestClose && Common.Gateway.requestClose(); + }); + PE.ApplicationView.tools.get('#idt-search') .on('click', function(){ common.controller.SearchBar.show(); diff --git a/apps/presentationeditor/main/app/controller/LeftMenu.js b/apps/presentationeditor/main/app/controller/LeftMenu.js index 1e07462bed..1be43fb805 100644 --- a/apps/presentationeditor/main/app/controller/LeftMenu.js +++ b/apps/presentationeditor/main/app/controller/LeftMenu.js @@ -277,6 +277,7 @@ define([ } break; case 'external-help': close_menu = true; break; + case 'close-editor': Common.NotificationCenter.trigger('close'); break; default: close_menu = false; } diff --git a/apps/presentationeditor/main/app/controller/Main.js b/apps/presentationeditor/main/app/controller/Main.js index 6f7f72e6b0..a0b0366886 100644 --- a/apps/presentationeditor/main/app/controller/Main.js +++ b/apps/presentationeditor/main/app/controller/Main.js @@ -211,6 +211,7 @@ define([ this.api.asc_registerCallback('asc_onSpellCheckInit', _.bind(this.loadLanguages, this)); Common.NotificationCenter.on('api:disconnect', _.bind(this.onCoAuthoringDisconnect, this)); Common.NotificationCenter.on('goback', _.bind(this.goBack, this)); + Common.NotificationCenter.on('close', _.bind(this.closeEditor, this)); Common.NotificationCenter.on('showmessage', _.bind(this.onExternalMessage, this)); Common.NotificationCenter.on('showerror', _.bind(this.onError, this)); Common.NotificationCenter.on('markfavorite', _.bind(this.markFavorite, this)); @@ -399,10 +400,6 @@ define([ this.appOptions.saveAsUrl = this.editorConfig.saveAsUrl; this.appOptions.fileChoiceUrl = this.editorConfig.fileChoiceUrl; this.appOptions.canAnalytics = false; - this.appOptions.canRequestClose = this.editorConfig.canRequestClose; - this.appOptions.canBackToFolder = (this.editorConfig.canBackToFolder!==false) && (typeof (this.editorConfig.customization) == 'object') && (typeof (this.editorConfig.customization.goback) == 'object') - && (!_.isEmpty(this.editorConfig.customization.goback.url) || this.editorConfig.customization.goback.requestClose && this.appOptions.canRequestClose); - this.appOptions.canBack = this.appOptions.canBackToFolder === true; this.appOptions.canPlugins = false; this.appOptions.canRequestUsers = this.editorConfig.canRequestUsers; this.appOptions.canRequestSendNotify = this.editorConfig.canRequestSendNotify; @@ -415,8 +412,26 @@ define([ this.appOptions.user.guest && this.appOptions.canRenameAnonymous && Common.NotificationCenter.on('user:rename', _.bind(this.showRenameUserDialog, this)); + this.appOptions.canRequestClose = this.editorConfig.canRequestClose; + this.appOptions.canCloseEditor = false; + + var _canback = false; + if (typeof this.appOptions.customization === 'object') { + if (typeof this.appOptions.customization.goback == 'object' && this.editorConfig.canBackToFolder!==false) { + _canback = this.appOptions.customization.close===undefined ? + !_.isEmpty(this.editorConfig.customization.goback.url) || this.editorConfig.customization.goback.requestClose && this.appOptions.canRequestClose : + !_.isEmpty(this.editorConfig.customization.goback.url) && !this.editorConfig.customization.goback.requestClose; + + if (this.appOptions.customization.goback.requestClose) + console.log("Obsolete: The 'requestClose' parameter of the 'customization.goback' section is deprecated. Please use 'close' parameter in the 'customization' section instead."); + } + if (typeof this.appOptions.customization.close === 'object') + this.appOptions.canCloseEditor = !!this.appOptions.customization.close.visible && this.appOptions.canRequestClose && !this.appOptions.isDesktopApp; + } + this.appOptions.canBack = this.appOptions.canBackToFolder = !!_canback; + appHeader = this.getApplication().getController('Viewport').getView('Common.Views.Header'); - appHeader.setCanBack(this.appOptions.canBackToFolder === true, (this.appOptions.canBackToFolder) ? this.editorConfig.customization.goback.text : ''); + appHeader.setCanBack(this.appOptions.canBack, this.appOptions.canBack ? this.appOptions.customization.goback.text : ''); if (this.editorConfig.lang) this.api.asc_setLocale(this.editorConfig.lang); @@ -616,6 +631,10 @@ define([ } }, + closeEditor: function() { + this.appOptions.canRequestClose && this.onRequestClose(); + }, + markFavorite: function(favorite) { if ( !Common.Controllers.Desktop.process('markfavorite') ) { Common.Gateway.metaChange({ diff --git a/apps/presentationeditor/main/app/view/FileMenu.js b/apps/presentationeditor/main/app/view/FileMenu.js index caf7fc58bf..17933e897b 100644 --- a/apps/presentationeditor/main/app/view/FileMenu.js +++ b/apps/presentationeditor/main/app/view/FileMenu.js @@ -513,6 +513,19 @@ define([ dataHintDirection: 'left-top', dataHintOffset: [2, 14] })); + } else if (this.mode.canCloseEditor) { + $('
  • ' + + '
  • ').insertAfter($('#fm-btn-back', this.$el)); + this.items.push( + new Common.UI.MenuItem({ + el : $('#fm-btn-close', this.$el), + action : 'close-editor', + caption : this.mode.customization.close.text || this.btnCloseEditor, + canFocused: false, + dataHint: 1, + dataHintDirection: 'left-top', + dataHintOffset: [2, 14] + })); } }, @@ -662,6 +675,7 @@ define([ btnSaveCopyAsCaption : 'Save Copy as...', btnHistoryCaption : 'Versions History', btnExitCaption : 'Exit', - btnFileOpenCaption : 'Open...' + btnFileOpenCaption : 'Open...', + btnCloseEditor : 'Close File' }, PE.Views.FileMenu || {})); }); diff --git a/apps/presentationeditor/main/locale/en.json b/apps/presentationeditor/main/locale/en.json index 7d00e557e2..6b2fcc727d 100644 --- a/apps/presentationeditor/main/locale/en.json +++ b/apps/presentationeditor/main/locale/en.json @@ -636,6 +636,7 @@ "Common.Views.Header.tipViewUsers": "View users and manage document access rights", "Common.Views.Header.txtAccessRights": "Change access rights", "Common.Views.Header.txtRename": "Rename", + "Common.Views.Header.textClose": "Close file", "Common.Views.History.textCloseHistory": "Close History", "Common.Views.History.textHide": "Collapse", "Common.Views.History.textHideAll": "Hide detailed changes", @@ -1926,6 +1927,7 @@ "PE.Views.FileMenu.btnSaveCopyAsCaption": "Save Copy As", "PE.Views.FileMenu.btnSettingsCaption": "Advanced Settings", "PE.Views.FileMenu.btnToEditCaption": "Edit Presentation", + "PE.Views.FileMenu.btnCloseEditor": "Close File", "PE.Views.FileMenuPanels.CreateNew.txtBlank": "Blank Presentation", "PE.Views.FileMenuPanels.CreateNew.txtCreateNew": "Create New", "PE.Views.FileMenuPanels.DocumentInfo.okButtonText": "Apply", diff --git a/apps/presentationeditor/mobile/locale/en.json b/apps/presentationeditor/mobile/locale/en.json index 5f6a669a37..fe45a24318 100644 --- a/apps/presentationeditor/mobile/locale/en.json +++ b/apps/presentationeditor/mobile/locale/en.json @@ -549,7 +549,8 @@ "txtScheme6": "Concourse", "txtScheme7": "Equity", "txtScheme8": "Flow", - "txtScheme9": "Foundry" + "txtScheme9": "Foundry", + "textClose": "Close" } } } \ No newline at end of file diff --git a/apps/presentationeditor/mobile/src/controller/Toolbar.jsx b/apps/presentationeditor/mobile/src/controller/Toolbar.jsx index 99ddf0760a..1d4f83f86c 100644 --- a/apps/presentationeditor/mobile/src/controller/Toolbar.jsx +++ b/apps/presentationeditor/mobile/src/controller/Toolbar.jsx @@ -35,6 +35,7 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeFocusObjects' Common.Notifications.on('toolbar:activatecontrols', activateControls); Common.Notifications.on('toolbar:deactivateeditcontrols', deactivateEditControls); Common.Notifications.on('goback', goBack); + Common.Notifications.on('close', onRequestClose); if (isDisconnected) { f7.popover.close(); @@ -46,6 +47,7 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeFocusObjects' Common.Notifications.off('toolbar:activatecontrols', activateControls); Common.Notifications.off('toolbar:deactivateeditcontrols', deactivateEditControls); Common.Notifications.off('goback', goBack); + Common.Notifications.off('close', onRequestClose); } }); @@ -53,10 +55,11 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeFocusObjects' const [isShowBack, setShowBack] = useState(appOptions.canBackToFolder); const loadConfig = (data) => { if (data && data.config && data.config.canBackToFolder !== false && - data.config.customization && data.config.customization.goback && - (data.config.customization.goback.url || data.config.customization.goback.requestClose && data.config.canRequestClose)) - { - setShowBack(true); + data.config.customization && data.config.customization.goback) { + const canback = data.config.customization.close === undefined ? + data.config.customization.goback.url || data.config.customization.goback.requestClose && data.config.canRequestClose : + data.config.customization.goback.url && !data.config.customization.goback.requestClose; + canback && setShowBack(true); } }; diff --git a/apps/presentationeditor/mobile/src/store/appOptions.js b/apps/presentationeditor/mobile/src/store/appOptions.js index af772e02c3..34cfde081e 100644 --- a/apps/presentationeditor/mobile/src/store/appOptions.js +++ b/apps/presentationeditor/mobile/src/store/appOptions.js @@ -62,9 +62,30 @@ export class storeAppOptions { this.mergeFolderUrl = config.mergeFolderUrl; this.canAnalytics = false; this.canRequestClose = config.canRequestClose; - this.canBackToFolder = (config.canBackToFolder!==false) && (typeof (config.customization) == 'object') && (typeof (config.customization.goback) == 'object') - && (!!(config.customization.goback.url) || config.customization.goback.requestClose && this.canRequestClose); - this.canBack = this.canBackToFolder === true; + this.canCloseEditor = false; + + let canBack = false; + + if (typeof config.customization === 'object' && config.customization !== null) { + const { goback, close } = config.customization; + + if (typeof goback === 'object' && config.canBackToFolder !== false) { + const hasUrl = !!goback.url; + const requestClose = goback.requestClose && this.canRequestClose; + + canBack = close === undefined ? hasUrl || requestClose : hasUrl && !goback.requestClose; + + if (goback.requestClose) { + console.log("Obsolete: The 'requestClose' parameter of the 'customization.goback' section is deprecated. Please use 'close' parameter in the 'customization' section instead."); + } + } + + if (typeof close === 'object' && close !== null) { + this.canCloseEditor = !!close.visible && this.canRequestClose && !this.isDesktopApp; + } + } + + this.canBack = this.canBackToFolder = canBack; this.canPlugins = false; AscCommon.UserInfoParser.setParser(true); diff --git a/apps/presentationeditor/mobile/src/view/settings/SettingsPage.jsx b/apps/presentationeditor/mobile/src/view/settings/SettingsPage.jsx index 6bd9838e7a..ce04763c8a 100644 --- a/apps/presentationeditor/mobile/src/view/settings/SettingsPage.jsx +++ b/apps/presentationeditor/mobile/src/view/settings/SettingsPage.jsx @@ -17,6 +17,8 @@ const SettingsPage = inject('storeAppOptions', 'storeToolbarSettings', 'storePre const disabledPreview = storeToolbarSettings.countPages <= 0; const storePresentationInfo = props.storePresentationInfo; const docTitle = storePresentationInfo.dataDoc ? storePresentationInfo.dataDoc.title : ''; + const canCloseEditor = appOptions.canCloseEditor; + const closeButtonText = canCloseEditor && appOptions.customization.close.text; const navbar =
    {docTitle}
    @@ -121,9 +123,12 @@ const SettingsPage = inject('storeAppOptions', 'storeToolbarSettings', 'storePre } {_canFeedback && - + } + {canCloseEditor && + Common.Notifications.trigger('close')}> + } ) diff --git a/apps/spreadsheeteditor/embed/index.html b/apps/spreadsheeteditor/embed/index.html index 21b7254852..49dbff7d27 100644 --- a/apps/spreadsheeteditor/embed/index.html +++ b/apps/spreadsheeteditor/embed/index.html @@ -237,6 +237,7 @@ + diff --git a/apps/spreadsheeteditor/embed/index.html.deploy b/apps/spreadsheeteditor/embed/index.html.deploy index ba2bd08c01..65013a74ca 100644 --- a/apps/spreadsheeteditor/embed/index.html.deploy +++ b/apps/spreadsheeteditor/embed/index.html.deploy @@ -228,6 +228,7 @@ + diff --git a/apps/spreadsheeteditor/embed/index_loader.html b/apps/spreadsheeteditor/embed/index_loader.html index 1c7dab986a..bad38ace6d 100644 --- a/apps/spreadsheeteditor/embed/index_loader.html +++ b/apps/spreadsheeteditor/embed/index_loader.html @@ -301,6 +301,7 @@ + diff --git a/apps/spreadsheeteditor/embed/index_loader.html.deploy b/apps/spreadsheeteditor/embed/index_loader.html.deploy index 39dbc34571..50e66e1569 100644 --- a/apps/spreadsheeteditor/embed/index_loader.html.deploy +++ b/apps/spreadsheeteditor/embed/index_loader.html.deploy @@ -293,6 +293,7 @@ + diff --git a/apps/spreadsheeteditor/embed/js/ApplicationController.js b/apps/spreadsheeteditor/embed/js/ApplicationController.js index ed00a3dc40..47d8611d19 100644 --- a/apps/spreadsheeteditor/embed/js/ApplicationController.js +++ b/apps/spreadsheeteditor/embed/js/ApplicationController.js @@ -86,8 +86,22 @@ SSE.ApplicationController = new(function(){ $('.viewer').addClass('top'); } - config.canBackToFolder = (config.canBackToFolder!==false) && config.customization && config.customization.goback && - (config.customization.goback.url || config.customization.goback.requestClose && config.canRequestClose); + config.canCloseEditor = false; + var _canback = false; + if (typeof config.customization === 'object') { + if (typeof config.customization.goback == 'object' && config.canBackToFolder!==false) { + _canback = config.customization.close===undefined ? + config.customization.goback.url || config.customization.goback.requestClose && config.canRequestClose : + config.customization.goback.url && !config.customization.goback.requestClose; + + if (config.customization.goback.requestClose) + console.log("Obsolete: The 'requestClose' parameter of the 'customization.goback' section is deprecated. Please use 'close' parameter in the 'customization' section instead."); + } + if (typeof config.customization.close === 'object') + config.canCloseEditor = !!config.customization.close.visible && config.canRequestClose && !config.isDesktopApp; + } + config.canBackToFolder = !!_canback; + var reg = (typeof (config.region) == 'string') ? config.region.toLowerCase() : config.region; reg = Common.util.LanguageInfo.getLanguages().hasOwnProperty(reg) ? reg : Common.util.LanguageInfo.getLocalLanguageCode(reg); if (reg!==null) @@ -239,6 +253,10 @@ SSE.ApplicationController = new(function(){ text && (typeof text == 'string') && $('#idt-close .caption').text(text); } + if (config.canCloseEditor) { + $('#id-btn-close-editor').removeClass('hidden'); + } + if (itemsCount < 7) { $(dividers[0]).hide(); $(dividers[1]).hide(); @@ -310,6 +328,10 @@ SSE.ApplicationController = new(function(){ } }); + $('#id-btn-close-editor').on('click', function(){ + config.canRequestClose && Common.Gateway.requestClose(); + }); + SSE.ApplicationView.tools.get('#idt-search') .on('click', function(){ common.controller.SearchBar.show(); diff --git a/apps/spreadsheeteditor/main/app/controller/LeftMenu.js b/apps/spreadsheeteditor/main/app/controller/LeftMenu.js index 9066d45c7d..6173131bfa 100644 --- a/apps/spreadsheeteditor/main/app/controller/LeftMenu.js +++ b/apps/spreadsheeteditor/main/app/controller/LeftMenu.js @@ -318,6 +318,7 @@ define([ } break; case 'external-help': close_menu = true; break; + case 'close-editor': Common.NotificationCenter.trigger('close'); break; default: close_menu = false; } diff --git a/apps/spreadsheeteditor/main/app/controller/Main.js b/apps/spreadsheeteditor/main/app/controller/Main.js index 4f6496d7e4..316be9d0d0 100644 --- a/apps/spreadsheeteditor/main/app/controller/Main.js +++ b/apps/spreadsheeteditor/main/app/controller/Main.js @@ -234,6 +234,7 @@ define([ this.api.asc_registerCallback('asc_onOleEditorReady', _.bind(this.onOleEditorReady, this)); Common.NotificationCenter.on('api:disconnect', _.bind(this.onCoAuthoringDisconnect, this)); Common.NotificationCenter.on('goback', _.bind(this.goBack, this)); + Common.NotificationCenter.on('close', _.bind(this.closeEditor, this)); Common.NotificationCenter.on('namedrange:locked', _.bind(this.onNamedRangeLocked, this)); Common.NotificationCenter.on('protectedrange:locked', _.bind(this.onProtectedRangeLocked, this)); Common.NotificationCenter.on('download:cancel', _.bind(this.onDownloadCancel, this)); @@ -450,10 +451,6 @@ define([ this.appOptions.isEditDiagram = this.editorConfig.mode == 'editdiagram'; this.appOptions.isEditMailMerge = this.editorConfig.mode == 'editmerge'; this.appOptions.isEditOle = this.editorConfig.mode == 'editole'; - this.appOptions.canRequestClose = this.editorConfig.canRequestClose; - this.appOptions.canBackToFolder = (this.editorConfig.canBackToFolder!==false) && (typeof (this.editorConfig.customization) == 'object') && (typeof (this.editorConfig.customization.goback) == 'object') - && (!_.isEmpty(this.editorConfig.customization.goback.url) || this.editorConfig.customization.goback.requestClose && this.appOptions.canRequestClose); - this.appOptions.canBack = this.appOptions.canBackToFolder === true; this.appOptions.canPlugins = false; this.appOptions.canRequestUsers = this.editorConfig.canRequestUsers; this.appOptions.canRequestSendNotify = this.editorConfig.canRequestSendNotify; @@ -473,8 +470,26 @@ define([ if (this.appOptions.user.guest && this.appOptions.canRenameAnonymous && !this.appOptions.isEditDiagram && !this.appOptions.isEditMailMerge && !this.appOptions.isEditOle) Common.NotificationCenter.on('user:rename', _.bind(this.showRenameUserDialog, this)); + this.appOptions.canRequestClose = this.editorConfig.canRequestClose; + this.appOptions.canCloseEditor = false; + + var _canback = false; + if (typeof this.appOptions.customization === 'object') { + if (typeof this.appOptions.customization.goback == 'object' && this.editorConfig.canBackToFolder!==false) { + _canback = this.appOptions.customization.close===undefined ? + !_.isEmpty(this.editorConfig.customization.goback.url) || this.editorConfig.customization.goback.requestClose && this.appOptions.canRequestClose : + !_.isEmpty(this.editorConfig.customization.goback.url) && !this.editorConfig.customization.goback.requestClose; + + if (this.appOptions.customization.goback.requestClose) + console.log("Obsolete: The 'requestClose' parameter of the 'customization.goback' section is deprecated. Please use 'close' parameter in the 'customization' section instead."); + } + if (typeof this.appOptions.customization.close === 'object') + this.appOptions.canCloseEditor = !!this.appOptions.customization.close.visible && this.appOptions.canRequestClose && !this.appOptions.isDesktopApp; + } + this.appOptions.canBack = this.appOptions.canBackToFolder = !!_canback; + this.headerView = this.getApplication().getController('Viewport').getView('Common.Views.Header'); - this.headerView.setCanBack(this.appOptions.canBackToFolder === true, (this.appOptions.canBackToFolder) ? this.editorConfig.customization.goback.text : ''); + this.headerView.setCanBack(this.appOptions.canBack, this.appOptions.canBack ? this.editorConfig.customization.goback.text : ''); var reg = Common.localStorage.getItem("sse-settings-reg-settings"), isUseBaseSeparator = Common.localStorage.getBool("sse-settings-use-base-separator", true), @@ -703,6 +718,10 @@ define([ } }, + closeEditor: function() { + this.appOptions.canRequestClose && this.onRequestClose(); + }, + markFavorite: function(favorite) { if ( !Common.Controllers.Desktop.process('markfavorite') ) { Common.Gateway.metaChange({ diff --git a/apps/spreadsheeteditor/main/app/view/FileMenu.js b/apps/spreadsheeteditor/main/app/view/FileMenu.js index 594b1086f5..4a69c3c73b 100644 --- a/apps/spreadsheeteditor/main/app/view/FileMenu.js +++ b/apps/spreadsheeteditor/main/app/view/FileMenu.js @@ -501,6 +501,19 @@ define([ dataHintDirection: 'left-top', dataHintOffset: [2, 14] })); + } else if (this.mode.canCloseEditor) { + $('
  • ' + + '
  • ').insertAfter($('#fm-btn-back', this.$el)); + this.items.push( + new Common.UI.MenuItem({ + el : $('#fm-btn-close', this.$el), + action : 'close-editor', + caption : this.mode.customization.close.text || this.btnCloseEditor, + canFocused: false, + dataHint: 1, + dataHintDirection: 'left-top', + dataHintOffset: [2, 14] + })); } }, @@ -638,6 +651,7 @@ define([ btnHistoryCaption : 'Versions History', btnExitCaption : 'Exit', btnFileOpenCaption : 'Open...', - btnExportToPDFCaption : 'Export to PDF' + btnExportToPDFCaption : 'Export to PDF', + btnCloseEditor : 'Close File' }, SSE.Views.FileMenu || {})); }); diff --git a/apps/spreadsheeteditor/main/locale/en.json b/apps/spreadsheeteditor/main/locale/en.json index e510abd179..f25f9a927c 100644 --- a/apps/spreadsheeteditor/main/locale/en.json +++ b/apps/spreadsheeteditor/main/locale/en.json @@ -473,6 +473,7 @@ "Common.Views.Header.tipViewUsers": "View users and manage document access rights", "Common.Views.Header.txtAccessRights": "Change access rights", "Common.Views.Header.txtRename": "Rename", + "Common.Views.Header.textClose": "Close file", "Common.Views.History.textCloseHistory": "Close History", "Common.Views.History.textHide": "Collapse", "Common.Views.History.textHideAll": "Hide detailed changes", @@ -2552,6 +2553,7 @@ "SSE.Views.FileMenu.btnSaveCopyAsCaption": "Save Copy As", "SSE.Views.FileMenu.btnSettingsCaption": "Advanced Settings", "SSE.Views.FileMenu.btnToEditCaption": "Edit Spreadsheet", + "SSE.Views.FileMenu.btnCloseEditor": "Close File", "SSE.Views.FileMenuPanels.CreateNew.txtBlank": "Blank Spreadsheet", "SSE.Views.FileMenuPanels.CreateNew.txtCreateNew": "Create New", "SSE.Views.FileMenuPanels.DocumentInfo.okButtonText": "Apply", diff --git a/apps/spreadsheeteditor/mobile/locale/en.json b/apps/spreadsheeteditor/mobile/locale/en.json index 441ec98efb..0787c5666c 100644 --- a/apps/spreadsheeteditor/mobile/locale/en.json +++ b/apps/spreadsheeteditor/mobile/locale/en.json @@ -827,7 +827,8 @@ "txtUk": "Ukrainian", "txtVi": "Vietnamese", "txtZh": "Chinese", - "warnDownloadAs": "If you continue saving in this format all features except the text will be lost.
    Are you sure you want to continue?" + "warnDownloadAs": "If you continue saving in this format all features except the text will be lost.
    Are you sure you want to continue?", + "textClose": "Close" } } } \ No newline at end of file diff --git a/apps/spreadsheeteditor/mobile/src/controller/Toolbar.jsx b/apps/spreadsheeteditor/mobile/src/controller/Toolbar.jsx index cf36b9a986..b188fb9466 100644 --- a/apps/spreadsheeteditor/mobile/src/controller/Toolbar.jsx +++ b/apps/spreadsheeteditor/mobile/src/controller/Toolbar.jsx @@ -43,6 +43,7 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeSpreadsheetIn Common.Notifications.on('toolbar:activatecontrols', activateControls); Common.Notifications.on('toolbar:deactivateeditcontrols', deactivateEditControls); Common.Notifications.on('goback', goBack); + Common.Notifications.on('close', onClose); Common.Notifications.on('sheet:active', onApiActiveSheetChanged); if (isDisconnected) { @@ -55,6 +56,7 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeSpreadsheetIn Common.Notifications.off('toolbar:activatecontrols', activateControls); Common.Notifications.off('toolbar:deactivateeditcontrols', deactivateEditControls); Common.Notifications.off('goback', goBack); + Common.Notifications.off('close', onClose); Common.Notifications.off('sheet:active', onApiActiveSheetChanged); } }); @@ -63,10 +65,11 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeSpreadsheetIn const [isShowBack, setShowBack] = useState(appOptions.canBackToFolder); const loadConfig = (data) => { if (data && data.config && data.config.canBackToFolder !== false && - data.config.customization && data.config.customization.goback && - (data.config.customization.goback.url || data.config.customization.goback.requestClose && data.config.canRequestClose)) - { - setShowBack(true); + data.config.customization && data.config.customization.goback) { + const canback = data.config.customization.close === undefined ? + data.config.customization.goback.url || data.config.customization.goback.requestClose && data.config.canRequestClose : + data.config.customization.goback.url && !data.config.customization.goback.requestClose; + canback && setShowBack(true); } }; @@ -117,6 +120,10 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeSpreadsheetIn } } + const onClose = () => { + onRequestClose(); + } + const onUndo = () => { const api = Common.EditorApi.get(); if (api) { diff --git a/apps/spreadsheeteditor/mobile/src/store/appOptions.js b/apps/spreadsheeteditor/mobile/src/store/appOptions.js index b2c36e461b..4c63c24774 100644 --- a/apps/spreadsheeteditor/mobile/src/store/appOptions.js +++ b/apps/spreadsheeteditor/mobile/src/store/appOptions.js @@ -71,9 +71,30 @@ export class storeAppOptions { this.mergeFolderUrl = config.mergeFolderUrl; this.canAnalytics = false; this.canRequestClose = config.canRequestClose; - this.canBackToFolder = (config.canBackToFolder!==false) && (typeof (config.customization) == 'object') && (typeof (config.customization.goback) == 'object') - && (!!(config.customization.goback.url) || config.customization.goback.requestClose && this.canRequestClose); - this.canBack = this.canBackToFolder === true; + this.canCloseEditor = false; + + let canBack = false; + + if (typeof config.customization === 'object' && config.customization !== null) { + const { goback, close } = config.customization; + + if (typeof goback === 'object' && config.canBackToFolder !== false) { + const hasUrl = !!goback.url; + const requestClose = goback.requestClose && this.canRequestClose; + + canBack = close === undefined ? hasUrl || requestClose : hasUrl && !goback.requestClose; + + if (goback.requestClose) { + console.log("Obsolete: The 'requestClose' parameter of the 'customization.goback' section is deprecated. Please use 'close' parameter in the 'customization' section instead."); + } + } + + if (typeof close === 'object' && close !== null) { + this.canCloseEditor = !!close.visible && this.canRequestClose && !this.isDesktopApp; + } + } + + this.canBack = this.canBackToFolder = canBack; this.canPlugins = false; AscCommon.UserInfoParser.setParser(true); diff --git a/apps/spreadsheeteditor/mobile/src/view/settings/SettingsPage.jsx b/apps/spreadsheeteditor/mobile/src/view/settings/SettingsPage.jsx index 170f24329e..8984f2a08f 100644 --- a/apps/spreadsheeteditor/mobile/src/view/settings/SettingsPage.jsx +++ b/apps/spreadsheeteditor/mobile/src/view/settings/SettingsPage.jsx @@ -15,6 +15,8 @@ const SettingsPage = inject('storeAppOptions', 'storeSpreadsheetInfo')(observer( const settingsContext = useContext(SettingsContext); const _t = t('View.Settings', {returnObjects: true}); const docTitle = storeSpreadsheetInfo.dataDoc?.title ?? ''; + const canCloseEditor = appOptions.canCloseEditor; + const closeButtonText = canCloseEditor && appOptions.customization.close.text; const navbar =
    {docTitle}
    @@ -124,6 +126,9 @@ const SettingsPage = inject('storeAppOptions', 'storeSpreadsheetInfo')(observer( } + {canCloseEditor && + Common.Notifications.trigger('close')}> + } )