Migrate editors to components, disable previous editor when selecting new one
This commit is contained in:
@@ -93,17 +93,18 @@ angular.module('app.frontend')
|
||||
|
||||
this.selectedEditor = function(editorComponent) {
|
||||
this.showEditorMenu = false;
|
||||
|
||||
if(this.editorComponent && this.editorComponent !== editorComponent) {
|
||||
// This disassociates the editor from the note, but the component itself still needs to be deactivated
|
||||
this.disableComponentForCurrentItem(this.editorComponent);
|
||||
// Now deactivate the component
|
||||
componentManager.deactivateComponent(this.editorComponent);
|
||||
}
|
||||
|
||||
if(editorComponent) {
|
||||
this.enableComponentForCurrentItem(editorComponent);
|
||||
} else {
|
||||
// Use plain system editor
|
||||
if(this.editorComponent) {
|
||||
// This disassociates the editor from the note, but the component itself still needs to be deactivated
|
||||
this.disableComponentForCurrentItem(this.editorComponent);
|
||||
// Now deactivate the component
|
||||
componentManager.deactivateComponent(this.editorComponent);
|
||||
}
|
||||
}
|
||||
|
||||
this.editorComponent = editorComponent;
|
||||
}.bind(this)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
angular.module('app.frontend')
|
||||
.controller('HomeCtrl', function ($scope, $location, $rootScope, $timeout, modelManager,
|
||||
dbManager, syncManager, authManager, themeManager, passcodeManager, storageManager) {
|
||||
dbManager, syncManager, authManager, themeManager, passcodeManager, storageManager, migrationManager) {
|
||||
|
||||
storageManager.initialize(passcodeManager.hasPasscode(), authManager.isEphemeralSession());
|
||||
|
||||
|
||||
@@ -148,6 +148,12 @@ class ComponentManager {
|
||||
})
|
||||
}
|
||||
|
||||
componentForUrl(url) {
|
||||
return this.components.filter(function(component){
|
||||
return component.url === url;
|
||||
})[0];
|
||||
}
|
||||
|
||||
componentForSessionKey(key) {
|
||||
return _.find(this.components, {sessionKey: key});
|
||||
}
|
||||
@@ -493,18 +499,27 @@ class ComponentManager {
|
||||
}
|
||||
|
||||
disassociateComponentWithItem(component, item) {
|
||||
_.pull(component.associatedItemIds, item.uuid);
|
||||
|
||||
if(component.disassociatedItemIds.indexOf(item.uuid) !== -1) {
|
||||
return;
|
||||
}
|
||||
_.pull(component.associatedItemIds, item.uuid);
|
||||
|
||||
component.disassociatedItemIds.push(item.uuid);
|
||||
|
||||
component.setDirty(true);
|
||||
this.syncManager.sync();
|
||||
}
|
||||
|
||||
associateComponentWithItem(component, item) {
|
||||
_.pull(component.disassociatedItemIds, item.uuid);
|
||||
|
||||
if(component.associatedItemIds.includes(item.uuid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
component.associatedItemIds.push(item.uuid);
|
||||
|
||||
component.setDirty(true);
|
||||
this.syncManager.sync();
|
||||
}
|
||||
|
||||
@@ -7,14 +7,13 @@ class GlobalExtensionsMenu {
|
||||
};
|
||||
}
|
||||
|
||||
controller($scope, extensionManager, syncManager, modelManager, themeManager, editorManager, componentManager) {
|
||||
controller($scope, extensionManager, syncManager, modelManager, themeManager, componentManager) {
|
||||
'ngInject';
|
||||
|
||||
$scope.formData = {};
|
||||
|
||||
$scope.extensionManager = extensionManager;
|
||||
$scope.themeManager = themeManager;
|
||||
$scope.editorManager = editorManager;
|
||||
$scope.componentManager = componentManager;
|
||||
|
||||
$scope.serverExtensions = modelManager.itemsForContentType("SF|Extension");
|
||||
@@ -120,23 +119,6 @@ class GlobalExtensionsMenu {
|
||||
}
|
||||
|
||||
|
||||
// Editors
|
||||
|
||||
$scope.deleteEditor = function(editor) {
|
||||
if(confirm("Are you sure you want to delete this editor?")) {
|
||||
editorManager.deleteEditor(editor);
|
||||
}
|
||||
}
|
||||
|
||||
$scope.setDefaultEditor = function(editor) {
|
||||
editorManager.setDefaultEditor(editor);
|
||||
}
|
||||
|
||||
$scope.removeDefaultEditor = function(editor) {
|
||||
editorManager.removeDefaultEditor(editor);
|
||||
}
|
||||
|
||||
|
||||
// Components
|
||||
|
||||
$scope.revokePermissions = function(component) {
|
||||
@@ -219,11 +201,6 @@ class GlobalExtensionsMenu {
|
||||
}
|
||||
}
|
||||
|
||||
$scope.handleEditorLink = function(link, completion) {
|
||||
editorManager.addNewEditorFromURL(link);
|
||||
completion();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
class EditorManager {
|
||||
|
||||
constructor($rootScope, modelManager, syncManager) {
|
||||
this.syncManager = syncManager;
|
||||
this.modelManager = modelManager;
|
||||
|
||||
this.editorType = "SN|Editor";
|
||||
this._systemEditor = {
|
||||
systemEditor: true,
|
||||
name: "Plain"
|
||||
}
|
||||
|
||||
$rootScope.$on("sync:completed", function(){
|
||||
// we want to wait for sync completion before creating a syncable system editor
|
||||
// we need to sync the system editor so that we can assign note preferences to it
|
||||
// that is, when a user selects Plain for a note, we need to remember that
|
||||
if(this.systemEditor.uuid) {
|
||||
return;
|
||||
}
|
||||
|
||||
var liveSysEditor = _.find(this.allEditors, {systemEditor: true});
|
||||
if(liveSysEditor) {
|
||||
this._systemEditor = liveSysEditor;
|
||||
} else {
|
||||
this._systemEditor = modelManager.createItem({
|
||||
content_type: this.editorType,
|
||||
systemEditor: true,
|
||||
name: "Plain"
|
||||
})
|
||||
modelManager.addItem(this._systemEditor);
|
||||
this._systemEditor.setDirty(true);
|
||||
syncManager.sync();
|
||||
}
|
||||
}.bind(this))
|
||||
}
|
||||
|
||||
get allEditors() {
|
||||
return this.modelManager.itemsForContentType(this.editorType);
|
||||
}
|
||||
|
||||
get externalEditors() {
|
||||
return this.allEditors.filter(function(editor){
|
||||
return !editor.systemEditor;
|
||||
})
|
||||
}
|
||||
|
||||
get systemEditors() {
|
||||
return [this.systemEditor];
|
||||
}
|
||||
|
||||
get systemEditor() {
|
||||
return this._systemEditor;
|
||||
}
|
||||
|
||||
get defaultEditor() {
|
||||
return _.find(this.externalEditors, {default: true});
|
||||
}
|
||||
|
||||
editorForUrl(url) {
|
||||
return this.externalEditors.filter(function(editor){return editor.url == url})[0];
|
||||
}
|
||||
|
||||
setDefaultEditor(editor) {
|
||||
var defaultEditor = this.defaultEditor;
|
||||
if(defaultEditor) {
|
||||
defaultEditor.default = false;
|
||||
defaultEditor.setDirty(true);
|
||||
}
|
||||
editor.default = true;
|
||||
editor.setDirty(true);
|
||||
this.syncManager.sync();
|
||||
}
|
||||
|
||||
removeDefaultEditor(editor) {
|
||||
editor.default = false;
|
||||
editor.setDirty(true);
|
||||
this.syncManager.sync();
|
||||
}
|
||||
|
||||
addNewEditorFromURL(url) {
|
||||
var name = getParameterByName("name", url);
|
||||
var editor = this.modelManager.createItem({
|
||||
content_type: this.editorType,
|
||||
url: url,
|
||||
name: name
|
||||
})
|
||||
|
||||
this.modelManager.addItem(editor);
|
||||
editor.setDirty(true);
|
||||
this.syncManager.sync();
|
||||
}
|
||||
|
||||
deleteEditor(editor) {
|
||||
this.modelManager.setItemToBeDeleted(editor);
|
||||
this.syncManager.sync();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
angular.module('app.frontend').service('editorManager', EditorManager);
|
||||
62
app/assets/javascripts/app/services/migrationManager.js
Normal file
62
app/assets/javascripts/app/services/migrationManager.js
Normal file
@@ -0,0 +1,62 @@
|
||||
class MigrationManager {
|
||||
|
||||
constructor($rootScope, modelManager, syncManager, componentManager) {
|
||||
this.$rootScope = $rootScope;
|
||||
this.modelManager = modelManager;
|
||||
this.syncManager = syncManager;
|
||||
this.componentManager = componentManager;
|
||||
|
||||
this.migrators = [];
|
||||
|
||||
this.addEditorToComponentMigrator();
|
||||
|
||||
this.modelManager.addItemSyncObserver("migration-manager", "*", (allItems, validItems, deletedItems) => {
|
||||
for(var migrator of this.migrators) {
|
||||
var items = allItems.filter((item) => {return item.content_type == migrator.content_type});
|
||||
if(items.length > 0) {
|
||||
migrator.handler(items);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
Migrate SN|Editor to SN|Component. Editors are deprecated as of November 2017. Editors using old APIs must
|
||||
convert to using the new component API.
|
||||
*/
|
||||
|
||||
addEditorToComponentMigrator() {
|
||||
this.migrators.push({
|
||||
content_type: "SN|Editor",
|
||||
|
||||
handler: (editors) => {
|
||||
// Convert editors to components
|
||||
for(var editor of editors) {
|
||||
// If there's already a component for this url, then skip this editor
|
||||
if(editor.url && !this.componentManager.componentForUrl(editor.url)) {
|
||||
var component = this.modelManager.createItem({
|
||||
content_type: "SN|Component",
|
||||
url: editor.url,
|
||||
name: editor.name,
|
||||
area: "editor-editor"
|
||||
})
|
||||
component.setAppDataItem("data", editor.data);
|
||||
component.setDirty(true);
|
||||
this.modelManager.addItem(component);
|
||||
console.log("Created component", component, "From editor", editor);
|
||||
}
|
||||
}
|
||||
|
||||
for(let editor of editors) {
|
||||
editor.setItemToBeDeleted();
|
||||
}
|
||||
|
||||
this.syncManager.sync();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
angular.module('app.frontend').service('migrationManager', MigrationManager);
|
||||
@@ -4,7 +4,7 @@
|
||||
.float-group.h20
|
||||
%h1.tinted.pull-left Extensions
|
||||
%a.block.pull-right.dashboard-link{"href" => "https://dashboard.standardnotes.org", "target" => "_blank"} Open Dashboard
|
||||
%div.clear{"ng-if" => "!extensionManager.extensions.length && !themeManager.themes.length && !editorManager.externalEditors.length"}
|
||||
%div.clear{"ng-if" => "!extensionManager.extensions.length && !themeManager.themes.length && !componentManager.components.length"}
|
||||
%p Customize your experience with editors, themes, and actions.
|
||||
.tinted-box.mt-10
|
||||
%h3 Available as part of the Extended subscription.
|
||||
@@ -34,25 +34,6 @@
|
||||
%p.small.selectable.wrap{"ng-if" => "theme.showLink"}
|
||||
{{theme.url}}
|
||||
|
||||
%div{"ng-if" => "editorManager.externalEditors.length > 0"}
|
||||
.header.container.section-margin
|
||||
%h2 Editors
|
||||
%p{"style" => "margin-top: 3px;"} Choose "Editor" in the note menu to use an editor for a specific note.
|
||||
%ul
|
||||
%li{"ng-repeat" => "editor in editorManager.externalEditors | orderBy: 'name'", "ng-click" => "clickedExtension(editor)"}
|
||||
.container
|
||||
%strong.red.medium{"ng-if" => "editor.conflict_of"} Conflicted copy
|
||||
%h3
|
||||
%input.bold{"ng-if" => "editor.rename", "ng-model" => "editor.tempName", "ng-keyup" => "$event.keyCode == 13 && submitExtensionRename(editor);", "mb-autofocus" => "true", "should-focus" => "true"}
|
||||
%span{"ng-if" => "!editor.rename"} {{editor.name}}
|
||||
%div.mt-5{"ng-if" => "editor.showDetails"}
|
||||
.link-group
|
||||
%a{"ng-if" => "!editor.default", "ng-click" => "setDefaultEditor(editor); $event.stopPropagation();"} Make Default
|
||||
%a.tinted{"ng-if" => "editor.default", "ng-click" => "removeDefaultEditor(editor); $event.stopPropagation();"} Remove as Default
|
||||
%a{"ng-click" => "renameExtension(editor); $event.stopPropagation();"} Rename
|
||||
%a{"ng-click" => "editor.showUrl = !editor.showUrl; $event.stopPropagation();"} Show Link
|
||||
%a.red{ "ng-click" => "deleteEditor(editor); $event.stopPropagation();"} Delete
|
||||
.wrap.mt-5.selectable{"ng-if" => "editor.showUrl"} {{editor.url}}
|
||||
|
||||
%div{"ng-if" => "extensionManager.extensions.length"}
|
||||
.header.container.section-margin
|
||||
|
||||
Reference in New Issue
Block a user