"use client"; import AlertRuleCredenza from "@app/components/AlertRuleCredenza"; import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog"; import { Button } from "@app/components/ui/button"; import { DataTable, ExtendedColumnDef } from "@app/components/ui/data-table"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@app/components/ui/dropdown-menu"; import { Switch } from "@app/components/ui/switch"; import { toast } from "@app/hooks/useToast"; import { type AlertRule, deleteRule, isoNow, loadRules, upsertRule } from "@app/lib/alertRulesLocalStorage"; import { ArrowUpDown, MoreHorizontal } from "lucide-react"; import moment from "moment"; import { useTranslations } from "next-intl"; import { useCallback, useEffect, useState } from "react"; import { Badge } from "@app/components/ui/badge"; type AlertingRulesTableProps = { orgId: string; }; function sourceSummary(rule: AlertRule, t: (k: string, o?: Record) => string) { if (rule.source.type === "site") { return t("alertingSummarySites", { count: rule.source.siteIds.length }); } return t("alertingSummaryHealthChecks", { count: rule.source.targetIds.length }); } function triggerLabel(rule: AlertRule, t: (k: string) => string) { switch (rule.trigger) { case "site_online": return t("alertingTriggerSiteOnline"); case "site_offline": return t("alertingTriggerSiteOffline"); case "health_check_healthy": return t("alertingTriggerHcHealthy"); case "health_check_unhealthy": return t("alertingTriggerHcUnhealthy"); default: return rule.trigger; } } function actionBadges(rule: AlertRule, t: (k: string) => string) { return rule.actions.map((a, i) => { if (a.type === "notify") { return ( {t("alertingActionNotify")} ); } if (a.type === "sms") { return ( {t("alertingActionSms")} ); } return ( {t("alertingActionWebhook")} ); }); } export default function AlertingRulesTable({ orgId }: AlertingRulesTableProps) { const t = useTranslations(); const [rows, setRows] = useState([]); const [credenzaOpen, setCredenzaOpen] = useState(false); const [credenzaRule, setCredenzaRule] = useState(null); const [deleteOpen, setDeleteOpen] = useState(false); const [selected, setSelected] = useState(null); const [isRefreshing, setIsRefreshing] = useState(false); const refreshFromStorage = useCallback(() => { setRows(loadRules(orgId)); }, [orgId]); useEffect(() => { refreshFromStorage(); }, [refreshFromStorage]); const refreshData = async () => { setIsRefreshing(true); try { await new Promise((r) => setTimeout(r, 200)); refreshFromStorage(); } finally { setIsRefreshing(false); } }; const setEnabled = (rule: AlertRule, enabled: boolean) => { upsertRule(orgId, { ...rule, enabled, updatedAt: isoNow() }); refreshFromStorage(); }; const confirmDelete = async () => { if (!selected) return; deleteRule(orgId, selected.id); refreshFromStorage(); setDeleteOpen(false); setSelected(null); toast({ title: t("alertingRuleDeleted") }); }; const columns: ExtendedColumnDef[] = [ { accessorKey: "name", enableHiding: false, friendlyName: t("name"), header: ({ column }) => ( ), cell: ({ row }) => ( {row.original.name} ) }, { id: "source", friendlyName: t("alertingColumnSource"), header: () => {t("alertingColumnSource")}, cell: ({ row }) => ( {sourceSummary(row.original, t)} ) }, { id: "trigger", friendlyName: t("alertingColumnTrigger"), header: () => ( {t("alertingColumnTrigger")} ), cell: ({ row }) => {triggerLabel(row.original, t)} }, { id: "actionsCol", friendlyName: t("alertingColumnActions"), header: () => ( {t("alertingColumnActions")} ), cell: ({ row }) => (
{actionBadges(row.original, t)}
) }, { accessorKey: "enabled", friendlyName: t("alertingColumnEnabled"), header: () => ( {t("alertingColumnEnabled")} ), cell: ({ row }) => { const r = row.original; return ( setEnabled(r, v)} /> ); } }, { accessorKey: "createdAt", friendlyName: t("createdAt"), header: () => ( {t("createdAt")} ), cell: ({ row }) => ( {moment(row.original.createdAt).format("lll")} ) }, { id: "rowActions", enableHiding: false, header: () => , cell: ({ row }) => { const r = row.original; return (
{ setCredenzaRule(r); setCredenzaOpen(true); }} > {t("edit")} { setSelected(r); setDeleteOpen(true); }} > {t("delete")}
); } } ]; return ( <> { setCredenzaOpen(v); if (!v) setCredenzaRule(null); }} orgId={orgId} rule={credenzaRule} onSaved={refreshFromStorage} /> {selected && ( { setDeleteOpen(val); if (!val) setSelected(null); }} dialog={

{t("alertingDeleteQuestion")}

} buttonText={t("delete")} onConfirm={confirmDelete} string={selected.name} title={t("alertingDeleteRule")} /> )} { setCredenzaRule(null); setCredenzaOpen(true); }} onRefresh={refreshData} isRefreshing={isRefreshing} addButtonText={t("alertingAddRule")} enableColumnVisibility stickyLeftColumn="name" stickyRightColumn="rowActions" /> ); }