Functioning password change
This commit is contained in:
@@ -17,9 +17,9 @@ class AccountMenu {
|
|||||||
$scope.user = authManager.user;
|
$scope.user = authManager.user;
|
||||||
$scope.server = syncManager.serverURL;
|
$scope.server = syncManager.serverURL;
|
||||||
|
|
||||||
$timeout(() => {
|
// $timeout(() => {
|
||||||
$scope.openPasswordWizard("change-pw");
|
// $scope.openPasswordWizard("change-pw");
|
||||||
}, 0)
|
// }, 0)
|
||||||
|
|
||||||
$scope.close = function() {
|
$scope.close = function() {
|
||||||
$timeout(() => {
|
$timeout(() => {
|
||||||
|
|||||||
@@ -8,9 +8,20 @@ class PasswordWizard {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
controller($scope, modelManager, archiveManager, $timeout) {
|
link($scope, el, attrs) {
|
||||||
|
$scope.el = el;
|
||||||
|
}
|
||||||
|
|
||||||
|
controller($scope, modelManager, archiveManager, authManager, syncManager, $timeout) {
|
||||||
'ngInject';
|
'ngInject';
|
||||||
|
|
||||||
|
$scope.dismiss = function() {
|
||||||
|
$scope.el.remove();
|
||||||
|
$scope.$destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.formData = {};
|
||||||
|
|
||||||
const IntroStep = 0;
|
const IntroStep = 0;
|
||||||
const BackupStep = 1;
|
const BackupStep = 1;
|
||||||
const SignoutStep = 2;
|
const SignoutStep = 2;
|
||||||
@@ -21,7 +32,7 @@ class PasswordWizard {
|
|||||||
let DefaultContinueTitle = "Continue";
|
let DefaultContinueTitle = "Continue";
|
||||||
$scope.continueTitle = DefaultContinueTitle;
|
$scope.continueTitle = DefaultContinueTitle;
|
||||||
|
|
||||||
$scope.step = PasswordStep;
|
$scope.step = IntroStep;
|
||||||
|
|
||||||
$scope.titleForStep = function(step) {
|
$scope.titleForStep = function(step) {
|
||||||
switch (step) {
|
switch (step) {
|
||||||
@@ -30,9 +41,11 @@ class PasswordWizard {
|
|||||||
case SignoutStep:
|
case SignoutStep:
|
||||||
return "Sign out of all your devices";
|
return "Sign out of all your devices";
|
||||||
case PasswordStep:
|
case PasswordStep:
|
||||||
return $scope.changePassword ? "Enter password information" : "Enter your current password";
|
return $scope.changePassword ? "Password information" : "Enter your current password";
|
||||||
case SyncStep:
|
case SyncStep:
|
||||||
return "Encrypt and sync data with new keys";
|
return "Encrypt and sync data with new keys";
|
||||||
|
case FinishStep:
|
||||||
|
return "Sign back in to your devices";
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -49,6 +62,12 @@ class PasswordWizard {
|
|||||||
}();
|
}();
|
||||||
|
|
||||||
$scope.continue = function() {
|
$scope.continue = function() {
|
||||||
|
|
||||||
|
if($scope.step == FinishStep) {
|
||||||
|
$scope.dismiss();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let next = () => {
|
let next = () => {
|
||||||
$scope.step += 1;
|
$scope.step += 1;
|
||||||
$scope.initializeStep($scope.step);
|
$scope.initializeStep($scope.step);
|
||||||
@@ -74,86 +93,118 @@ class PasswordWizard {
|
|||||||
$scope.showSpinner = true;
|
$scope.showSpinner = true;
|
||||||
$scope.continueTitle = "Generating Keys...";
|
$scope.continueTitle = "Generating Keys...";
|
||||||
$timeout(() => {
|
$timeout(() => {
|
||||||
$scope.validatePasswordInformation(() => {
|
$scope.validateCurrentPassword((success) => {
|
||||||
$scope.showSpinner = false;
|
$scope.showSpinner = false;
|
||||||
$scope.continueTitle = DefaultContinueTitle;
|
$scope.continueTitle = DefaultContinueTitle;
|
||||||
callback();
|
if(success) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let FailedSyncMessage = "There was an error re-encrypting your items. Your password was changed, but not all your items were properly re-encrypted and synced. You should try syncing again. If all else fails, you should restore your notes from backup.";
|
||||||
|
|
||||||
$scope.initializeStep = function(step) {
|
$scope.initializeStep = function(step) {
|
||||||
if(step == SyncStep) {
|
if(step == SyncStep) {
|
||||||
$scope.lockContinue = true;
|
$scope.lockContinue = true;
|
||||||
$scope.resyncData(() => {
|
$scope.formData.status = "Processing encryption keys...";
|
||||||
$scope.lockContinue = false;
|
$scope.formData.processing = true;
|
||||||
|
|
||||||
|
$scope.processPasswordChange((passwordSuccess) => {
|
||||||
|
$scope.formData.statusError = $scope.formData.processing = !passwordSuccess;
|
||||||
|
if(passwordSuccess) {
|
||||||
|
$scope.formData.status = "Encrypting data with new keys...";
|
||||||
|
|
||||||
|
$scope.resyncData((syncSuccess) => {
|
||||||
|
$scope.formData.statusError = $scope.formData.processing = !syncSuccess;
|
||||||
|
if(syncSuccess) {
|
||||||
|
$scope.lockContinue = false;
|
||||||
|
|
||||||
|
if($scope.changePassword) {
|
||||||
|
$scope.formData.status = "Successfully changed password and re-encrypted all items. Press Continue to proceed.";
|
||||||
|
} else if($scope.securityUpdate) {
|
||||||
|
$scope.formData.status = "Successfully performed security update and re-encrypted all items. Press Continue to proceed.";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$scope.formData.status = FailedSyncMessage;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
$scope.formData.status = "Unable to process your password. Please try again.";
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(step == FinishStep) {
|
||||||
|
$scope.continueTitle = "Finish";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.validatePasswordInformation = function(callback) {
|
$scope.validateCurrentPassword = function(callback) {
|
||||||
$timeout(() => {
|
let currentPassword = $scope.formData.currentPassword;
|
||||||
callback();
|
let newPass = $scope.securityUpdate ? currentPassword : $scope.formData.newPassword;
|
||||||
}, 1000)
|
|
||||||
|
if($scope.changePassword) {
|
||||||
|
if(!newPass || newPass.length == 0) {
|
||||||
|
callback(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newPass != $scope.formData.newPasswordConfirmation) {
|
||||||
|
alert("Your new password does not match its confirmation.");
|
||||||
|
$scope.formData.status = null;
|
||||||
|
callback(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!authManager.user.email) {
|
||||||
|
alert("We don't have your email stored. Please log out then log back in to fix this issue.");
|
||||||
|
$scope.formData.status = null;
|
||||||
|
callback(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure value for current password matches what's saved
|
||||||
|
let authParams = authManager.getAuthParams();
|
||||||
|
let password = $scope.formData.currentPassword;
|
||||||
|
SFJS.crypto.computeEncryptionKeysForUser(password, authParams, (keys) => {
|
||||||
|
let success = keys.mk === authManager.keys().mk;
|
||||||
|
if(!success) {
|
||||||
|
alert("The current password you entered is not correct. Please try again.");
|
||||||
|
}
|
||||||
|
$timeout(() => callback(success));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.resyncData = function(callback) {
|
$scope.resyncData = function(callback) {
|
||||||
$timeout(() => {
|
modelManager.setAllItemsDirty();
|
||||||
callback();
|
syncManager.sync((response) => {
|
||||||
}, 2000)
|
if(response.error) {
|
||||||
|
alert(FailedSyncMessage)
|
||||||
|
$timeout(() => callback(false));
|
||||||
|
} else {
|
||||||
|
$timeout(() => callback(true));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.submitPasswordChange = function() {
|
$scope.processPasswordChange = function(callback) {
|
||||||
|
let currentPassword = $scope.formData.currentPassword;
|
||||||
let newPass = $scope.newPasswordData.newPassword;
|
let newPass = $scope.securityUpdate ? currentPassword : $scope.formData.newPassword;
|
||||||
let currentPass = $scope.newPasswordData.currentPassword;
|
|
||||||
|
|
||||||
if(!newPass || newPass.length == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(newPass != $scope.newPasswordData.newPasswordConfirmation) {
|
|
||||||
alert("Your new password does not match its confirmation.");
|
|
||||||
$scope.newPasswordData.status = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var email = $scope.user.email;
|
|
||||||
if(!email) {
|
|
||||||
alert("We don't have your email stored. Please log out then log back in to fix this issue.");
|
|
||||||
$scope.newPasswordData.status = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.newPasswordData.status = "Generating New Keys...";
|
|
||||||
$scope.newPasswordData.showForm = false;
|
|
||||||
|
|
||||||
// perform a sync beforehand to pull in any last minutes changes before we change the encryption key (and thus cant decrypt new changes)
|
// perform a sync beforehand to pull in any last minutes changes before we change the encryption key (and thus cant decrypt new changes)
|
||||||
syncManager.sync(function(response){
|
syncManager.sync((response) => {
|
||||||
authManager.changePassword(email, currentPass, newPass, function(response){
|
authManager.changePassword(currentPassword, newPass, (response) => {
|
||||||
if(response.error) {
|
if(response.error) {
|
||||||
alert("There was an error changing your password. Please try again.");
|
alert("There was an error changing your password. Please try again.");
|
||||||
$scope.newPasswordData.status = null;
|
$timeout(() => callback(false));
|
||||||
return;
|
} else {
|
||||||
|
$timeout(() => callback(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// re-encrypt all items
|
|
||||||
$scope.newPasswordData.status = "Re-encrypting all items with your new key...";
|
|
||||||
|
|
||||||
modelManager.setAllItemsDirty();
|
|
||||||
syncManager.sync(function(response){
|
|
||||||
if(response.error) {
|
|
||||||
alert("There was an error re-encrypting your items. Your password was changed, but not all your items were properly re-encrypted and synced. You should try syncing again. If all else fails, you should restore your notes from backup.")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$scope.newPasswordData.status = "Successfully changed password and re-encrypted all items.";
|
|
||||||
$timeout(function(){
|
|
||||||
alert("Your password has been changed, and your items successfully re-encrypted and synced. You must sign out of all other signed in applications and sign in again, or else you may corrupt your data.")
|
|
||||||
$scope.newPasswordData = {};
|
|
||||||
}, 1000)
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
}, null, "submitPasswordChange")
|
}, null, "submitPasswordChange")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -235,7 +235,8 @@ angular.module('app')
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.changePassword = function(email, current_password, new_password, callback) {
|
this.changePassword = function(current_password, new_password, callback) {
|
||||||
|
let email = this.user.email;
|
||||||
SFJS.crypto.generateInitialEncryptionKeysForUser(email, new_password, (keys, authParams) => {
|
SFJS.crypto.generateInitialEncryptionKeysForUser(email, new_password, (keys, authParams) => {
|
||||||
var requestUrl = storageManager.getItem("server") + "/auth/change_pw";
|
var requestUrl = storageManager.getItem("server") + "/auth/change_pw";
|
||||||
var params = _.merge({current_password: current_password, new_password: keys.pw}, authParams);
|
var params = _.merge({current_password: current_password, new_password: keys.pw}, authParams);
|
||||||
|
|||||||
@@ -51,6 +51,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.small {
|
||||||
|
> .content {
|
||||||
|
width: 700px;
|
||||||
|
height: 335px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.background {
|
.background {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
|
|||||||
@@ -70,6 +70,10 @@ $screen-md-max: ($screen-lg-min - 1) !default;
|
|||||||
margin-top: 10px !important;
|
margin-top: 10px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mr-5 {
|
||||||
|
margin-right: 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
.faded {
|
.faded {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
@@ -107,10 +111,10 @@ $screen-md-max: ($screen-lg-min - 1) !default;
|
|||||||
font-weight: normal !important;
|
font-weight: normal !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.small {
|
.small-text {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.medium {
|
.medium-text {
|
||||||
font-size: 14px !important;
|
font-size: 14px !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,42 +76,6 @@
|
|||||||
|
|
||||||
%a.panel-row.condensed{"ng-click" => "openPasswordWizard('change-pw')"} Change Password
|
%a.panel-row.condensed{"ng-click" => "openPasswordWizard('change-pw')"} Change Password
|
||||||
|
|
||||||
-# .notification.warning{"ng-if" => "newPasswordData.changePassword"}
|
|
||||||
-# %h1.title Change Password
|
|
||||||
-# .text
|
|
||||||
-# %p Since your encryption key is based on your password, changing your password requires all your notes and tags to be re-encrypted using your new key.
|
|
||||||
-# %p If you have thousands of items, this can take several minutes — you must keep the application window open during this process.
|
|
||||||
-# %p After changing your password, you must log out of all other applications currently signed in to your account.
|
|
||||||
-# %p.bold It is highly recommended you download a backup of your data before proceeding.
|
|
||||||
-# .panel-row{"ng-if" => "!newPasswordData.status"}
|
|
||||||
-# .horizontal-group{"ng-if" => "!newPasswordData.showForm"}
|
|
||||||
-# %a.red{"ng-click" => "showPasswordChangeForm()"} Continue
|
|
||||||
-# %a{"ng-click" => "newPasswordData.changePassword = false; newPasswordData.showForm = false"} Cancel
|
|
||||||
-# .panel-row{"ng-if" => "newPasswordData.showForm"}
|
|
||||||
-# %form.panel-form.stretch
|
|
||||||
-# %input{:type => 'password', "ng-model" => "newPasswordData.newPassword", "placeholder" => "Enter new password"}
|
|
||||||
-# %input{:type => 'password', "ng-model" => "newPasswordData.newPasswordConfirmation", "placeholder" => "Confirm new password"}
|
|
||||||
-# .button-group.stretch.panel-row.form-submit
|
|
||||||
-# .button.info{"type" => "submit", "ng-click" => "submitPasswordChange()"}
|
|
||||||
-# .label Submit
|
|
||||||
-# %a{"ng-click" => "newPasswordData.changePassword = false; newPasswordData.showForm = false"} Cancel
|
|
||||||
-#
|
|
||||||
-# %p.italic.mt-10{"ng-if" => "newPasswordData.status"} {{newPasswordData.status}}
|
|
||||||
|
|
||||||
%a.panel-row.condensed{"ng-if" => "securityUpdateAvailable()", "ng-click" => "clickedSecurityUpdate()"} Security Update Available
|
|
||||||
.notification.default{"ng-if" => "securityUpdateData.showForm"}
|
|
||||||
%p
|
|
||||||
%a{"href" => "https://standardnotes.org/help/security-update", "target" => "_blank"} Learn more.
|
|
||||||
%form.panel-form.stretch{"ng-if" => "!securityUpdateData.processing", "ng-submit" => "submitSecurityUpdateForm()"}
|
|
||||||
%p Enter your password to update:
|
|
||||||
%input.panel-row{:type => 'password', "ng-model" => "securityUpdateData.password", "placeholder" => "Enter password"}
|
|
||||||
.button-group.stretch.panel-row.form-submit
|
|
||||||
%button.button.info{"ng-type" => "submit"}
|
|
||||||
.label Update
|
|
||||||
.panel-row{"ng-if" => "securityUpdateData.processing"}
|
|
||||||
%p.info Processing...
|
|
||||||
|
|
||||||
|
|
||||||
.panel-section
|
.panel-section
|
||||||
%h3.title.panel-row Encryption
|
%h3.title.panel-row Encryption
|
||||||
%h5.subtitle.info.panel-row{"ng-if" => "encryptionEnabled()"}
|
%h5.subtitle.info.panel-row{"ng-if" => "encryptionEnabled()"}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
access to this note.
|
access to this note.
|
||||||
|
|
||||||
|
|
||||||
.modal.medium{"ng-if" => "renderData.showRenderModal", "ng-click" => "$event.stopPropagation();"}
|
.modal.medium-text{"ng-if" => "renderData.showRenderModal", "ng-click" => "$event.stopPropagation();"}
|
||||||
.content
|
.content
|
||||||
.sn-component
|
.sn-component
|
||||||
.panel
|
.panel
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
"has-button" => "selectedEditor == editor || defaultEditor == editor", "button-text" => "defaultEditor == editor ? 'Undefault' : 'Set Default'",
|
"has-button" => "selectedEditor == editor || defaultEditor == editor", "button-text" => "defaultEditor == editor ? 'Undefault' : 'Set Default'",
|
||||||
"button-action" => "toggleDefaultForEditor(editor)", "button-class" => "defaultEditor == editor ? 'warning' : 'info'"}
|
"button-action" => "toggleDefaultForEditor(editor)", "button-class" => "defaultEditor == editor ? 'warning' : 'info'"}
|
||||||
.column{"ng-if" => "component.conflict_of || shouldDisplayRunningLocallyLabel(editor)"}
|
.column{"ng-if" => "component.conflict_of || shouldDisplayRunningLocallyLabel(editor)"}
|
||||||
%strong.red.medium{"ng-if" => "editor.conflict_of"} Conflicted copy
|
%strong.red.medium-text{"ng-if" => "editor.conflict_of"} Conflicted copy
|
||||||
.sublabel{"ng-if" => "shouldDisplayRunningLocallyLabel(editor)"} Running Locally
|
.sublabel{"ng-if" => "shouldDisplayRunningLocallyLabel(editor)"} Running Locally
|
||||||
|
|
||||||
%a.no-decoration{"ng-if" => "editors.length == 0", "href" => "https://standardnotes.org/extensions", "target" => "blank"}
|
%a.no-decoration{"ng-if" => "editors.length == 0", "href" => "https://standardnotes.org/extensions", "target" => "blank"}
|
||||||
@@ -22,5 +22,5 @@
|
|||||||
%menu-row{"ng-repeat" => "component in stack", "ng-click" => "selectComponent($event, component)", "title" => "component.name",
|
%menu-row{"ng-repeat" => "component in stack", "ng-click" => "selectComponent($event, component)", "title" => "component.name",
|
||||||
"circle" => "stackComponentEnabled(component) ? 'success' : 'danger'"}
|
"circle" => "stackComponentEnabled(component) ? 'success' : 'danger'"}
|
||||||
.column{"ng-if" => "component.conflict_of || shouldDisplayRunningLocallyLabel(component)"}
|
.column{"ng-if" => "component.conflict_of || shouldDisplayRunningLocallyLabel(component)"}
|
||||||
%strong.red.medium{"ng-if" => "component.conflict_of"} Conflicted copy
|
%strong.red.medium-text{"ng-if" => "component.conflict_of"} Conflicted copy
|
||||||
.sublabel{"ng-if" => "shouldDisplayRunningLocallyLabel(component)"} Running Locally
|
.sublabel{"ng-if" => "shouldDisplayRunningLocallyLabel(component)"} Running Locally
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
.modal.medium
|
.modal.small
|
||||||
.content
|
.content
|
||||||
.sn-component
|
.sn-component
|
||||||
.panel
|
.panel
|
||||||
.header
|
.header
|
||||||
%h1.title {{title}}
|
%h1.title {{title}}
|
||||||
%a.close-button{"ng-click" => "close()"} Close
|
%a.close-button{"ng-click" => "dismiss()"} Close
|
||||||
.content
|
.content
|
||||||
|
|
||||||
%div{"ng-if" => "step == 0"}
|
%div{"ng-if" => "step == 0"}
|
||||||
%div{"ng-if" => "changePassword"}
|
%div{"ng-if" => "changePassword"}
|
||||||
%p Since your encryption key is based on your password, changing your password requires all your notes and tags to be re-encrypted using your new key.
|
%h3.title.panel-row Change your password
|
||||||
%p If you have thousands of items, this can take several minutes—you must keep the application window open during this process.
|
%p Because your encryption key is based on your password, changing your password requires all your data to be re-encrypted using your new key.
|
||||||
|
%p This process will guide you through changing your password.
|
||||||
|
%p If you have many items, re-uploading your data can take several minutes. You must keep the application window open during this process.
|
||||||
%div{"ng-if" => "securityUpdate"}
|
%div{"ng-if" => "securityUpdate"}
|
||||||
|
%h3.title.panel-row Perform security update
|
||||||
%p Welcome to the security update process.
|
%p Welcome to the security update process.
|
||||||
|
|
||||||
%p.info Press Continue to proceed.
|
.panel-row
|
||||||
|
%strong.info Press Continue to proceed.
|
||||||
|
|
||||||
.panel-section{"ng-if" => "step > 0"}
|
.panel-section{"ng-if" => "step > 0"}
|
||||||
|
|
||||||
@@ -59,7 +63,20 @@
|
|||||||
%p.panel-row.danger
|
%p.panel-row.danger
|
||||||
Do not close this window until this process completes.
|
Do not close this window until this process completes.
|
||||||
|
|
||||||
|
%p.panel-row
|
||||||
|
.spinner.small.inline.info.mr-5{"ng-if" => "formData.processing"}
|
||||||
|
.inline.bold{"ng-class" => "{'info' : !formData.statusError, 'error' : formData.statusError}"}
|
||||||
|
{{formData.status}}
|
||||||
|
|
||||||
|
%div{"ng-if" => "step == 5"}
|
||||||
|
%div{"ng-if" => "changePassword"}
|
||||||
|
%p.panel-row Your password has been successfully changed.
|
||||||
|
%div{"ng-if" => "securityUpdate"}
|
||||||
|
%p.panel-row The security update has been successfully applied to your account.
|
||||||
|
|
||||||
|
%p.panel-row You may now sign back in to all your devices and close this window.
|
||||||
|
|
||||||
.footer
|
.footer
|
||||||
%a.right{"ng-click" => "continue()", "ng-class" => "{'disabled' : lockContinue}"}
|
%a.right{"ng-click" => "continue()", "ng-class" => "{'disabled' : lockContinue}"}
|
||||||
.spinner.small.inline.info{"ng-if" => "showSpinner", "style" => "margin-right: 5px;"}
|
.spinner.small.inline.info.mr-5{"ng-if" => "showSpinner"}
|
||||||
{{continueTitle}}
|
{{continueTitle}}
|
||||||
|
|||||||
@@ -44,16 +44,16 @@
|
|||||||
.infinite-scroll#notes-scrollable{"infinite-scroll" => "ctrl.paginate()", "can-load" => "true", "threshold" => "200"}
|
.infinite-scroll#notes-scrollable{"infinite-scroll" => "ctrl.paginate()", "can-load" => "true", "threshold" => "200"}
|
||||||
.note{"ng-repeat" => "note in (ctrl.sortedNotes = (ctrl.tag.notes | filter: ctrl.filterNotes | sortBy: ctrl.sortBy | limitTo:ctrl.notesToDisplay)) track by note.uuid",
|
.note{"ng-repeat" => "note in (ctrl.sortedNotes = (ctrl.tag.notes | filter: ctrl.filterNotes | sortBy: ctrl.sortBy | limitTo:ctrl.notesToDisplay)) track by note.uuid",
|
||||||
"ng-click" => "ctrl.selectNote(note, true)", "ng-class" => "{'selected' : ctrl.selectedNote == note}"}
|
"ng-click" => "ctrl.selectNote(note, true)", "ng-class" => "{'selected' : ctrl.selectedNote == note}"}
|
||||||
%strong.red.medium{"ng-if" => "note.conflict_of"} Conflicted copy
|
%strong.red.medium-text{"ng-if" => "note.conflict_of"} Conflicted copy
|
||||||
%strong.red.medium{"ng-if" => "note.errorDecrypting"} Error decrypting
|
%strong.red.medium-text{"ng-if" => "note.errorDecrypting"} Error decrypting
|
||||||
|
|
||||||
.pinned.tinted{"ng-if" => "note.pinned", "ng-class" => "{'tinted-selected' : ctrl.selectedNote == note}"}
|
.pinned.tinted{"ng-if" => "note.pinned", "ng-class" => "{'tinted-selected' : ctrl.selectedNote == note}"}
|
||||||
%i.icon.ion-bookmark
|
%i.icon.ion-bookmark
|
||||||
%strong.medium Pinned
|
%strong.medium-text Pinned
|
||||||
|
|
||||||
.archived.tinted{"ng-if" => "note.archived && !ctrl.tag.archiveTag", "ng-class" => "{'tinted-selected' : ctrl.selectedNote == note}"}
|
.archived.tinted{"ng-if" => "note.archived && !ctrl.tag.archiveTag", "ng-class" => "{'tinted-selected' : ctrl.selectedNote == note}"}
|
||||||
%i.icon.ion-ios-box
|
%i.icon.ion-ios-box
|
||||||
%strong.medium Archived
|
%strong.medium-text Archived
|
||||||
|
|
||||||
.tags-string{"ng-if" => "ctrl.shouldShowTags(note)"}
|
.tags-string{"ng-if" => "ctrl.shouldShowTags(note)"}
|
||||||
.faded {{note.savedTagsString || note.tagsString()}}
|
.faded {{note.savedTagsString || note.tagsString()}}
|
||||||
|
|||||||
@@ -22,8 +22,8 @@
|
|||||||
"ng-change" => "ctrl.tagTitleDidChange(tag)", "ng-blur" => "ctrl.saveTag($event, tag)", "spellcheck" => "false"}
|
"ng-change" => "ctrl.tagTitleDidChange(tag)", "ng-blur" => "ctrl.saveTag($event, tag)", "spellcheck" => "false"}
|
||||||
.count {{ctrl.noteCount(tag)}}
|
.count {{ctrl.noteCount(tag)}}
|
||||||
|
|
||||||
.red.small.bold{"ng-if" => "tag.conflict_of"} Conflicted copy
|
.red.small-text.bold{"ng-if" => "tag.conflict_of"} Conflicted copy
|
||||||
.red.small.bold{"ng-if" => "tag.errorDecrypting"} Error decrypting
|
.red.small-text.bold{"ng-if" => "tag.errorDecrypting"} Error decrypting
|
||||||
|
|
||||||
.menu{"ng-if" => "ctrl.selectedTag == tag"}
|
.menu{"ng-if" => "ctrl.selectedTag == tag"}
|
||||||
%a.item{"ng-click" => "ctrl.selectedRenameTag($event, tag)", "ng-if" => "!ctrl.editingTag"} Rename
|
%a.item{"ng-click" => "ctrl.selectedRenameTag($event, tag)", "ng-if" => "!ctrl.editingTag"} Rename
|
||||||
|
|||||||
Reference in New Issue
Block a user