improve: change db schema for settings

This commit is contained in:
h z
2025-03-20 13:58:24 +00:00
parent 2c330904e4
commit dc0ff3b406
7 changed files with 658 additions and 389 deletions

View File

@@ -1,363 +1,71 @@
import React, { useState, useEffect } from "react";
import {
useCreateWebhookSetting,
useUpdateWebhookSetting,
useWebhookSettingByPathId,
useWebhooks,
useCreateWebhook,
useUpdateWebhook,
useDeleteWebhook
} from "../../utils/webhook-queries";
import {useUpdatePath} from "../../utils/path-queries";
import {useCreatePathSetting, usePathSetting} from "../../utils/setting-queries";
import WebhookSettingPanel from "../Settings/PathSettings/WebhookSettingPanel";
import React, {useState} from "react";
const PathSettingModal = ({ isOpen, path, onClose }) => {
const {data: pathSetting, isLoading: isPathSettingLoading} = usePathSetting(path?.setting_id || 0);
const createPathSetting = useCreatePathSetting();
const updatePath = useUpdatePath();
const PathSettingModal = ({ pathId, isOpen, onClose }) => {
const { data: setting } = useWebhookSettingByPathId(pathId);
const { data: webhooks } = useWebhooks();
const createWebhookSetting = useCreateWebhookSetting();
const updateWebhookSetting = useUpdateWebhookSetting();
const createWebhook = useCreateWebhook();
const updateWebhook = useUpdateWebhook();
const deleteWebhook = useDeleteWebhook();
const [url, setUrl] = useState("");
const [enabled, setEnabled] = useState(false);
const [webhookId, setWebhookId] = useState(-1);
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 [triggerEvents, setTriggerEvents] = useState(0);
const [isRecursive, setIsRecursive] = useState(false);
const [additionalHeaders, setAdditionalHeaders] = useState({});
const [headerList, setHeaderList] = useState([]);
const handleTriggerEventsUpdate = (eventType, isChecked) => {
setTriggerEvents((prevEvents) => {
let newEvents = prevEvents;
switch (eventType) {
case "isOnMarkdownCreated":
newEvents = isChecked ? (newEvents | 1) : (newEvents & ~1);
break;
case "isOnMarkdownUpdated":
newEvents = isChecked ? (newEvents | 2) : (newEvents & ~2);
break;
case "isOnMarkdownDeleted":
newEvents = isChecked ? (newEvents | 4) : (newEvents & ~4);
break;
case "isOnPathCreated":
newEvents = isChecked ? (newEvents | 8) : (newEvents & ~8);
break;
case "isOnPathUpdated":
newEvents = isChecked ? (newEvents | 16) : (newEvents & ~16);
break;
case "isOnPathDeleted":
newEvents = isChecked ? (newEvents | 32) : (newEvents & ~32);
break;
default:
break;
const [activeTab, setActiveTab] = useState("webhook");
const handleCreatePathSetting = () => {
createPathSetting.mutate({}, {
onSuccess: (res) => {
updatePath.mutate({id: path.id, data: {setting_id: res.id}});
}
return newEvents;
});
};
const assignFromTriggerEvents = (events) => {
setIsOnMarkdownCreated((events & 1) > 0);
setIsOnMarkdownUpdated((events & 2) > 0);
setIsOnMarkdownDeleted((events & 4) > 0);
setIsOnPathCreated((events & 8) > 0);
setIsOnPathUpdated((events & 16) > 0);
setIsOnPathDeleted((events & 32) > 0);
};
useEffect(() => {
if (setting && webhooks) {
setEnabled(setting.enabled);
setWebhookId(setting.webhook_id || -1);
const selectedWebhook = webhooks?.find(hook => hook.id === setting.webhook_id);
if (selectedWebhook) {
setUrl(selectedWebhook.hook_url);
}
setTriggerEvents(setting.on_events);
assignFromTriggerEvents(setting.on_events);
setIsRecursive(setting.recursive);
try{
const headers = setting.additional_header ?
JSON.parse(setting.additional_header) : {};
setAdditionalHeaders(headers);
setHeaderList(Object.entries(headers).map(([key, value]) => ({key, value })));
} catch(err) {
setAdditionalHeaders({});
setHeaderList([]);
}
} else {
setUrl("");
setEnabled(false);
setWebhookId(-1);
setTriggerEvents(0);
assignFromTriggerEvents(0);
setIsRecursive(false);
setAdditionalHeaders({});
setHeaderList([]);
}
}, [setting, webhooks]);
const handleSave = () => {
const payload = {
path_id: pathId,
webhook_id: webhookId,
enabled,
on_events: triggerEvents,
recursive: isRecursive,
additional_header: JSON.stringify(additionalHeaders),
};
console.log(payload);
if (!setting) {
createWebhookSetting.mutate(payload, {
onSuccess: () => alert("Webhook setting created successfully"),
onError: () => alert("Webhook setting creation failed"),
});
} else {
updateWebhookSetting.mutate({ id: setting.id, data: payload }, {
onSuccess: () => alert("Webhook setting updated successfully"),
onError: () => alert("Webhook setting update failed"),
});
}
onClose();
};
const handleCreateWebhook = () => {
const newUrl = prompt("Enter new webhook URL");
if (newUrl) {
createWebhook.mutate(newUrl, {
onSuccess: () => alert("Webhook created successfully"),
onError: () => alert("Webhook creation failed"),
});
}
};
const handleUpdateWebhook = () => {
const newUrl = prompt("Enter new webhook URL", url);
if (newUrl && webhookId !== -1) {
updateWebhook.mutate({ id: webhookId, data: { hook_url: newUrl } }, {
onSuccess: () => alert("Webhook updated successfully"),
onError: () => alert("Webhook update failed"),
});
}
};
const handleDeleteWebhook = () => {
if (webhookId !== -1 && window.confirm("Are you sure you want to delete this webhook?")) {
deleteWebhook.mutate(webhookId, {
onSuccess: () => alert("Webhook deleted successfully"),
onError: () => alert("Webhook deletion failed"),
});
}
};
const handleApplyHeaders = () => {
const newHeaders = {};
headerList.forEach(({ key, value }) => {
if (key.trim()) newHeaders[key] = value;
});
setAdditionalHeaders(newHeaders);
};
const handleHeaderChange = (index, field, value) => {
const updatedHeaders = [...headerList];
updatedHeaders[index][field] = value;
setHeaderList(updatedHeaders);
};
const handleAddHeader = () => {
setHeaderList([...headerList, { key: "", value: "" }])
};
if(isPathSettingLoading)
return <p>Loading...</p>
return (
<div className={`modal ${isOpen ? "is-active" : ""}`}>
<div className="modal-background"></div>
<div className="modal-card">
<div className="modal-background" onClick={onClose}></div>
<div className="modal-card" style={{width: "60vw"}}>
<header className="modal-card-head">
<p className="modal-card-title">Webhook Settings</p>
<button className="delete" aria-label="close" onClick={onClose}></button>
<p className="modal-card-title">Path Settings</p>
<button type="button" className="delete" aria-label="close" onClick={onClose} />
</header>
<section className="modal-card-body">
<form>
<div className="field">
<label className="label">Webhook URL</label>
<div className="field has-addons">
<div className="control is-expanded">
<div className="select is-fullwidth">
<select
value={url}
onChange={(e) => {
setUrl(e.target.value);
const selectedWebhook = webhooks?.find(h => h.hook_url === e.target.value);
setWebhookId(selectedWebhook?.id || -1);
}}
>
<option value="">Select a webhook</option>
{webhooks?.map(hook => (
<option key={hook.id} value={hook.hook_url}>{hook.hook_url}</option>
))}
</select>
</div>
</div>
<div className="control">
<button type="button" className="button is-primary" onClick={handleCreateWebhook}>Add</button>
</div>
</div>
{webhookId !== -1 && (
<div className="buttons">
<button type="button" className="button is-info" onClick={handleUpdateWebhook}>Update Webhook URL</button>
<button type="button" className="button is-danger" onClick={handleDeleteWebhook}>Delete Webhook</button>
</div>
)}
<div className="field">
<label className="checkbox">
<input
type="checkbox"
checked={enabled}
onChange={(e) => setEnabled(e.target.checked)}
/>
Enabled
</label>
</div>
<div className="field">
<label className="label">On Events</label>
<div className="box">
<div className="columns">
<div className="column">
<label className="checkbox">
<input
type="checkbox"
checked={isOnMarkdownCreated}
onChange={(e) => {
setIsOnMarkdownCreated(e.target.checked);
handleTriggerEventsUpdate("isOnMarkdownCreated", e.target.checked);
}}
/>
Markdown Created
</label>
<br />
<label className="checkbox">
<input
type="checkbox"
checked={isOnMarkdownUpdated}
onChange={(e) => {
setIsOnMarkdownUpdated(e.target.checked);
handleTriggerEventsUpdate("isOnMarkdownUpdated", e.target.checked);
}}
/>
Markdown Updated
</label>
<br />
<label className="checkbox">
<input
type="checkbox"
checked={isOnMarkdownDeleted}
onChange={(e) => {
setIsOnMarkdownDeleted(e.target.checked);
handleTriggerEventsUpdate("isOnMarkdownDeleted", e.target.checked);
}}
/>
Markdown Deleted
</label>
</div>
<div className="column">
<label className="checkbox">
<input
type="checkbox"
checked={isOnPathCreated}
onChange={(e) => {
setIsOnPathCreated(e.target.checked);
handleTriggerEventsUpdate("isOnPathCreated", e.target.checked);
}}
/>
Path Created
</label>
<br />
<label className="checkbox">
<input
type="checkbox"
checked={isOnPathUpdated}
onChange={(e) => {
setIsOnPathUpdated(e.target.checked);
handleTriggerEventsUpdate("isOnPathUpdated", e.target.checked);
}}
/>
Path Updated
</label>
<br />
<label className="checkbox">
<input
type="checkbox"
checked={isOnPathDeleted}
onChange={(e) => {
setIsOnPathDeleted(e.target.checked);
handleTriggerEventsUpdate("isOnPathDeleted", e.target.checked);
}}
/>
Path Deleted
</label>
</div>
</div>
</div>
</div>
<div className="field">
<label className="checkbox">
<input
type="checkbox"
checked={isRecursive}
onChange={(e) => setIsRecursive(e.target.checked)}
/>
Recursive
</label>
</div>
<div className="field">
<label className="checkbox">Additional Headers</label>
<div className="box">
{headerList.map((header, index) => (
<div className="columns" key={index}>
<div className="column">
<input
type="text"
className="input"
placeholder="key"
value={header.key}
onChange={(e) => {handleHeaderChange(index, "key", e.target.value)}}
/>
</div>
<div className="column">
<input
type="text"
className="input"
placeholder="value"
value={header.value}
onChange={(e) => handleHeaderChange(index, "value", e.target.value)}
/>
</div>
</div>
))}
<button type="button" className="button is-small is-info" onClick={handleAddHeader}>Add Header</button>
<button type="button" className="button is-small is-success" onClick={handleApplyHeaders}>Apply</button>
</div>
</div>
{!pathSetting && !isPathSettingLoading ? (
<section className="modal-card-body">
<button
type="button"
className="button is-primary"
onClick={handleCreatePathSetting}
>
Create Path Setting
</button>
</section>
) : (
<section className="modal-card-body">
<div className="tabs">
<ul>
<li className={activeTab === "webhook" ? "is-active" : ""}>
<a onClick={() => setActiveTab("webhook")}>Webhook</a>
</li>
<li className={activeTab === "template" ? "is-active" : ""}>
<a onClick={() => setActiveTab("template")}>Template</a>
</li>
</ul>
</div>
</form>
</section>
<footer className="modal-card-foot">
<button className="button is-success" type="button" onClick={handleSave}>Save</button>
<button className="button" onClick={onClose}>Cancel</button>
</footer>
{activeTab === "webhook" && (
<WebhookSettingPanel
pathSetting={pathSetting}
onClose={onClose}
/>
)}
{activeTab === "template" && (
<div></div>
)}
</section>
)}
</div>
</div>
);
};
export default PathSettingModal;

View File

@@ -1,6 +1,6 @@
import React, {useEffect, useState, useRef, useContext} from "react";
import { useCreatePath, usePaths } from "../utils/path-queries";
import {useCreatePath, usePath, usePaths} from "../utils/path-queries";
import { useQueryClient } from "react-query";
import "./PathManager.css";
import {fetch_} from "../utils/request-utils";
@@ -9,7 +9,8 @@ import PathSettingModal from "./Modals/PathSettingModal";
const PathManager = ({ currentPathId = 1, onPathChange }) => {
const [currentPath, setCurrentPath] = useState([{ name: "Root", id: 1 }]);
const { data: currentPath } = usePath(currentPathId);
const [currentFullPath, setCurrentFullPath] = useState([{ name: "Root", id: 1 }]);
const [searchTerm, setSearchTerm] = useState("");
const [dropdownActive, setDropdownActive] = useState(false);
@@ -25,7 +26,7 @@ const PathManager = ({ currentPathId = 1, onPathChange }) => {
setIsPathSettingModalModalOpen(true);
}
const buildPath = async (pathId) => {
const buildFullPath = async (pathId) => {
const path = [];
let current_id = pathId;
while (current_id) {
@@ -47,21 +48,21 @@ const PathManager = ({ currentPathId = 1, onPathChange }) => {
useEffect(() => {
const init = async () => {
const path = await buildPath(currentPathId);
setCurrentPath(path);
const path = await buildFullPath(currentPathId);
setCurrentFullPath(path);
};
init();
}, [currentPathId, queryClient]);
const handlePathClick = (pathId, pathIndex) => {
const newPath = currentPath.slice(0, pathIndex + 1);
setCurrentPath(newPath);
const newPath = currentFullPath.slice(0, pathIndex + 1);
setCurrentFullPath(newPath);
onPathChange(pathId);
};
const handleSubPathSelect = (subPath) => {
const updatedPath = [...currentPath, { name: subPath.name, id: subPath.id }];
setCurrentPath(updatedPath);
const updatedPath = [...currentFullPath, { name: subPath.name, id: subPath.id }];
setCurrentFullPath(updatedPath);
onPathChange(subPath.id);
setSearchTerm("");
setDropdownActive(false);
@@ -113,14 +114,14 @@ const PathManager = ({ currentPathId = 1, onPathChange }) => {
<div className="path-manager">
<div className="path-manager-header field has-addons">
<div className="current-path control">
{currentPath.map((path, index) => (
{currentFullPath.map((path, index) => (
<span
key={path.id}
className="breadcrumb-item is-clickable"
onClick={() => handlePathClick(path.id, index)}
>
{path.name}
{index < currentPath.length - 1 && " / "}
{index < currentFullPath.length - 1 && " / "}
</span>
))}
</div>
@@ -137,7 +138,7 @@ const PathManager = ({ currentPathId = 1, onPathChange }) => {
</button>
<PathSettingModal
isOpen={isPathSettingModalOpen}
pathId={currentPathId}
path={currentPath}
onClose={() => setIsPathSettingModalModalOpen(false)}
/>
</div>

View File

@@ -0,0 +1,433 @@
import React, { useEffect, useState } from "react";
import {
useWebhookSetting,
useCreateWebhookSetting,
useUpdateWebhookSetting,
useWebhooks,
} from "../../../utils/webhook-queries";
import {
useCreateWebhook,
useUpdateWebhook,
useDeleteWebhook,
} from "../../../utils/webhook-queries";
import {useUpdatePathSetting} from "../../../utils/setting-queries";
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);
console.log("found", found);
console.log("webhooks", webhooks);
console.log("setting.webhook_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,
};
console.log(webhooks);
console.log(payload);
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 ? (
<div className="box" style={{ marginTop: "1rem" }}>
<h4 className="title is-5">Webhook Setting</h4>
<div className="field">
<label className="label">Select or Create a Webhook</label>
<div className="field has-addons">
<div className="control is-expanded">
{isWebhooksLoading ? (
<p>Loading...</p>
) : (
<div className="select is-fullwidth">
<select
value={selectedUrl}
onChange={(e) => setSelectedUrl(e.target.value)}
>
<option value="">(none)</option>
{webhooks.map((hook) => (
<option key={hook.id} value={hook.hook_url}>
{hook.hook_url}
</option>
))}
</select>
</div>
)}
</div>
<div className="control">
<button
type="button"
className="button is-primary"
onClick={handleCreateWebhook}
>
Add
</button>
</div>
</div>
{setting?.webhook_id && (
<div className="buttons" style={{ marginTop: "0.5rem" }}>
<button
type="button"
className="button is-info"
onClick={handleUpdateWebhook}
>
Update Webhook URL
</button>
<button
type="button"
className="button is-danger"
onClick={handleDeleteWebhook}
>
Delete Webhook
</button>
</div>
)}
</div>
<div className="field">
<label className="checkbox">
<input
type="checkbox"
checked={enabled}
onChange={(e) => setEnabled(e.target.checked)}
/>
&nbsp; Enabled
</label>
</div>
<div className="field">
<label className="label">On Events</label>
<div className="box">
<div className="columns">
<div className="column">
<label className="checkbox">
<input
type="checkbox"
checked={isOnMarkdownCreated}
onChange={(e) =>
handleTriggerEventsUpdate("MARKDOWN_CREATED", e.target.checked)
}
/>
&nbsp; Markdown Created
</label>
<br />
<label className="checkbox">
<input
type="checkbox"
checked={isOnMarkdownUpdated}
onChange={(e) =>
handleTriggerEventsUpdate("MARKDOWN_UPDATED", e.target.checked)
}
/>
&nbsp; Markdown Updated
</label>
<br />
<label className="checkbox">
<input
type="checkbox"
checked={isOnMarkdownDeleted}
onChange={(e) =>
handleTriggerEventsUpdate("MARKDOWN_DELETED", e.target.checked)
}
/>
&nbsp; Markdown Deleted
</label>
</div>
<div className="column">
<label className="checkbox">
<input
type="checkbox"
checked={isOnPathCreated}
onChange={(e) =>
handleTriggerEventsUpdate("PATH_CREATED", e.target.checked)
}
/>
&nbsp; Path Created
</label>
<br />
<label className="checkbox">
<input
type="checkbox"
checked={isOnPathUpdated}
onChange={(e) =>
handleTriggerEventsUpdate("PATH_UPDATED", e.target.checked)
}
/>
&nbsp; Path Updated
</label>
<br />
<label className="checkbox">
<input
type="checkbox"
checked={isOnPathDeleted}
onChange={(e) =>
handleTriggerEventsUpdate("PATH_DELETED", e.target.checked)
}
/>
&nbsp; Path Deleted
</label>
</div>
</div>
</div>
</div>
<div className="field">
<label className="checkbox">
<input
type="checkbox"
checked={isRecursive}
onChange={(e) => setIsRecursive(e.target.checked)}
/>
&nbsp; Recursive
</label>
</div>
<div className="field">
<label className="label">Additional Headers</label>
<div className="box">
{headerList.map((h, idx) => (
<div className="columns" key={idx}>
<div className="column">
<input
type="text"
className="input"
placeholder="key"
value={h.key}
onChange={(e) => handleHeaderChange(idx, "key", e.target.value)}
/>
</div>
<div className="column">
<input
type="text"
className="input"
placeholder="value"
value={h.value}
onChange={(e) =>
handleHeaderChange(idx, "value", e.target.value)
}
/>
</div>
</div>
))}
<button
type="button"
className="button is-small is-info"
onClick={handleAddHeader}
>
+ Header
</button>
<button
type="button"
className="button is-small is-success"
onClick={handleApplyHeaders}
style={{ marginLeft: "0.5rem" }}
>
Apply
</button>
</div>
</div>
<button
type="button"
className="button is-primary"
onClick={handleSaveWebhookSetting}
>
Save Webhook Setting
</button>
</div>
) : (
<button
className="button is-primary"
type="button"
onClick={handleCreateWebhookSetting}
>
Create Webhook Setting
</button>
);
}
export default WebhookSettingPanel