@@ -8,8 +8,8 @@ import XMarkIcon from '../../assets/icons/icon-x-mark.svg'
88import Avatar from 'appirio-tech-react-components/components/Avatar/Avatar'
99import { getAvatarResized } from '../../helpers/tcHelpers'
1010import Dropdown from 'appirio-tech-react-components/components/Dropdown/Dropdown'
11-
12-
11+ import FormsyForm from 'appirio-tech-react-components/components/Formsy'
12+ const TCFormFields = FormsyForm . Fields
1313
1414
1515class Dialog extends React . Component {
@@ -21,12 +21,14 @@ class Dialog extends React.Component {
2121 validUserText : false ,
2222 managerType : { } ,
2323 clearText : false ,
24+ members : { } ,
25+ showAlreadyMemberError : false
2426 }
2527
2628 this . onUserRoleChange = this . onUserRoleChange . bind ( this )
27- this . onInviteChange = this . onInviteChange . bind ( this )
2829 this . handleRoles = this . handleRoles . bind ( this )
2930 this . addUsers = this . addUsers . bind ( this )
31+ this . onChange = this . onChange . bind ( this )
3032 }
3133
3234 componentWillMount ( ) {
@@ -40,16 +42,19 @@ class Dialog extends React.Component {
4042 title : 'Copilot' ,
4143 value : 'copilot' ,
4244 } ]
45+ this . setState ( {
46+ members : this . props . members
47+ } )
4348 }
4449
45-
4650 componentWillReceiveProps ( nextProps ) {
4751 if ( this . state . clearText && nextProps . processingInvites !== this . props . processingInvites &&
4852 ! nextProps . processingInvites ) {
4953 this . setState ( {
5054 userText : '' ,
5155 validUserText : false ,
5256 clearText : false ,
57+ members : this . props . members
5358 } )
5459 }
5560 }
@@ -61,22 +66,6 @@ class Dialog extends React.Component {
6166 this . setState ( { managerType} )
6267 }
6368
64- onInviteChange ( evt ) {
65- const text = evt . target . value
66- const users = text . split ( / [ , ; ] / g)
67- const isInvalid = users . some ( user => {
68- user = user . trim ( )
69- if ( user === '' ) {
70- return false
71- }
72- return ! ( user . startsWith ( '@' ) && user . length > 1 )
73- } )
74- this . setState ( {
75- validUserText : ! isInvalid && text . trim ( ) . length > 0 ,
76- userText : evt . target . value
77- } )
78- }
79-
8069 handleRoles ( value ) {
8170 this . setState ( {
8271 userRole : value
@@ -96,6 +85,27 @@ class Dialog extends React.Component {
9685 this . setState ( { clearText : true } )
9786 }
9887
88+ onChange ( currentValues ) {
89+ const text = currentValues . handlesText
90+ let handles = text . split ( / [ , ; ] / g)
91+ const isInvalid = handles . some ( user => {
92+ user = user . trim ( )
93+ if ( user === '' ) {
94+ return false
95+ }
96+ return ! ( user . startsWith ( '@' ) && user . length > 1 )
97+ } )
98+ const validText = ! isInvalid && text . trim ( ) . length > 0
99+ handles = handles . filter ( ( handle ) => ( handle . trim ( ) . startsWith ( '@' ) && handle . length > 1 ) )
100+ handles = handles . map ( handle => handle . trim ( ) . replace ( / ^ @ / , '' ) )
101+ const present = _ . some ( this . state . members , m => handles . indexOf ( m . handle ) > - 1 )
102+ this . setState ( {
103+ validUserText : ! present && validText ,
104+ showAlreadyMemberError : present ,
105+ userText : text
106+ } )
107+ }
108+
99109 render ( ) {
100110 const { members, currentUser, isMember, removeMember, onCancel, removeInvite, invites = [ ] } = this . props
101111 const showRemove = currentUser . isAdmin || ( isMember && currentUser . isManager )
@@ -221,17 +231,19 @@ class Dialog extends React.Component {
221231 } ) ) }
222232 </ div >
223233
224- { showRemove && < div className = "input-container" >
234+ { showRemove && < Formsy . Form className = "input-container" onValidSubmit = { this . addUsers } onChange = { this . onChange } >
225235 < div className = "hint" > invite more people</ div >
226- < input
236+ < TCFormFields . TextInput
237+ name = "handlesText"
238+ wrapperClass = "inviteTextInput"
227239 type = "text"
228240 value = { this . state . userText }
229- onInput = { this . onInviteChange }
230241 placeholder = "Enter one or more user @handles separated by ';' or comma ','"
231- className = "tc-file-field__inputs"
232242 disabled = { ! isMember || this . state . clearText }
233243 />
234-
244+ { this . state . showAlreadyMemberError && < div className = "error-message" >
245+ Project Member(s) can't be invited again. Please remove them from list.
246+ </ div > }
235247 < Dropdown className = "role-drop-down default" >
236248 < div className = "dropdown-menu-header" >
237249 { ( ( ) => {
@@ -254,17 +266,15 @@ class Dialog extends React.Component {
254266 </ ul >
255267 </ div >
256268 </ Dropdown >
257-
258-
259269 < button
260270 className = "tc-btn tc-btn-primary tc-btn-md"
261- onClick = { this . addUsers }
271+ type = "submit"
262272 disabled = { ! this . state . validUserText || this . state . clearText }
263273 >
264274 Send Invite
265275 </ button >
266- </ div > }
267-
276+ </ Formsy . Form >
277+ }
268278 { ! showRemove && < div className = "dialog-placeholder" /> }
269279 </ div >
270280 </ Modal >
0 commit comments