chore: improve event-type atom desc, data fetch (#16890)

This commit is contained in:
Morgan
2024-10-01 10:38:37 +00:00
committed by GitHub
parent b283f1f8cd
commit 9d3be8de03
3 changed files with 83 additions and 33 deletions
@@ -3,6 +3,7 @@ import { Controller, useFormContext } from "react-hook-form";
import type { UseFormGetValues, UseFormSetValue, Control, FormState } from "react-hook-form";
import type { MultiValue } from "react-select";
import { useIsPlatform } from "@calcom/atoms/monorepo";
import useLockedFieldsManager from "@calcom/features/ee/managed-event-types/hooks/useLockedFieldsManager";
import Locations from "@calcom/features/eventtypes/components/Locations";
import type { EventTypeSetupProps } from "@calcom/features/eventtypes/lib/types";
@@ -11,7 +12,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { md } from "@calcom/lib/markdownIt";
import { slugify } from "@calcom/lib/slugify";
import turndown from "@calcom/lib/turndownService";
import { Label, Select, SettingsToggle, Skeleton, TextField, Editor } from "@calcom/ui";
import { Label, Select, SettingsToggle, Skeleton, TextField, Editor, TextAreaField } from "@calcom/ui";
export type EventSetupTabProps = Pick<
EventTypeSetupProps,
@@ -19,6 +20,7 @@ export type EventSetupTabProps = Pick<
>;
export const EventSetupTab = (props: EventSetupTabProps & { urlPrefix: string; hasOrgBranding: boolean }) => {
const { t } = useLocale();
const isPlatform = useIsPlatform();
const formMethods = useFormContext<FormValues>();
const { eventType, team, urlPrefix, hasOrgBranding } = props;
const [multipleDuration, setMultipleDuration] = useState(
@@ -66,38 +68,51 @@ export const EventSetupTab = (props: EventSetupTabProps & { urlPrefix: string; h
{...formMethods.register("title")}
/>
<div>
<Label htmlFor="editor">
{t("description")}
{(isManagedEventType || isChildrenManagedEventType) && shouldLockIndicator("description")}
</Label>
<Editor
getText={() => md.render(formMethods.getValues("description") || "")}
setText={(value: string) =>
formMethods.setValue("description", turndown(value), { shouldDirty: true })
}
excludedToolbarItems={["blockType"]}
placeholder={t("quick_video_meeting")}
editable={!descriptionLockedProps.disabled}
firstRender={firstRender}
setFirstRender={setFirstRender}
/>
{isPlatform ? (
<TextAreaField
{...formMethods.register("description", {
disabled: descriptionLockedProps.disabled,
})}
placeholder={t("quick_video_meeting")}
/>
) : (
<>
<Label htmlFor="editor">
{t("description")}
{(isManagedEventType || isChildrenManagedEventType) && shouldLockIndicator("description")}
</Label>
<Editor
getText={() => md.render(formMethods.getValues("description") || "")}
setText={(value: string) =>
formMethods.setValue("description", turndown(value), { shouldDirty: true })
}
excludedToolbarItems={["blockType"]}
placeholder={t("quick_video_meeting")}
editable={!descriptionLockedProps.disabled}
firstRender={firstRender}
setFirstRender={setFirstRender}
/>
</>
)}
</div>
<TextField
required
label={t("URL")}
label={isPlatform ? "Slug" : t("URL")}
{...(isManagedEventType || isChildrenManagedEventType ? urlLockedProps : {})}
defaultValue={eventType.slug}
data-testid="event-slug"
addOnLeading={
<>
{urlPrefix}/
{!isManagedEventType
? team
? (hasOrgBranding ? "" : "team/") + team.slug
: formMethods.getValues("users")[0].username
: t("username_placeholder")}
/
</>
isPlatform ? undefined : (
<>
{urlPrefix}/
{!isManagedEventType
? team
? (hasOrgBranding ? "" : "team/") + team.slug
: formMethods.getValues("users")[0].username
: t("username_placeholder")}
/
</>
)
}
{...formMethods.register("slug", {
setValueAs: (v) => slugify(v),
@@ -1,17 +1,18 @@
"use client";
import { useRef, useState } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { useRef, useState, useEffect } from "react";
import type { ChildrenEventType } from "@calcom/features/eventtypes/components/ChildrenEventTypeSelect";
import { EventType as EventTypeComponent } from "@calcom/features/eventtypes/components/EventType";
import ManagedEventTypeDialog from "@calcom/features/eventtypes/components/dialogs/ManagedEventDialog";
import type { EventTypeSetupProps, TabMap } from "@calcom/features/eventtypes/lib/types";
import type { EventTypeSetupProps, FormValues, TabMap } from "@calcom/features/eventtypes/lib/types";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { SchedulingType } from "@calcom/prisma/enums";
import { AtomsWrapper } from "../../src/components/atoms-wrapper";
import { useToast } from "../../src/components/ui/use-toast";
import { useAtomsEventTypeById } from "../hooks/useAtomEventTypeById";
import { useAtomsEventTypeById, QUERY_KEY as ATOM_EVENT_TYPE_QUERY_KEY } from "../hooks/useAtomEventTypeById";
import { useAtomUpdateEventType } from "../hooks/useAtomUpdateEventType";
import { useEventTypeForm } from "../hooks/useEventTypeForm";
import { useHandleRouteChange } from "../hooks/useHandleRouteChange";
@@ -23,10 +24,14 @@ export type PlatformTabs = keyof Omit<TabMap, "workflows" | "webhooks" | "instan
export type EventTypePlatformWrapperProps = {
id: number;
tabs?: PlatformTabs[];
onSuccess?: (eventType: FormValues) => void;
onError?: (eventType: FormValues, error: Error) => void;
};
const EventType = ({
tabs = ["setup", "availability", "team", "limits", "advanced"],
onSuccess,
onError,
...props
}: EventTypeSetupProps & EventTypePlatformWrapperProps) => {
const { t } = useLocale();
@@ -52,13 +57,16 @@ const EventType = ({
form.reset(currentValues);
toast({ description: t("event_type_updated_successfully", { eventTypeTitle: eventType.title }) });
onSuccess?.(currentValues);
},
async onSettled() {
return;
},
onError: (err: Error) => {
const currentValues = form.getValues();
const message = err?.message;
toast({ description: message ? t(message) : t(err.message) });
onError?.(currentValues, err);
},
});
@@ -158,10 +166,25 @@ const EventType = ({
);
};
export const EventTypePlatformWrapper = ({ id, tabs }: EventTypePlatformWrapperProps) => {
export const EventTypePlatformWrapper = ({ id, tabs, onSuccess, onError }: EventTypePlatformWrapperProps) => {
const { data: eventTypeQueryData } = useAtomsEventTypeById(id);
const queryClient = useQueryClient();
useEffect(() => {
return () => {
if (eventTypeQueryData) {
// on component unmount or eventTypeId change, reset and invalidate query to get fresh data on next mount
queryClient.invalidateQueries({
queryKey: [ATOM_EVENT_TYPE_QUERY_KEY, id],
});
queryClient.resetQueries({
queryKey: [ATOM_EVENT_TYPE_QUERY_KEY, id],
});
}
};
}, [queryClient, id]);
if (!eventTypeQueryData) return null;
return <EventType {...eventTypeQueryData} id={id} tabs={tabs} />;
return <EventType {...eventTypeQueryData} id={id} tabs={tabs} onSuccess={onSuccess} onError={onError} />;
};
@@ -12,7 +12,7 @@ export default function Bookings(props: { calUsername: string; calEmail: string
const [eventTypeId, setEventTypeId] = useState<number | null>(null);
const [isTeamEvent, setIsTeamEvent] = useState<boolean>(false);
const router = useRouter();
const { isLoading: isLoadingEvents, data: eventTypes } = useEventTypes(props.calUsername);
const { isLoading: isLoadingEvents, data: eventTypes, refetch } = useEventTypes(props.calUsername);
const { data: teams } = useTeams();
const { isLoading: isLoadingTeamEvents, data: teamEventTypes } = useTeamEventTypes(teams?.[0]?.id || 0);
const rescheduleUid = (router.query.rescheduleUid as string) ?? "";
@@ -85,7 +85,19 @@ export default function Bookings(props: { calUsername: string; calEmail: string
)}
{eventTypeId && (
<div>
<EventTypeSettings id={eventTypeId} tabs={["setup"]} />
<EventTypeSettings
id={eventTypeId}
tabs={["setup"]}
onSuccess={(eventType) => {
console.log(eventType);
setEventTypeId(null);
refetch();
}}
onError={(eventType, error) => {
console.log(eventType);
console.error(error);
}}
/>
</div>
)}
</div>