feat: resolving bugs in checklist testing

This commit is contained in:
=
2025-10-10 00:09:46 +05:30
parent c2490380f0
commit 44b50c93c3
19 changed files with 140 additions and 111 deletions
@@ -92,7 +92,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privilege: { privilege: {
...privilege, ...privilege,
identityId: req.body.identityId, identityId: req.body.identityId,
projectMembershipId: "", projectMembershipId: projectId,
projectId, projectId,
slug: privilege.name slug: privilege.name
} }
@@ -186,7 +186,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privilege: { privilege: {
...privilege, ...privilege,
identityId: req.body.identityId, identityId: req.body.identityId,
projectMembershipId: "", projectMembershipId: projectId,
projectId, projectId,
slug: privilege.name slug: privilege.name
} }
@@ -299,7 +299,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privilege: { privilege: {
...privilege, ...privilege,
identityId: req.body.identityId, identityId: req.body.identityId,
projectMembershipId: "", projectMembershipId: projectId,
projectId, projectId,
slug: privilege.name slug: privilege.name
} }
@@ -363,7 +363,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privilege: { privilege: {
...privilege, ...privilege,
identityId: req.body.identityId, identityId: req.body.identityId,
projectMembershipId: "", projectMembershipId: projectId,
projectId, projectId,
slug: privilege.name slug: privilege.name
} }
@@ -429,7 +429,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privilege: { privilege: {
...privilege, ...privilege,
identityId: req.query.identityId, identityId: req.query.identityId,
projectMembershipId: "", projectMembershipId: projectId,
projectId, projectId,
slug: privilege.name slug: privilege.name
} }
@@ -486,7 +486,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privileges: privileges.map((privilege) => ({ privileges: privileges.map((privilege) => ({
...privilege, ...privilege,
identityId: req.query.identityId, identityId: req.query.identityId,
projectMembershipId: "", projectMembershipId: projectId,
projectId, projectId,
slug: privilege.name slug: privilege.name
})) }))
@@ -211,7 +211,6 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
} }
}); });
// TODO(simp): switch to top level roles
server.route({ server.route({
method: "GET", method: "GET",
url: "/:organizationId/roles", url: "/:organizationId/roles",
@@ -248,7 +247,6 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
} }
}); });
// TODO(simp): get this fixed
server.route({ server.route({
method: "GET", method: "GET",
url: "/:organizationId/permissions", url: "/:organizationId/permissions",
@@ -84,7 +84,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privilege: { privilege: {
...privilege, ...privilege,
identityId: req.body.identityId, identityId: req.body.identityId,
projectMembershipId: "", projectMembershipId: req.body.projectId,
projectId: req.body.projectId, projectId: req.body.projectId,
slug: privilege.name slug: privilege.name
} }
@@ -167,7 +167,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privilege: { privilege: {
...privilege, ...privilege,
identityId: privilegeDoc.actorIdentityId as string, identityId: privilegeDoc.actorIdentityId as string,
projectMembershipId: "", projectMembershipId: privilegeDoc.projectId as string,
projectId: privilegeDoc.projectId as string, projectId: privilegeDoc.projectId as string,
slug: privilege.name slug: privilege.name
} }
@@ -221,7 +221,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privilege: { privilege: {
...privilege, ...privilege,
identityId: privilegeDoc.actorIdentityId as string, identityId: privilegeDoc.actorIdentityId as string,
projectMembershipId: "", projectMembershipId: privilegeDoc.projectId as string,
projectId: privilegeDoc.projectId as string, projectId: privilegeDoc.projectId as string,
slug: privilege.name slug: privilege.name
} }
@@ -275,7 +275,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privilege: { privilege: {
...privilege, ...privilege,
identityId: privilegeDoc.actorIdentityId as string, identityId: privilegeDoc.actorIdentityId as string,
projectMembershipId: "", projectMembershipId: privilegeDoc.projectId as string,
projectId: privilegeDoc.projectId as string, projectId: privilegeDoc.projectId as string,
slug: privilege.name slug: privilege.name
} }
@@ -338,7 +338,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privilege: { privilege: {
...privilege, ...privilege,
identityId: req.query.identityId, identityId: req.query.identityId,
projectMembershipId: "", projectMembershipId: privilege.projectId as string,
projectId, projectId,
slug: privilege.name slug: privilege.name
} }
@@ -390,7 +390,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privileges: privileges.map((privilege) => ({ privileges: privileges.map((privilege) => ({
...privilege, ...privilege,
identityId: req.query.identityId, identityId: req.query.identityId,
projectMembershipId: "", projectMembershipId: privilege.projectId as string,
projectId: req.query.projectId, projectId: req.query.projectId,
slug: privilege.name slug: privilege.name
})) }))
+2 -2
View File
@@ -40,7 +40,7 @@ export const groupDALFactory = (db: TDbClient) => {
.where(`${TableName.Membership}.scope`, AccessScope.Organization) .where(`${TableName.Membership}.scope`, AccessScope.Organization)
.join(TableName.Membership, `${TableName.Groups}.id`, `${TableName.Membership}.actorGroupId`) .join(TableName.Membership, `${TableName.Groups}.id`, `${TableName.Membership}.actorGroupId`)
.join(TableName.MembershipRole, `${TableName.MembershipRole}.membershipId`, `${TableName.Membership}.id`) .join(TableName.MembershipRole, `${TableName.MembershipRole}.membershipId`, `${TableName.Membership}.id`)
.join(TableName.Role, `${TableName.MembershipRole}.customRoleId`, `${TableName.Role}.id`) .leftJoin(TableName.Role, `${TableName.MembershipRole}.customRoleId`, `${TableName.Role}.id`)
.select(selectAllTableCols(TableName.Groups)) .select(selectAllTableCols(TableName.Groups))
// cr stands for custom role // cr stands for custom role
.select(db.ref("id").as("crId").withSchema(TableName.Role)) .select(db.ref("id").as("crId").withSchema(TableName.Role))
@@ -210,7 +210,7 @@ export const groupDALFactory = (db: TDbClient) => {
.where(`${TableName.Membership}.scope`, AccessScope.Organization) .where(`${TableName.Membership}.scope`, AccessScope.Organization)
.where((queryBuilder) => { .where((queryBuilder) => {
Object.entries(filter).forEach(([key, value]) => { Object.entries(filter).forEach(([key, value]) => {
void queryBuilder.where(`${TableName.Membership}.${key}`, value); void queryBuilder.where(`${TableName.Groups}.${key}`, value);
}); });
}) })
.select( .select(
+14 -10
View File
@@ -223,16 +223,20 @@ export const groupServiceFactory = ({
} }
} }
const [updated] = await groupDAL.update( let updated = group;
{
id: group.id if (name || slug) {
}, [updated] = await groupDAL.update(
{ {
name, id: group.id
slug: slug ? slugify(slug) : undefined },
}, {
tx name,
); slug: slug ? slugify(slug) : undefined
},
tx
);
}
if (role) { if (role) {
const membership = await membershipGroupDAL.findOne( const membership = await membershipGroupDAL.findOne(
@@ -40,7 +40,7 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({
oidcSSO: false, oidcSSO: false,
scim: false, scim: false,
ldap: false, ldap: false,
groups: false, groups: true,
status: null, status: null,
trial_end: null, trial_end: null,
has_used_trial: true, has_used_trial: true,
@@ -236,7 +236,8 @@ export const permissionDALFactory = (db: TDbClient): TPermissionDALFactory => {
} else if (actorType === ActorType.IDENTITY) { } else if (actorType === ActorType.IDENTITY) {
void qb.where(`${TableName.Membership}.actorIdentityId`, actorId); void qb.where(`${TableName.Membership}.actorIdentityId`, actorId);
} }
})
.where((qb) => {
if (scopeData.scope === AccessScope.Organization) { if (scopeData.scope === AccessScope.Organization) {
void qb.where(`${TableName.Membership}.scope`, AccessScope.Organization); void qb.where(`${TableName.Membership}.scope`, AccessScope.Organization);
} else if (scopeData.scope === AccessScope.Namespace) { } else if (scopeData.scope === AccessScope.Namespace) {
@@ -361,6 +362,8 @@ export const permissionDALFactory = (db: TDbClient): TPermissionDALFactory => {
} }
] ]
}); });
console.log(">>>", data);
return data; return data;
} catch (error) { } catch (error) {
throw new DatabaseError({ error, name: "Get Permission" }); throw new DatabaseError({ error, name: "Get Permission" });
@@ -95,7 +95,6 @@ export type TPermissionServiceFactory = {
membershipId: string; membershipId: string;
}[]; }[];
}>; }>;
// TODO(simp): switch to role dal later
getOrgPermissionByRoles: ( getOrgPermissionByRoles: (
roles: string[], roles: string[],
orgId: string orgId: string
@@ -216,11 +216,9 @@ export const identityServiceFactory = ({
if (role) { if (role) {
await membershipRoleDAL.delete({ membershipId: identityOrgMembership.id }, tx); await membershipRoleDAL.delete({ membershipId: identityOrgMembership.id }, tx);
await membershipRoleDAL.update( await membershipRoleDAL.create(
{
membershipId: identityOrgMembership.id
},
{ {
membershipId: identityOrgMembership.id,
role: customRole ? OrgMembershipRole.Custom : role, role: customRole ? OrgMembershipRole.Custom : role,
customRoleId: customRole?.id || null customRoleId: customRole?.id || null
}, },
@@ -54,8 +54,8 @@ export const membershipGroupServiceFactory = ({
const { scopeData, data } = dto; const { scopeData, data } = dto;
const factory = scopeFactory[scopeData.scope]; const factory = scopeFactory[scopeData.scope];
const hasOnePermanentRole = data.roles.some((el) => el.isTemporary); const hasNoPermanentRole = data.roles.every((el) => el.isTemporary);
if (hasOnePermanentRole) { if (hasNoPermanentRole) {
throw new BadRequestError({ throw new BadRequestError({
message: "Group must have atleast one permanent role" message: "Group must have atleast one permanent role"
}); });
@@ -148,8 +148,8 @@ export const membershipGroupServiceFactory = ({
const customInputRoles = data.roles.filter((el) => factory.isCustomRole(el.role)); const customInputRoles = data.roles.filter((el) => factory.isCustomRole(el.role));
const hasCustomRole = customInputRoles.length > 0; const hasCustomRole = customInputRoles.length > 0;
const hasOnePermanentRole = data.roles.some((el) => el.isTemporary); const hasNoPermanentRole = data.roles.every((el) => el.isTemporary);
if (hasOnePermanentRole) { if (hasNoPermanentRole) {
throw new BadRequestError({ throw new BadRequestError({
message: "Group must have atleast one permanent role" message: "Group must have atleast one permanent role"
}); });
@@ -172,7 +172,7 @@ export const membershipGroupServiceFactory = ({
const existingMembership = await membershipGroupDAL.findOne({ const existingMembership = await membershipGroupDAL.findOne({
scope: scopeData.scope, scope: scopeData.scope,
...scopeDatabaseFields, ...scopeDatabaseFields,
actorIdentityId: dto.selector.groupId actorGroupId: dto.selector.groupId
}); });
if (!existingMembership) if (!existingMembership)
throw new BadRequestError({ throw new BadRequestError({
@@ -193,13 +193,16 @@ export const membershipGroupServiceFactory = ({
const customRolesGroupBySlug = groupBy(customRoles, ({ slug }) => slug); const customRolesGroupBySlug = groupBy(customRoles, ({ slug }) => slug);
const membershipDoc = await membershipGroupDAL.transaction(async (tx) => { const membershipDoc = await membershipGroupDAL.transaction(async (tx) => {
const doc = await membershipGroupDAL.updateById( const doc =
existingMembership.id, typeof data?.isActive === "undefined"
{ ? existingMembership
isActive: data.isActive : await membershipGroupDAL.updateById(
}, existingMembership.id,
tx {
); isActive: data.isActive
},
tx
);
const roleDocs: TMembershipRolesInsert[] = []; const roleDocs: TMembershipRolesInsert[] = [];
data.roles.forEach((membershipRole) => { data.roles.forEach((membershipRole) => {
@@ -253,14 +256,14 @@ export const membershipGroupServiceFactory = ({
const existingMembership = await membershipGroupDAL.findOne({ const existingMembership = await membershipGroupDAL.findOne({
scope: scopeData.scope, scope: scopeData.scope,
...scopeDatabaseFields, ...scopeDatabaseFields,
actorIdentityId: dto.selector.groupId actorGroupId: dto.selector.groupId
}); });
if (!existingMembership) if (!existingMembership)
throw new BadRequestError({ throw new BadRequestError({
message: "Group doesn't have membership" message: "Group doesn't have membership"
}); });
if (existingMembership.actorIdentityId === dto.permission.id) if (existingMembership.actorGroupId === dto.permission.id)
throw new BadRequestError({ throw new BadRequestError({
message: "You can't delete you own membership" message: "You can't delete you own membership"
}); });
@@ -57,8 +57,8 @@ export const membershipIdentityServiceFactory = ({
const { scopeData, data } = dto; const { scopeData, data } = dto;
const factory = scopeFactory[scopeData.scope]; const factory = scopeFactory[scopeData.scope];
const hasOnePermanentRole = data.roles.some((el) => el.isTemporary); const hasNoPermanentRole = data.roles.every((el) => el.isTemporary);
if (hasOnePermanentRole) { if (hasNoPermanentRole) {
throw new BadRequestError({ throw new BadRequestError({
message: "Identity must have atleast one permanent role" message: "Identity must have atleast one permanent role"
}); });
@@ -151,8 +151,8 @@ export const membershipIdentityServiceFactory = ({
const customInputRoles = data.roles.filter((el) => factory.isCustomRole(el.role)); const customInputRoles = data.roles.filter((el) => factory.isCustomRole(el.role));
const hasCustomRole = customInputRoles.length > 0; const hasCustomRole = customInputRoles.length > 0;
const hasOnePermanentRole = data.roles.some((el) => el.isTemporary); const hasNoPermanentRole = data.roles.every((el) => el.isTemporary);
if (hasOnePermanentRole) { if (hasNoPermanentRole) {
throw new BadRequestError({ throw new BadRequestError({
message: "Identity must have atleast one permanent role" message: "Identity must have atleast one permanent role"
}); });
@@ -196,13 +196,16 @@ export const membershipIdentityServiceFactory = ({
const customRolesGroupBySlug = groupBy(customRoles, ({ slug }) => slug); const customRolesGroupBySlug = groupBy(customRoles, ({ slug }) => slug);
const membershipDoc = await membershipIdentityDAL.transaction(async (tx) => { const membershipDoc = await membershipIdentityDAL.transaction(async (tx) => {
const doc = await membershipIdentityDAL.updateById( const doc =
existingMembership.id, typeof data.isActive === "undefined"
{ ? existingMembership
isActive: data.isActive : await membershipIdentityDAL.updateById(
}, existingMembership.id,
tx {
); isActive: data.isActive
},
tx
);
const roleDocs: TMembershipRolesInsert[] = []; const roleDocs: TMembershipRolesInsert[] = [];
data.roles.forEach((membershipRole) => { data.roles.forEach((membershipRole) => {
@@ -1,4 +1,10 @@
import { AccessScope, ProjectMembershipRole, TemporaryPermissionMode, TMembershipRolesInsert } from "@app/db/schemas"; import {
AccessScope,
OrgMembershipStatus,
ProjectMembershipRole,
TemporaryPermissionMode,
TMembershipRolesInsert
} from "@app/db/schemas";
import { TUserGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal"; import { TUserGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
@@ -147,8 +153,8 @@ export const membershipUserServiceFactory = ({
const { scopeData, data } = dto; const { scopeData, data } = dto;
const factory = scopeFactory[scopeData.scope]; const factory = scopeFactory[scopeData.scope];
const hasOnePermanentRole = data.roles.some((el) => el.isTemporary); const hasNoPermanentRole = data.roles.every((el) => el.isTemporary);
if (hasOnePermanentRole) { if (hasNoPermanentRole) {
throw new BadRequestError({ throw new BadRequestError({
message: "User must have atleast one permanent role" message: "User must have atleast one permanent role"
}); });
@@ -184,7 +190,9 @@ export const membershipUserServiceFactory = ({
const newMemberships = newMembershipUsers.map((user) => ({ const newMemberships = newMembershipUsers.map((user) => ({
scope: scopeData.scope, scope: scopeData.scope,
...scopeDatabaseFields, ...scopeDatabaseFields,
actorUserId: user.id actorUserId: user.id,
status: scopeData.scope === AccessScope.Organization ? OrgMembershipStatus.Invited : undefined,
inviteEmail: scopeData.scope === AccessScope.Organization ? user.email : undefined
})); }));
const customInputRoles = data.roles.filter((el) => factory.isCustomRole(el.role)); const customInputRoles = data.roles.filter((el) => factory.isCustomRole(el.role));
@@ -270,8 +278,8 @@ export const membershipUserServiceFactory = ({
}); });
} }
const hasOnePermanentRole = data.roles.some((el) => el.isTemporary); const hasNoPermanentRole = data.roles.every((el) => el.isTemporary);
if (hasOnePermanentRole) { if (hasNoPermanentRole) {
throw new BadRequestError({ throw new BadRequestError({
message: "User must have atleast one permanent role" message: "User must have atleast one permanent role"
}); });
@@ -315,13 +323,16 @@ export const membershipUserServiceFactory = ({
const customRolesGroupBySlug = groupBy(customRoles, ({ slug }) => slug); const customRolesGroupBySlug = groupBy(customRoles, ({ slug }) => slug);
const membershipDoc = await membershipUserDAL.transaction(async (tx) => { const membershipDoc = await membershipUserDAL.transaction(async (tx) => {
const doc = await membershipUserDAL.updateById( const doc =
existingMembership.id, typeof data?.isActive === "undefined"
{ ? existingMembership
isActive: data.isActive : await membershipUserDAL.updateById(
}, existingMembership.id,
tx {
); isActive: data.isActive
},
tx
);
const roleDocs: TMembershipRolesInsert[] = []; const roleDocs: TMembershipRolesInsert[] = [];
data.roles.forEach((membershipRole) => { data.roles.forEach((membershipRole) => {
@@ -105,10 +105,12 @@ export const newOrgMembershipUserFactory = ({
}); });
if (el.email) { if (el.email) {
signUpTokens.push({ if (!appCfg.isSmtpConfigured) {
email: el.email, signUpTokens.push({
link: `${appCfg.SITE_URL}/signupinvite?token=${token}&to=${el.email}&organization_id=${dto.permission.orgId}` email: el.email,
}); link: `${appCfg.SITE_URL}/signupinvite?token=${token}&to=${el.email}&organization_id=${dto.permission.orgId}`
});
}
await smtpService.sendMail({ await smtpService.sendMail({
template: SmtpTemplates.OrgInvite, template: SmtpTemplates.OrgInvite,
+11 -7
View File
@@ -779,16 +779,20 @@ export const orgServiceFactory = ({
userRoleId = customRole.id; userRoleId = customRole.id;
} }
const membership = await orgDAL.transaction(async (tx) => { const membership = await orgDAL.transaction(async (tx) => {
const [updatedOrgMembership] = await orgDAL.updateMembership( // this is because if isActive is undefined then this would fail due to knexjs error
{ id: membershipId, scopeOrgId: orgId }, const [updatedOrgMembership] =
{ isActive }, typeof isActive === "undefined"
tx ? [foundMembership]
); : await orgDAL.updateMembership(
{ id: membershipId, scopeOrgId: orgId, scope: AccessScope.Organization },
{ isActive },
tx
);
if (userRole) { if (userRole) {
await membershipRoleDAL.delete({ membershipId: updatedOrgMembership.id }, tx); await membershipRoleDAL.delete({ membershipId }, tx);
await membershipRoleDAL.create( await membershipRoleDAL.create(
{ {
membershipId: updatedOrgMembership.id, membershipId,
role: userRole, role: userRole,
customRoleId: userRoleId customRoleId: userRoleId
}, },
+1 -1
View File
@@ -78,7 +78,7 @@ export const useGetProjectRoleBySlug = (projectId: string, roleSlug: string) =>
const getOrgRoles = async (orgId: string) => { const getOrgRoles = async (orgId: string) => {
const { data } = await apiRequest.get<{ const { data } = await apiRequest.get<{
data: { roles: Array<Omit<TOrgRole, "permissions"> & { permissions: unknown }> }; data: { roles: Array<Omit<TOrgRole, "permissions"> & { permissions: TPermission[] }> };
}>(`/api/v1/organization/${orgId}/roles`); }>(`/api/v1/organization/${orgId}/roles`);
return data.data.roles; return data.data.roles;
}; };
+1 -10
View File
@@ -190,20 +190,11 @@ export const useAddUsersToOrg = () => {
mutationFn: (dto) => { mutationFn: (dto) => {
return apiRequest.post("/api/v1/invite-org/signup", dto); return apiRequest.post("/api/v1/invite-org/signup", dto);
}, },
onSuccess: (_, { organizationId, projects }) => { onSuccess: (_, { organizationId }) => {
queryClient.invalidateQueries({ queryKey: userKeys.getOrgUsers(organizationId) }); queryClient.invalidateQueries({ queryKey: userKeys.getOrgUsers(organizationId) });
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: subscriptionQueryKeys.getOrgSubsription(organizationId) queryKey: subscriptionQueryKeys.getOrgSubsription(organizationId)
}); });
projects?.forEach((project) => {
if (project.slug) {
queryClient.invalidateQueries({
queryKey: projectKeys.getProjectGroupMemberships(project.slug)
});
}
queryClient.invalidateQueries({ queryKey: projectKeys.getProjectUsers(project.id) });
});
} }
}); });
}; };
-3
View File
@@ -167,9 +167,6 @@ export type AddUserToOrgDTO = {
inviteeEmails: string[]; inviteeEmails: string[];
organizationRoleSlug: string; organizationRoleSlug: string;
organizationId: string; organizationId: string;
// We need the slug in order to invalidate the groups query. `slug` is only used for invalidation purposes.
projects?: { id: string; slug?: string; projectRoleSlug: string[] }[];
}; };
export type CreateAPIKeyRes = { export type CreateAPIKeyRes = {
@@ -19,6 +19,7 @@ import { useOrganization } from "@app/context";
import { findOrgMembershipRole } from "@app/helpers/roles"; import { findOrgMembershipRole } from "@app/helpers/roles";
import { import {
useAddUsersToOrg, useAddUsersToOrg,
useAddUserToWsNonE2EE,
useFetchServerStatus, useFetchServerStatus,
useGetOrgRoles, useGetOrgRoles,
useGetUserProjects useGetUserProjects
@@ -76,6 +77,7 @@ export const AddOrgMemberModal = ({
const { data: organizationRoles } = useGetOrgRoles(currentOrg?.id ?? ""); const { data: organizationRoles } = useGetOrgRoles(currentOrg?.id ?? "");
const { data: serverDetails } = useFetchServerStatus(); const { data: serverDetails } = useFetchServerStatus();
const { mutateAsync: addUsersMutateAsync } = useAddUsersToOrg(); const { mutateAsync: addUsersMutateAsync } = useAddUsersToOrg();
const { mutateAsync: addUserToProject } = useAddUserToWsNonE2EE();
const { data: projects, isPending: isProjectsLoading } = useGetUserProjects({ const { data: projects, isPending: isProjectsLoading } = useGetUserProjects({
includeRoles: true includeRoles: true
}); });
@@ -140,13 +142,24 @@ export const AddOrgMemberModal = ({
return; return;
} }
const usernames = emails.split(",").map((email) => email.trim());
const { data } = await addUsersMutateAsync({ const { data } = await addUsersMutateAsync({
organizationId: currentOrg?.id, organizationId: currentOrg?.id,
inviteeEmails: emails.split(",").map((email) => email.trim()), inviteeEmails: usernames,
organizationRoleSlug: organizationRole.slug, organizationRoleSlug: organizationRole.slug
projects: selectedProjects.map(({ id }) => ({ id, projectRoleSlug: [projectRoleSlug] }))
}); });
await Promise.allSettled(
selectedProjects.map((el) =>
addUserToProject({
orgId: currentOrg.id,
projectId: el.id,
roleSlugs: [projectRoleSlug],
usernames
})
)
);
setCompleteInviteLinks(data?.completeInviteLinks ?? null); setCompleteInviteLinks(data?.completeInviteLinks ?? null);
// only show this notification when email is configured. // only show this notification when email is configured.
@@ -26,6 +26,7 @@ import {
} from "@app/context"; } from "@app/context";
import { import {
useAddUsersToOrg, useAddUsersToOrg,
useAddUserToWsNonE2EE,
useGetOrgUsers, useGetOrgUsers,
useGetProjectRoles, useGetProjectRoles,
useGetWorkspaceUsers useGetWorkspaceUsers
@@ -85,7 +86,8 @@ export const AddMemberModal = ({ popUp, handlePopUpToggle }: Props) => {
defaultValues: { orgMemberships: [], projectRoleSlugs: [] } defaultValues: { orgMemberships: [], projectRoleSlugs: [] }
}); });
const { mutateAsync: addMembersToProject } = useAddUsersToOrg(); const { mutateAsync: addMemberToOrg } = useAddUsersToOrg();
const { mutateAsync: addUserToProject } = useAddUserToWsNonE2EE();
useEffect(() => { useEffect(() => {
if (requesterEmail) { if (requesterEmail) {
@@ -139,18 +141,19 @@ export const AddMemberModal = ({ popUp, handlePopUpToggle }: Props) => {
return; return;
} }
if (inviteeEmails.length || newInvitees.length) { if (newInvitees.length) {
await addMembersToProject({ await addMemberToOrg({
inviteeEmails: [...inviteeEmails, ...newInvitees], inviteeEmails: newInvitees,
organizationId: orgId, organizationId: orgId,
organizationRoleSlug: ProjectMembershipRole.Member, // only applies to new invites organizationRoleSlug: ProjectMembershipRole.Member // only applies to new invites
projects: [ });
{ }
slug: currentProject.slug, if (newInvitees.length || inviteeEmails.length) {
id: currentProject.id, await addUserToProject({
projectRoleSlug: projectRoleSlugs.map((role) => role.slug) usernames: [...inviteeEmails, ...newInvitees],
} orgId,
] projectId: currentProject.id,
roleSlugs: projectRoleSlugs.map((role) => role.slug)
}); });
} }
} }