2016-07-06 22:47:30 +03:00
import Controller from 'ember-controller' ;
import RSVP from 'rsvp' ;
import computed , { alias } from 'ember-computed' ;
import { A as emberA } from 'ember-array/utils' ;
import injectService from 'ember-service/inject' ;
import injectController from 'ember-controller/inject' ;
import { htmlSafe } from 'ember-string' ;
import run from 'ember-runloop' ;
2015-07-07 20:14:23 +03:00
import DS from 'ember-data' ;
2015-03-29 21:10:53 +03:00
2015-10-28 14:36:45 +03:00
const { Errors } = DS ;
2015-08-10 07:40:27 +03:00
2015-10-28 14:36:45 +03:00
export default Controller . extend ( {
2016-07-06 22:47:30 +03:00
notifications : injectService ( ) ,
two : injectController ( 'setup/two' ) ,
2015-10-28 14:36:45 +03:00
errors : Errors . create ( ) ,
hasValidated : emberA ( ) ,
2015-03-29 21:10:53 +03:00
users : '' ,
2015-10-28 14:36:45 +03:00
ownerEmail : alias ( 'two.email' ) ,
2015-08-10 18:43:49 +03:00
submitting : false ,
2015-08-27 11:41:24 +03:00
2015-10-28 14:36:45 +03:00
usersArray : computed ( 'users' , function ( ) {
let errors = this . get ( 'errors' ) ;
let users = this . get ( 'users' ) . split ( '\n' ) . filter ( function ( email ) {
2015-05-28 16:58:52 +03:00
return email . trim ( ) . length > 0 ;
} ) ;
2015-08-27 11:41:24 +03:00
// remove "no users to invite" error if we have users
if ( users . uniq ( ) . length > 0 && errors . get ( 'users.length' ) === 1 ) {
if ( errors . get ( 'users.firstObject' ) . message . match ( /no users/i ) ) {
errors . remove ( 'users' ) ;
}
}
2015-05-28 16:58:52 +03:00
return users . uniq ( ) ;
} ) ,
2015-08-27 11:41:24 +03:00
2015-10-28 14:36:45 +03:00
validUsersArray : computed ( 'usersArray' , 'ownerEmail' , function ( ) {
let ownerEmail = this . get ( 'ownerEmail' ) ;
2015-08-27 11:41:24 +03:00
2015-05-28 16:58:52 +03:00
return this . get ( 'usersArray' ) . filter ( function ( user ) {
2015-08-27 11:41:24 +03:00
return validator . isEmail ( user ) && user !== ownerEmail ;
2015-03-29 21:10:53 +03:00
} ) ;
} ) ,
2015-05-28 16:58:52 +03:00
2015-10-28 14:36:45 +03:00
invalidUsersArray : computed ( 'usersArray' , 'ownerEmail' , function ( ) {
let ownerEmail = this . get ( 'ownerEmail' ) ;
2015-08-27 11:41:24 +03:00
2015-10-28 14:36:45 +03:00
return this . get ( 'usersArray' ) . reject ( ( user ) => {
2015-08-27 11:41:24 +03:00
return validator . isEmail ( user ) || user === ownerEmail ;
} ) ;
2015-05-28 16:58:52 +03:00
} ) ,
2015-08-27 11:41:24 +03:00
2015-10-28 14:36:45 +03:00
validationResult : computed ( 'invalidUsersArray' , function ( ) {
let errors = [ ] ;
2015-08-27 11:41:24 +03:00
2015-10-28 14:36:45 +03:00
this . get ( 'invalidUsersArray' ) . forEach ( ( user ) => {
2015-08-27 11:41:24 +03:00
errors . push ( {
2015-10-28 14:36:45 +03:00
user ,
2015-08-27 11:41:24 +03:00
error : 'email'
} ) ;
} ) ;
if ( errors . length === 0 ) {
// ensure we aren't highlighting fields when everything is fine
this . get ( 'errors' ) . clear ( ) ;
return true ;
} else {
return errors ;
}
2015-05-28 16:58:52 +03:00
} ) ,
2015-10-28 14:36:45 +03:00
validate ( ) {
let errors = this . get ( 'errors' ) ;
let validationResult = this . get ( 'validationResult' ) ;
let property = 'users' ;
2015-08-27 11:41:24 +03:00
errors . clear ( ) ;
2015-08-27 23:28:41 +03:00
// If property isn't in the `hasValidated` array, add it to mark that this field can show a validation result
this . get ( 'hasValidated' ) . addObject ( property ) ;
2015-10-28 14:36:45 +03:00
if ( validationResult === true ) {
return true ;
}
2015-08-27 11:41:24 +03:00
2015-10-28 14:36:45 +03:00
validationResult . forEach ( ( error ) => {
2015-08-27 11:41:24 +03:00
// Only one error type here so far, but one day the errors might be more detailed
switch ( error . error ) {
2016-06-11 19:52:36 +03:00
case 'email' :
errors . add ( property , ` ${ error . user } is not a valid email. ` ) ;
2015-08-27 11:41:24 +03:00
}
} ) ;
return false ;
} ,
2015-10-28 14:36:45 +03:00
buttonText : computed ( 'errors.users' , 'validUsersArray' , 'invalidUsersArray' , function ( ) {
let usersError = this . get ( 'errors.users.firstObject.message' ) ;
let validNum = this . get ( 'validUsersArray' ) . length ;
let invalidNum = this . get ( 'invalidUsersArray' ) . length ;
let userCount ;
2015-08-27 11:41:24 +03:00
if ( usersError && usersError . match ( /no users/i ) ) {
return usersError ;
}
if ( invalidNum > 0 ) {
userCount = invalidNum === 1 ? 'email address' : 'email addresses' ;
return ` ${ invalidNum } invalid ${ userCount } ` ;
}
if ( validNum > 0 ) {
userCount = validNum === 1 ? 'user' : 'users' ;
2015-10-28 14:36:45 +03:00
userCount = ` ${ validNum } ${ userCount } ` ;
2015-05-28 16:58:52 +03:00
} else {
2015-08-27 11:41:24 +03:00
userCount = 'some users' ;
2015-05-28 16:58:52 +03:00
}
2015-10-28 14:36:45 +03:00
return ` Invite ${ userCount } ` ;
2015-03-29 21:10:53 +03:00
} ) ,
2015-08-27 11:41:24 +03:00
2015-10-28 14:36:45 +03:00
buttonClass : computed ( 'validationResult' , 'usersArray.length' , function ( ) {
2015-08-27 11:41:24 +03:00
if ( this . get ( 'validationResult' ) === true && this . get ( 'usersArray.length' ) > 0 ) {
2015-05-28 16:58:52 +03:00
return 'btn-green' ;
} else {
return 'btn-minor' ;
}
2015-03-29 21:10:53 +03:00
} ) ,
2015-08-27 11:41:24 +03:00
2015-10-28 14:36:45 +03:00
authorRole : computed ( function ( ) {
return this . store . findAll ( 'role' , { reload : true } ) . then ( ( roles ) => {
2015-05-28 16:58:52 +03:00
return roles . findBy ( 'name' , 'Author' ) ;
} ) ;
2015-03-29 21:10:53 +03:00
} ) ,
2015-08-27 11:41:24 +03:00
2016-01-08 20:01:23 +03:00
_transitionAfterSubmission ( ) {
if ( ! this . _hasTransitioned ) {
this . _hasTransitioned = true ;
this . transitionToRoute ( 'posts.index' ) ;
}
} ,
2015-03-29 21:10:53 +03:00
actions : {
2015-10-28 14:36:45 +03:00
validate ( ) {
2015-08-27 11:41:24 +03:00
this . validate ( ) ;
} ,
2015-10-28 14:36:45 +03:00
invite ( ) {
let users = this . get ( 'usersArray' ) ;
let notifications = this . get ( 'notifications' ) ;
2016-01-08 20:01:23 +03:00
let invitationsString , submissionTimeout ;
2015-03-29 21:10:53 +03:00
2015-08-27 11:41:24 +03:00
if ( this . validate ( ) && users . length > 0 ) {
2016-01-08 20:01:23 +03:00
this . set ( 'submitting' , true ) ;
this . _hasTransitioned = false ;
// wait for 4 seconds, otherwise transition anyway
submissionTimeout = run . later ( this , function ( ) {
this . _transitionAfterSubmission ( ) ;
} , 4000 ) ;
2015-10-28 14:36:45 +03:00
this . get ( 'authorRole' ) . then ( ( authorRole ) => {
RSVP . Promise . all (
users . map ( ( user ) => {
2016-09-26 19:03:53 +03:00
let invite = this . store . createRecord ( 'invite' , {
2015-05-28 16:58:52 +03:00
email : user ,
role : authorRole
} ) ;
2015-03-29 21:10:53 +03:00
2016-09-26 19:03:53 +03:00
return invite . save ( ) . then ( ( ) => {
2015-05-28 16:58:52 +03:00
return {
email : user ,
2016-09-26 19:03:53 +03:00
success : invite . get ( 'status' ) === 'sent'
2015-05-28 16:58:52 +03:00
} ;
2015-10-28 14:36:45 +03:00
} ) . catch ( ( ) => {
2015-05-28 16:58:52 +03:00
return {
email : user ,
success : false
} ;
} ) ;
} )
2015-10-28 14:36:45 +03:00
) . then ( ( invites ) => {
let erroredEmails = [ ] ;
let successCount = 0 ;
let message ;
2015-03-29 21:10:53 +03:00
2016-01-08 20:01:23 +03:00
run . cancel ( submissionTimeout ) ;
2015-10-28 14:36:45 +03:00
invites . forEach ( ( invite ) => {
2015-05-28 16:58:52 +03:00
if ( invite . success ) {
successCount ++ ;
} else {
erroredEmails . push ( invite . email ) ;
}
} ) ;
if ( erroredEmails . length > 0 ) {
2015-08-27 20:17:13 +03:00
invitationsString = erroredEmails . length > 1 ? ' invitations: ' : ' invitation: ' ;
2015-10-28 14:36:45 +03:00
message = ` Failed to send ${ erroredEmails . length } ${ invitationsString } ` ;
2015-05-28 16:58:52 +03:00
message += erroredEmails . join ( ', ' ) ;
2016-01-08 20:01:23 +03:00
message += ". Please check your email configuration, see <a href=\'http://support.ghost.org/mail\' target=\'_blank\'>http://support.ghost.org/mail</a> for instructions" ;
2016-06-11 19:52:36 +03:00
message = htmlSafe ( message ) ;
2015-10-07 17:44:23 +03:00
notifications . showAlert ( message , { type : 'error' , delayed : successCount > 0 , key : 'signup.send-invitations.failed' } ) ;
2015-05-28 16:58:52 +03:00
}
if ( successCount > 0 ) {
// pluralize
invitationsString = successCount > 1 ? 'invitations' : 'invitation' ;
2015-10-28 14:36:45 +03:00
notifications . showAlert ( ` ${ successCount } ${ invitationsString } sent! ` , { type : 'success' , delayed : true , key : 'signup.send-invitations.success' } ) ;
2015-05-28 16:58:52 +03:00
}
2016-01-08 20:01:23 +03:00
this . set ( 'submitting' , false ) ;
run . schedule ( 'actions' , this , function ( ) {
this . send ( 'loadServerNotifications' ) ;
this . _transitionAfterSubmission ( ) ;
} ) ;
2015-05-28 16:58:52 +03:00
} ) ;
} ) ;
} else if ( users . length === 0 ) {
2015-08-27 11:41:24 +03:00
this . get ( 'errors' ) . add ( 'users' , 'No users to invite' ) ;
2015-05-28 16:58:52 +03:00
}
2015-08-10 07:40:27 +03:00
} ,
2015-08-27 11:41:24 +03:00
2015-10-28 14:36:45 +03:00
skipInvite ( ) {
2015-08-10 07:40:27 +03:00
this . send ( 'loadServerNotifications' ) ;
2015-08-25 12:54:39 +03:00
this . transitionToRoute ( 'posts.index' ) ;
2015-03-29 21:10:53 +03:00
}
}
} ) ;