diff --git a/apps/web/components/booking/BookingListItem.tsx b/apps/web/components/booking/BookingListItem.tsx index 0d9cbc216b..3cfa857580 100644 --- a/apps/web/components/booking/BookingListItem.tsx +++ b/apps/web/components/booking/BookingListItem.tsx @@ -1,3 +1,4 @@ +import type { AssignmentReason } from "@prisma/client"; import Link from "next/link"; import { useState } from "react"; import { Controller, useFieldArray, useForm } from "react-hook-form"; @@ -45,6 +46,8 @@ import { Tooltip, } from "@calcom/ui"; +import assignmentReasonBadgeTitleMap from "@lib/booking/assignmentReasonBadgeTitleMap"; + import { AddGuestsDialog } from "@components/dialog/AddGuestsDialog"; import { ChargeCardDialog } from "@components/dialog/ChargeCardDialog"; import { EditLocationDialog } from "@components/dialog/EditLocationDialog"; @@ -508,72 +511,94 @@ function BookingListItem(booking: BookingItemProps) { - - -
- {eventTypeColor &&
} - -
-
{startTime}
-
- {formatTime(booking.startTime, userTimeFormat, userTimeZone)} -{" "} - {formatTime(booking.endTime, userTimeFormat, userTimeZone)} - -
- {!isPending && ( -
- {(provider?.label || locationToDisplay?.startsWith("https://")) && - locationToDisplay.startsWith("http") && ( - e.stopPropagation()} - target="_blank" - title={locationToDisplay} - rel="noreferrer" - className="text-sm leading-6 text-blue-600 hover:underline dark:text-blue-400"> -
- {provider?.iconUrl && ( - {`${provider?.label} - )} - {provider?.label - ? t("join_event_location", { eventLocationType: provider?.label }) - : t("join_meeting")} -
-
- )} + +
+ +
+ {eventTypeColor && ( +
+ )} + +
+
{startTime}
+
+ {formatTime(booking.startTime, userTimeFormat, userTimeZone)} -{" "} + {formatTime(booking.endTime, userTimeFormat, userTimeZone)} +
- )} + {!isPending && ( + + )} +
+ +
+ + + + {/* Time and Badges for mobile */} +
+
+
{startTime}
+
+ {formatTime(booking.startTime, userTimeFormat, userTimeZone)} -{" "} + {formatTime(booking.endTime, userTimeFormat, userTimeZone)} + +
+
+ {isPending && ( - + {t("unconfirmed")} )} {booking.eventType?.team && ( - + {booking.eventType.team.name} )} - {booking.paid && !booking.payment[0] ? ( - - {t("error_collecting_card")} + {showPendingPayment && ( + + {t("pending_payment")} - ) : booking.paid ? ( - - {booking.payment[0].paymentOption === "HOLD" ? t("card_held") : t("paid")} - - ) : null} + )} {recurringDates !== undefined && ( -
+
)}
- -
- - - - {/* Time and Badges for mobile */} -
-
-
{startTime}
-
- {formatTime(booking.startTime, userTimeFormat, userTimeZone)} -{" "} - {formatTime(booking.endTime, userTimeFormat, userTimeZone)} - + +
+
+ {title} + + + {showPendingPayment && ( + + {t("pending_payment")} + + )}
-
- - {isPending && ( - - {t("unconfirmed")} - - )} - {booking.eventType?.team && ( - - {booking.eventType.team.name} - - )} - {showPendingPayment && ( - - {t("pending_payment")} - - )} - {recurringDates !== undefined && ( -
- + "{booking.description}" +
+ )} + {booking.attendees.length !== 0 && ( + -
- )} -
- -
-
- {title} - - - {showPendingPayment && ( - - {t("pending_payment")} - + )} + {isCancelled && booking.rescheduled && ( +
+ +
)}
- {booking.description && ( -
- "{booking.description}" + + + + {isUpcoming && !isCancelled ? ( + <> + {isPending && } + {isConfirmed && } + {isRejected &&
{t("rejected")}
} + + ) : null} + {isBookingInPast && isPending && !isConfirmed ? : null} + {isBookingInPast && isConfirmed ? : null} + {(showViewRecordingsButton || showCheckRecordingButton) && ( + + )} + {isCancelled && booking.rescheduled && ( +
+ +
+ )} + {booking.status === "ACCEPTED" && + booking.paid && + booking.payment[0]?.paymentOption === "HOLD" && ( +
+
)} - {booking.attendees.length !== 0 && ( - - )} - {isCancelled && booking.rescheduled && ( -
- -
- )} -
- - - - {isUpcoming && !isCancelled ? ( - <> - {isPending && } - {isConfirmed && } - {isRejected &&
{t("rejected")}
} - - ) : null} - {isBookingInPast && isPending && !isConfirmed ? : null} - {isBookingInPast && isConfirmed ? : null} - {(showViewRecordingsButton || showCheckRecordingButton) && ( - - )} - {isCancelled && booking.rescheduled && ( -
- -
- )} - {booking.status === "ACCEPTED" && booking.paid && booking.payment[0]?.paymentOption === "HOLD" && ( -
- -
- )} - + +
+ + {isBookingReroutable(parsedBooking) && ( { + const { t } = useLocale(); + + return ( +
+ {isPending && ( + + {t("unconfirmed")} + + )} + {booking.eventType?.team && ( + + {booking.eventType.team.name} + + )} + {booking?.assignmentReason.length > 0 && ( + + )} + {booking.paid && !booking.payment[0] ? ( + + {t("error_collecting_card")} + + ) : booking.paid ? ( + + {booking.payment[0].paymentOption === "HOLD" ? t("card_held") : t("paid")} + + ) : null} + {recurringDates !== undefined && ( +
+ +
+ )} +
+ ); +}; + interface RecurringBookingsTooltipProps { booking: BookingItemProps; recurringDates: Date[]; @@ -1205,4 +1246,18 @@ const DisplayAttendees = ({ ); }; +const AssignmentReasonTooltip = ({ assignmentReason }: { assignmentReason: AssignmentReason }) => { + const { t } = useLocale(); + const badgeTitle = assignmentReasonBadgeTitleMap(assignmentReason.reasonEnum); + return ( + {assignmentReason.reasonString}

}> +
+ + {t(badgeTitle)} + +
+
+ ); +}; + export default BookingListItem; diff --git a/apps/web/lib/booking/assignmentReasonBadgeTitleMap.ts b/apps/web/lib/booking/assignmentReasonBadgeTitleMap.ts new file mode 100644 index 0000000000..b695ac2e67 --- /dev/null +++ b/apps/web/lib/booking/assignmentReasonBadgeTitleMap.ts @@ -0,0 +1,18 @@ +import { AssignmentReasonEnum } from "@calcom/prisma/enums"; + +const assignmentReasonBadgeTitleMap = (assignmentReason: AssignmentReasonEnum) => { + switch (assignmentReason) { + case AssignmentReasonEnum.ROUTING_FORM_ROUTING || AssignmentReasonEnum.ROUTING_FORM_ROUTING_FALLBACK: + return "routed"; + case AssignmentReasonEnum.REASSIGNED: + return "reassigned"; + case AssignmentReasonEnum.REROUTED: + return "rerouted"; + case AssignmentReasonEnum.SALESFORCE_ASSIGNMENT: + return "salesforce_assignment"; + default: + return "routed"; + } +}; + +export default assignmentReasonBadgeTitleMap; diff --git a/apps/web/public/static/locales/en/common.json b/apps/web/public/static/locales/en/common.json index 5401779406..3c5c886669 100644 --- a/apps/web/public/static/locales/en/common.json +++ b/apps/web/public/static/locales/en/common.json @@ -2863,5 +2863,9 @@ "lock_attribute_for_assignment_description": "Locking would only allow assignments from Directory Sync", "attribute_edited_successfully": "Attribute edited successfully", "new_group_option": "New group option", + "routed": "Routed", + "reassigned": "Reassigned", + "rerouted": "Rerouted", + "salesforce_assigned": "Salesforce assignment", "ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑" } diff --git a/packages/trpc/server/routers/viewer/bookings/get.handler.ts b/packages/trpc/server/routers/viewer/bookings/get.handler.ts index b76472c999..df8d6af1fc 100644 --- a/packages/trpc/server/routers/viewer/bookings/get.handler.ts +++ b/packages/trpc/server/routers/viewer/bookings/get.handler.ts @@ -1,3 +1,5 @@ +import { Prisma as PrismaClientType } from "@prisma/client"; + import { parseRecurringEvent, parseEventTypeColor } from "@calcom/lib"; import getAllUserBookings from "@calcom/lib/bookings/getAllUserBookings"; import type { PrismaClient } from "@calcom/prisma"; @@ -283,6 +285,10 @@ export async function getBookings({ }, }, }, + assignmentReason: { + orderBy: { createdAt: PrismaClientType.SortOrder.desc }, + take: 1, + }, }; const [