diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts
index 8e07d2f609..aec453da3a 100644
--- a/src/backend/src/services/calendar.services.ts
+++ b/src/backend/src/services/calendar.services.ts
@@ -311,17 +311,16 @@ export default class CalendarService {
});
// Validate required memberIds
- if (requiredMemberIds.length > 0) {
- const foundMembers = await prisma.user.findMany({
- where: {
- userId: { in: requiredMemberIds },
- organizations: { some: { organizationId: organization.organizationId } }
- }
- });
- if (foundMembers.length !== requiredMemberIds.length) {
- const missingIds = requiredMemberIds.filter((id) => !foundMembers.some((user) => user.userId === id));
- throw new NotFoundException('User', missingIds.join(', '));
+
+ const foundMembers = await prisma.user.findMany({
+ where: {
+ userId: { in: requiredMemberIds || submitter.userId },
+ organizations: { some: { organizationId: organization.organizationId } }
}
+ });
+ if (foundMembers.length !== requiredMemberIds.length) {
+ const missingIds = requiredMemberIds.filter((id) => !foundMembers.some((user) => user.userId === id));
+ throw new NotFoundException('User', missingIds.join(', '));
}
// Validate optionals memberIds
@@ -422,6 +421,11 @@ export default class CalendarService {
// Check for conflicts using expanded slots
const { hasConflict, conflictingEvent } = await checkEventConflicts(scheduleSlots, organization, location, undefined);
+ const allRequiredMembers = [
+ ...requiredMemberIds,
+ ...(requiredMemberIds.includes(submitter.userId) ? [] : [submitter.userId])
+ ];
+
const newEvent = await prisma.event.create({
data: {
userCreatedId: submitter.userId,
@@ -429,7 +433,7 @@ export default class CalendarService {
title,
eventTypeId,
requiredMembers: {
- connect: requiredMemberIds.map((userId) => ({ userId }))
+ connect: allRequiredMembers.map((userId) => ({ userId }))
},
optionalMembers: {
connect: optionalMemberIds.map((userId) => ({ userId }))
@@ -471,7 +475,7 @@ export default class CalendarService {
let calendarEventIds: string[] = [];
if (process.env.NODE_ENV === 'production') {
try {
- const allMemberIds = [...requiredMemberIds, ...optionalMemberIds];
+ const allMemberIds = [...allRequiredMembers, ...optionalMemberIds];
const isInPerson = !!location;
calendarEventIds = await createCalendarEvent(
@@ -496,7 +500,11 @@ export default class CalendarService {
if (foundEventType.sendSlackNotifications) {
const members = await prisma.user.findMany({
- where: { userId: { in: optionalMemberIds.concat(requiredMemberIds) } }
+ where: {
+ userId: {
+ in: optionalMemberIds.concat(allRequiredMembers)
+ }
+ }
});
// get the user settings for all the members invited, who are leaderingship
@@ -633,17 +641,15 @@ export default class CalendarService {
}
// Validate required memberIds
- if (requiredMemberIds.length > 0) {
- const foundMembers = await prisma.user.findMany({
- where: {
- userId: { in: requiredMemberIds },
- organizations: { some: { organizationId: organization.organizationId } }
- }
- });
- if (foundMembers.length !== requiredMemberIds.length) {
- const missingIds = requiredMemberIds.filter((id) => !foundMembers.some((user) => user.userId === id));
- throw new NotFoundException('User', missingIds.join(', '));
+ const foundMembers = await prisma.user.findMany({
+ where: {
+ userId: { in: requiredMemberIds || submitter.userId },
+ organizations: { some: { organizationId: organization.organizationId } }
}
+ });
+ if (foundMembers.length !== requiredMemberIds.length) {
+ const missingIds = requiredMemberIds.filter((id) => !foundMembers.some((user) => user.userId === id));
+ throw new NotFoundException('User', missingIds.join(', '));
}
// Validate optional memberIds
@@ -741,8 +747,13 @@ export default class CalendarService {
}
}
+ const allRequiredMembers = [
+ ...requiredMemberIds,
+ ...(requiredMemberIds.includes(submitter.userId) ? [] : [submitter.userId])
+ ];
+
// throw if a user isn't found, then build prisma queries for connecting userIds
- const updatedRequiredMembers = getPrismaQueryUserIds(await getUsers(requiredMemberIds));
+ const updatedRequiredMembers = [...getPrismaQueryUserIds(await getUsers(allRequiredMembers))];
const updatedOptionalMembers = getPrismaQueryUserIds(await getUsers(optionalMemberIds));
// Update the event with new data (excluding schedule slots)
diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts
index 50a6b39623..ddcbaa9b25 100644
--- a/src/backend/tests/unit/calendar.test.ts
+++ b/src/backend/tests/unit/calendar.test.ts
@@ -901,8 +901,8 @@ describe('Calendar Tests', () => {
expect(result.title).toBe('Team Sync');
expect(result.eventTypeId).toBe(eventType.eventTypeId);
- expect(result.requiredMembers).toHaveLength(1);
- expect(result.requiredMembers[0].userId).toBe(member.userId);
+ expect(result.requiredMembers).toHaveLength(2);
+ expect(result.requiredMembers[1].userId).toBe(member.userId);
expect(result.optionalMembers).toHaveLength(1);
expect(result.optionalMembers[0].userId).toBe(adminUser.userId);
expect(result.shops).toHaveLength(1);
@@ -1007,8 +1007,8 @@ describe('Calendar Tests', () => {
expect(result.title).toBe('Minimal Event');
expect(result.eventTypeId).toBe(eventType.eventTypeId);
- expect(result.requiredMembers).toHaveLength(1);
- expect(result.requiredMembers[0].userId).toBe(member.userId);
+ expect(result.requiredMembers).toHaveLength(2);
+ expect(result.requiredMembers[1].userId).toBe(member.userId);
expect(result.optionalMembers).toHaveLength(1);
expect(result.optionalMembers[0].userId).toBe(adminUser.userId);
expect(result.shops).toHaveLength(1);
@@ -1887,8 +1887,8 @@ describe('Calendar Tests', () => {
expect(result.eventId).toBe(event.eventId);
expect(result.title).toBe('Updated Event Title');
- expect(result.requiredMembers).toHaveLength(1);
- expect(result.requiredMembers[0].userId).toBe(newMember.userId);
+ expect(result.requiredMembers).toHaveLength(2);
+ expect(result.requiredMembers[1].userId).toBe(newMember.userId);
expect(result.optionalMembers).toHaveLength(1);
expect(result.optionalMembers[0].userId).toBe(adminUser.userId);
expect(result.documents).toEqual([]);
diff --git a/src/frontend/src/pages/CalendarPage/Components/EventAvailabilityPage.tsx b/src/frontend/src/pages/CalendarPage/Components/EventAvailabilityPage.tsx
index c0e133b704..35daeb1ff7 100644
--- a/src/frontend/src/pages/CalendarPage/Components/EventAvailabilityPage.tsx
+++ b/src/frontend/src/pages/CalendarPage/Components/EventAvailabilityPage.tsx
@@ -334,12 +334,17 @@ export const EventAvailabilityPage: React.FC = () => {
{currentAvailableUsers.length > 0 ? (
reorderByConfirmation(currentAvailableUsers).map((user) => {
const isConfirmed = event.confirmedMembers.some((cm) => cm.userId === user.userId);
+ const isRequired = event.requiredMembers.some((cm) => cm.userId === user.userId);
const displayName = fullNamePipe(user);
return (
{displayName}
@@ -361,12 +366,17 @@ export const EventAvailabilityPage: React.FC = () => {
{currentUnavailableUsers.length > 0 ? (
reorderByConfirmation(currentUnavailableUsers).map((user) => {
const isConfirmed = event.confirmedMembers.some((cm) => cm.userId === user.userId);
+ const isRequired = event.requiredMembers.some((cm) => cm.userId === user.userId);
const displayName = fullNamePipe(user);
return (
{displayName}
@@ -383,7 +393,10 @@ export const EventAvailabilityPage: React.FC = () => {
{(currentAvailableUsers.length > 0 || currentUnavailableUsers.length > 0) && (
- Red means has not confirmed availability
+ Red means that member has not confirmed availability
+
+ Underline means that member is required for the meeting
+
)}