feat: team owner/admin, be able to confirm/reject "requires confirmation" team events (#15326)
* feat: eam owner/admin, be able to confirm/reject requir es confirmation team events * update * addressed requested changes * remove console.log --------- Co-authored-by: Keith Williams <keithwillcode@gmail.com> Co-authored-by: Somay Chauhan <somaychauhan98@gmail.com> Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
This commit is contained in:
4 files changed
+19
-6
No files matched your search
@@ -542,7 +542,9 @@ function BookingListItem(booking: BookingItemProps) {
|
||||
<td className="flex w-full justify-end py-4 pl-4 text-right text-sm font-medium ltr:pr-4 rtl:pl-4 sm:pl-0">
|
||||
{isUpcoming && !isCancelled ? (
|
||||
<>
|
||||
{isPending && userId === booking.user?.id && <TableActions actions={pendingActions} />}
|
||||
{isPending && (userId === booking.user?.id || booking.isUserTeamAdminOrOwner) && (
|
||||
<TableActions actions={pendingActions} />
|
||||
)}
|
||||
{isConfirmed && <TableActions actions={bookedActions} />}
|
||||
{isRejected && <div className="text-subtle text-sm">{t("rejected")}</div>}
|
||||
</>
|
||||
|
||||
@@ -75,7 +75,7 @@ export const bookingsRouter = router({
|
||||
});
|
||||
}),
|
||||
|
||||
confirm: bookingsProcedure.input(ZConfirmInputSchema).mutation(async ({ input, ctx }) => {
|
||||
confirm: authedProcedure.input(ZConfirmInputSchema).mutation(async ({ input, ctx }) => {
|
||||
if (!UNSTABLE_HANDLER_CACHE.confirm) {
|
||||
UNSTABLE_HANDLER_CACHE.confirm = await import("./confirm.handler").then((mod) => mod.confirmHandler);
|
||||
}
|
||||
|
||||
@@ -25,12 +25,11 @@ import { TRPCError } from "@trpc/server";
|
||||
|
||||
import type { TrpcSessionUser } from "../../../trpc";
|
||||
import type { TConfirmInputSchema } from "./confirm.schema";
|
||||
import type { BookingsProcedureContext } from "./util";
|
||||
|
||||
type ConfirmOptions = {
|
||||
ctx: {
|
||||
user: NonNullable<TrpcSessionUser>;
|
||||
} & BookingsProcedureContext;
|
||||
};
|
||||
input: TConfirmInputSchema;
|
||||
};
|
||||
|
||||
@@ -75,6 +74,7 @@ export const confirmHandler = async ({ ctx, input }: ConfirmOptions) => {
|
||||
team: {
|
||||
select: {
|
||||
parentId: true,
|
||||
members: true,
|
||||
},
|
||||
},
|
||||
workflows: {
|
||||
@@ -122,7 +122,11 @@ export const confirmHandler = async ({ ctx, input }: ConfirmOptions) => {
|
||||
},
|
||||
});
|
||||
|
||||
if (eventType && !eventType.users.find((user) => booking.userId === user.id)) {
|
||||
const membership = booking.eventType?.team?.members.find((membership) => membership.userId === user.id);
|
||||
const isTeamAdminOrOwner =
|
||||
membership?.role === MembershipRole.OWNER || membership?.role === MembershipRole.ADMIN;
|
||||
|
||||
if (eventType && !eventType.users.find((user) => booking.userId === user.id) && !isTeamAdminOrOwner) {
|
||||
throw new TRPCError({ code: "UNAUTHORIZED", message: "UNAUTHORIZED" });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import getAllUserBookings from "@calcom/lib/bookings/getAllUserBookings";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
import { bookingMinimalSelect } from "@calcom/prisma";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
import type { BookingStatus } from "@calcom/prisma/enums";
|
||||
import { MembershipRole, type BookingStatus } from "@calcom/prisma/enums";
|
||||
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
|
||||
|
||||
import type { TrpcSessionUser } from "../../../trpc";
|
||||
@@ -183,6 +183,7 @@ export async function getBookings({
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
members: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -396,6 +397,11 @@ export async function getBookings({
|
||||
if (booking.seatsReferences.length && !booking.eventType?.seatsShowAttendees) {
|
||||
booking.attendees = booking.attendees.filter((attendee) => attendee.email === user.email);
|
||||
}
|
||||
|
||||
const membership = booking.eventType?.team?.members.find((membership) => membership.userId === user.id);
|
||||
const isUserTeamAdminOrOwner =
|
||||
membership?.role === MembershipRole.OWNER || membership?.role === MembershipRole.ADMIN;
|
||||
|
||||
return {
|
||||
...booking,
|
||||
eventType: {
|
||||
@@ -407,6 +413,7 @@ export async function getBookings({
|
||||
},
|
||||
startTime: booking.startTime.toISOString(),
|
||||
endTime: booking.endTime.toISOString(),
|
||||
isUserTeamAdminOrOwner,
|
||||
};
|
||||
});
|
||||
return { bookings, recurringInfo };
|
||||
|
||||
Reference in new issue
Block a user