-
+
+
+
-
+
-
+
-
+
-
-
-
+
+
{/* @NOTE: To be released in next iteration */}
{/*
@@ -70,6 +72,7 @@ export const Filters = () => {
/>
*/}
+
);
};
diff --git a/packages/features/insights/server/events.ts b/packages/features/insights/server/events.ts
index 5c9f878dee..e6ef45e069 100644
--- a/packages/features/insights/server/events.ts
+++ b/packages/features/insights/server/events.ts
@@ -113,6 +113,9 @@ class EventsInsights {
if (timeView) {
switch (timeView) {
+ case "day":
+ resultTimeLine = this.getDailyTimeline(startDate, endDate);
+ break;
case "week":
resultTimeLine = this.getWeekTimeline(startDate, endDate);
break;
@@ -143,16 +146,36 @@ class EventsInsights {
return resultTimeView;
};
+ static getDailyTimeline(startDate: Dayjs, endDate: Dayjs): string[] {
+ const now = dayjs();
+ const endOfDay = now.endOf("day");
+ let pivotDate = dayjs(startDate);
+ const dates: string[] = [];
+ while ((pivotDate.isBefore(endDate) || pivotDate.isSame(endDate)) && pivotDate.isBefore(endOfDay)) {
+ dates.push(pivotDate.format("YYYY-MM-DD"));
+ pivotDate = pivotDate.add(1, "day");
+ }
+ return dates;
+ }
+
static getWeekTimeline(startDate: Dayjs, endDate: Dayjs): string[] {
const now = dayjs();
const endOfDay = now.endOf("day");
let pivotDate = dayjs(startDate);
const dates: string[] = [];
- while (pivotDate.isBefore(endDate) && pivotDate.isBefore(endOfDay)) {
- const weekEndDate = pivotDate.add(7, "day").isBefore(endOfDay) ? pivotDate.add(7, "day") : endOfDay;
+
+ while (pivotDate.isBefore(endDate) || pivotDate.isSame(endDate)) {
+ const pivotAdded = pivotDate.add(6, "day");
+ const weekEndDate = pivotAdded.isBefore(endOfDay) ? pivotAdded : endOfDay;
dates.push(pivotDate.format("YYYY-MM-DD"));
+
+ if (pivotDate.isSame(endDate)) {
+ break;
+ }
+
pivotDate = weekEndDate.add(1, "day");
}
+
return dates;
}
diff --git a/packages/features/insights/server/trpc-router.ts b/packages/features/insights/server/trpc-router.ts
index 15671e2e35..87b3ca0508 100644
--- a/packages/features/insights/server/trpc-router.ts
+++ b/packages/features/insights/server/trpc-router.ts
@@ -12,10 +12,9 @@ import { EventsInsights } from "./events";
const UserBelongsToTeamInput = z.object({
teamId: z.coerce.number().optional().nullable(),
+ isAll: z.boolean().optional(),
});
-//const userBelongsToTeamMiddleware = isAuthed.unstable_pipe();
-
const userBelongsToTeamProcedure = authedProcedure.use(async ({ ctx, next, rawInput }) => {
const parse = UserBelongsToTeamInput.safeParse(rawInput);
if (!parse.success) {
@@ -27,6 +26,7 @@ const userBelongsToTeamProcedure = authedProcedure.use(async ({ ctx, next, rawIn
const membershipWhereConditional: Prisma.MembershipWhereInput = {
userId: ctx.user.id,
+ accepted: true,
};
if (parse.data.teamId) {
@@ -37,8 +37,33 @@ const userBelongsToTeamProcedure = authedProcedure.use(async ({ ctx, next, rawIn
where: membershipWhereConditional,
});
- if (!membership) {
- throw new TRPCError({ code: "UNAUTHORIZED" });
+ // Probably we couldn't find a membership because the user is not a direct member of the team
+ // So that would mean ctx.user.organization is present
+ if ((parse.data.isAll && ctx.user.organizationId) || (!membership && ctx.user.organizationId)) {
+ //Look for membership type in organizationId
+ const membershipOrg = await ctx.prisma.membership.findFirst({
+ where: {
+ userId: ctx.user.id,
+ teamId: ctx.user.organizationId,
+ accepted: true,
+ role: {
+ in: ["OWNER", "ADMIN"],
+ },
+ },
+ });
+ if (!membershipOrg) {
+ throw new TRPCError({ code: "UNAUTHORIZED" });
+ }
+
+ return next({
+ ctx: {
+ ...ctx,
+ user: {
+ ...ctx.user,
+ isOwnerAdminOfParentTeam: true,
+ },
+ },
+ });
}
return next();
@@ -49,6 +74,7 @@ const UserSelect = {
name: true,
email: true,
avatar: true,
+ username: true,
};
const emptyResponseEventsByStatus = {
@@ -75,6 +101,15 @@ const emptyResponseEventsByStatus = {
},
};
+interface IResultTeamList {
+ id: number;
+ slug: string | null;
+ name: string | null;
+ logo: string | null;
+ userId?: number;
+ isOrg?: boolean;
+}
+
export const insightsRouter = router({
eventsByStatus: userBelongsToTeamProcedure
.input(
@@ -85,16 +120,17 @@ export const insightsRouter = router({
eventTypeId: z.coerce.number().optional(),
memberUserId: z.coerce.number().optional(),
userId: z.coerce.number().optional(),
+ isAll: z.boolean().optional(),
})
)
.query(async ({ ctx, input }) => {
- const { teamId, startDate, endDate, eventTypeId, memberUserId, userId } = input;
-
+ const { teamId, startDate, endDate, eventTypeId, memberUserId, userId, isAll } = input;
if (userId && userId !== ctx.user.id) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
let whereConditional: Prisma.BookingTimeStatusWhereInput = {};
+ let teamConditional: Prisma.TeamWhereInput = {};
if (eventTypeId) {
whereConditional["eventTypeId"] = eventTypeId;
@@ -107,10 +143,56 @@ export const insightsRouter = router({
whereConditional["userId"] = userId;
}
- if (teamId) {
+ if (isAll && ctx.user.isOwnerAdminOfParentTeam && ctx.user.organizationId) {
+ const teamsFromOrg = await ctx.prisma.team.findMany({
+ where: {
+ parentId: ctx.user.organizationId,
+ },
+ select: {
+ id: true,
+ },
+ });
+ if (teamsFromOrg.length === 0) {
+ return emptyResponseEventsByStatus;
+ }
+ teamConditional = {
+ id: {
+ in: [ctx.user.organizationId, ...teamsFromOrg.map((t) => t.id)],
+ },
+ };
+ const usersFromOrg = await ctx.prisma.membership.findMany({
+ where: {
+ team: teamConditional,
+ accepted: true,
+ },
+ select: {
+ userId: true,
+ },
+ });
+ const userIdsFromOrg = usersFromOrg.map((u) => u.userId);
+ whereConditional = {
+ ...whereConditional,
+ OR: [
+ {
+ userId: {
+ in: userIdsFromOrg,
+ },
+ teamId: null,
+ },
+ {
+ teamId: {
+ in: [ctx.user.organizationId, ...teamsFromOrg.map((t) => t.id)],
+ },
+ },
+ ],
+ };
+ }
+
+ if (teamId && !isAll) {
const usersFromTeam = await ctx.prisma.membership.findMany({
where: {
teamId: teamId,
+ accepted: true,
},
select: {
userId: true,
@@ -133,7 +215,6 @@ export const insightsRouter = router({
};
}
- // Migrate to use prisma views
const baseBookings = await EventsInsights.getBaseBookingForEventStatus({
...whereConditional,
createdAt: {
@@ -213,17 +294,19 @@ export const insightsRouter = router({
endDate: z.string(),
eventTypeId: z.coerce.number().optional(),
memberUserId: z.coerce.number().optional(),
- timeView: z.enum(["week", "month", "year"]),
+ timeView: z.enum(["week", "month", "year", "day"]),
userId: z.coerce.number().optional(),
+ isAll: z.boolean().optional(),
})
)
.query(async ({ ctx, input }) => {
const {
teamId,
- startDate: startDateString,
- endDate: endDateString,
eventTypeId,
memberUserId,
+ isAll,
+ startDate: startDateString,
+ endDate: endDateString,
timeView: inputTimeView,
userId: selfUserId,
} = input;
@@ -240,14 +323,62 @@ export const insightsRouter = router({
return [];
}
- const timeView = inputTimeView;
+ let timeView = inputTimeView;
+
+ if (timeView === "week") {
+ // Difference between start and end date is less than 14 days use day view
+ if (endDate.diff(startDate, "day") < 14) {
+ timeView = "day";
+ }
+ }
let whereConditional: Prisma.BookingTimeStatusWhereInput = {};
- if (teamId) {
+ if (isAll && ctx.user.isOwnerAdminOfParentTeam && ctx.user.organizationId) {
+ const teamsFromOrg = await ctx.prisma.team.findMany({
+ where: {
+ parentId: user.organizationId,
+ },
+ select: {
+ id: true,
+ },
+ });
+
+ const usersFromOrg = await ctx.prisma.membership.findMany({
+ where: {
+ teamId: {
+ in: [ctx.user.organizationId, ...teamsFromOrg.map((t) => t.id)],
+ },
+ accepted: true,
+ },
+ select: {
+ userId: true,
+ },
+ });
+ const userIdsFromOrg = usersFromOrg.map((u) => u.userId);
+
+ whereConditional = {
+ OR: [
+ {
+ userId: {
+ in: userIdsFromOrg,
+ },
+ teamId: null,
+ },
+ {
+ teamId: {
+ in: [ctx.user.organizationId, ...teamsFromOrg.map((t) => t.id)],
+ },
+ },
+ ],
+ };
+ }
+
+ if (teamId && !isAll) {
const usersFromTeam = await ctx.prisma.membership.findMany({
where: {
teamId,
+ accepted: true,
},
select: {
userId: true,
@@ -308,11 +439,13 @@ export const insightsRouter = router({
Rescheduled: 0,
Cancelled: 0,
};
- const startOfEndOf = timeView === "year" ? "year" : timeView === "month" ? "month" : "week";
-
- const startDate = dayjs(date).startOf(startOfEndOf);
- const endDate = dayjs(date).endOf(startOfEndOf);
-
+ const startOfEndOf = timeView;
+ let startDate = dayjs(date).startOf(startOfEndOf);
+ let endDate = dayjs(date).endOf(startOfEndOf);
+ if (timeView === "week") {
+ startDate = dayjs(date).startOf("day");
+ endDate = dayjs(date).add(6, "day").endOf("day");
+ }
const promisesResult = await Promise.all([
EventsInsights.getCreatedEventsInTimeRange(
{
@@ -360,10 +493,11 @@ export const insightsRouter = router({
startDate: z.string(),
endDate: z.string(),
userId: z.coerce.number().optional(),
+ isAll: z.boolean().optional(),
})
)
.query(async ({ ctx, input }) => {
- const { teamId, startDate, endDate, memberUserId, userId } = input;
+ const { teamId, startDate, endDate, memberUserId, userId, isAll } = input;
const user = ctx.user;
@@ -381,10 +515,53 @@ export const insightsRouter = router({
lte: dayjs(endDate).endOf("day").toDate(),
},
};
- if (teamId) {
+
+ if (isAll && ctx.user.isOwnerAdminOfParentTeam && ctx.user.organizationId) {
+ const teamsFromOrg = await ctx.prisma.team.findMany({
+ where: {
+ parentId: user.organizationId,
+ },
+ select: {
+ id: true,
+ },
+ });
+
+ const usersFromOrg = await ctx.prisma.membership.findMany({
+ where: {
+ teamId: {
+ in: [ctx.user.organizationId, ...teamsFromOrg.map((t) => t.id)],
+ },
+ accepted: true,
+ },
+ select: {
+ userId: true,
+ },
+ });
+ const userIdsFromOrg = usersFromOrg.map((u) => u.userId);
+
+ bookingWhere = {
+ ...bookingWhere,
+ OR: [
+ {
+ userId: {
+ in: userIdsFromOrg,
+ },
+ teamId: null,
+ },
+ {
+ teamId: {
+ in: [ctx.user.organizationId, ...teamsFromOrg.map((t) => t.id)],
+ },
+ },
+ ],
+ };
+ }
+
+ if (teamId && !isAll) {
const usersFromTeam = await ctx.prisma.membership.findMany({
where: {
teamId,
+ accepted: true,
},
select: {
userId: true,
@@ -519,10 +696,18 @@ export const insightsRouter = router({
startDate: z.string(),
endDate: z.string(),
userId: z.coerce.number().optional(),
+ isAll: z.boolean().optional(),
})
)
.query(async ({ ctx, input }) => {
- const { teamId, startDate: startDateString, endDate: endDateString, memberUserId, userId } = input;
+ const {
+ teamId,
+ startDate: startDateString,
+ endDate: endDateString,
+ memberUserId,
+ userId,
+ isAll,
+ } = input;
if (userId && ctx.user?.id !== userId) {
throw new TRPCError({ code: "UNAUTHORIZED" });
@@ -546,10 +731,36 @@ export const insightsRouter = router({
whereConditional["userId"] = userId;
}
- if (teamId) {
+ if (isAll && ctx.user.isOwnerAdminOfParentTeam && ctx.user.organizationId) {
+ const teamsFromOrg = await ctx.prisma.team.findMany({
+ where: {
+ parentId: ctx.user?.organizationId,
+ },
+ select: {
+ id: true,
+ },
+ });
+ whereConditional = {
+ ...whereConditional,
+ OR: [
+ {
+ teamId: {
+ in: [ctx.user?.organizationId, ...teamsFromOrg.map((t) => t.id)],
+ },
+ },
+ {
+ userId: ctx.user?.id,
+ teamId: null,
+ },
+ ],
+ };
+ }
+
+ if (teamId && !isAll) {
const usersFromTeam = await ctx.prisma.membership.findMany({
where: {
teamId,
+ accepted: true,
},
select: {
userId: true,
@@ -629,14 +840,16 @@ export const insightsRouter = router({
membersWithMostBookings: userBelongsToTeamProcedure
.input(
z.object({
- teamId: z.coerce.number().nullable(),
+ teamId: z.coerce.number().nullable().optional(),
startDate: z.string(),
endDate: z.string(),
eventTypeId: z.coerce.number().optional(),
+ isAll: z.boolean().optional(),
})
)
.query(async ({ ctx, input }) => {
- const { teamId, startDate, endDate, eventTypeId } = input;
+ const { teamId, startDate, endDate, eventTypeId, isAll } = input;
+
if (!teamId) {
return [];
}
@@ -654,10 +867,47 @@ export const insightsRouter = router({
bookingWhere.eventTypeId = eventTypeId;
}
- if (teamId) {
+ if (isAll && user.isOwnerAdminOfParentTeam && user.organizationId) {
+ delete bookingWhere.teamId;
+ const teamsFromOrg = await ctx.prisma.team.findMany({
+ where: {
+ parentId: user?.organizationId,
+ },
+ select: {
+ id: true,
+ },
+ });
+ const usersFromTeam = await ctx.prisma.membership.findMany({
+ where: {
+ teamId: {
+ in: [user?.organizationId, ...teamsFromOrg.map((t) => t.id)],
+ },
+ accepted: true,
+ },
+ select: {
+ userId: true,
+ },
+ });
+ bookingWhere["OR"] = [
+ {
+ teamId: {
+ in: [user?.organizationId, ...teamsFromOrg.map((t) => t.id)],
+ },
+ },
+ {
+ userId: {
+ in: usersFromTeam.map((u) => u.userId),
+ },
+ teamId: null,
+ },
+ ];
+ }
+
+ if (teamId && !isAll) {
const usersFromTeam = await ctx.prisma.membership.findMany({
where: {
teamId,
+ accepted: true,
},
select: {
userId: true,
@@ -699,12 +949,14 @@ export const insightsRouter = router({
if (userIds.length === 0) {
return [];
}
+
const usersFromTeam = await ctx.prisma.user.findMany({
where: {
id: {
in: userIds as number[],
},
},
+ select: UserSelect,
});
const userHashMap = new Map();
@@ -726,20 +978,22 @@ export const insightsRouter = router({
membersWithLeastBookings: userBelongsToTeamProcedure
.input(
z.object({
- teamId: z.coerce.number().nullable(),
+ teamId: z.coerce.number().nullable().optional(),
startDate: z.string(),
endDate: z.string(),
eventTypeId: z.coerce.number().optional(),
+ isAll: z.boolean().optional(),
})
)
.query(async ({ ctx, input }) => {
- const { teamId, startDate, endDate, eventTypeId } = input;
+ const { teamId, startDate, endDate, eventTypeId, isAll } = input;
if (!teamId) {
return [];
}
const user = ctx.user;
const bookingWhere: Prisma.BookingTimeStatusWhereInput = {
+ teamId,
eventTypeId,
createdAt: {
gte: dayjs(startDate).startOf("day").toDate(),
@@ -747,10 +1001,48 @@ export const insightsRouter = router({
},
};
- if (teamId) {
+ if (isAll && user.isOwnerAdminOfParentTeam) {
+ delete bookingWhere.teamId;
+ const teamsFromOrg = await ctx.prisma.team.findMany({
+ where: {
+ parentId: user?.organizationId,
+ },
+ select: {
+ id: true,
+ },
+ });
+ const usersFromTeam = await ctx.prisma.membership.findMany({
+ where: {
+ teamId: {
+ in: teamsFromOrg.map((t) => t.id),
+ },
+ accepted: true,
+ },
+ select: {
+ userId: true,
+ },
+ });
+
+ bookingWhere["OR"] = [
+ {
+ teamId: {
+ in: teamsFromOrg.map((t) => t.id),
+ },
+ },
+ {
+ userId: {
+ in: usersFromTeam.map((u) => u.userId),
+ },
+ teamId: null,
+ },
+ ];
+ }
+
+ if (teamId && !isAll) {
const usersFromTeam = await ctx.prisma.membership.findMany({
where: {
teamId,
+ accepted: true,
},
select: {
userId: true,
@@ -796,6 +1088,7 @@ export const insightsRouter = router({
in: userIds as number[],
},
},
+ select: UserSelect,
});
const userHashMap = new Map();
@@ -822,29 +1115,80 @@ export const insightsRouter = router({
where: {
id: user.id,
},
- select: {
- id: true,
- name: true,
- avatar: true,
- },
+ select: UserSelect,
});
- // Look if user it's admin in multiple teams
- const belongsToTeams = await ctx.prisma.membership.findMany({
- where: {
- userId: user.id,
- team: {
- slug: { not: null },
- },
- OR: [
- {
- role: "ADMIN",
- },
- {
- role: "OWNER",
- },
- ],
+ if (!userData) {
+ return [];
+ }
+
+ const membershipConditional: Prisma.MembershipWhereInput = {
+ team: {
+ slug: { not: null },
},
+ accepted: true,
+ userId: user.id,
+ OR: [
+ {
+ role: "ADMIN",
+ },
+ {
+ role: "OWNER",
+ },
+ ],
+ };
+
+ // Validate if user belongs to org as admin/owner
+ if (user.organizationId) {
+ const teamsFromOrg = await ctx.prisma.team.findMany({
+ where: {
+ parentId: user.organizationId,
+ },
+ select: {
+ id: true,
+ slug: true,
+ name: true,
+ logo: true,
+ },
+ });
+ const orgTeam = await ctx.prisma.team.findUnique({
+ where: {
+ id: user.organizationId,
+ },
+ select: {
+ id: true,
+ slug: true,
+ name: true,
+ logo: true,
+ },
+ });
+ if (!orgTeam) {
+ return [];
+ }
+
+ const result: IResultTeamList[] = [
+ {
+ id: orgTeam.id,
+ slug: orgTeam.slug,
+ name: orgTeam.name,
+ logo: orgTeam.logo,
+ isOrg: true,
+ },
+ ...teamsFromOrg.map(
+ (team: Prisma.TeamGetPayload<{ select: { id: true; slug: true; name: true; logo: true } }>) => {
+ return {
+ ...team,
+ };
+ }
+ ),
+ ];
+
+ return result;
+ }
+
+ // Look if user it's admin/owner in multiple teams
+ const belongsToTeams = await ctx.prisma.membership.findMany({
+ where: membershipConditional,
include: {
team: {
select: {
@@ -852,48 +1196,78 @@ export const insightsRouter = router({
name: true,
logo: true,
slug: true,
+ metadata: true,
},
},
},
});
- const result: {
- id: number;
- slug: string | null;
- name: string | null;
- logo: string | null;
- userId?: number;
- }[] = belongsToTeams.map((membership) => {
+ if (belongsToTeams.length === 0) {
+ return [];
+ }
+
+ const result: IResultTeamList[] = belongsToTeams.map((membership) => {
return { ...membership.team };
});
- if (userData && userData.id) {
- result.push({
- id: 0,
- slug: "",
- userId: userData.id,
- name: userData.name,
- logo: userData.avatar,
- });
- }
+
return result;
}),
userList: userBelongsToTeamProcedure
.input(
z.object({
teamId: z.coerce.number().nullable(),
+ isAll: z.boolean().nullable(),
})
)
.query(async ({ ctx, input }) => {
const user = ctx.user;
+ const { teamId, isAll } = input;
- if (!input.teamId) {
+ if (!teamId) {
return [];
}
+ if (isAll && user.organizationId && user.isOwnerAdminOfParentTeam) {
+ const usersInTeam = await ctx.prisma.membership.findMany({
+ where: {
+ team: {
+ parentId: user.organizationId,
+ },
+ },
+ include: {
+ user: {
+ select: UserSelect,
+ },
+ },
+ });
+ return usersInTeam.map((membership) => membership.user);
+ }
+
const membership = await ctx.prisma.membership.findFirst({
where: {
userId: user.id,
- teamId: input.teamId,
+ teamId,
+ accepted: true,
+ },
+ include: {
+ user: {
+ select: UserSelect,
+ },
+ },
+ });
+ if (!membership) {
+ return [];
+ }
+ const isMember = membership && membership.role === "MEMBER";
+ // If user is not admin, return himself only
+ if (isMember) {
+ return [membership.user];
+ }
+
+ const usersInTeam = await ctx.prisma.membership.findMany({
+ where: {
+ teamId,
+ accepted: true,
},
include: {
user: {
@@ -902,20 +1276,6 @@ export const insightsRouter = router({
},
});
- // If user is not admin, return himself only
- if (membership && membership.role === "MEMBER") {
- return [membership.user];
- }
- const usersInTeam = await ctx.prisma.membership.findMany({
- where: {
- teamId: input.teamId,
- },
- include: {
- user: {
- select: UserSelect,
- },
- },
- });
return usersInTeam.map((membership) => membership.user);
}),
eventTypeList: userBelongsToTeamProcedure
@@ -923,18 +1283,39 @@ export const insightsRouter = router({
z.object({
teamId: z.coerce.number().optional().nullable(),
userId: z.coerce.number().optional().nullable(),
+ isAll: z.boolean().optional(),
})
)
.query(async ({ ctx, input }) => {
const { prisma, user } = ctx;
- const { teamId, userId } = input;
+ const { teamId, userId, isAll } = input;
if (!teamId && !userId) {
return [];
}
const membershipWhereConditional: Prisma.MembershipWhereInput = {};
- if (teamId) {
+
+ let childrenTeamIds: number[] = [];
+
+ if (isAll && teamId && user.organizationId && user.isOwnerAdminOfParentTeam) {
+ const childTeams = await prisma.team.findMany({
+ where: {
+ parentId: user.organizationId,
+ },
+ select: {
+ id: true,
+ },
+ });
+ if (childTeams.length > 0) {
+ childrenTeamIds = childTeams.map((team) => team.id);
+ }
+ membershipWhereConditional["teamId"] = {
+ in: [user.organizationId, ...childrenTeamIds],
+ };
+ }
+
+ if (teamId && !isAll) {
membershipWhereConditional["teamId"] = teamId;
membershipWhereConditional["userId"] = user.id;
}
@@ -948,12 +1329,17 @@ export const insightsRouter = router({
where: membershipWhereConditional,
});
- if (!membership) {
- throw new Error("User is not part of a team");
+ if (!membership && !user.isOwnerAdminOfParentTeam) {
+ throw new Error("User is not part of a team/org");
}
const eventTypeWhereConditional: Prisma.EventTypeWhereInput = {};
- if (teamId) {
+ if (isAll && childrenTeamIds.length > 0 && user.organizationId && user.isOwnerAdminOfParentTeam) {
+ eventTypeWhereConditional["teamId"] = {
+ in: [user.organizationId, ...childrenTeamIds],
+ };
+ }
+ if (teamId && !isAll) {
eventTypeWhereConditional["teamId"] = teamId;
}
if (userId) {
@@ -965,40 +1351,41 @@ export const insightsRouter = router({
slug: true;
teamId: true;
title: true;
+ team: {
+ select: {
+ name: true;
+ };
+ };
};
}>[] = [];
- switch (membership?.role) {
- case "MEMBER":
- eventTypeWhereConditional["OR"] = {
- userId: user.id,
- users: { some: { id: user.id } },
- // @TODO this is not working as expected
- // hosts: { some: { id: user.id } },
- };
- eventTypeResult = await prisma.eventType.findMany({
- select: {
- id: true,
- slug: true,
- teamId: true,
- title: true,
- },
- where: eventTypeWhereConditional,
- });
- break;
-
- default:
- eventTypeResult = await prisma.eventType.findMany({
- select: {
- id: true,
- slug: true,
- teamId: true,
- title: true,
- },
- where: eventTypeWhereConditional,
- });
- break;
+ let isMember = membership?.role === "MEMBER";
+ if (user.isOwnerAdminOfParentTeam) {
+ isMember = false;
}
+ if (isMember) {
+ eventTypeWhereConditional["OR"] = [
+ { userId: user.id },
+ { users: { some: { id: user.id } } },
+ // @TODO this is not working as expected
+ // hosts: { some: { id: user.id } },
+ ];
+ }
+ eventTypeResult = await prisma.eventType.findMany({
+ select: {
+ id: true,
+ slug: true,
+ title: true,
+ teamId: true,
+ team: {
+ select: {
+ name: true,
+ },
+ },
+ },
+ where: eventTypeWhereConditional,
+ });
+
return eventTypeResult;
}),
});
diff --git a/packages/features/schedules/components/ScheduleListItem.tsx b/packages/features/schedules/components/ScheduleListItem.tsx
index 5ac10beebb..4bb0566842 100644
--- a/packages/features/schedules/components/ScheduleListItem.tsx
+++ b/packages/features/schedules/components/ScheduleListItem.tsx
@@ -15,7 +15,6 @@ import {
DropdownMenuTrigger,
showToast,
} from "@calcom/ui";
-
import { Globe, MoreHorizontal, Trash, Star, Copy } from "@calcom/ui/components/icon";
export function ScheduleListItem({
diff --git a/packages/trpc/server/routers/viewer/teams/listMembers.handler.ts b/packages/trpc/server/routers/viewer/teams/listMembers.handler.ts
index 13660c3a6a..d2acf1d91e 100644
--- a/packages/trpc/server/routers/viewer/teams/listMembers.handler.ts
+++ b/packages/trpc/server/routers/viewer/teams/listMembers.handler.ts
@@ -37,16 +37,20 @@ export const listMembersHandler = async ({ ctx, input }: ListMembersOptions) =>
username: true,
},
},
+ accepted: true,
},
},
},
});
- type UserMap = Record
;
+ type UserMap = Record;
// flatten users to be unique by id
const users = teams
.flatMap((t) => t.members)
- .reduce((acc, m) => (m.user.id in acc ? acc : { ...acc, [m.user.id]: m.user }), {} as UserMap);
+ .reduce(
+ (acc, m) => (m.user.id in acc ? acc : { ...acc, [m.user.id]: { ...m.user, accepted: m.accepted } }),
+ {} as UserMap
+ );
return Object.values(users);
};
diff --git a/packages/ui/components/form/dropdown/Dropdown.tsx b/packages/ui/components/form/dropdown/Dropdown.tsx
index 945f2de115..4416e7ec86 100644
--- a/packages/ui/components/form/dropdown/Dropdown.tsx
+++ b/packages/ui/components/form/dropdown/Dropdown.tsx
@@ -108,6 +108,7 @@ type DropdownItemProps = {
EndIcon?: SVGComponent;
href?: string;
disabled?: boolean;
+ childrenClassName?: string;
} & ButtonOrLinkProps;
type ButtonOrLinkProps = ComponentProps<"button"> & ComponentProps<"a">;
@@ -129,7 +130,7 @@ export function ButtonOrLink({ href, ...props }: ButtonOrLinkProps) {
}
export const DropdownItem = (props: DropdownItemProps) => {
- const { StartIcon, EndIcon, children, color, ...rest } = props;
+ const { StartIcon, EndIcon, children, color, childrenClassName, ...rest } = props;
return (
{
)}>
<>
{StartIcon && }
- {children}
+ {children}
{EndIcon && }
>