-
Notifications
You must be signed in to change notification settings - Fork 645
Ability to add/update user email #921
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
Changes from 22 commits
d89c3b0
0e663a4
a39b380
0e61301
ccc82e1
671eeab
cb8efee
820d1d2
94e1a25
7bdb157
45ce186
c603bcb
33addcf
28dc5ed
9fe427f
593853e
09786c8
ed1d2ee
8c4d959
0dba390
b2b854c
96bb903
33abaa4
0e618a3
0b90a74
48774f8
45b6669
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import Component from '@ember/component'; | ||
import { empty } from '@ember/object/computed'; | ||
|
||
export default Component.extend({ | ||
type: '', | ||
value: '', | ||
isEditing: false, | ||
user: null, | ||
disableSave: empty('user.email'), | ||
notValidEmail: false, | ||
prevEmail: '', | ||
emailIsNull: true, | ||
|
||
actions: { | ||
editEmail() { | ||
let email = this.get('value'); | ||
let isEmailNull = function(email) { | ||
if (email == null) { | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
}; | ||
|
||
this.set('emailIsNull', isEmailNull(email)); | ||
this.set('isEditing', true); | ||
this.set('prevEmail', this.get('value')); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we've got |
||
}, | ||
|
||
saveEmail() { | ||
let userEmail = this.get('value'); | ||
let user = this.get('user'); | ||
|
||
let emailIsProperFormat = function(userEmail) { | ||
let regExp = /\S+@\S+\.\S+/; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm remembering a thing.... where if you don't put "beginning of value" and "end of value" things in the regex, somehow people could put newlines in and the regex would match when it shouldn't have? I forget if javascript is vulnerable to this or not, and if it is, if the things we want at the beginning and end are |
||
return regExp.test(userEmail); | ||
}; | ||
|
||
if (!emailIsProperFormat(userEmail)) { | ||
this.set('notValidEmail', true); | ||
return; | ||
} | ||
|
||
user.set('email', userEmail); | ||
user.save() | ||
.then(() => this.set('serverError', null)) | ||
.catch(err => { | ||
let msg; | ||
if (err.errors && err.errors[0] && err.errors[0].detail) { | ||
msg = `An error occurred while saving this email, ${err.errors[0].detail}`; | ||
} else { | ||
msg = 'An unknown error occurred while saving this token.'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this error message say email instead of token? |
||
} | ||
this.set('serverError', msg); | ||
}); | ||
|
||
this.set('isEditing', false); | ||
this.set('notValidEmail', false); | ||
}, | ||
|
||
cancelEdit() { | ||
this.set('isEditing', false); | ||
this.set('value', this.get('prevEmail')); | ||
} | ||
} | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import Ember from 'ember'; | ||
|
||
const { | ||
computed, | ||
defineProperty | ||
} = Ember; | ||
|
||
export default Ember.Component.extend({ | ||
classNames: ['validated-input'], | ||
classNameBindings: ['showErrorClass:has-error', 'isValid:has-success'], | ||
model: null, | ||
value: null, | ||
type: 'text', | ||
valuePath: '', | ||
placeholder: '', | ||
validation: null, | ||
showValidations: false, | ||
didValidate: false, | ||
|
||
notValidating: computed.not('validation.isValidating').readOnly(), | ||
hasContent: computed.notEmpty('value').readOnly(), | ||
hasWarnings: computed.notEmpty('validation.warnings').readOnly(), | ||
isValid: computed.and('hasContent', 'validation.isTruelyValid').readOnly(), | ||
shouldDisplayValidations: computed.or('showValidations', 'didValidate', 'hasContent').readOnly(), | ||
|
||
showErrorClass: computed.and('notValidating', 'showErrorMessage', 'hasContent', 'validation').readOnly(), | ||
showErrorMessage: computed.and('shouldDisplayValidations', 'validation.isInvalid').readOnly(), | ||
|
||
init() { | ||
this._super(...arguments); | ||
let valuePath = this.get('valuePath'); | ||
|
||
defineProperty(this, 'validation', computed.readOnly(`model.validations.attrs.${valuePath}`)); | ||
defineProperty(this, 'value', computed.alias(`model.${valuePath}`)); | ||
}, | ||
|
||
focusOut() { | ||
this._super(...arguments); | ||
this.set('showValidations', true); | ||
} | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
{{#if isEditing }} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good call on moving the check for editing out to be able to separate the markup between editing and not editing :) 💯 |
||
<div class='row'> | ||
<div class='label'> | ||
<dt>Email</dt> | ||
</div> | ||
<form {{action 'saveEmail' on='submit'}}> | ||
{{input type=type value=value placeholder='Email' class='form-control space-bottom'}} | ||
{{#if notValidEmail }} | ||
<p class='small-text error'>Invalid email format. Please try again.</p> | ||
{{/if}} | ||
{{#if emailIsNull }} | ||
<p class='small-text'> Please add your email address. We need this in | ||
order to contact you just in case anything goes wrong. We promise | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking about this phrasing a little bit more, especially since we just came up with a potential use case in ownership notifications that we might want to use email for, which isn't really something going wrong... how about something like "Please add your email address. We will only use it to contact you about your account. We promise we'll never share it!"? |
||
we'll never share it! | ||
</p> | ||
{{/if}} | ||
<div class='actions'> | ||
<button type='submit' class='small yellow-button space-right' disabled={{disableSave}}>Save</button> | ||
<button class='small yellow-button' {{action 'cancelEdit'}}>Cancel</button> | ||
</div> | ||
</form> | ||
</div> | ||
{{else}} | ||
<div class='row align-center'> | ||
<div class='label'> | ||
<dt>Email</dt> | ||
</div> | ||
<div class='email'> | ||
<dd class='no-space-left'>{{ user.email }}</dd> | ||
</div> | ||
<div class='actions'> | ||
<button class='small yellow-button space-left' {{action 'editEmail'}}>Edit</button> | ||
</div> | ||
</div> | ||
{{/if}} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<div class='form-group'> | ||
{{input type=type value=value placeholder=placeholder class='form-control' name=valuePath}} | ||
{{#if isValid}} | ||
<span class='valid-input fa fa-check'></span> | ||
{{/if}} | ||
|
||
<div class='input-error'> | ||
{{#if showErrorMessage}} | ||
<div class='error'> | ||
{{v-get model valuePath 'message'}} | ||
</div> | ||
{{/if}} | ||
</div> | ||
</div> |
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 think we can shorten this by doing:
Does that work? My javascript is a bit rusty...
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.
OOH WAIT what's this
empty
function on line 9? could we doempty(email)
? or is that special for models?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 think this might be special for models? I'm not sure exactly how it works on line 9 but when I print out the result of empty it isn't just a boolean type.