"use client"; import { ActionBlock, AddActionPanel, AlertRuleSourceFields, AlertRuleTriggerFields } from "@app/components/alert-rule-editor/AlertRuleFields"; import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert"; import { SettingsContainer } from "@app/components/Settings"; import { SwitchInput } from "@app/components/SwitchInput"; import { Button } from "@app/components/ui/button"; import { Card, CardContent } from "@app/components/ui/card"; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "@app/components/ui/form"; import { Input } from "@app/components/ui/input"; import { useEnvContext } from "@app/hooks/useEnvContext"; import { toast } from "@app/hooks/useToast"; import { buildFormSchema, defaultFormValues, formValuesToApiPayload, type AlertRuleFormValues } from "@app/lib/alertRuleForm"; import { createApiClient, formatAxiosError } from "@app/lib/api"; import { zodResolver } from "@hookform/resolvers/zod"; import { tierMatrix } from "@server/lib/billing/tierMatrix"; import type { CreateAlertRuleResponse } from "@server/routers/alertRule/types"; import type { AxiosResponse } from "axios"; import { Cog, Flag, Zap, ZapIcon } from "lucide-react"; import { useTranslations } from "next-intl"; import { useRouter } from "next/navigation"; import { useActionState, useMemo, useTransition, type ReactNode } from "react"; import { useFieldArray, useForm, type Resolver } from "react-hook-form"; import { Badge } from "../ui/badge"; const FORM_ID = "alert-rule-form"; type StepAccent = { labelClass: string; icon: typeof Flag; }; type AlertRuleGraphEditorProps = { orgId: string; alertRuleId?: number; initialValues: AlertRuleFormValues; isNew: boolean; disabled?: boolean; }; function VerticalRuleStep({ stepNumber, isLast, title, accent, children }: { stepNumber: number; isLast: boolean; title: string; accent: StepAccent; children: ReactNode; }) { const Icon = accent.icon; return (
  • {stepNumber}
    {!isLast && (
    )}
    {title}
    {children}
  • ); } export default function AlertRuleGraphEditor({ orgId, alertRuleId, initialValues, isNew, disabled = false }: AlertRuleGraphEditorProps) { const t = useTranslations(); const router = useRouter(); const api = createApiClient(useEnvContext()); const schema = useMemo(() => buildFormSchema(t), [t]); const form = useForm({ resolver: zodResolver(schema) as Resolver, defaultValues: initialValues ?? defaultFormValues() }); const { fields, append, remove, update } = useFieldArray({ control: form.control, name: "actions" }); const saveAlert = async () => { const isValid = await form.trigger(); if (!isValid) { const values = form.getValues(); if (values.actions.length === 0) { toast({ variant: "warning", title: t("alertingNoActionsTitle"), description: t("alertingNoActionsSaveDescription") }); } return; } const values = form.getValues(); try { const payload = formValuesToApiPayload(values); if (isNew) { const res = await api.put< AxiosResponse >(`/org/${orgId}/alert-rule`, payload); toast({ title: t("alertingRuleSaved"), description: t("alertingRuleSavedCreatedDescription") }); router.replace( `/${orgId}/settings/alerting/${res.data.data.alertRuleId}` ); } else { await api.post( `/org/${orgId}/alert-rule/${alertRuleId}`, payload ); toast({ title: t("alertingRuleSaved"), description: t("alertingRuleSavedUpdatedDescription") }); } } catch (e) { toast({ title: t("error"), description: formatAxiosError(e), variant: "destructive" }); } }; const testAlert = async () => { const isValid = await form.trigger("actions"); const values = form.getValues(); if (!isValid) { if (values.actions.length === 0) { toast({ variant: "warning", title: t("alertingNoActionsTitle"), description: t("alertingNoActionsTestDescription") }); } return; } try { const payload = formValuesToApiPayload(values); await api.post(`/org/${orgId}/test-alert-rule`, payload); toast({ title: t("alertingTestAlertSent"), description: t("alertingTestAlertSentDescription") }); } catch (e) { toast({ title: t("error"), description: formatAxiosError(e), variant: "destructive" }); } }; const [, formAction, isSaving] = useActionState(saveAlert, null); const [isTestingAlert, startTransition] = useTransition(); return (
    { e.preventDefault(); startTransition(() => { formAction(); }); }} >
      { if (type === "notify") { append({ type: "notify", userTags: [], roleTags: [], emailTags: [] }); } else { append({ type: "webhook", url: "", method: "POST", headers: [ { key: "", value: "" } ], authType: "none", bearerToken: "", basicCredentials: "", customHeaderName: "", customHeaderValue: "", useBodyTemplate: false, bodyTemplate: "" }); } }} /> {fields.length > 0 && (
      )} {fields.map((f, index) => (
      {index > 0 && (
      )} remove(index) } onUpdate={(val) => update(index, val) } canRemove />
      ))}
    ); }