* managed by tooltip * updated for team admin * updated for typechecks and naming * for multiple admins * update to show team link when more than 2 admins * nit/chore : variable naming * improvement --------- Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com> Co-authored-by: unknown <adhabal2002@gmail.com>
This commit is contained in:
co-authored by
Anik Dhabal Babu
unknown
parent
3c6e9aaa63
commit
100136aae7
@@ -2528,5 +2528,6 @@
|
||||
"outlook_connect_atom_already_connected_label": "Connected Outlook Calendar",
|
||||
"outlook_connect_atom_loading_label": "Checking Outlook Calendar",
|
||||
"booking_question_response_variables": "Booking question response variables",
|
||||
"managed_by_teamAdmins": "Managed by {{teamAdmins}}",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Prisma } from "@prisma/client";
|
||||
import Link from "next/link";
|
||||
import { useMemo } from "react";
|
||||
import type { z } from "zod";
|
||||
|
||||
@@ -10,7 +11,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import type { baseEventTypeSelect } from "@calcom/prisma";
|
||||
import { SchedulingType } from "@calcom/prisma/enums";
|
||||
import type { EventTypeModel } from "@calcom/prisma/zod";
|
||||
import { Badge } from "@calcom/ui";
|
||||
import { Badge, Tooltip } from "@calcom/ui";
|
||||
|
||||
export type EventTypeDescriptionProps = {
|
||||
eventType: Pick<
|
||||
@@ -19,6 +20,7 @@ export type EventTypeDescriptionProps = {
|
||||
> & {
|
||||
descriptionAsSafeHTML?: string | null;
|
||||
recurringEvent: Prisma.JsonValue;
|
||||
managedBy?: { teamId: number | undefined; admins: string[] };
|
||||
};
|
||||
className?: string;
|
||||
shortenDescription?: boolean;
|
||||
@@ -40,6 +42,32 @@ export const EventTypeDescription = ({
|
||||
|
||||
const paymentAppData = getPaymentAppData(eventType);
|
||||
|
||||
const showManagedBadge = eventType.metadata?.managedEventConfig && !isPublic;
|
||||
const numberOfAdmins = eventType.managedBy?.admins.length || 0;
|
||||
let managedByToolTipContent;
|
||||
|
||||
if (numberOfAdmins > 0) {
|
||||
managedByToolTipContent = t("managed_by_teamAdmins", {
|
||||
teamAdmins: eventType.managedBy?.admins?.slice(0, 2).join(", "),
|
||||
});
|
||||
if (numberOfAdmins > 2) {
|
||||
managedByToolTipContent = (
|
||||
<>
|
||||
{`${managedByToolTipContent} ${t("and")} `}
|
||||
{!!eventType.managedBy?.teamId ? (
|
||||
<Link
|
||||
href={`/settings/teams/${eventType.managedBy?.teamId}/members`}
|
||||
className="text-blue-500 underline hover:text-blue-600 focus:outline-none">
|
||||
{`${numberOfAdmins - 2} ${t("more")}`}
|
||||
</Link>
|
||||
) : (
|
||||
<span>{`${numberOfAdmins - 2} ${t("more")}`}</span>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={classNames("text-subtle", className)}>
|
||||
@@ -78,11 +106,22 @@ export const EventTypeDescription = ({
|
||||
</Badge>
|
||||
</li>
|
||||
)}
|
||||
{eventType.metadata?.managedEventConfig && !isPublic && (
|
||||
<Badge variant="gray" startIcon="lock">
|
||||
{t("managed")}
|
||||
</Badge>
|
||||
)}
|
||||
{showManagedBadge &&
|
||||
(numberOfAdmins === 0 ? (
|
||||
<div>
|
||||
<Badge variant="gray" startIcon="lock">
|
||||
{t("managed")}
|
||||
</Badge>
|
||||
</div>
|
||||
) : (
|
||||
<Tooltip content={managedByToolTipContent}>
|
||||
<div>
|
||||
<Badge variant="gray" startIcon="lock">
|
||||
{t("managed")}
|
||||
</Badge>
|
||||
</div>
|
||||
</Tooltip>
|
||||
))}
|
||||
{recurringEvent?.count && recurringEvent.count > 0 && (
|
||||
<li className="hidden xl:block" data-testid="repeat-eventtype">
|
||||
<Badge variant="gray" startIcon="refresh-cw">
|
||||
|
||||
@@ -105,32 +105,43 @@ export const getEventTypesByViewer = async (user: User, filters?: Filters, forRo
|
||||
|
||||
type UserEventTypes = (typeof profileEventTypes)[number];
|
||||
|
||||
const mapEventType = async (eventType: UserEventTypes) => ({
|
||||
...eventType,
|
||||
safeDescription: eventType?.description ? markdownToSafeHTML(eventType.description) : undefined,
|
||||
users: await Promise.all(
|
||||
(!!eventType?.hosts?.length ? eventType?.hosts.map((host) => host.user) : eventType.users).map(
|
||||
async (u) =>
|
||||
await UserRepository.enrichUserWithItsProfile({
|
||||
user: u,
|
||||
})
|
||||
)
|
||||
),
|
||||
metadata: eventType.metadata ? EventTypeMetaDataSchema.parse(eventType.metadata) : null,
|
||||
children: await Promise.all(
|
||||
(eventType.children || []).map(async (c) => ({
|
||||
...c,
|
||||
users: await Promise.all(
|
||||
c.users.map(
|
||||
async (u) =>
|
||||
await UserRepository.enrichUserWithItsProfile({
|
||||
user: u,
|
||||
})
|
||||
)
|
||||
),
|
||||
}))
|
||||
),
|
||||
});
|
||||
const mapEventType = async (eventType: UserEventTypes) => {
|
||||
const { parent, ...rest } = eventType;
|
||||
return {
|
||||
...rest,
|
||||
safeDescription: eventType?.description ? markdownToSafeHTML(eventType.description) : undefined,
|
||||
users: await Promise.all(
|
||||
(!!eventType?.hosts?.length ? eventType?.hosts.map((host) => host.user) : eventType.users).map(
|
||||
async (u) =>
|
||||
await UserRepository.enrichUserWithItsProfile({
|
||||
user: u,
|
||||
})
|
||||
)
|
||||
),
|
||||
metadata: eventType.metadata ? EventTypeMetaDataSchema.parse(eventType.metadata) : null,
|
||||
children: await Promise.all(
|
||||
(eventType.children || []).map(async (c) => ({
|
||||
...c,
|
||||
users: await Promise.all(
|
||||
c.users.map(
|
||||
async (u) =>
|
||||
await UserRepository.enrichUserWithItsProfile({
|
||||
user: u,
|
||||
})
|
||||
)
|
||||
),
|
||||
}))
|
||||
),
|
||||
managedBy: {
|
||||
teamId: parent?.team?.id,
|
||||
admins:
|
||||
parent?.team?.members
|
||||
.filter((member) => member.role === MembershipRole.ADMIN && member.accepted === true)
|
||||
.map((member) => member.user?.name || member.user?.username || member.user?.email)
|
||||
.filter((name) => !!name) || [],
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const userEventTypes = (await Promise.all(profileEventTypes.map(mapEventType))).filter((eventType) => {
|
||||
const isAChildEvent = eventType.parentId;
|
||||
|
||||
@@ -50,4 +50,26 @@ export const eventTypeSelect = Prisma.validator<Prisma.EventTypeSelect>()({
|
||||
secondaryEmailId: true,
|
||||
bookingLimits: true,
|
||||
durationLimits: true,
|
||||
parent: {
|
||||
select: {
|
||||
team: {
|
||||
select: {
|
||||
id: true,
|
||||
members: {
|
||||
select: {
|
||||
user: {
|
||||
select: {
|
||||
name: true,
|
||||
username: true,
|
||||
email: true,
|
||||
},
|
||||
},
|
||||
role: true,
|
||||
accepted: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user