summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorelijahe <elijahe@ca.ibm.com>2014-09-09 16:07:28 -0400
committerelijahe <elijahe@ca.ibm.com>2014-09-09 16:07:39 -0400
commit5f53e2237d3d855af190e8b2c27c1095536f1927 (patch)
treee31ac354ef3c6215adc89d2161a8dff9d0390aa8
parent5a988822f5bdba985f7ac37f1d6d864680e87d82 (diff)
downloadorg.eclipse.orion.client-origin/bogBranch.zip
org.eclipse.orion.client-origin/bogBranch.tar.gz
org.eclipse.orion.client-origin/bogBranch.tar.bz2
Bug 443339 - Orion Settings Page UI Redesignorigin/bogBranch
- Improved password modification flow
-rw-r--r--bundles/org.eclipse.orion.client.ui/web/orion/settings/nls/root/messages.js5
-rw-r--r--bundles/org.eclipse.orion.client.ui/web/orion/webui/tooltip.js20
-rw-r--r--bundles/org.eclipse.orion.client.ui/web/orion/widgets/input/TextField.js4
-rw-r--r--bundles/org.eclipse.orion.client.ui/web/orion/widgets/settings/UserSettings.js244
-rw-r--r--bundles/org.eclipse.orion.client.ui/web/settings/settings.css6
5 files changed, 197 insertions, 82 deletions
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/settings/nls/root/messages.js b/bundles/org.eclipse.orion.client.ui/web/orion/settings/nls/root/messages.js
index 1ccc733..45aa33c 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/settings/nls/root/messages.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/settings/nls/root/messages.js
@@ -58,7 +58,10 @@ define({
"New Password": "New Password:",
"Verify Password": "Verify Password:",
"UserSettings.PasswordsDoNotMatch" : "New password, and retyped password do not match",
- "UserSettings.TypeCurrentPassword" : "Need to type your current password",
+ "UserSettings.TypeCurrentPassword" : "You must type your current password in order to set a new one",
+ "UserSettings.InvalidPasswordLength" : "Password must be at least 8 characters long",
+ "UserSettings.InvalidPasswordAlpha" : "Password must contain at least one alpha character and one non alpha character",
+ "UserSettings.PasswordRules" : "Password must be at least 8 characters long and contain at least one alpha character and one non alpha character",
"Password": "Password",
"OpenId": "OpenId",
"AOL": "AOL",
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/webui/tooltip.js b/bundles/org.eclipse.orion.client.ui/web/orion/webui/tooltip.js
index 86d08ff..9327d39 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/webui/tooltip.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/webui/tooltip.js
@@ -24,7 +24,7 @@ define(['orion/webui/littlelib'], function(lib) {
* @param options.text The text in the tooltip. Optional. If not specified, the client is expected to add content
* to the tooltip prior to triggering it.
* @param options.trigger The event that triggers the tooltip. Optional. Defaults to "mouseover". Can be one of "mouseover",
- * "click", or "none". If "none" then the creator will be responsible for showing, hiding, and destroying the tooltip.
+ * "click", "focus", or "none". If "none" then the creator will be responsible for showing, hiding, and destroying the tooltip.
* If "mouseover" then the aria attributes for tooltips will be set up.
* @param options.position An array specifying the preferred positions to try positioning the tooltip. Positions can be "left", "right",
* "above", or "below". If no position will fit on the screen, the first position specified is used. Optional. Defaults to
@@ -82,6 +82,22 @@ define(['orion/webui/littlelib'], function(lib) {
for (var i=0; i<leave.length; i++) {
this._node.addEventListener(leave[i], this._leaveHandler, false);
}
+ } else if (this._trigger === "focus") { //$NON-NLS-0$
+ this._showDelay = options.showDelay === undefined ? 0 : options.showDelay;
+ this._hideDelay = options.hideDelay === undefined ? 0 : options.hideDelay;
+ this._node.addEventListener("focus", this._focusHandler = function(event) { //$NON-NLS-0$
+ if (lib.contains(self._node, event.target)) {
+ self.show();
+ }
+ }, false);
+
+ this._blurHandler = function(event) { //$NON-NLS-0$
+ if (lib.contains(self._node, event.target)) {
+ self.hide();
+ }
+ };
+
+ this._node.addEventListener("blur", this._blurHandler, false); //$NON-NLS-0$
}
},
@@ -295,6 +311,8 @@ define(['orion/webui/littlelib'], function(lib) {
if (this._node) {
this._node.removeEventListener("click", this._clickHandler, false); //$NON-NLS-0$
this._node.removeEventListener("mouseover", this._mouseoverHandler, false); //$NON-NLS-0$
+ this._node.removeEventListener("focus", this._focusHandler, false); //$NON-NLS-0$
+ this._node.removeEventListener("blur", this._blurHandler, false); //$NON-NLS-0$
var leave = ["mouseout", "click"]; //$NON-NLS-1$ //$NON-NLS-0$
for (var i=0; i<leave.length; i++) {
this._node.removeEventListener(leave[i], this._leaveHandler, false);
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/widgets/input/TextField.js b/bundles/org.eclipse.orion.client.ui/web/orion/widgets/input/TextField.js
index 2cd1cab..d530529 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/widgets/input/TextField.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/widgets/input/TextField.js
@@ -71,9 +71,9 @@ define(['orion/objects', 'orion/webui/littlelib'], function(objects, lib) {
}
},
- change: function(){
+ change: function(event){
if (this.postChange) {
- this.postChange(this.textfield.value);
+ this.postChange(this.textfield.value, event);
}
}
});
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/widgets/settings/UserSettings.js b/bundles/org.eclipse.orion.client.ui/web/orion/widgets/settings/UserSettings.js
index d696eb1..5f47f15 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/widgets/settings/UserSettings.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/widgets/settings/UserSettings.js
@@ -10,8 +10,17 @@
******************************************************************************/
/*eslint-env browser, amd*/
-define(['i18n!orion/settings/nls/messages', 'orion/commands', 'orion/section', 'orion/webui/littlelib', 'orion/objects', 'orion/widgets/settings/Subsection', 'orion/widgets/input/LabeledTextfield', 'orion/widgets/input/LabeledCheckbox'
- ], function(messages, mCommands, mSection, lib, objects, Subsection, LabeledTextfield, LabeledCheckbox) {
+define([
+ 'i18n!orion/settings/nls/messages',
+ 'orion/commands',
+ 'orion/section',
+ 'orion/webui/littlelib',
+ 'orion/objects',
+ 'orion/widgets/settings/Subsection',
+ 'orion/widgets/input/LabeledTextfield',
+ 'orion/widgets/input/LabeledCheckbox',
+ 'orion/webui/tooltip'
+], function(messages, mCommands, mSection, lib, objects, Subsection, LabeledTextfield, LabeledCheckbox, mTooltip) {
function UserSettings(options, node) {
objects.mixin(this, options);
@@ -49,26 +58,34 @@ define(['i18n!orion/settings/nls/messages', 'orion/commands', 'orion/section', '
createSections: function(){
- var saveFunction = this.update.bind(this);
+ var updateAccountFunction = this.updateAccount.bind(this);
+ var updatePasswordFunction = this.updatePassword.bind(this);
/* - account ----------------------------------------------------- */
this.accountFields = [
- new LabeledTextfield( {fieldlabel:messages['Username'], editmode:'readonly', postChange: saveFunction}), //$NON-NLS-0$
- new LabeledTextfield( {fieldlabel:messages['Full Name'], postChange: saveFunction}),
- new LabeledTextfield( {fieldlabel:messages['Email Address'], postChange: saveFunction}),
- new LabeledCheckbox( {fieldlabel: messages['Email Confirmed'], editmode:'readonly', postChange: saveFunction}) //$NON-NLS-0$
+ new LabeledTextfield( {fieldlabel:messages['Username'], editmode:'readonly'}), //$NON-NLS-0$
+ new LabeledTextfield( {fieldlabel:messages['Full Name'], postChange: updateAccountFunction}),
+ new LabeledTextfield( {fieldlabel:messages['Email Address'], postChange: updateAccountFunction}),
+ new LabeledCheckbox( {fieldlabel: messages['Email Confirmed'], editmode:'readonly'}) //$NON-NLS-0$
];
var accountSubsection = new Subsection( {sectionName: messages['Account'], parentNode: this.sections, children: this.accountFields} );
accountSubsection.show();
/* - password ---------------------------------------------------- */
this.passwordFields = [
- new LabeledTextfield( {fieldlabel:messages['Current Password'], inputType:'password'} ), //$NON-NLS-1$ //$NON-NLS-0$
- new LabeledTextfield( {fieldlabel:messages['New Password'], inputType:'password'} ), //$NON-NLS-1$ //$NON-NLS-0$
- new LabeledTextfield( {fieldlabel:messages['Verify Password'], inputType:'password', postChange: saveFunction} ) //$NON-NLS-1$ //$NON-NLS-0$
+ new LabeledTextfield( {fieldlabel:messages['Current Password'], inputType:'password', postChange: updatePasswordFunction} ), //$NON-NLS-1$ //$NON-NLS-0$
+ new LabeledTextfield( {fieldlabel:messages['New Password'], inputType:'password', postChange: updatePasswordFunction} ), //$NON-NLS-1$ //$NON-NLS-0$
+ new LabeledTextfield( {fieldlabel:messages['Verify Password'], inputType:'password', postChange: updatePasswordFunction} ) //$NON-NLS-1$ //$NON-NLS-0$
];
var passwordSection = new Subsection( {sectionName:messages['Password'], parentNode: this.sections, children: this.passwordFields } );
passwordSection.show();
+
+ this._passwordTooltip = new mTooltip.Tooltip({
+ node: this.passwordFields[1].textfield,
+ text: messages['UserSettings.PasswordRules'],
+ trigger: 'focus', //$NON-NLS-0$
+ position: ['right', 'above', 'below', 'left'] //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
+ });
this.username = "";
var deleteCommand = new mCommands.Command({
@@ -108,92 +125,159 @@ define(['i18n!orion/settings/nls/messages', 'orion/commands', 'orion/section', '
}
},
- deleteUser: function(){
- if(confirm(messages["DeleteUserComfirmation"])){
- var userService = this.userService; //$NON-NLS-0$
- userService.deleteUser("/users/" + this.username).then(function(jsonData) { //$NON-NLS-0$
- window.location.reload();
- }, function(jsonData) {
- alert(jsonData.Message);
- });
- }
- },
-
- update: function(){
-
+ deleteUser: function(){
+ if(confirm(messages["DeleteUserComfirmation"])){
+ var userService = this.userService; //$NON-NLS-0$
+ userService.deleteUser("/users/" + this.username).then(function(jsonData) { //$NON-NLS-0$
+ window.location.reload();
+ }, function(jsonData) {
+ alert(jsonData.Message);
+ });
+ }
+ },
+
+ updateAccount: function(){
var authenticationIds = [];
-
var authServices = this.registry.getServiceReferences("orion.core.auth"); //$NON-NLS-0$
-
var messageService = this.registry.getService("orion.page.message"); //$NON-NLS-0$
-
var userService = this.userService;
-
var userdata = {};
userdata.login = this.accountFields[0].getValue();
userdata.Name = this.accountFields[1].getValue();
userdata.email = this.accountFields[2].getValue();
- var pword = this.passwordFields[1].getValue();
- var pwordRetype = this.passwordFields[2].getValue();
-
- if( pword.length > 0 || pwordRetype.length > 0){
+ for(var i=0; i<authServices.length; i++){
+ var servicePtr = authServices[i];
+ var authService = this.registry.getService(servicePtr);
+
+ authService.getKey().then(function(key){
+ authenticationIds.push(key);
+ authService.getUser().then(function(jsonData){
+ userService.updateUserInfo(jsonData.Location, userdata).then( function(args){
+ if(args){
+ messageService.setProgressResult(args);
+ }else{
+ messageService.setProgressResult( messages['User profile data successfully updated.'] );
+ }
+ }, function(error){
+ messageService.setProgressResult(error);
+ });
+ });
+ });
+ }
+ },
- if( pword !== pwordRetype ){
- messageService.setProgressResult( {Message: messages['UserSettings.PasswordsDoNotMatch'], Severity: 'Error'} ); //$NON-NLS-1$ //$NON-NLS-0$
-
- this.dispatch = false;
-
- }else{
-
- if( this.passwordFields[0].getValue().length > 0 ){
- userdata.oldPassword = this.passwordFields[0].getValue();
- userdata.password = pword;
- userdata.passwordRetype = pwordRetype;
-
- this.dispatch = true;
-
- }else{
- messageService.setProgressResult( {Message: messages['UserSettings.TypeCurrentPassword'], Severity: 'Warning'} ); //$NON-NLS-1$ //$NON-NLS-0$
-
- this.dispatch = false;
- }
- }
+ updatePassword: function(value, event){
+ var authenticationIds = [];
+ var authServices = this.registry.getServiceReferences("orion.core.auth"); //$NON-NLS-0$
+ var messageService = this.registry.getService("orion.page.message"); //$NON-NLS-0$
+ var userService = this.userService;
+ var userdata = {};
+
+ if (!value) {
+ //user deleted input from field, remove any error state and do nothing else
+ event.target.classList.remove("setting-control-error"); //$NON-NLS-0$
+ return;
}
- if( this.dispatch === true ){
+ var currentPassword = this.passwordFields[0].getValue();
+ var newPassword = this.passwordFields[1].getValue();
+ var newPasswordRetype = this.passwordFields[2].getValue();
- for(var i=0; i<authServices.length; i++){
- var servicePtr = authServices[i];
- var authService = this.registry.getService(servicePtr);
-
- authService.getKey().then(function(key){
- authenticationIds.push(key);
- authService.getUser().then(function(jsonData){
- var b = userService.updateUserInfo(jsonData.Location, userdata).then( function(args){
- if(args){
- messageService.setProgressResult(args);
- }else{
- messageService.setProgressResult( messages['User profile data successfully updated.'] );
- }
- }, function(error){
- messageService.setProgressResult(error);
- });
- });
- });
- }
+ var currentPasswordTextField = this.passwordFields[0].textfield;
+ var newPasswordTextField = this.passwordFields[1].textfield;
+ var newPasswordRetypeTextField = this.passwordFields[2].textfield;
+ var validNewPassword = true;
+
+ if (event.target === newPasswordTextField) {
+ validNewPassword = this._verifyPassword(newPassword);
+ }
+
+ if (validNewPassword) {
+ if (newPassword && newPasswordRetype) {
+ if (newPassword === newPasswordRetype) {
+ if(currentPassword.length > 0){
+ userdata.oldPassword = currentPassword;
+ userdata.password = newPassword;
+ userdata.passwordRetype = newPasswordRetype;
+
+ //dispatch passwords to user service
+ authServices.forEach(function(servicePtr) {
+ var authService = this.registry.getService(servicePtr);
+ var passwordFields = this.passwordFields;
+ authService.getKey().then(function(key){
+ authenticationIds.push(key);
+ authService.getUser().then(function(jsonData){
+ userService.updateUserInfo(jsonData.Location, userdata).then( function(args){
+ if(args){
+ messageService.setProgressResult(args);
+ } else {
+ messageService.setProgressResult( messages['User profile data successfully updated.'] ); //$NON-NLS-0$
+ currentPasswordTextField.classList.remove("setting-control-error"); //$NON-NLS-0$
+ passwordFields.forEach(function(passwordField){
+ passwordField.setValue(""); //$NON-NLS-0$
+ });
+ }
+ }, function(jsonError){
+ var errorObject = JSON.parse(jsonError);
+ if (errorObject && (400 === errorObject.HttpCode)) {
+ //wrong current password
+ setTimeout(function(){
+ currentPasswordTextField.select();
+ currentPasswordTextField.focus();
+ currentPasswordTextField.classList.add("setting-control-error"); //$NON-NLS-0$
+ }, 100);
+ }
+ messageService.setProgressResult(jsonError);
+ });
+ });
+ });
+ }, this);
+ } else {
+ messageService.setProgressResult( {Message: messages['UserSettings.TypeCurrentPassword'], Severity: 'Warning'} ); //$NON-NLS-1$ //$NON-NLS-0$
+ setTimeout(function(){
+ currentPasswordTextField.focus();
+ }.bind(this), 100);
+ }
+ newPasswordTextField.classList.remove("setting-control-error"); //$NON-NLS-0$
+ newPasswordRetypeTextField.classList.remove("setting-control-error"); //$NON-NLS-0$
+ } else {
+ messageService.setProgressResult( {Message: messages['UserSettings.PasswordsDoNotMatch'], Severity: 'Error'} ); //$NON-NLS-1$ //$NON-NLS-0$
+ setTimeout(function(){
+ newPasswordRetypeTextField.select();
+ newPasswordRetypeTextField.focus();
+ }.bind(this), 100);
+ newPasswordTextField.classList.add("setting-control-error"); //$NON-NLS-0$
+ newPasswordRetypeTextField.classList.add("setting-control-error"); //$NON-NLS-0$
+ }
+ } else {
+ event.target.classList.remove("setting-control-error"); //$NON-NLS-0$
+ }
} else {
- // There was an issue with the password modification attempt
- // Reset all password fields and focus on first one
- this.passwordFields.forEach(function(passwordField){
- passwordField.setValue(""); //$NON-NLS-0$
- });
-
- this.passwordFields[0].textfield.focus();
+ event.target.classList.add("setting-control-error"); //$NON-NLS-0$
+ setTimeout(function(){
+ event.target.select();
+ event.target.focus();
+ }.bind(this), 100);
}
},
+ _verifyPassword: function(password) {
+ var passwordIsValid = true;
+ var messageService = this.registry.getService("orion.page.message"); //$NON-NLS-0$
+
+ if (password.length < 8) {
+ passwordIsValid = false;
+ messageService.setProgressResult( {Message: messages['UserSettings.InvalidPasswordLength'], Severity: 'Error'} ); //$NON-NLS-1$ //$NON-NLS-0$
+ } else if (!/[a-zA-Z]+/.test(password) || !/[^a-zA-Z]+/.test(password)) {
+ passwordIsValid = false;
+ messageService.setProgressResult( {Message: messages['UserSettings.InvalidPasswordAlpha'], Severity: 'Error'} ); //$NON-NLS-1$ //$NON-NLS-0$
+ }
+
+ return passwordIsValid;
+ },
+
show:function(){
this.createElements();
@@ -247,6 +331,10 @@ define(['i18n!orion/settings/nls/messages', 'orion/commands', 'orion/section', '
lib.empty(this.node);
this.node = this.sections = null;
}
+ if (this._passwordTooltip) {
+ this._passwordTooltip.destroy();
+ this._passwordTooltip = null;
+ }
}
});
return UserSettings;
diff --git a/bundles/org.eclipse.orion.client.ui/web/settings/settings.css b/bundles/org.eclipse.orion.client.ui/web/settings/settings.css
index 33c2b0c..26a5138 100644
--- a/bundles/org.eclipse.orion.client.ui/web/settings/settings.css
+++ b/bundles/org.eclipse.orion.client.ui/web/settings/settings.css
@@ -454,6 +454,12 @@ div.page section:last-child {
background-color: #f4f4f4;
}
+.setting-control-error {
+ background: #f2dede;
+ border: 1px solid #b94a48;
+ outline: none;
+}
+
.overlay{
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;