import { useEffect, useState } from "react"; import { Controller, useForm } from "react-hook-form"; import { WEBAPP_URL } from "@calcom/lib/constants"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { WebhookTriggerEvents } from "@calcom/prisma/enums"; import type { RouterOutputs } from "@calcom/trpc/react"; import { Button, Form, Label, Select, Switch, TextArea, TextField, ToggleGroup, DialogFooter, } from "@calcom/ui"; import customTemplate, { hasTemplateIntegration } from "../lib/integrationTemplate"; import WebhookTestDisclosure from "./WebhookTestDisclosure"; export type TWebhook = RouterOutputs["viewer"]["webhook"]["list"][number]; export type WebhookFormData = { id?: string; subscriberUrl: string; active: boolean; eventTriggers: WebhookTriggerEvents[]; secret: string | null; payloadTemplate: string | undefined | null; }; export type WebhookFormSubmitData = WebhookFormData & { changeSecret: boolean; newSecret: string; }; type WebhookTriggerEventOptions = readonly { value: WebhookTriggerEvents; label: string }[]; const WEBHOOK_TRIGGER_EVENTS_GROUPED_BY_APP_V2: Record = { core: [ { value: WebhookTriggerEvents.BOOKING_CANCELLED, label: "booking_cancelled" }, { value: WebhookTriggerEvents.BOOKING_CREATED, label: "booking_created" }, { value: WebhookTriggerEvents.BOOKING_REJECTED, label: "booking_rejected" }, { value: WebhookTriggerEvents.BOOKING_REQUESTED, label: "booking_requested" }, { value: WebhookTriggerEvents.BOOKING_RESCHEDULED, label: "booking_rescheduled" }, { value: WebhookTriggerEvents.BOOKING_PAID, label: "booking_paid" }, { value: WebhookTriggerEvents.MEETING_ENDED, label: "meeting_ended" }, { value: WebhookTriggerEvents.RECORDING_READY, label: "recording_ready" }, ], "routing-forms": [{ value: WebhookTriggerEvents.FORM_SUBMITTED, label: "form_submitted" }], } as const; const WebhookForm = (props: { webhook?: WebhookFormData; apps?: (keyof typeof WEBHOOK_TRIGGER_EVENTS_GROUPED_BY_APP_V2)[]; onSubmit: (event: WebhookFormSubmitData) => void; onCancel?: () => void; noRoutingFormTriggers: boolean; }) => { const { apps = [] } = props; const { t } = useLocale(); const triggerOptions = [...WEBHOOK_TRIGGER_EVENTS_GROUPED_BY_APP_V2["core"]]; if (apps) { for (const app of apps) { if (app === "routing-forms" && props.noRoutingFormTriggers) continue; if (WEBHOOK_TRIGGER_EVENTS_GROUPED_BY_APP_V2[app]) { triggerOptions.push(...WEBHOOK_TRIGGER_EVENTS_GROUPED_BY_APP_V2[app]); } } } const translatedTriggerOptions = triggerOptions.map((option) => ({ ...option, label: t(option.label) })); const formMethods = useForm({ defaultValues: { subscriberUrl: props.webhook?.subscriberUrl || "", active: props.webhook ? props.webhook.active : true, eventTriggers: !props.webhook ? translatedTriggerOptions.map((option) => option.value) : props.webhook.eventTriggers, secret: props?.webhook?.secret || "", payloadTemplate: props?.webhook?.payloadTemplate || undefined, }, }); const [useCustomTemplate, setUseCustomTemplate] = useState(false); const [newSecret, setNewSecret] = useState(""); const [changeSecret, setChangeSecret] = useState(false); const hasSecretKey = !!props?.webhook?.secret; // const currentSecret = props?.webhook?.secret; useEffect(() => { if (changeSecret) { formMethods.unregister("secret", { keepDefaultValue: false }); } }, [changeSecret, formMethods]); return ( <>
props.onSubmit({ ...values, changeSecret, newSecret })}> ( <> { formMethods.setValue("subscriberUrl", e?.target.value); if (hasTemplateIntegration({ url: e.target.value })) { setUseCustomTemplate(true); formMethods.setValue("payloadTemplate", customTemplate({ url: e.target.value })); } }} /> )} /> (
{ formMethods.setValue("active", value); }} />
)} /> { const selectValue = translatedTriggerOptions.filter((option) => value.includes(option.value)); return (