From 6dad78715b8c69c9fa575f72c4ad8191dd44a963 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 14 Dec 2018 14:12:02 -0600 Subject: [PATCH] Use editors for revision preview --- .../javascripts/app/controllers/editor.js | 12 +---- .../directives/views/revisionPreviewModal.js | 46 +++++++++++++++++-- .../app/services/componentManager.js | 37 ++++++++++++++- .../revision-preview-modal.html.haml | 4 +- 4 files changed, 80 insertions(+), 19 deletions(-) diff --git a/app/assets/javascripts/app/controllers/editor.js b/app/assets/javascripts/app/controllers/editor.js index 5855c2a0a..830585bd8 100644 --- a/app/assets/javascripts/app/controllers/editor.js +++ b/app/assets/javascripts/app/controllers/editor.js @@ -158,17 +158,7 @@ angular.module('app') } this.editorForNote = function(note) { - let editors = componentManager.componentsForArea("editor-editor"); - for(var editor of editors) { - if(editor.isExplicitlyEnabledForItem(note)) { - return editor; - } - } - - // No editor found for note. Use default editor, if note does not prefer system editor - if(!note.getAppDataItem("prefersPlainEditor")) { - return editors.filter((e) => {return e.isDefaultEditor()})[0]; - } + return componentManager.editorForNote(note); } this.closeAllMenus = function() { diff --git a/app/assets/javascripts/app/directives/views/revisionPreviewModal.js b/app/assets/javascripts/app/directives/views/revisionPreviewModal.js index d5d6313d3..03fde5113 100644 --- a/app/assets/javascripts/app/directives/views/revisionPreviewModal.js +++ b/app/assets/javascripts/app/directives/views/revisionPreviewModal.js @@ -10,15 +10,51 @@ class RevisionPreviewModal { } link($scope, el, attrs) { - - $scope.dismiss = function() { - el.remove(); - } + $scope.el = el; } - controller($scope, modelManager, syncManager) { + controller($scope, modelManager, syncManager, componentManager) { 'ngInject'; + $scope.dismiss = function() { + $scope.el.remove(); + $scope.$destroy(); + } + + $scope.$on("$destroy", function() { + componentManager.deregisterHandler($scope.identifier); + }); + + $scope.note = new SFItem({content: $scope.content, content_type: "Note"}); + // Set UUID to editoForNote can find proper editor, + // but then generate new uuid for note as not to save changes to original, if editor makes changes. + $scope.note.uuid = $scope.uuid; + let editor = componentManager.editorForNote($scope.note); + $scope.note.uuid = SFJS.crypto.generateUUIDSync(); + + if(editor) { + // Create temporary copy, as a lot of componentManager is uuid based, + // so might interfere with active editor. Be sure to copy only the content, as the + // top level editor object has non-copyable properties like .window, which cannot be transfered + $scope.editor = new SNComponent({content: editor.content}); + $scope.editor.readonly = true; + $scope.identifier = $scope.editor.uuid; + + componentManager.registerHandler({identifier: $scope.identifier, areas: ["editor-editor"], + contextRequestHandler: (component) => { + if(component == $scope.editor) { + return $scope.note; + } + }, + componentForSessionKeyHandler: (key) => { + if(key == $scope.editor.sessionKey) { + return $scope.editor; + } + } + }); + } + + $scope.restore = function(asCopy) { if(!asCopy && !confirm("Are you sure you want to replace the current note's contents with what you see in this preview?")) { return; diff --git a/app/assets/javascripts/app/services/componentManager.js b/app/assets/javascripts/app/services/componentManager.js index 628561489..ac0b4d34a 100644 --- a/app/assets/javascripts/app/services/componentManager.js +++ b/app/assets/javascripts/app/services/componentManager.js @@ -294,7 +294,15 @@ class ComponentManager { } componentForSessionKey(key) { - return _.find(this.components, {sessionKey: key}); + let component = _.find(this.components, {sessionKey: key}); + if(!component) { + for(let handler of this.handlers) { + if(handler.componentForSessionKeyHandler) { + component = handler.componentForSessionKeyHandler(key); + } + } + } + return component; } handleMessage(component, message) { @@ -350,7 +358,7 @@ class ComponentManager { // Notify observers for(let handler of this.handlers) { - if(handler.areas.includes(component.area) || handler.areas.includes("*")) { + if(handler.actionHandler && (handler.areas.includes(component.area) || handler.areas.includes("*"))) { this.timeout(function(){ handler.actionHandler(component, message.action, message.data); }) @@ -465,6 +473,13 @@ class ComponentManager { } handleSaveItemsMessage(component, message) { + if(component.readonly) { + // A component can be marked readonly if changes should not be saved. + // Particullary used for revision preview windows where the notes should not be savable. + alert(`The extension ${component.name} is trying to save, but it is in a locked state and cannot accept changes.`); + return; + } + var responseItems = message.data.items; var requiredPermissions; @@ -798,6 +813,10 @@ class ComponentManager { deregisterHandler(identifier) { var handler = _.find(this.handlers, {identifier: identifier}); + if(!handler) { + console.log("Attempting to deregister non-existing handler"); + return; + } this.handlers.splice(this.handlers.indexOf(handler), 1); } @@ -1021,6 +1040,20 @@ class ComponentManager { } } + editorForNote(note) { + let editors = this.componentsForArea("editor-editor"); + for(var editor of editors) { + if(editor.isExplicitlyEnabledForItem(note)) { + return editor; + } + } + + // No editor found for note. Use default editor, if note does not prefer system editor + if(!note.getAppDataItem("prefersPlainEditor")) { + return editors.filter((e) => {return e.isDefaultEditor()})[0]; + } + } + } diff --git a/app/assets/templates/directives/revision-preview-modal.html.haml b/app/assets/templates/directives/revision-preview-modal.html.haml index d9b8e3b87..bd0a5158a 100644 --- a/app/assets/templates/directives/revision-preview-modal.html.haml +++ b/app/assets/templates/directives/revision-preview-modal.html.haml @@ -10,6 +10,8 @@ %a.sk-a.info.close-button{"ng-click" => "restore(false)"} Restore %a.sk-a.info.close-button{"ng-click" => "restore(true)"} Restore as copy %a.sk-a.info.close-button{"ng-click" => "dismiss(); $event.stopPropagation()"} Close - .sk-panel-content.selectable + .sk-panel-content.selectable{"ng-if" => "!editor"} .sk-h2 {{content.title}} %p.normal.sk-p{"style" => "white-space: pre-wrap; font-size: 16px;"} {{content.text}} + + %component-view.component-view{"ng-if" => "editor", "component" => "editor"}