Skip to content

Commit e551d12

Browse files
committed
feat: modifications on copilot addition to project
1 parent e950796 commit e551d12

File tree

3 files changed

+155
-103
lines changed

3 files changed

+155
-103
lines changed

src/components/Users/Users.module.scss

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@
4040
}
4141
}
4242

43+
.textContent {
44+
font-size: 18px;
45+
margin-top: 25px;
46+
}
47+
4348

4449
.row {
4550
display: flex;
@@ -400,7 +405,7 @@
400405
justify-content: center;
401406
}
402407

403-
.addButtonContainer {
408+
.addButtonContainer, .buttonWrapper {
404409
display: flex;
405410
justify-content: flex-start;
406411
height: 30px;
@@ -412,10 +417,6 @@
412417
}
413418
}
414419

415-
.addUserContentContainer {
416-
417-
}
418-
419420
.tcRadioButton {
420421
.tc-radioButton-label {
421422
@include roboto-light();

src/components/Users/index.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,12 @@ class Users extends Component {
6363
})
6464
}
6565

66-
resetAddUserState () {
66+
resetAddUserState (doReloadList) {
6767
this.setState({ showAddUserModal: false })
68+
69+
if (doReloadList) {
70+
71+
}
6872
}
6973

7074
resetInviteUserState () {
@@ -225,6 +229,9 @@ class Users extends Component {
225229
addNewProjectMember={this.props.addNewProjectMember}
226230
onMemberInvited={this.props.addNewProjectInvite}
227231
onClose={this.resetAddUserState}
232+
projectOption={this.state.projectOption}
233+
projectMembers={projectMembers}
234+
updateProjectMember={updateProjectMember}
228235
/>
229236
)
230237
}

src/components/Users/user-add.modal.js

Lines changed: 141 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,30 @@ import Modal from '../Modal'
66
import SelectUserAutocomplete from '../SelectUserAutocomplete'
77
import { PROJECT_ROLES } from '../../config/constants'
88
import PrimaryButton from '../Buttons/PrimaryButton'
9-
import { addUserToProject, inviteUserToProject } from '../../services/projects'
9+
import { addUserToProject, inviteUserToProject, updateProjectMemberRole } from '../../services/projects'
1010

1111
import styles from './Users.module.scss'
1212

1313
const theme = {
1414
container: styles.modalContainer
1515
}
1616

17-
const UserAddModalContent = ({ projectId, addNewProjectMember, onMemberInvited, onClose }) => {
17+
const UserAddModalContent = ({
18+
projectMembers,
19+
projectOption,
20+
projectId,
21+
addNewProjectMember,
22+
onMemberInvited,
23+
onClose,
24+
updateProjectMember
25+
}) => {
1826
const [userToAdd, setUserToAdd] = useState(null)
1927
const [userPermissionToAdd, setUserPermissionToAdd] = useState(PROJECT_ROLES.READ)
2028
const [showSelectUserError, setShowSelectUserError] = useState(false)
2129
const [addUserError, setAddUserError] = useState(null)
2230
const [isAdding, setIsAdding] = useState(false)
31+
const [isUserAddingFailed, setUserAddingFailed] = useState(false)
32+
const [existingRole, setExistingRole] = useState('')
2333

2434
const onUpdateUserToAdd = (option) => {
2535
if (option && option.value) {
@@ -52,8 +62,12 @@ const UserAddModalContent = ({ projectId, addNewProjectMember, onMemberInvited,
5262
})
5363
if (failed) {
5464
const error = get(failed, '0.message', 'User cannot be invited')
65+
const errorCode = get(failed, '0.error')
66+
const role = get(failed, '0.role')
5567
setAddUserError(error)
5668
setIsAdding(false)
69+
setUserAddingFailed(errorCode === 'ALREADY_MEMBER')
70+
setExistingRole(role)
5771
} else if (rest.message) {
5872
setAddUserError(rest.message)
5973
setIsAdding(false)
@@ -74,121 +88,151 @@ const UserAddModalContent = ({ projectId, addNewProjectMember, onMemberInvited,
7488
}
7589
}
7690

91+
const onConfirmCopilotRoleChange = async () => {
92+
const member = projectMembers.find(item => item.userId === userToAdd.userId)
93+
const response = await updateProjectMemberRole(projectId, member.id, 'copilot')
94+
updateProjectMember(response)
95+
onClose(true)
96+
}
97+
98+
const onCancelCopilotRoleChange = () => {
99+
setUserAddingFailed(false)
100+
setAddUserError('')
101+
}
102+
77103
return (
78104
<Modal theme={theme} onCancel={onClose}>
79-
<div className={cn(styles.contentContainer, styles.confirm)}>
80-
<div className={styles.title}>Add User</div>
81-
<div className={styles.addUserContentContainer}>
82-
<div className={styles.row}>
83-
<div className={cn(styles.field, styles.col1, styles.addUserTitle)}>
84-
Member<span className={styles.required}>*</span> :
85-
</div>
86-
<div className={cn(styles.field, styles.col2)}>
87-
<SelectUserAutocomplete
88-
value={userToAdd ? { label: userToAdd.handle, value: userToAdd.userId.toString() } : null}
89-
onChange={onUpdateUserToAdd}
90-
/>
105+
{
106+
isUserAddingFailed && (existingRole === 'observer' || existingRole === 'customer' || existingRole === 'copilot') && (
107+
<div className={cn(styles.contentContainer, styles.confirm)}>
108+
<div className={styles.textContent}>{`The copilot ${userToAdd.handle} is part of ${projectOption.label} project with ${existingRole} role.`}</div>
109+
<div className={styles.buttonWrapper}>
110+
<PrimaryButton onClick={onConfirmCopilotRoleChange} text={'Confirm'} type={'info'} />
111+
<PrimaryButton onClick={onCancelCopilotRoleChange} text={'Cancel'} type={'disabled'} />
91112
</div>
92113
</div>
93-
{showSelectUserError && (
94-
<div className={styles.row}>
95-
<div className={styles.errorMesssage}>Please select a member.</div>
96-
</div>
97-
)}
98-
<div className={styles.row}>
99-
<div className={cn(styles.field, styles.col1, styles.addUserTitle)}>
100-
<label htmlFor='memberToAdd'>Role :</label>
101-
</div>
102-
<div className={cn(styles.col5)}>
103-
<div className={styles.tcRadioButton}>
104-
<input
105-
name={`add-user-radio`}
106-
type='radio'
107-
id={`read-add-user`}
108-
checked={userPermissionToAdd === PROJECT_ROLES.READ}
109-
onChange={() => setUserPermissionToAdd(PROJECT_ROLES.READ)}
110-
/>
111-
<label htmlFor={`read-add-user`}>
112-
<div>Read</div>
113-
<input type='hidden' />
114-
</label>
114+
)
115+
}
116+
{
117+
!isUserAddingFailed && (
118+
<div className={cn(styles.contentContainer, styles.confirm)}>
119+
<div className={styles.title}>Add User</div>
120+
<div className={styles.addUserContentContainer}>
121+
<div className={styles.row}>
122+
<div className={cn(styles.field, styles.col1, styles.addUserTitle)}>
123+
Member<span className={styles.required}>*</span> :
124+
</div>
125+
<div className={cn(styles.field, styles.col2)}>
126+
<SelectUserAutocomplete
127+
value={userToAdd ? { label: userToAdd.handle, value: userToAdd.userId.toString() } : null}
128+
onChange={onUpdateUserToAdd}
129+
/>
130+
</div>
115131
</div>
116-
</div>
117-
<div className={cn(styles.col5)}>
118-
<div className={styles.tcRadioButton}>
119-
<input
120-
name={`add-user-radio`}
121-
type='radio'
122-
id={`write-add-user`}
123-
checked={userPermissionToAdd === PROJECT_ROLES.WRITE}
124-
onChange={() => setUserPermissionToAdd(PROJECT_ROLES.WRITE)}
125-
/>
126-
<label htmlFor={`write-add-user`}>
127-
<div>Write</div>
128-
<input type='hidden' />
129-
</label>
132+
{showSelectUserError && (
133+
<div className={styles.row}>
134+
<div className={styles.errorMesssage}>Please select a member.</div>
135+
</div>
136+
)}
137+
<div className={styles.row}>
138+
<div className={cn(styles.field, styles.col1, styles.addUserTitle)}>
139+
<label htmlFor='memberToAdd'>Role :</label>
140+
</div>
141+
<div className={cn(styles.col5)}>
142+
<div className={styles.tcRadioButton}>
143+
<input
144+
name={`add-user-radio`}
145+
type='radio'
146+
id={`read-add-user`}
147+
checked={userPermissionToAdd === PROJECT_ROLES.READ}
148+
onChange={() => setUserPermissionToAdd(PROJECT_ROLES.READ)}
149+
/>
150+
<label htmlFor={`read-add-user`}>
151+
<div>Read</div>
152+
<input type='hidden' />
153+
</label>
154+
</div>
155+
</div>
156+
<div className={cn(styles.col5)}>
157+
<div className={styles.tcRadioButton}>
158+
<input
159+
name={`add-user-radio`}
160+
type='radio'
161+
id={`write-add-user`}
162+
checked={userPermissionToAdd === PROJECT_ROLES.WRITE}
163+
onChange={() => setUserPermissionToAdd(PROJECT_ROLES.WRITE)}
164+
/>
165+
<label htmlFor={`write-add-user`}>
166+
<div>Write</div>
167+
<input type='hidden' />
168+
</label>
169+
</div>
170+
</div>
171+
<div className={cn(styles.col5)}>
172+
<div className={styles.tcRadioButton}>
173+
<input
174+
name={`add-user-radio`}
175+
type='radio'
176+
id={`full-access-add-user`}
177+
checked={userPermissionToAdd === PROJECT_ROLES.MANAGER}
178+
onChange={() => setUserPermissionToAdd(PROJECT_ROLES.MANAGER)}
179+
/>
180+
<label htmlFor={`full-access-add-user`}>
181+
<div>Full Access</div>
182+
<input type='hidden' />
183+
</label>
184+
</div>
185+
</div>
186+
<div className={cn(styles.col5)}>
187+
<div className={styles.tcRadioButton}>
188+
<input
189+
name={`add-user-radio`}
190+
type='radio'
191+
id={`copilot-add-user`}
192+
checked={userPermissionToAdd === PROJECT_ROLES.COPILOT}
193+
onChange={() => setUserPermissionToAdd(PROJECT_ROLES.COPILOT)}
194+
/>
195+
<label htmlFor={`copilot-add-user`}>
196+
<div>Copilot</div>
197+
<input type='hidden' />
198+
</label>
199+
</div>
200+
</div>
130201
</div>
202+
{addUserError && (
203+
<div className={styles.errorMesssage}>{addUserError}</div>
204+
)}
131205
</div>
132-
<div className={cn(styles.col5)}>
133-
<div className={styles.tcRadioButton}>
134-
<input
135-
name={`add-user-radio`}
136-
type='radio'
137-
id={`full-access-add-user`}
138-
checked={userPermissionToAdd === PROJECT_ROLES.MANAGER}
139-
onChange={() => setUserPermissionToAdd(PROJECT_ROLES.MANAGER)}
206+
<div className={styles.buttonGroup}>
207+
<div className={styles.buttonSizeA}>
208+
<PrimaryButton
209+
text={'Close'}
210+
type={'info'}
211+
onClick={onClose}
140212
/>
141-
<label htmlFor={`full-access-add-user`}>
142-
<div>Full Access</div>
143-
<input type='hidden' />
144-
</label>
145213
</div>
146-
</div>
147-
<div className={cn(styles.col5)}>
148-
<div className={styles.tcRadioButton}>
149-
<input
150-
name={`add-user-radio`}
151-
type='radio'
152-
id={`copilot-add-user`}
153-
checked={userPermissionToAdd === PROJECT_ROLES.COPILOT}
154-
onChange={() => setUserPermissionToAdd(PROJECT_ROLES.COPILOT)}
214+
<div className={styles.buttonSizeA}>
215+
<PrimaryButton
216+
text={isAdding ? 'Adding user...' : 'Add User'}
217+
type={'info'}
218+
onClick={onAddUserConfirmClick}
155219
/>
156-
<label htmlFor={`copilot-add-user`}>
157-
<div>Copilot</div>
158-
<input type='hidden' />
159-
</label>
160220
</div>
161221
</div>
162222
</div>
163-
{addUserError && (
164-
<div className={styles.errorMesssage}>{addUserError}</div>
165-
)}
166-
</div>
167-
<div className={styles.buttonGroup}>
168-
<div className={styles.buttonSizeA}>
169-
<PrimaryButton
170-
text={'Close'}
171-
type={'info'}
172-
onClick={onClose}
173-
/>
174-
</div>
175-
<div className={styles.buttonSizeA}>
176-
<PrimaryButton
177-
text={isAdding ? 'Adding user...' : 'Add User'}
178-
type={'info'}
179-
onClick={onAddUserConfirmClick}
180-
/>
181-
</div>
182-
</div>
183-
</div>
223+
)
224+
}
184225
</Modal>
185226
)
186227
}
187228
UserAddModalContent.propTypes = {
188229
projectId: PropTypes.number.isRequired,
189230
addNewProjectMember: PropTypes.func.isRequired,
190231
onMemberInvited: PropTypes.func.isRequired,
191-
onClose: PropTypes.func.isRequired
232+
onClose: PropTypes.func.isRequired,
233+
projectOption: PropTypes.any.isRequired,
234+
projectMembers: PropTypes.array.isRequired,
235+
updateProjectMember: PropTypes.func.isRequired
192236
}
193237

194238
export default UserAddModalContent

0 commit comments

Comments
 (0)