-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Change password hint color to red when invalid, else grey #5130
fix: Change password hint color to red when invalid, else grey #5130
Conversation
…s invalid, else grey
src/pages/settings/PasswordPage.js
Outdated
@@ -86,8 +80,8 @@ class PasswordPage extends Component { | |||
} | |||
} | |||
|
|||
isValidPassword() { | |||
return this.state.newPassword.match(CONST.PASSWORD_COMPLEXITY_REGEX_STRING); | |||
isInvalidPassword() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why change from isValidPassword
to isInvalidPassword
? We usually use the "positive" version of things rather than check if something is "not" something like isNotValid()
or isInvalid()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, earlier this function was used for a flag that we don’t use anymore. I’ll update the logic to use ‘isValidPassword’
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@marcaaron Are you suggesting we have
isValidPassword() {
return this.state.newPassword.match(CONST.PASSWORD_COMPLEXITY_REGEX_STRING);
}
and then `this.state.newPassword && !isValidPassword()`
That is what we initially thought to use but wanted to move this && to a separate function. Let me know and I'll accordingly update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point on keeping the function positive, in that case, yes I think we'd have to leave that logic in the render function the way you specified (maybe split out the style array into separate lines like we do here to avoid a giant line).
Alternatively, you could change the function to be called something like shouldApplyPasswordErrorStyles
and include the empty state check, but I don't like that solution as much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah agree and hence, lets just split into lines with an &&
check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why we need two separate lines. If there's no password it's not valid, right?
return this.state.newPassword && this.state.newPassword.match(CONST.PASSWORD_COMPLEXITY_REGEX_STRING);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe we just mean syntactically use a line break? That seems fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We wanted to match the same behavior from the screenshots in #5093 where the field shows as grey initially if the user hasn't typed anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to isValidPassword
…d to isValidPassword
@Jag96 @marcaaron PR updated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple of style nitpicks, otherwise looks good!
src/pages/settings/PasswordPage.js
Outdated
> | ||
{this.props.translate('passwordPage.newPasswordPrompt')} | ||
</Text> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove spaces between elements
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/pages/settings/PasswordPage.js
Outdated
)} | ||
|
||
<Text style={[ | ||
styles.textLabelSupporting, styles.mt1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you put each of these on their own line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move the style prop to its own line and indent accordingly? There's an example in the // Good
section of https://github.com/Expensify/App/blob/main/STYLING.md#when-to-create-a-new-style
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. Thanks for the share. I wasn't sure if every style will be moved to a new line. Do you think this should be added as a lint config?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds like a good improvement, I think it's worth bringing up in slack to at least get a discussion going, but we'll keep that separate from this PR.
PR updated |
Thanks for the update @mananjadhav! In slack, we just agreed on some updated ways to handle displaying errors, so if you'd like to update this PR to match the new standard we're happy to provide a bonus (equal to the current price) for the updated scope. Otherwise, we can merge this PR as it is and open a separate issue to update the code to the new standard. Either is fine, just let us know what you prefer! The updates we're looking to implement are:
Feel free to ask any questions as well! |
Hi it makes sense to update the code in this PR only. I’ll do the needful. |
…ssword-hint-color
@Jag96 I started with the implementation and have one more question. Once we get rid of the following block, we'll also have to show
|
@mananjadhav sounds great! To answer your questions
Yes, that's correct, the required field validations will have to move into |
Hi @mananjadhav, I've placed this issue on hold as per this update, as we are prioritising issues related to a feature release scheduled for 9/24. As an apology for the delay, we will add a $100 bonus as a thank you for waiting. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one request to update JS docs, otherwise looks good!
src/pages/settings/PasswordPage.js
Outdated
|
||
this.setState(stateToUpdate); | ||
clearErrorAndSetValue(field, value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add jsdocs here and to other functions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated. Sorry, not sure how I missed these 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conflicts and a couple of things, otherwise looking good
src/languages/en.js
Outdated
currentPassword: 'Current password is required', | ||
confirmNewPassword: 'Confirm password is required', | ||
newPasswordSameAsOld: 'New password must be different than your old password', | ||
newPassword: 'Your password must have at least 8 characters,\n1 capital letter, 1 lowercase letter, 1 number.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
newPassword: 'Your password must have at least 8 characters,\n1 capital letter, 1 lowercase letter, 1 number.', | |
newPassword: 'Your password must have at least 8 characters,\n1 capital letter, 1 lowercase letter, and 1 number.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for the Spanish translation
src/libs/ValidationUtils.js
Outdated
@@ -248,6 +258,7 @@ function isValidLengthForFirstOrLastName(name) { | |||
return name.length <= 50; | |||
} | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary extra space
src/pages/settings/PasswordPage.js
Outdated
} else { | ||
this.setState({shouldShowPasswordConfirmError: false}); | ||
/** | ||
* Validate all fields and submit the form if no errors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update comment, this function no longer submits the form
…ssword-hint-color # Conflicts: # src/pages/settings/PasswordPage.js
@Jag96 PR updated with the changes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, @marcaaron all yours
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks pretty good, but I did have some suggestions. I think the logic around which errors are getting set is a lot more difficult to suss out now - but I don't have a great suggestion for that other than extract some of the conditions into variables so there's less to parse mentally.
src/libs/ValidationUtils.js
Outdated
@@ -230,6 +230,16 @@ function isValidUSPhone(phoneNumber) { | |||
return CONST.REGEX.PHONE_E164_PLUS.test(phoneNumber.replace(CONST.REGEX.NON_ALPHA_NUMERIC, '')) && CONST.REGEX.US_PHONE.test(phoneNumber); | |||
} | |||
|
|||
/** | |||
* Checks if the password matches regex |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this comment please
src/pages/settings/PasswordPage.js
Outdated
} else { | ||
stateToUpdate.isPasswordRequirementsVisible = false; | ||
/** | ||
* Return the error message for the field |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this comment please
src/pages/settings/PasswordPage.js
Outdated
} | ||
return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the doc says we are returning a string then don't return null
return an empty string.
src/pages/settings/PasswordPage.js
Outdated
stateToUpdate.shouldShowPasswordConfirmError = false; | ||
|
||
/** | ||
* Set value for the field in state and clear error flag |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this comment
src/pages/settings/PasswordPage.js
Outdated
} else { | ||
this.setState({shouldShowPasswordConfirmError: false}); | ||
/** | ||
* Validate all fields |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove
src/pages/settings/PasswordPage.js
Outdated
* @param {String} value | ||
* @param {String[]} additionalErrorFlags | ||
*/ | ||
clearErrorAndSetValue(field, value, additionalErrorFlags) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
additionalErrorsToClear
would be a better name
src/pages/settings/PasswordPage.js
Outdated
onFocus={() => this.setState({isPasswordRequirementsVisible: true})} | ||
onBlur={() => this.onBlurNewPassword()} | ||
hasError={this.state.errors.newPassword || this.state.errors.newPasswordSameAsOld} | ||
errorText={!this.state.errors.newPassword && this.state.errors.newPasswordSameAsOld |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to check both of these conditions to determine which errorText to show? If there's no error it will not return anything?
src/pages/settings/PasswordPage.js
Outdated
</Text> | ||
)} | ||
{ | ||
!this.state.errors.newPassword && !this.state.errors.newPasswordSameAsOld |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NAB, I would probably extract this to a variable for readability like const shouldShowNewPasswordPrompt
src/pages/settings/PasswordPage.js
Outdated
/> | ||
</View> | ||
{!this.state.shouldShowPasswordConfirmError && !isEmpty(this.props.account.error) && ( | ||
{!_.some(_.values(this.state.errors)) && !_.isEmpty(this.props.account.error) && ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inverting _.some()
is a bit confusing and the _.values()
isn't necessary.
Maybe clearer to just do something like....
_.every(this.state.errors, error => !error);
@marcaaron PR updated |
These changes look good, however there is one strange thing happening... after changing the password the fields are not cleared and we see this: Should we clear the state here? I think my expectation is that the old passwords would not be sticking around in these fields, but it looks like we are pushing the settings page on top of the change password page instead of popping it off the stack and returning us to the settings page. Maybe things already work this way on production, but should be fixed. Thoughts @Jag96 ? |
Agreed. Let me know what you and @Jag96 decide. Will do the needful. |
Any updates for me on this one? |
I think going back is better than navigating to the settings page, so I agree with the improvement being proposed. Also, per this message we're putting all non-critical issues on merge hold including this one, and adding a $250 bonus. |
@marcaaron Can you tell me in which scenario are the fields retained? I just tried and it didn't. I tried clicking on back, etc. too. One area where I saw the values being retained in the fields is when there's an error. Can you help me with the steps so that I can fix and do the needful. change-password-redirect.mov |
Hmm, it looks like if you load the page by typing For the actual submit, we can do the same thing, since it seems to behave the same. |
This issue has been taken off hold! @mananjadhav if you have any questions on #5130 (comment) let me know! |
@Jag96 PR was updated yesterday |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@marcaaron all yours
isValidPassword() { | ||
return this.state.newPassword.match(CONST.PASSWORD_COMPLEXITY_REGEX_STRING); | ||
} | ||
if (!this.state.newPassword || !isValidPassword(this.state.newPassword)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NAB, !this.state.newPassword
check should be performed inside isValidPassword()
?
🚀 Deployed to staging by @marcaaron in version: 1.1.15-19 🚀
|
🚀 Deployed to production by @roryabraham in version: 1.1.16-10 🚀
|
@Jag96 Can you please review this?
Details
Fixed Issues
$ #4995
Tests
QA Steps
Tested On
Screenshots
Web
v1
https://user-images.githubusercontent.com/3069065/135293821-e1f56e42-5e7c-4e49-b211-a1799de306eb.mov
Latest
https://user-images.githubusercontent.com/3069065/137942020-5fefb22e-6dd2-4962-82a1-4aa981841e57.mov
Mobile Web
v1
Latest
Desktop
v1
Latest
iOS
v1
Latest
Android
v1
Latest