diff --git a/apps/web/components/booking/AvailableEventLocations.tsx b/apps/web/components/booking/AvailableEventLocations.tsx
index bcb61e982c..1d459f8dbc 100644
--- a/apps/web/components/booking/AvailableEventLocations.tsx
+++ b/apps/web/components/booking/AvailableEventLocations.tsx
@@ -8,54 +8,61 @@ import { FiLink } from "@calcom/ui/components/icon";
import type { Props } from "./pages/AvailabilityPage";
+const excludeNullValues = (value: unknown) => !!value;
+
export function AvailableEventLocations({ locations }: { locations: Props["eventType"]["locations"] }) {
const { t } = useLocale();
- return locations.length ? (
-
- {locations.map((location, index) => {
- const eventLocationType = getEventLocationType(location.type);
- if (!eventLocationType) {
- // It's possible that the location app got uninstalled
- return null;
- }
+ const renderLocations = locations.map((location, index) => {
+ const eventLocationType = getEventLocationType(location.type);
+ if (!eventLocationType) {
+ // It's possible that the location app got uninstalled
+ return null;
+ }
+ if (eventLocationType.variable === "hostDefault") {
+ return null;
+ }
- const translateAbleKeys = [
- "attendee_in_person",
- "in_person",
- "attendee_phone_number",
- "link_meeting",
- "organizer_phone_number",
- ];
+ const translateAbleKeys = [
+ "attendee_in_person",
+ "in_person",
+ "attendee_phone_number",
+ "link_meeting",
+ "organizer_phone_number",
+ ];
- const locationKey = z.string().default("").parse(locationKeyToString(location));
+ const locationKey = z.string().default("").parse(locationKeyToString(location));
+ const translatedLocation = location.type.startsWith("integrations:")
+ ? eventLocationType.label
+ : translateAbleKeys.includes(locationKey)
+ ? t(locationKey)
+ : locationKey;
- const translatedLocation = location.type.startsWith("integrations:")
- ? eventLocationType.label
- : translateAbleKeys.includes(locationKey)
- ? t(locationKey)
- : locationKey;
-
- return (
-
- {eventLocationType.iconUrl === "/link.svg" ? (
-
- ) : (
-
+ return (
+
+ {eventLocationType.iconUrl === "/link.svg" ? (
+
+ ) : (
+
-
{translatedLocation}
-
-
- );
- })}
+ alt={`${eventLocationType.label} icon`}
+ />
+ )}
+
+ {translatedLocation}
+
+
+ );
+ });
+
+ const filteredLocations = renderLocations.filter(excludeNullValues) as JSX.Element[];
+ return filteredLocations.length ? (
+
+ {filteredLocations}
) : null;
}
diff --git a/apps/web/components/dialog/EditLocationDialog.tsx b/apps/web/components/dialog/EditLocationDialog.tsx
index dfb2b443dd..d680371cef 100644
--- a/apps/web/components/dialog/EditLocationDialog.tsx
+++ b/apps/web/components/dialog/EditLocationDialog.tsx
@@ -33,6 +33,7 @@ interface ISetLocationDialog {
saveLocation: (newLocationType: EventLocationType["type"], details: { [key: string]: string }) => void;
selection?: LocationOption;
booking?: BookingItem;
+ isTeamEvent?: boolean;
defaultValues?: LocationObject[];
setShowLocationModal: React.Dispatch
>;
isOpenDialog: boolean;
@@ -74,6 +75,7 @@ export const EditLocationDialog = (props: ISetLocationDialog) => {
saveLocation,
selection,
booking,
+ isTeamEvent,
setShowLocationModal,
isOpenDialog,
defaultValues,
@@ -290,7 +292,9 @@ export const EditLocationDialog = (props: ISetLocationDialog) => {
query={locationsQuery}
success={({ data }) => {
if (!data.length) return null;
- const locationOptions = [...data];
+ const locationOptions = [...data].filter((option) => {
+ return !isTeamEvent ? option.label !== "Conferencing" : true;
+ });
if (booking) {
locationOptions.map((location) =>
location.options.filter((l) => !["phone", "attendeeInPerson"].includes(l.value))
diff --git a/apps/web/components/eventtype/EventSetupTab.tsx b/apps/web/components/eventtype/EventSetupTab.tsx
index 3dc78075c9..49129ef9f6 100644
--- a/apps/web/components/eventtype/EventSetupTab.tsx
+++ b/apps/web/components/eventtype/EventSetupTab.tsx
@@ -35,16 +35,6 @@ const getLocationFromType = (
}
};
-const getDefaultLocationValue = (options: EventTypeSetupProps["locationOptions"], type: string) => {
- for (const locationType of options) {
- for (const location of locationType.options) {
- if (location.value === type && location.disabled === false) {
- return location;
- }
- }
- }
-};
-
export const EventSetupTab = (
props: Pick<
EventTypeSetupProps,
@@ -53,12 +43,16 @@ export const EventSetupTab = (
) => {
const { t } = useLocale();
const formMethods = useFormContext();
- const { eventType, locationOptions, team, destinationCalendar } = props;
+ const { eventType, team, destinationCalendar } = props;
const [showLocationModal, setShowLocationModal] = useState(false);
const [editingLocationType, setEditingLocationType] = useState("");
const [selectedLocation, setSelectedLocation] = useState(undefined);
const [multipleDuration, setMultipleDuration] = useState(eventType.metadata.multipleDuration);
+ const locationOptions = props.locationOptions.filter((option) => {
+ return !team ? option.label !== "Conferencing" : true;
+ });
+
const multipleDurationOptions = [5, 10, 15, 20, 25, 30, 45, 50, 60, 75, 80, 90, 120, 180].map((mins) => ({
value: mins,
label: t("multiple_duration_mins", { count: mins }),
@@ -409,6 +403,7 @@ export const EventSetupTab = (
{/* We portal this modal so we can submit the form inside. Otherwise we get issues submitting two forms at once */}
>;
+} & Partial<
+ Record<"address" | "attendeeAddress" | "link" | "hostPhoneNumber" | "hostDefault" | "phone", string>
+>;
// integrations:jitsi | 919999999999 | Delhi | https://manual.meeting.link | Around Video
export type BookingLocationValue = string;
diff --git a/packages/features/bookings/lib/handleNewBooking.ts b/packages/features/bookings/lib/handleNewBooking.ts
index 3f435a1c1f..71371d3a11 100644
--- a/packages/features/bookings/lib/handleNewBooking.ts
+++ b/packages/features/bookings/lib/handleNewBooking.ts
@@ -622,6 +622,7 @@ async function handler(
let locationBodyString = location;
let defaultLocationUrl = undefined;
+
if (dynamicUserList.length > 1) {
users = users.sort((a, b) => {
const aIndex = (a.username && dynamicUserList.indexOf(a.username)) || 0;
@@ -701,6 +702,18 @@ async function handler(
const [organizerUser] = users;
const tOrganizer = await getTranslation(organizerUser?.locale ?? "en", "common");
+ // use host default
+ if (isTeamEventType && locationBodyString === "conferencing") {
+ const metadataParseResult = userMetadataSchema.safeParse(organizerUser.metadata);
+ const organizerMetadata = metadataParseResult.success ? metadataParseResult.data : undefined;
+ if (organizerMetadata) {
+ const app = getAppFromSlug(organizerMetadata?.defaultConferencingApp?.appSlug);
+ locationBodyString = app?.appData?.location?.type || locationBodyString;
+ defaultLocationUrl = organizerMetadata?.defaultConferencingApp?.appLink;
+ } else {
+ locationBodyString = "";
+ }
+ }
const invitee = [
{
diff --git a/packages/lib/defaultEvents.ts b/packages/lib/defaultEvents.ts
index 1fcc4f9936..e76525b779 100644
--- a/packages/lib/defaultEvents.ts
+++ b/packages/lib/defaultEvents.ts
@@ -26,6 +26,7 @@ type UsernameSlugLinkProps = {
};
const user: User = {
+ metadata: null,
theme: null,
credentials: [],
username: "john.doe",
diff --git a/packages/prisma/selects/user.ts b/packages/prisma/selects/user.ts
index dcea2c8b60..e87f6a511d 100644
--- a/packages/prisma/selects/user.ts
+++ b/packages/prisma/selects/user.ts
@@ -45,6 +45,7 @@ export const userSelect = Prisma.validator()({
theme: true,
brandColor: true,
darkBrandColor: true,
+ metadata: true,
...availabilityUserSelect,
},
});