diff --git a/apiserver/plane/app/views/project.py b/apiserver/plane/app/views/project.py index e411e0e39..5d2f95673 100644 --- a/apiserver/plane/app/views/project.py +++ b/apiserver/plane/app/views/project.py @@ -685,6 +685,19 @@ class ProjectMemberViewSet(BaseViewSet): .order_by("sort_order") ) + bulk_project_members = [] + member_roles = {member.get("member_id"): member.get("role") for member in members} + # Update roles in the members array based on the member_roles dictionary + for project_member in ProjectMember.objects.filter(project_id=project_id, member_id__in=[member.get("member_id") for member in members]): + project_member.role = member_roles[str(project_member.member_id)] + project_member.is_active = True + bulk_project_members.append(project_member) + + # Update the roles of the existing members + ProjectMember.objects.bulk_update( + bulk_project_members, ["is_active", "role"], batch_size=100 + ) + for member in members: sort_order = [ project_member.get("sort_order") @@ -711,25 +724,6 @@ class ProjectMemberViewSet(BaseViewSet): ) ) - # Check if the user is already a member of the project and is inactive - if ProjectMember.objects.filter( - workspace__slug=slug, - project_id=project_id, - member_id=member.get("member_id"), - is_active=False, - ).exists(): - member_detail = ProjectMember.objects.get( - workspace__slug=slug, - project_id=project_id, - member_id=member.get("member_id"), - is_active=False, - ) - # Check if the user has not deactivated the account - user = User.objects.filter(pk=member.get("member_id")).first() - if user.is_active: - member_detail.is_active = True - member_detail.save(update_fields=["is_active"]) - project_members = ProjectMember.objects.bulk_create( bulk_project_members, batch_size=10, @@ -740,8 +734,8 @@ class ProjectMemberViewSet(BaseViewSet): bulk_issue_props, batch_size=10, ignore_conflicts=True ) - serializer = ProjectMemberSerializer(project_members, many=True) - + project_members = ProjectMember.objects.filter(project_id=project_id, member_id__in=[member.get("member_id") for member in members]) + serializer = ProjectMemberRoleSerializer(project_members, many=True) return Response(serializer.data, status=status.HTTP_201_CREATED) def list(self, request, slug, project_id): diff --git a/web/components/onboarding/invitations.tsx b/web/components/onboarding/invitations.tsx index f4f23373d..c9ec19cc8 100644 --- a/web/components/onboarding/invitations.tsx +++ b/web/components/onboarding/invitations.tsx @@ -99,7 +99,7 @@ export const Invitations: React.FC = (props) => { >
- {invitedWorkspace.logo && invitedWorkspace.logo !== "" ? ( + {invitedWorkspace?.logo && invitedWorkspace.logo !== "" ? ( = (props) => { /> ) : ( - {invitedWorkspace.name[0]} + {invitedWorkspace?.name[0]} )}
-
{truncateText(invitedWorkspace.name, 30)}
+
{truncateText(invitedWorkspace?.name, 30)}

{ROLE[invitation.role]}

diff --git a/web/components/project/member-select.tsx b/web/components/project/member-select.tsx index e019a29e7..7dc9b3233 100644 --- a/web/components/project/member-select.tsx +++ b/web/components/project/member-select.tsx @@ -19,20 +19,30 @@ export const MemberSelect: React.FC = observer((props) => { project: { projectMemberIds, getProjectMemberDetails }, } = useMember(); - const options = projectMemberIds?.map((userId) => { - const memberDetails = getProjectMemberDetails(userId); + const options = projectMemberIds + ?.map((userId) => { + const memberDetails = getProjectMemberDetails(userId); - return { - value: `${memberDetails?.member.id}`, - query: `${memberDetails?.member.display_name}`, - content: ( -
- - {memberDetails?.member.display_name} -
- ), - }; - }); + if (!memberDetails?.member) return; + + return { + value: `${memberDetails?.member.id}`, + query: `${memberDetails?.member.display_name}`, + content: ( +
+ + {memberDetails?.member.display_name} +
+ ), + }; + }) + .filter((option) => !!option) as + | { + value: string; + query: string; + content: React.JSX.Element; + }[] + | undefined; const selectedOption = getProjectMemberDetails(value); return ( diff --git a/web/store/root.store.ts b/web/store/root.store.ts index 4714c8b19..b3aeeea04 100644 --- a/web/store/root.store.ts +++ b/web/store/root.store.ts @@ -59,4 +59,23 @@ export class RootStore { this.projectPages = new ProjectPageStore(this); this.dashboard = new DashboardStore(this); } + + resetOnSignout() { + this.workspaceRoot = new WorkspaceRootStore(this); + this.projectRoot = new ProjectRootStore(this); + this.memberRoot = new MemberRootStore(this); + // independent stores + this.cycle = new CycleStore(this); + this.module = new ModulesStore(this); + this.projectView = new ProjectViewStore(this); + this.globalView = new GlobalViewStore(this); + this.issue = new IssueRootStore(this); + this.inbox = new InboxRootStore(this); + this.state = new StateStore(this); + this.label = new LabelStore(this); + this.estimate = new EstimateStore(this); + this.mention = new MentionStore(this); + this.projectPages = new ProjectPageStore(this); + this.dashboard = new DashboardStore(this); + } } diff --git a/web/store/user/index.ts b/web/store/user/index.ts index d3a16c3fc..b07764a05 100644 --- a/web/store/user/index.ts +++ b/web/store/user/index.ts @@ -249,6 +249,8 @@ export class UserRootStore implements IUserRootStore { this.currentUserError = null; this.isUserLoggedIn = false; }); + this.membership = new UserMembershipStore(this.rootStore); + this.rootStore.resetOnSignout(); }); /** @@ -261,5 +263,7 @@ export class UserRootStore implements IUserRootStore { this.currentUser = null; this.isUserLoggedIn = false; }); + this.membership = new UserMembershipStore(this.rootStore); + this.rootStore.resetOnSignout(); }); }