Skip to content

feat(PM-1506): Overwrite role if the copilot is already a member of the project with "read"/"write" access #1658

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 29, 2025

Conversation

hentrymartin
Copy link
Collaborator

What's in this PR?

  • Overwrite role if the copilot is already a member of the project with "read"/"write" access

Ticket link - https://topcoder.atlassian.net/browse/PM-1506

@hentrymartin hentrymartin requested a review from kkartunov July 28, 2025 11:16
@@ -225,6 +225,9 @@ class Users extends Component {
addNewProjectMember={this.props.addNewProjectMember}
onMemberInvited={this.props.addNewProjectInvite}
onClose={this.resetAddUserState}
projectOption={this.state.projectOption}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider checking if projectOption is correctly initialized and used within the component. Ensure that it aligns with the intended functionality described in the pull request.

@@ -225,6 +225,9 @@ class Users extends Component {
addNewProjectMember={this.props.addNewProjectMember}
onMemberInvited={this.props.addNewProjectInvite}
onClose={this.resetAddUserState}
projectOption={this.state.projectOption}
projectMembers={projectMembers}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verify that projectMembers is correctly populated and used within the component. Ensure it reflects the current state of project members accurately.

@@ -225,6 +225,9 @@ class Users extends Component {
addNewProjectMember={this.props.addNewProjectMember}
onMemberInvited={this.props.addNewProjectInvite}
onClose={this.resetAddUserState}
projectOption={this.state.projectOption}
projectMembers={projectMembers}
updateProjectMember={updateProjectMember}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that updateProjectMember is properly defined and handles the logic for updating project members as intended. Consider edge cases where the update might fail or need additional validation.

const UserAddModalContent = ({ projectId, addNewProjectMember, onMemberInvited, onClose }) => {
const UserAddModalContent = ({
projectMembers,
projectOption,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The projectOption parameter is added but not used in the function. Consider removing it if it's unnecessary.

const [userToAdd, setUserToAdd] = useState(null)
const [userPermissionToAdd, setUserPermissionToAdd] = useState(PROJECT_ROLES.READ)
const [showSelectUserError, setShowSelectUserError] = useState(false)
const [addUserError, setAddUserError] = useState(null)
const [isAdding, setIsAdding] = useState(false)
const [isUserAddingFailed, setUserAddingFailed] = useState(false)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable isUserAddingFailed is introduced but not used in the code. Ensure it is utilized or remove it if not needed.

const [userToAdd, setUserToAdd] = useState(null)
const [userPermissionToAdd, setUserPermissionToAdd] = useState(PROJECT_ROLES.READ)
const [showSelectUserError, setShowSelectUserError] = useState(false)
const [addUserError, setAddUserError] = useState(null)
const [isAdding, setIsAdding] = useState(false)
const [isUserAddingFailed, setUserAddingFailed] = useState(false)
const [existingRole, setExistingRole] = useState('')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable existingRole is introduced but not used in the code. Ensure it is utilized or remove it if not needed.

@@ -52,8 +62,12 @@ const UserAddModalContent = ({ projectId, addNewProjectMember, onMemberInvited,
})
if (failed) {
const error = get(failed, '0.message', 'User cannot be invited')
const errorCode = get(failed, '0.error')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider checking if failed is not null or undefined before attempting to access its properties to avoid potential runtime errors.

@@ -52,8 +62,12 @@ const UserAddModalContent = ({ projectId, addNewProjectMember, onMemberInvited,
})
if (failed) {
const error = get(failed, '0.message', 'User cannot be invited')
const errorCode = get(failed, '0.error')
const role = get(failed, '0.role')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider checking if failed is not null or undefined before attempting to access its properties to avoid potential runtime errors.

setAddUserError(error)
setIsAdding(false)
setUserAddingFailed(errorCode === 'ALREADY_MEMBER')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a constant or enum for the error code 'ALREADY_MEMBER' to avoid magic strings and improve maintainability.

@@ -74,121 +88,152 @@ const UserAddModalContent = ({ projectId, addNewProjectMember, onMemberInvited,
}
}

const onConfirmCopilotRoleChange = async () => {
const member = projectMembers.find(item => item.userId === userToAdd.userId)
const action = member.role === 'manager' ? 'complete-copilot-requests' : ''

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider checking if member is undefined before accessing its properties. This will prevent potential runtime errors if projectMembers.find does not find a matching member.

const onConfirmCopilotRoleChange = async () => {
const member = projectMembers.find(item => item.userId === userToAdd.userId)
const action = member.role === 'manager' ? 'complete-copilot-requests' : ''
const response = await updateProjectMemberRole(projectId, member.id, 'copilot', action)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The action variable is set to an empty string if the member's role is not 'manager'. Consider handling other roles explicitly or documenting why an empty string is appropriate for roles other than 'manager'.

onChange={onUpdateUserToAdd}
/>
{
isUserAddingFailed && (['observer', 'customer', 'copilot', 'manager'].includes(existingRole)) && (

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition (['observer', 'customer', 'copilot', 'manager'].includes(existingRole)) is repeated multiple times. Consider defining a constant array for these roles to improve readability and maintainability.

</label>
{showSelectUserError && (
<div className={styles.row}>
<div className={styles.errorMesssage}>Please select a member.</div>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a typo in the class name styles.errorMesssage. It should be styles.errorMessage.

</Modal>
)
}
UserAddModalContent.propTypes = {
projectId: PropTypes.number.isRequired,
addNewProjectMember: PropTypes.func.isRequired,
onMemberInvited: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired
onClose: PropTypes.func.isRequired,
projectOption: PropTypes.any.isRequired,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a more specific PropType instead of PropTypes.any for projectOption to ensure type safety and clarity. If the type is not clear, consider defining it or using a more descriptive PropType.

@@ -103,9 +103,10 @@ export async function fetchProjectPhases (id) {
* @param newRole the new role
* @returns {Promise<*>}
*/
export async function updateProjectMemberRole (projectId, memberRecordId, newRole) {
export async function updateProjectMemberRole (projectId, memberRecordId, newRole, action) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function updateProjectMemberRole now includes an additional parameter action. Ensure that all calls to this function throughout the codebase are updated to pass this new parameter, or provide a default value to maintain backward compatibility.

@kkartunov kkartunov merged commit 9e8f76f into develop Jul 29, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy