diff --git a/app/assets/javascripts/app/frontend/models/app/extension.js b/app/assets/javascripts/app/frontend/models/app/extension.js index 097f9212f..acd42b4e2 100644 --- a/app/assets/javascripts/app/frontend/models/app/extension.js +++ b/app/assets/javascripts/app/frontend/models/app/extension.js @@ -58,7 +58,7 @@ class Extension extends Item { actionsInGlobalContext() { return this.actions.filter(function(action){ - return action.context == "global" || action.sync_provider == true; + return action.context == "global"; }) } diff --git a/app/assets/javascripts/app/services/authManager.js b/app/assets/javascripts/app/services/authManager.js index d2b0ea24c..72a1dbe84 100644 --- a/app/assets/javascripts/app/services/authManager.js +++ b/app/assets/javascripts/app/services/authManager.js @@ -167,12 +167,6 @@ angular.module('app.frontend') }) } - - /* - Sync - */ - - /* Import */ diff --git a/app/assets/javascripts/app/services/directives/views/globalExtensionsMenu.js b/app/assets/javascripts/app/services/directives/views/globalExtensionsMenu.js index 5834e4bc7..9945ac81c 100644 --- a/app/assets/javascripts/app/services/directives/views/globalExtensionsMenu.js +++ b/app/assets/javascripts/app/services/directives/views/globalExtensionsMenu.js @@ -31,9 +31,7 @@ class GlobalExtensionsMenu { } $scope.selectedAction = function(action, extension) { - action.running = true; extensionManager.executeAction(action, extension, null, function(response){ - action.running = false; if(response && response.error) { action.error = true; alert("There was an error performing this action. Please try again."); diff --git a/app/assets/javascripts/app/services/extensionManager.js b/app/assets/javascripts/app/services/extensionManager.js index 9dadd8b34..ff44b6350 100644 --- a/app/assets/javascripts/app/services/extensionManager.js +++ b/app/assets/javascripts/app/services/extensionManager.js @@ -6,7 +6,6 @@ class ExtensionManager { this.authManager = authManager; this.enabledRepeatActionUrls = JSON.parse(localStorage.getItem("enabledRepeatActionUrls")) || []; this.decryptedExtensions = JSON.parse(localStorage.getItem("decryptedExtensions")) || []; - this.extensionEks = JSON.parse(localStorage.getItem("extensionEks")) || {}; this.syncManager = syncManager; modelManager.addItemSyncObserver("extensionManager", "Extension", function(items){ @@ -33,15 +32,6 @@ class ExtensionManager { }) } - ekForExtension(extension) { - return this.extensionEks[extension.url]; - } - - setEkForExtension(extension, ek) { - this.extensionEks[extension.url] = ek; - localStorage.setItem("extensionEks", JSON.stringify(this.extensionEks)); - } - actionWithURL(url) { for (var extension of this.extensions) { return _.find(extension.actions, {url: url}) @@ -146,23 +136,30 @@ class ExtensionManager { executeAction(action, extension, item, callback) { - //todo - if(this.extensionUsesEncryptedData(extension)) { + if(this.extensionUsesEncryptedData(extension) && this.authManager.offline()) { alert("To send data encrypted, you must have an encryption key, and must therefore be signed in."); callback(null); return; } + var customCallback = function(response) { + action.running = false; + callback(response); + } + + action.running = true; + switch (action.verb) { case "get": { this.Restangular.oneUrl(action.url, action.url).get().then(function(response){ action.error = false; var items = response.items; this.modelManager.mapResponseItemsToLocalModels(items); - callback(items); + customCallback(items); }.bind(this)) .catch(function(response){ action.error = true; + customCallback(null); }) break; @@ -171,7 +168,7 @@ class ExtensionManager { case "show": { var win = window.open(action.url, '_blank'); win.focus(); - callback(); + customCallback(); break; } @@ -190,7 +187,7 @@ class ExtensionManager { } this.performPost(action, extension, params, function(response){ - callback(response); + customCallback(response); }); break; @@ -274,14 +271,18 @@ class ExtensionManager { var params = this.outgoingParamsForItem(item, extension); return params; }.bind(this)) - this.performPost(action, extension, params, null); + + action.running = true; + this.performPost(action, extension, params, function(){ + action.running = false; + }); } else { // todo } } outgoingParamsForItem(item, extension) { - var itemParams = new itemParams(item, extension.ek); + var itemParams = new ItemParams(item, this.syncManager.masterKey); return itemParams.paramsForExtension(); } diff --git a/app/assets/stylesheets/app/_directives.scss b/app/assets/stylesheets/app/_directives.scss index e9a9625bd..39eb623dc 100644 --- a/app/assets/stylesheets/app/_directives.scss +++ b/app/assets/stylesheets/app/_directives.scss @@ -5,7 +5,6 @@ margin-top: 18px; } - .ext-header { background-color: #ededed; border-bottom: 1px solid #d3d3d3; @@ -69,147 +68,3 @@ } } } - - -/** -Extensions -*/ - -.extensions-panel { - font-size: 14px; - - .extension-link { - margin-top: 8px; - - a { - color: $blue-color !important; - font-weight: bold; - } - } -} - -.extension-form { - margin-top: 8px; -} - -.registered-extensions { - - .extension { - margin-bottom: 18px; - padding: 14px 6px; - padding-bottom: 8px; - color: black; - - .ek-input-wrapper { - text-align: center; - margin-top: 14px; - height: 30px; - - > input { - height: 100%; - border: 1px solid rgba(gray, 0.15); - padding: 5px; - width: 78%; - margin-right: 0; - } - - > button { - width: 20% !important; - height: 100% !important; - display: inline-block !important; - margin: 0 !important; - } - } - - a.option-link { - margin-top: 6px; - display: block; - text-align: center; - } - - .show-ek { - > .ek { - font-weight: bold; - margin-top: 2px; - } - - > .disclaimer { - margin-top: 2px; - font-size: 10px; - font-style: italic; - width: 60%; - margin-left: auto; - margin-right: auto; - } - } - - a { - color: $blue-color !important; - font-size: 12px !important; - font-weight: bold !important; - } - - .extension-name { - font-weight: bold; - font-size: 16px; - margin-bottom: 6px; - text-align: center; - } - - .encryption-format { - margin-top: 4px; - font-size: 12px; - text-align: center; - - > .title { - font-size: 13px; - // font-weight: bold; - margin-bottom: 2px; - } - } - - .extension-subtitle { - font-size: 14px; - margin-bottom: 10px; - } - - .extension-actions { - margin-top: 15px; - font-size: 12px; - - .action { - padding: 13px; - margin-bottom: 10px; - background-color: rgba(white, 0.9); - border: 1px solid rgba(gray, 0.15); - - .action-name { - font-weight: bold; - } - - .action-permissions { - margin-top: 2px; - a { - font-weight: normal !important; - } - } - - > .execute-type { - font-size: 12px; - margin-bottom: 1px; - } - - > .error { - color: red; - margin-top: 6px; - } - - > .last-run { - opacity: 0.5; - font-size: 11px; - margin-top: 6px; - } - } - } - } -} diff --git a/app/assets/stylesheets/app/_header.scss b/app/assets/stylesheets/app/_header.scss index 9f4bb069a..be5c8c8ce 100644 --- a/app/assets/stylesheets/app/_header.scss +++ b/app/assets/stylesheets/app/_header.scss @@ -22,6 +22,10 @@ margin-top: 25px !important; } +.mb-5 { + margin-bottom: 5px !important; +} + .mb-10 { margin-bottom: 10px !important; } @@ -72,6 +76,10 @@ padding: 10px !important; } +.pb-4 { + padding-bottom: 4px !important; +} + .large-padding { padding: 22px !important; } @@ -92,6 +100,10 @@ font-weight: normal !important; } +.small { + font-size: 10px !important; +} + .inline { display: inline-block; } diff --git a/app/assets/templates/frontend/directives/global-extensions-menu.html.haml b/app/assets/templates/frontend/directives/global-extensions-menu.html.haml index e1119a642..9f9f8d57a 100644 --- a/app/assets/templates/frontend/directives/global-extensions-menu.html.haml +++ b/app/assets/templates/frontend/directives/global-extensions-menu.html.haml @@ -1,58 +1,55 @@ -.panel.panel-default.account-panel.panel-right.extensions-panel +.panel.panel-default.account-panel.panel-right .panel-body %div{"style" => "font-size: 18px;", "ng-if" => "!extensionManager.extensions.length"} No extensions installed - .registered-extensions{"ng-if" => "extensionManager.extensions.length"} - .extension{"ng-repeat" => "extension in extensionManager.extensions", "ng-init" => "extension.formData = {}"} - .extension-name {{extension.name}} - .encryption-format - .title Send data: - %label + %div{"ng-if" => "extensionManager.extensions.length"} + %section.gray-bg.inline-h.mb-10.medium-padding{"ng-repeat" => "extension in extensionManager.extensions", "ng-init" => "extension.formData = {}"} + %h3.center-align {{extension.name}} + .center-align.centered.mt-10 + %label.block.normal Send data: + %label.normal %input{"type" => "radio", "ng-model" => "extension.encrypted", "ng-value" => "true", "ng-change" => "changeExtensionEncryptionFormat(true, extension)"} Encrypted - %label + %label.normal %input{"type" => "radio", "ng-model" => "extension.encrypted", "ng-value" => "false", "ng-change" => "changeExtensionEncryptionFormat(false, extension)"} Decrypted - .extension-actions - .action{"ng-repeat" => "action in extension.actionsInGlobalContext()"} - .action-name {{action.label}} - .action-desc{"style" => "font-style: italic;"} {{action.desc}} - .execute-type{"ng-if" => "action.repeat_mode == 'watch'"} - Repeats when a change is made to your items. - .execute-type{"ng-if" => "action.repeat_mode == 'loop'"} - Repeats at most once every {{action.repeat_timeout}} seconds - .action-permissions - %a{"ng-click" => "action.showPermissions = !action.showPermissions"} {{action.showPermissions ? "Hide permissions" : "Show permissions"}} - %div{"ng-if" => "action.showPermissions"} - {{action.permissionsString}} - .encryption-type - %span {{action.encryptionModeString}} - .execute - %div{"ng-if" => "action.repeat_mode"} - %div{"ng-if" => "extensionManager.isRepeatActionEnabled(action)", "ng-click" => "extensionManager.disableRepeatAction(action, extension)"} Disable - %div{"ng-if" => "!extensionManager.isRepeatActionEnabled(action)", "ng-click" => "extensionManager.enableRepeatAction(action, extension)"} Enable - %div{"ng-if" => "!action.repeat_mode", "ng-click" => "selectedAction(action, extension)"} - %div{"ng-if" => "!action.running"} - Perform Action - %div{"ng-if" => "action.running"} - .spinner.execution-spinner - .last-run{"ng-if" => "!action.error && action.lastExecuted && !action.running"} - Last run {{action.lastExecuted | appDateTime}} - .error{"ng-if" => "action.error"} - Error performing action. + .small-v-space - %a.option-link{"ng-click" => "deleteExtension(extension)"} Remove extension + %section.inline-h.white-bg.medium-padding.mb-10.pb-4{"ng-repeat" => "action in extension.actionsInGlobalContext()"} + %label.block {{action.label}} + %em{"style" => "font-style: italic;"} {{action.desc}} + %em{"ng-if" => "action.repeat_mode == 'watch'"} + Repeats when a change is made to your items. + %em{"ng-if" => "action.repeat_mode == 'loop'"} + Repeats at most once every {{action.repeat_timeout}} seconds + %div + %a{"ng-click" => "action.showPermissions = !action.showPermissions"} {{action.showPermissions ? "Hide permissions" : "Show permissions"}} + %div{"ng-if" => "action.showPermissions"} + {{action.permissionsString}} + %label.block.normal {{action.encryptionModeString}} - .extension-link - %a{"ng-click" => "toggleExtensionForm()"} Add new extension + %div + .mt-5{"ng-if" => "action.repeat_mode"} + %button.light{"ng-if" => "extensionManager.isRepeatActionEnabled(action)", "ng-click" => "extensionManager.disableRepeatAction(action, extension)"} Disable + %button.light{"ng-if" => "!extensionManager.isRepeatActionEnabled(action)", "ng-click" => "extensionManager.enableRepeatAction(action, extension)"} Enable + %button.light.mt-10{"ng-if" => "!action.running && !action.repeat_mode", "ng-click" => "selectedAction(action, extension)"} + Perform Action + .spinner.execution-spinner.mb-5.centered.center-align.block{"ng-if" => "action.running"} + %p.mb-5.mt-5.small{"ng-if" => "!action.error && action.lastExecuted && !action.running"} + Last run {{action.lastExecuted | appDateTime}} + %label.red{"ng-if" => "action.error"} + Error performing action. - %form.extension-form{"ng-if" => "showNewExtensionForm"} - .form-tag.has-feedback - %input.form-control{:autofocus => 'autofocus', :name => 'url', :placeholder => 'Extension URL', :required => true, :type => 'url', 'ng-model' => 'newExtensionData.url'} + %a.block.center-align.mt-10{"ng-click" => "deleteExtension(extension)"} Remove extension + + .large-v-space + + %a.block{"ng-click" => "toggleExtensionForm()"} Add new extension + + %form.mt-10.mb-10{"ng-if" => "showNewExtensionForm"} + %input.form-control{:autofocus => 'autofocus', :name => 'url', :placeholder => 'Extension URL', :required => true, :type => 'url', 'ng-model' => 'newExtensionData.url'} %button.btn.dark-button.btn-block{"ng-click" => "submitNewExtensionForm()", :type => 'submit', "data-style" => "expand-right", "data-size" => "s", "state" => "buttonState"} - %span.ladda-label Add Extension + Add Extension - .extension-link - %a{"ng-click" => "reloadExtensionsPressed()", "ng-if" => "extensionManager.extensions.length > 0"} Reload all extensions - .extension-link - %a{"href" => "https://standardnotes.org/extensions", "target" => "_blank"} List of available extensions + %a.block.mt-5{"ng-click" => "reloadExtensionsPressed()", "ng-if" => "extensionManager.extensions.length > 0"} Reload all extensions + %a.block.mt-5{"href" => "https://standardnotes.org/extensions", "target" => "_blank"} List of available extensions