@@ -22,13 +22,15 @@ class Dialog extends React.Component {
2222 managerType : { } ,
2323 clearText : false ,
2424 members : { } ,
25- showAlreadyMemberError : false
25+ showAlreadyMemberError : false ,
26+ errorMessage : null ,
2627 }
2728
2829 this . onUserRoleChange = this . onUserRoleChange . bind ( this )
2930 this . handleRoles = this . handleRoles . bind ( this )
3031 this . addUsers = this . addUsers . bind ( this )
3132 this . onChange = this . onChange . bind ( this )
33+ this . onErrorMessage = this . onErrorMessage . bind ( this )
3234 }
3335
3436 componentWillMount ( ) {
@@ -89,6 +91,40 @@ class Dialog extends React.Component {
8991 this . props . onSelectedMembersUpdate ( selectedMembers )
9092 }
9193
94+ componentWillReceiveProps ( nextProps ) {
95+ const { processingInvites} = this . props
96+ if ( processingInvites && ! nextProps . processingInvites && nextProps . error ) {
97+ this . onErrorMessage ( nextProps . error , this . props . selectedMembers )
98+ }
99+ }
100+
101+ onErrorMessage ( error , selectedMembers ) {
102+ if ( error . msg ) {
103+ this . setState ( {
104+ errorMessage : error . msg
105+ } )
106+ return
107+ }
108+ const msg = [ ]
109+ _ . forEach ( error . failed , ( failed ) => {
110+ const existingMessage = _ . find ( msg , ( m ) => failed . message === m . message )
111+ if ( existingMessage ) {
112+ existingMessage . allUsers . push ( ( failed . email ? failed . email : _ . find ( selectedMembers , ( m ) => m . userId === failed . id ) . handle ) )
113+ const index = _ . find ( msg , ( m ) => failed . message === m . message )
114+ msg . splice ( index , 1 , existingMessage )
115+ } else {
116+ msg . push ( {
117+ message : failed . message ,
118+ allUsers : [ ( failed . email ? failed . email : _ . find ( selectedMembers , ( m ) => m . userId === failed . id ) . handle ) ]
119+ } )
120+ }
121+ } )
122+ const listMessages = _ . map ( msg , m => `${ m . allUsers } : ${ m . message } ` )
123+ this . setState ( {
124+ errorMessage : _ . join ( listMessages , '\n' )
125+ } )
126+ }
127+
92128 render ( ) {
93129 const {
94130 members, currentUser, isMember, removeMember, onCancel, removeInvite, approveOrDecline, invites = [ ] ,
@@ -98,6 +134,12 @@ class Dialog extends React.Component {
98134 const showApproveDecline = currentUser . isAdmin || currentUser . isCopilotManager
99135 let i = 0
100136 const allMembers = [ ...members , ...invites . map ( i => i . member ) ]
137+ const existingInvites = _ . map ( invites , ( m ) => m . member . handle )
138+ let newSelectedMembers = [ ]
139+ if ( selectedMembers ) {
140+ newSelectedMembers = selectedMembers . filter ( i => ! _ . includes ( existingInvites , i . handle ) )
141+ }
142+
101143 return (
102144 < Modal
103145 isOpen
@@ -244,7 +286,7 @@ class Dialog extends React.Component {
244286 </ div >
245287
246288 {
247- invite . status === PROJECT_MEMBER_INVITE_STATUS_REQUESTED && showApproveDecline &&
289+ invite . status === PROJECT_MEMBER_INVITE_STATUS_REQUESTED && showApproveDecline &&
248290 < div className = "member-remove" >
249291 < span onClick = { approve } > approve</ span >
250292 < span onClick = { decline } > decline</ span >
@@ -254,15 +296,15 @@ class Dialog extends React.Component {
254296 </ div >
255297 }
256298 {
257- invite . status === PROJECT_MEMBER_INVITE_STATUS_REQUESTED && ! showApproveDecline && showRemove &&
299+ invite . status === PROJECT_MEMBER_INVITE_STATUS_REQUESTED && ! showApproveDecline && showRemove &&
258300 < div className = "member-remove" >
259301 < span className = "email-date" >
260302 Requested { moment ( invite . createdAt ) . format ( 'MMM D, YY' ) }
261303 </ span >
262304 </ div >
263305 }
264306 {
265- invite . status === PROJECT_MEMBER_INVITE_STATUS_PENDING && showRemove &&
307+ invite . status === PROJECT_MEMBER_INVITE_STATUS_PENDING && showRemove &&
266308 < div className = "member-remove" onClick = { remove } >
267309 Remove
268310 < span className = "email-date" >
@@ -271,14 +313,14 @@ class Dialog extends React.Component {
271313 </ div >
272314 }
273315 {
274- invite . status === PROJECT_MEMBER_INVITE_STATUS_PENDING && ! showRemove &&
316+ invite . status === PROJECT_MEMBER_INVITE_STATUS_PENDING && ! showRemove &&
275317 < div className = "member-remove" >
276318 < span className = "email-date" >
277319 Invited { moment ( invite . createdAt ) . format ( 'MMM D, YY' ) }
278320 </ span >
279321 </ div >
280322 }
281-
323+
282324 </ div >
283325 )
284326 } ) ) }
@@ -289,7 +331,7 @@ class Dialog extends React.Component {
289331 < AutocompleteInput
290332 onUpdate = { this . onChange }
291333 currentUser = { currentUser }
292- selectedMembers = { selectedMembers }
334+ selectedMembers = { newSelectedMembers }
293335 disabled = { processingInvites || ( ! currentUser . isAdmin && ! isMember && ! currentUser . isCopilotManager ) }
294336 allMembers = { allMembers }
295337 />
@@ -305,13 +347,16 @@ class Dialog extends React.Component {
305347 onSelect = { this . handleRoles }
306348 />
307349 </ Formsy . Form >
350+ { this . state . errorMessage && < div className = "error-message" >
351+ { this . state . errorMessage }
352+ </ div > }
308353 < button
309354 className = "tc-btn tc-btn-primary tc-btn-md"
310355 type = "submit"
311356 disabled = { processingInvites || ! this . state . validUserText || this . state . clearText }
312357 onClick = { this . addUsers }
313358 >
314- { _ . find ( this . roles , { value :this . state . userRole } ) . canAddDirectly && ! showApproveDecline
359+ { _ . find ( this . roles , { value :this . state . userRole } ) . canAddDirectly && ! showApproveDecline
315360 ?'Request invite'
316361 :'Invite users' }
317362 </ button >
0 commit comments