import React, { useEffect, useState } from "react"; import { useWebhookSetting, useCreateWebhookSetting, useUpdateWebhookSetting, useWebhooks, } from "../../../utils/queries/webhook-queries"; import { useCreateWebhook, useUpdateWebhook, useDeleteWebhook, } from "../../../utils/queries/webhook-queries"; import {useUpdatePathSetting} from "../../../utils/queries/path-setting-queries"; import { Plus, Save, Pencil, Trash2, Check } from "lucide-react"; import { Button } from "../../ui/button"; import { Input, Label } from "../../ui/input"; import { Spinner } from "../../ui/misc"; const SELECT_CLASS = "flex h-9 w-full rounded-md border border-input bg-background/60 px-3 py-1 text-sm text-foreground transition-colors focus-visible:outline-none focus-visible:border-primary/60 focus-visible:ring-2 focus-visible:ring-ring/40"; const CheckboxRow = ({ checked, onChange, label }) => ( ); const WebhookSettingPanel = ({pathSetting, onClose}) => { const {data: setting} = useWebhookSetting(pathSetting?.webhook_setting_id || 0); const {data: webhooks, isLoading: isWebhooksLoading} = useWebhooks(); const createWebhookSetting = useCreateWebhookSetting(); const updateWebhookSetting = useUpdateWebhookSetting(); const createWebhook = useCreateWebhook(); const updateWebhook = useUpdateWebhook(); const deleteWebhook = useDeleteWebhook(); const updatePathSetting = useUpdatePathSetting(); const [enabled, setEnabled] = useState(false); const [isRecursive, setIsRecursive] = useState(false); const [onEvents, setOnEvents] = useState(0); const [selectedUrl, setSelectedUrl] = useState(""); const [headerList, setHeaderList] = useState([]); const [additionalHeaders, setAdditionalHeaders] = useState({}); const [isOnMarkdownCreated, setIsOnMarkdownCreated] = useState(false); const [isOnMarkdownUpdated, setIsOnMarkdownUpdated] = useState(false); const [isOnMarkdownDeleted, setIsOnMarkdownDeleted] = useState(false); const [isOnPathCreated, setIsOnPathCreated] = useState(false); const [isOnPathUpdated, setIsOnPathUpdated] = useState(false); const [isOnPathDeleted, setIsOnPathDeleted] = useState(false); const assignFromOnEvents = (bits) => { setIsOnMarkdownCreated(!!(bits & 1)); setIsOnMarkdownUpdated(!!(bits & 2)); setIsOnMarkdownDeleted(!!(bits & 4)); setIsOnPathCreated(!!(bits & 8)); setIsOnPathUpdated(!!(bits & 16)); setIsOnPathDeleted(!!(bits & 32)); }; const handleTriggerEventsUpdate = (eventType, isChecked) => { setOnEvents((prev) => { let nextVal = prev; switch (eventType) { case "MARKDOWN_CREATED": nextVal = isChecked ? nextVal | 1 : nextVal & ~1; setIsOnMarkdownCreated(isChecked); break; case "MARKDOWN_UPDATED": nextVal = isChecked ? nextVal | 2 : nextVal & ~2; setIsOnMarkdownUpdated(isChecked); break; case "MARKDOWN_DELETED": nextVal = isChecked ? nextVal | 4 : nextVal & ~4; setIsOnMarkdownDeleted(isChecked); break; case "PATH_CREATED": nextVal = isChecked ? nextVal | 8 : nextVal & ~8; setIsOnPathCreated(isChecked); break; case "PATH_UPDATED": nextVal = isChecked ? nextVal | 16 : nextVal & ~16; setIsOnPathUpdated(isChecked); break; case "PATH_DELETED": nextVal = isChecked ? nextVal | 32 : nextVal & ~32; setIsOnPathUpdated(isChecked); break; default: break; } return nextVal; }); }; const handleCreateWebhookSetting = () => { createWebhookSetting.mutate({}, { onSuccess: (data) => { updatePathSetting.mutate({ id: pathSetting.id, data: { webhook_setting_id: data.id } }); } }); }; useEffect(() => { if (setting && webhooks) { setEnabled(setting.enabled); setIsRecursive(setting.recursive); setOnEvents(setting.on_events); assignFromOnEvents(setting.on_events); try { const headers = setting.additional_header ? JSON.parse(setting.additional_header) : {}; setAdditionalHeaders(headers); setHeaderList( Object.entries(headers).map(([k, v]) => ({ key: k, value: v })) ); } catch (err) { setAdditionalHeaders({}); setHeaderList([]); } const found = webhooks.find((wh) => wh.id === setting.webhook_id); setSelectedUrl(found ? found.hook_url : ""); } else { setEnabled(false); setIsRecursive(false); setOnEvents(0); assignFromOnEvents(0); setAdditionalHeaders({}); setHeaderList([]); setSelectedUrl(""); } }, [setting, webhooks]); const handleAddHeader = () => { setHeaderList([...headerList, { key: "", value: "" }]); }; const handleHeaderChange = (index, field, val) => { const updated = [...headerList]; updated[index][field] = val; setHeaderList(updated); }; const handleApplyHeaders = () => { const out = {}; headerList.forEach(({ key, value }) => { if (key.trim()) out[key] = value; }); setAdditionalHeaders(out); }; const handleCreateWebhook = () => { const newUrl = prompt("Enter the new webhook URL"); if (!newUrl) return; createWebhook.mutate(newUrl, { onSuccess: () => alert("Created new Webhook successfully"), onError: () => alert("Failed to create new Webhook"), }); }; const handleUpdateWebhook = () => { if (!setting || !setting.webhook_id) { alert("No webhook selected. Must pick from dropdown first."); return; } const newUrl = prompt("Enter updated Webhook URL", selectedUrl); if (!newUrl) return; updateWebhook.mutate( { id: setting.webhook_id, data: { hook_url: newUrl } }, { onSuccess: () => alert("Updated Webhook successfully"), onError: () => alert("Failed to update Webhook"), } ); }; const handleDeleteWebhook = () => { if (!setting || !setting.webhook_id) { alert("No webhook selected to delete"); return; } if (!window.confirm("Are you sure?")) return; deleteWebhook.mutate(setting.webhook_id, { onSuccess: () => alert("Deleted Webhook successfully"), onError: () => alert("Failed to delete Webhook"), }); }; const handleSaveWebhookSetting = async () => { const hook = webhooks.find((wh) => wh.hook_url === selectedUrl); const payload = { webhook_id: hook? hook.id : null, recursive: isRecursive, additional_header: JSON.stringify(additionalHeaders), enabled, on_events: onEvents, }; if(!setting || !setting.id){ createWebhookSetting.mutate(payload, { onSuccess: (res) => { updatePathSetting.mutate({id: pathSetting.id, data: {webhook_setting_id: res.id}},{ onSuccess: () => alert("Webhook setting successfully created"), onError: () => alert("Failed to save Webhook"), }) }, onError: () => alert("Failed to save Webhook"), }); } else { updateWebhookSetting.mutate({id: setting.id, data: payload}, { onSuccess: () => alert("Updated Webhook successfully"), onError: () => alert("Failed to update Webhook"), }); } onClose(); }; return setting ? (

Webhook Setting

{isWebhooksLoading ? ( ) : ( )}
{setting?.webhook_id && (
)}
setEnabled(e.target.checked)} label="Enabled" />
handleTriggerEventsUpdate("MARKDOWN_CREATED", e.target.checked) } label="Markdown Created" /> handleTriggerEventsUpdate("MARKDOWN_UPDATED", e.target.checked) } label="Markdown Updated" /> handleTriggerEventsUpdate("MARKDOWN_DELETED", e.target.checked) } label="Markdown Deleted" />
handleTriggerEventsUpdate("PATH_CREATED", e.target.checked) } label="Path Created" /> handleTriggerEventsUpdate("PATH_UPDATED", e.target.checked) } label="Path Updated" /> handleTriggerEventsUpdate("PATH_DELETED", e.target.checked) } label="Path Deleted" />
setIsRecursive(e.target.checked)} label="Recursive" />
{headerList.map((h, idx) => (
handleHeaderChange(idx, "key", e.target.value)} /> handleHeaderChange(idx, "value", e.target.value) } />
))}
) : ( ); } export default WebhookSettingPanel