Skip to content

Commit 4fd1543

Browse files
committed
PM-973 - move add user to own component
1 parent c7d59d7 commit 4fd1543

File tree

3 files changed

+210
-194
lines changed

3 files changed

+210
-194
lines changed

src/components/Users/Users.module.scss

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,10 +395,15 @@
395395
}
396396

397397
.addButtonContainer {
398-
width: 110px;
398+
display: flex;
399+
justify-content: flex-start;
399400
height: 30px;
400401
margin-top: 20px;
401402
margin-bottom: 20px;
403+
gap: 8px;
404+
> * {
405+
width: 125px;
406+
}
402407
}
403408

404409
.addUserContentContainer {

src/components/Users/index.js

Lines changed: 29 additions & 193 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ import styles from './Users.module.scss'
66
import Select from '../Select'
77
import UserCard from '../UserCard'
88
import PrimaryButton from '../Buttons/PrimaryButton'
9-
import Modal from '../Modal'
10-
import SelectUserAutocomplete from '../SelectUserAutocomplete'
119
import { PROJECT_ROLES, AUTOCOMPLETE_DEBOUNCE_TIME_MS } from '../../config/constants'
1210
import { checkAdmin } from '../../util/tc'
13-
import { addUserToProject, removeUserFromProject } from '../../services/projects'
11+
import { removeUserFromProject } from '../../services/projects'
1412
import ConfirmationModal from '../Modal/ConfirmationModal'
13+
import UserAddModalContent from './user-add.modal'
14+
import InviteUserModalContent from './invite-user.modal' // Import the new component
1515

1616
const theme = {
1717
container: styles.modalContainer
@@ -23,11 +23,7 @@ class Users extends Component {
2323
this.state = {
2424
projectOption: null,
2525
showAddUserModal: false,
26-
userToAdd: null,
27-
userPermissionToAdd: PROJECT_ROLES.READ,
28-
showSelectUserError: false,
29-
isAdding: false,
30-
addUserError: false,
26+
showInviteUserModal: false, // Add state for invite user modal
3127
isRemoving: false,
3228
removeError: null,
3329
showRemoveConfirmationModal: false,
@@ -36,10 +32,9 @@ class Users extends Component {
3632
}
3733
this.setProjectOption = this.setProjectOption.bind(this)
3834
this.onAddUserClick = this.onAddUserClick.bind(this)
35+
this.onInviteUserClick = this.onInviteUserClick.bind(this) // Bind the new method
3936
this.resetAddUserState = this.resetAddUserState.bind(this)
40-
this.onUpdateUserToAdd = this.onUpdateUserToAdd.bind(this)
41-
this.onAddUserConfirmClick = this.onAddUserConfirmClick.bind(this)
42-
this.updatePermission = this.updatePermission.bind(this)
37+
this.resetInviteUserState = this.resetInviteUserState.bind(this) // Bind reset method
4338
this.onRemoveClick = this.onRemoveClick.bind(this)
4439
this.resetRemoveUserState = this.resetRemoveUserState.bind(this)
4540
this.onRemoveConfirmClick = this.onRemoveConfirmClick.bind(this)
@@ -54,78 +49,24 @@ class Users extends Component {
5449
loadProject(projectOption.value, false)
5550
}
5651

57-
updatePermission (newRole) {
58-
this.setState({
59-
userPermissionToAdd: newRole
60-
})
61-
}
62-
6352
onAddUserClick () {
6453
this.setState({
6554
showAddUserModal: true
6655
})
6756
}
6857

69-
resetAddUserState () {
58+
onInviteUserClick () {
7059
this.setState({
71-
userToAdd: null,
72-
showSelectUserError: false,
73-
isAdding: false,
74-
showAddUserModal: false,
75-
userPermissionToAdd: PROJECT_ROLES.READ,
76-
addUserError: null
60+
showInviteUserModal: true
7761
})
7862
}
7963

80-
onUpdateUserToAdd (option) {
81-
let userToAdd = null
82-
if (option && option.value) {
83-
userToAdd = {
84-
handle: option.label,
85-
userId: parseInt(option.value, 10)
86-
}
87-
}
88-
89-
this.setState({
90-
userToAdd,
91-
showSelectUserError: !userToAdd
92-
})
64+
resetAddUserState () {
65+
this.setState({ showAddUserModal: false })
9366
}
9467

95-
async onAddUserConfirmClick () {
96-
const { addNewProjectMember } = this.props
97-
if (this.state.isAdding) { return }
98-
99-
this.setState({
100-
showSelectUserError: false,
101-
addUserError: null
102-
})
103-
104-
if (!this.state.userToAdd) {
105-
this.setState({
106-
showSelectUserError: true
107-
})
108-
return
109-
}
110-
111-
this.setState({
112-
isAdding: true
113-
})
114-
115-
try {
116-
const newUserInfo = await addUserToProject(this.state.projectOption.value, this.state.userToAdd.userId, this.state.userPermissionToAdd)
117-
newUserInfo.handle = this.state.userToAdd.handle
118-
// wait for a second so that project's members are updated
119-
addNewProjectMember(newUserInfo)
120-
this.resetAddUserState()
121-
} catch (e) {
122-
const error = _.get(
123-
e,
124-
'response.data.message',
125-
`Unable to add user`
126-
)
127-
this.setState({ isAdding: false, addUserError: error })
128-
}
68+
resetInviteUserState () {
69+
this.setState({ showInviteUserModal: false })
12970
}
13071

13172
getHandle () {
@@ -260,133 +201,28 @@ class Users extends Component {
260201
text={'Add User'}
261202
type={'info'}
262203
onClick={() => this.onAddUserClick()} />
204+
<PrimaryButton
205+
text={'Invite User'}
206+
type={'info'}
207+
onClick={() => this.onInviteUserClick()} />
263208
</div>
264209
)
265210
}
266211
{
267212
this.state.showAddUserModal && (
268-
<Modal theme={theme} onCancel={() => this.resetAddUserState()}>
269-
<div className={cn(styles.contentContainer, styles.confirm)}>
270-
<div className={styles.title}>Add User</div>
271-
<div className={styles.addUserContentContainer}>
272-
<div className={styles.row}>
273-
<div className={cn(styles.field, styles.col1, styles.addUserTitle)}>
274-
Member<span className={styles.required}>*</span> :
275-
</div>
276-
<div className={cn(styles.field, styles.col2)}>
277-
<SelectUserAutocomplete
278-
value={this.state.userToAdd ? { label: this.state.userToAdd.handle, value: this.state.userToAdd.userId.toString() } : null}
279-
onChange={this.onUpdateUserToAdd}
280-
/>
281-
</div>
282-
</div>
283-
{
284-
this.state.showSelectUserError && (
285-
<div className={styles.row}>
286-
<div className={styles.errorMesssage}>Please select a member.</div>
287-
</div>
288-
)
289-
}
290-
<div className={styles.row}>
291-
<div className={cn(styles.field, styles.col1, styles.addUserTitle)}>
292-
<label htmlFor='memberToAdd'>Role :</label>
293-
</div>
294-
<div className={cn(styles.col5)}>
295-
<div className={styles.tcRadioButton}>
296-
<input
297-
name={`add-user-radio`}
298-
type='radio'
299-
id={`read-add-user`}
300-
checked={this.state.userPermissionToAdd === PROJECT_ROLES.READ}
301-
onChange={(e) => e.target.checked && this.updatePermission(PROJECT_ROLES.READ)}
302-
/>
303-
<label htmlFor={`read-add-user`}>
304-
<div>
305-
Read
306-
</div>
307-
<input type='hidden' />
308-
</label>
309-
</div>
310-
</div>
311-
<div className={cn(styles.col5)}>
312-
<div className={styles.tcRadioButton}>
313-
<input
314-
name={`add-user-radio`}
315-
type='radio'
316-
id={`write-add-user`}
317-
checked={this.state.userPermissionToAdd === PROJECT_ROLES.WRITE}
318-
onChange={(e) => e.target.checked && this.updatePermission(PROJECT_ROLES.WRITE)}
319-
/>
320-
<label htmlFor={`write-add-user`}>
321-
<div>
322-
Write
323-
</div>
324-
<input type='hidden' />
325-
</label>
326-
</div>
327-
</div>
328-
<div className={cn(styles.col5)}>
329-
<div className={styles.tcRadioButton}>
330-
<input
331-
name={`add-user-radio`}
332-
type='radio'
333-
id={`full-access-add-user`}
334-
checked={this.state.userPermissionToAdd === PROJECT_ROLES.MANAGER}
335-
onChange={(e) => e.target.checked && this.updatePermission(PROJECT_ROLES.MANAGER)}
336-
/>
337-
<label htmlFor={`full-access-add-user`}>
338-
<div>
339-
Full Access
340-
</div>
341-
<input type='hidden' />
342-
</label>
343-
</div>
344-
</div>
345-
<div className={cn(styles.col5)}>
346-
<div className={styles.tcRadioButton}>
347-
<input
348-
name={`add-user-radio`}
349-
type='radio'
350-
id={`copilot-add-user`}
351-
checked={this.state.userPermissionToAdd === PROJECT_ROLES.COPILOT}
352-
onChange={(e) => e.target.checked && this.updatePermission(PROJECT_ROLES.COPILOT)}
353-
/>
354-
<label htmlFor={`copilot-add-user`}>
355-
<div>
356-
Copilot
357-
</div>
358-
<input type='hidden' />
359-
</label>
360-
</div>
361-
</div>
362-
</div>
363-
{
364-
this.state.addUserError && (
365-
<div className={styles.errorMesssage}>
366-
{this.state.addUserError}
367-
</div>
368-
)
369-
}
370-
</div>
371-
372-
<div className={styles.buttonGroup}>
373-
<div className={styles.buttonSizeA}>
374-
<PrimaryButton
375-
text={'Close'}
376-
type={'info'}
377-
onClick={() => this.resetAddUserState()}
378-
/>
379-
</div>
380-
<div className={styles.buttonSizeA}>
381-
<PrimaryButton
382-
text={this.state.isAdding ? 'Adding user...' : 'Add User'}
383-
type={'info'}
384-
onClick={() => this.onAddUserConfirmClick()}
385-
/>
386-
</div>
387-
</div>
388-
</div>
389-
</Modal>
213+
<UserAddModalContent
214+
projectId={this.state.projectOption.value}
215+
addNewProjectMember={this.props.addNewProjectMember}
216+
onClose={this.resetAddUserState}
217+
/>
218+
)
219+
}
220+
{
221+
this.state.showInviteUserModal && (
222+
<InviteUserModalContent
223+
projectId={this.state.projectOption.value}
224+
onClose={this.resetInviteUserState}
225+
/>
390226
)
391227
}
392228
{

0 commit comments

Comments
 (0)