improve: change db schema for settings
This commit is contained in:
@@ -1,363 +1,71 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import {useUpdatePath} from "../../utils/path-queries";
|
||||||
import {
|
import {useCreatePathSetting, usePathSetting} from "../../utils/setting-queries";
|
||||||
useCreateWebhookSetting,
|
import WebhookSettingPanel from "../Settings/PathSettings/WebhookSettingPanel";
|
||||||
useUpdateWebhookSetting,
|
import React, {useState} from "react";
|
||||||
useWebhookSettingByPathId,
|
const PathSettingModal = ({ isOpen, path, onClose }) => {
|
||||||
useWebhooks,
|
const {data: pathSetting, isLoading: isPathSettingLoading} = usePathSetting(path?.setting_id || 0);
|
||||||
useCreateWebhook,
|
const createPathSetting = useCreatePathSetting();
|
||||||
useUpdateWebhook,
|
const updatePath = useUpdatePath();
|
||||||
useDeleteWebhook
|
|
||||||
} from "../../utils/webhook-queries";
|
|
||||||
|
|
||||||
const PathSettingModal = ({ pathId, isOpen, onClose }) => {
|
const [activeTab, setActiveTab] = useState("webhook");
|
||||||
const { data: setting } = useWebhookSettingByPathId(pathId);
|
const handleCreatePathSetting = () => {
|
||||||
const { data: webhooks } = useWebhooks();
|
createPathSetting.mutate({}, {
|
||||||
|
onSuccess: (res) => {
|
||||||
const createWebhookSetting = useCreateWebhookSetting();
|
updatePath.mutate({id: path.id, data: {setting_id: res.id}});
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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(isPathSettingLoading)
|
||||||
if (setting && webhooks) {
|
return <p>Loading...</p>
|
||||||
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: "" }])
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`modal ${isOpen ? "is-active" : ""}`}>
|
<div className={`modal ${isOpen ? "is-active" : ""}`}>
|
||||||
<div className="modal-background"></div>
|
<div className="modal-background" onClick={onClose}></div>
|
||||||
<div className="modal-card">
|
<div className="modal-card" style={{width: "60vw"}}>
|
||||||
<header className="modal-card-head">
|
<header className="modal-card-head">
|
||||||
<p className="modal-card-title">Webhook Settings</p>
|
<p className="modal-card-title">Path Settings</p>
|
||||||
<button className="delete" aria-label="close" onClick={onClose}></button>
|
<button type="button" className="delete" aria-label="close" onClick={onClose} />
|
||||||
</header>
|
</header>
|
||||||
|
{!pathSetting && !isPathSettingLoading ? (
|
||||||
<section className="modal-card-body">
|
<section className="modal-card-body">
|
||||||
<form>
|
<button
|
||||||
<div className="field">
|
type="button"
|
||||||
<label className="label">Webhook URL</label>
|
className="button is-primary"
|
||||||
<div className="field has-addons">
|
onClick={handleCreatePathSetting}
|
||||||
<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>
|
Create Path Setting
|
||||||
{webhooks?.map(hook => (
|
</button>
|
||||||
<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>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</section>
|
</section>
|
||||||
<footer className="modal-card-foot">
|
) : (
|
||||||
<button className="button is-success" type="button" onClick={handleSave}>Save</button>
|
<section className="modal-card-body">
|
||||||
<button className="button" onClick={onClose}>Cancel</button>
|
<div className="tabs">
|
||||||
</footer>
|
<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>
|
||||||
|
{activeTab === "webhook" && (
|
||||||
|
<WebhookSettingPanel
|
||||||
|
pathSetting={pathSetting}
|
||||||
|
onClose={onClose}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{activeTab === "template" && (
|
||||||
|
<div></div>
|
||||||
|
)}
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PathSettingModal;
|
export default PathSettingModal;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
import React, {useEffect, useState, useRef, useContext} from "react";
|
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 { useQueryClient } from "react-query";
|
||||||
import "./PathManager.css";
|
import "./PathManager.css";
|
||||||
import {fetch_} from "../utils/request-utils";
|
import {fetch_} from "../utils/request-utils";
|
||||||
@@ -9,7 +9,8 @@ import PathSettingModal from "./Modals/PathSettingModal";
|
|||||||
|
|
||||||
|
|
||||||
const PathManager = ({ currentPathId = 1, onPathChange }) => {
|
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 [searchTerm, setSearchTerm] = useState("");
|
||||||
const [dropdownActive, setDropdownActive] = useState(false);
|
const [dropdownActive, setDropdownActive] = useState(false);
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@ const PathManager = ({ currentPathId = 1, onPathChange }) => {
|
|||||||
setIsPathSettingModalModalOpen(true);
|
setIsPathSettingModalModalOpen(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildPath = async (pathId) => {
|
const buildFullPath = async (pathId) => {
|
||||||
const path = [];
|
const path = [];
|
||||||
let current_id = pathId;
|
let current_id = pathId;
|
||||||
while (current_id) {
|
while (current_id) {
|
||||||
@@ -47,21 +48,21 @@ const PathManager = ({ currentPathId = 1, onPathChange }) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
const path = await buildPath(currentPathId);
|
const path = await buildFullPath(currentPathId);
|
||||||
setCurrentPath(path);
|
setCurrentFullPath(path);
|
||||||
};
|
};
|
||||||
init();
|
init();
|
||||||
}, [currentPathId, queryClient]);
|
}, [currentPathId, queryClient]);
|
||||||
|
|
||||||
const handlePathClick = (pathId, pathIndex) => {
|
const handlePathClick = (pathId, pathIndex) => {
|
||||||
const newPath = currentPath.slice(0, pathIndex + 1);
|
const newPath = currentFullPath.slice(0, pathIndex + 1);
|
||||||
setCurrentPath(newPath);
|
setCurrentFullPath(newPath);
|
||||||
onPathChange(pathId);
|
onPathChange(pathId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubPathSelect = (subPath) => {
|
const handleSubPathSelect = (subPath) => {
|
||||||
const updatedPath = [...currentPath, { name: subPath.name, id: subPath.id }];
|
const updatedPath = [...currentFullPath, { name: subPath.name, id: subPath.id }];
|
||||||
setCurrentPath(updatedPath);
|
setCurrentFullPath(updatedPath);
|
||||||
onPathChange(subPath.id);
|
onPathChange(subPath.id);
|
||||||
setSearchTerm("");
|
setSearchTerm("");
|
||||||
setDropdownActive(false);
|
setDropdownActive(false);
|
||||||
@@ -113,14 +114,14 @@ const PathManager = ({ currentPathId = 1, onPathChange }) => {
|
|||||||
<div className="path-manager">
|
<div className="path-manager">
|
||||||
<div className="path-manager-header field has-addons">
|
<div className="path-manager-header field has-addons">
|
||||||
<div className="current-path control">
|
<div className="current-path control">
|
||||||
{currentPath.map((path, index) => (
|
{currentFullPath.map((path, index) => (
|
||||||
<span
|
<span
|
||||||
key={path.id}
|
key={path.id}
|
||||||
className="breadcrumb-item is-clickable"
|
className="breadcrumb-item is-clickable"
|
||||||
onClick={() => handlePathClick(path.id, index)}
|
onClick={() => handlePathClick(path.id, index)}
|
||||||
>
|
>
|
||||||
{path.name}
|
{path.name}
|
||||||
{index < currentPath.length - 1 && " / "}
|
{index < currentFullPath.length - 1 && " / "}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -137,7 +138,7 @@ const PathManager = ({ currentPathId = 1, onPathChange }) => {
|
|||||||
</button>
|
</button>
|
||||||
<PathSettingModal
|
<PathSettingModal
|
||||||
isOpen={isPathSettingModalOpen}
|
isOpen={isPathSettingModalOpen}
|
||||||
pathId={currentPathId}
|
path={currentPath}
|
||||||
onClose={() => setIsPathSettingModalModalOpen(false)}
|
onClose={() => setIsPathSettingModalModalOpen(false)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
433
src/components/Settings/PathSettings/WebhookSettingPanel.js
Normal file
433
src/components/Settings/PathSettings/WebhookSettingPanel.js
Normal 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)}
|
||||||
|
/>
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
Markdown Created
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<label className="checkbox">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={isOnMarkdownUpdated}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleTriggerEventsUpdate("MARKDOWN_UPDATED", e.target.checked)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
Markdown Updated
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<label className="checkbox">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={isOnMarkdownDeleted}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleTriggerEventsUpdate("MARKDOWN_DELETED", e.target.checked)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
Markdown Deleted
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="column">
|
||||||
|
<label className="checkbox">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={isOnPathCreated}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleTriggerEventsUpdate("PATH_CREATED", e.target.checked)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
Path Created
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<label className="checkbox">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={isOnPathUpdated}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleTriggerEventsUpdate("PATH_UPDATED", e.target.checked)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
Path Updated
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<label className="checkbox">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={isOnPathDeleted}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleTriggerEventsUpdate("PATH_DELETED", 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="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
|
||||||
@@ -67,9 +67,9 @@ export const useSaveMarkdown = () => {
|
|||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
})
|
})
|
||||||
},{
|
},{
|
||||||
onSuccess: (res, variables) => {
|
onSuccess: (res) => {
|
||||||
queryClient.invalidateQueries(["markdownsByPath", variables.data.path_id]);
|
queryClient.invalidateQueries(["markdownsByPath", res.path_id]);
|
||||||
queryClient.invalidateQueries(["markdown", variables.data.id]);
|
queryClient.invalidateQueries(["markdown", res.id]);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -93,7 +93,6 @@ export const useMoveMarkdown = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const useSearchMarkdown = (keyword) => {
|
export const useSearchMarkdown = (keyword) => {
|
||||||
const queryClient = useQueryClient();
|
|
||||||
const config = useConfig();
|
const config = useConfig();
|
||||||
return useQuery(["markdownsByKeyword", keyword],
|
return useQuery(["markdownsByKeyword", keyword],
|
||||||
() => fetch_(
|
() => fetch_(
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ export const useCreatePath = () => {
|
|||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
onSuccess: (res, variables) => {
|
onSuccess: (res) => {
|
||||||
queryClient.invalidateQueries(["paths", variables.parent_id]);
|
queryClient.invalidateQueries(["paths", res.parent_id]);
|
||||||
queryClient.invalidateQueries("tree");
|
queryClient.invalidateQueries("tree");
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -63,9 +63,9 @@ export const useUpdatePath = () => {
|
|||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
onSuccess: (res, variables) => {
|
onSuccess: (res) => {
|
||||||
queryClient.invalidateQueries(["paths", res.parent_id]);
|
queryClient.invalidateQueries(["paths", res.parent_id]);
|
||||||
queryClient.invalidateQueries(["path", variables.data.id]);
|
queryClient.invalidateQueries(["path", res.id]);
|
||||||
queryClient.invalidateQueries("tree");
|
queryClient.invalidateQueries("tree");
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
151
src/utils/setting-queries.js
Normal file
151
src/utils/setting-queries.js
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
import {fetch_} from "./request-utils";
|
||||||
|
import {useConfig} from "../ConfigProvider";
|
||||||
|
import {useMutation, useQuery, useQueryClient} from "react-query";
|
||||||
|
|
||||||
|
export const usePathSettings = () => {
|
||||||
|
const config = useConfig();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useQuery(
|
||||||
|
"path_settings",
|
||||||
|
() => fetch_(`${config.BACKEND_HOST}/api/setting/path/`),
|
||||||
|
{
|
||||||
|
onSuccess: (data) => {
|
||||||
|
if(data){
|
||||||
|
for(const setting of data)
|
||||||
|
queryClient.setQueryData(["path_setting", setting.id], setting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const usePathSetting = (setting_id) => {
|
||||||
|
const config = useConfig();
|
||||||
|
return useQuery(
|
||||||
|
["path_setting", setting_id],
|
||||||
|
() => fetch_(`${config.BACKEND_HOST}/api/setting/path/${setting_id}`),
|
||||||
|
{
|
||||||
|
enabled: !!setting_id,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useCreatePathSetting = () => {
|
||||||
|
const config = useConfig();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation(
|
||||||
|
(data) => fetch_(`${config.BACKEND_HOST}/api/setting/path/`, {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
}), {
|
||||||
|
onSuccess: (data) => {
|
||||||
|
queryClient.invalidateQueries(["path_setting", data.id]);
|
||||||
|
queryClient.invalidateQueries("path_setting");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const useUpdatePathSetting = () => {
|
||||||
|
const config = useConfig();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation(
|
||||||
|
({id, data}) => fetch_(`${config.BACKEND_HOST}/api/setting/path/${id}`, {
|
||||||
|
method: "PATCH",
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
}), {
|
||||||
|
onSuccess: (data, variables) => {
|
||||||
|
queryClient.invalidateQueries(["path_setting", variables.id]);
|
||||||
|
queryClient.invalidateQueries("path_setting");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useDeletePathSetting = () => {
|
||||||
|
const config = useConfig();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation(
|
||||||
|
(id) => fetch_(`${config.BACKEND_HOST}/api/setting/path/${id}`, {
|
||||||
|
method: "DELETE",
|
||||||
|
}),{
|
||||||
|
onSuccess: (data, variables) => {
|
||||||
|
queryClient.invalidateQueries(["path_setting", variables.id]);
|
||||||
|
queryClient.invalidateQueries("path_setting");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useMarkdownSettings = () => {
|
||||||
|
const config = useConfig();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useQuery(
|
||||||
|
"markdown_setting",
|
||||||
|
() => fetch_(`${config.BACKEND_HOST}/api/setting/markdown/`),
|
||||||
|
{
|
||||||
|
onSuccess: (data) => {
|
||||||
|
if(data){
|
||||||
|
for(const setting of data)
|
||||||
|
queryClient.invalidateQueries(["markdown_setting", setting.id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useMarkdownSetting = (setting_id) => {
|
||||||
|
const config = useConfig();
|
||||||
|
return useQuery(
|
||||||
|
["markdown_setting", setting_id],
|
||||||
|
() => fetch_(`${config.BACKEND_HOST}/api/setting/markdown/`), {
|
||||||
|
enabled: !!setting_id,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const useCreateMarkdownSetting = () => {
|
||||||
|
const config = useConfig();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation(
|
||||||
|
(data) => fetch_(`${config.BACKEND_HOST}/api/setting/markdown/`, {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
}), {
|
||||||
|
onSuccess: (data) => {
|
||||||
|
queryClient.invalidateQueries(["path_setting", data.id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const useUpdateMarkdownSetting = () => {
|
||||||
|
const config = useConfig();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation(
|
||||||
|
({id, data}) => fetch_(`${config.BACKEND_HOST}/api/setting/markdown/${id}`, {
|
||||||
|
method: "PATCH",
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
}),{
|
||||||
|
onSuccess: (data) => {
|
||||||
|
queryClient.invalidateQueries(["path_setting", data.id]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useDeleteMarkdownSetting = () => {
|
||||||
|
const config = useConfig();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation(
|
||||||
|
(id) => fetch_(`${config.BACKEND_HOST}/api/setting/markdown/${id}`, {
|
||||||
|
method: "DELETE",
|
||||||
|
}),{
|
||||||
|
onSuccess: (data) => {
|
||||||
|
queryClient.invalidateQueries(["path_setting", data.id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -17,7 +17,7 @@ export const useWebhooks = () =>{
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useCreateWebhook = () =>{
|
export const useCreateWebhook = () => {
|
||||||
const config = useConfig();
|
const config = useConfig();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
@@ -78,7 +78,6 @@ export const useWebhookSettings = () => {
|
|||||||
if(data){
|
if(data){
|
||||||
for(const setting of data){
|
for(const setting of data){
|
||||||
queryClient.setQueryData(["webhook_setting", setting.id], setting);
|
queryClient.setQueryData(["webhook_setting", setting.id], setting);
|
||||||
queryClient.setQueryData(["webhook_setting_path_id", setting.path_id], setting);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,33 +87,14 @@ export const useWebhookSettings = () => {
|
|||||||
|
|
||||||
export const useWebhookSetting = (setting_id) => {
|
export const useWebhookSetting = (setting_id) => {
|
||||||
const config = useConfig();
|
const config = useConfig();
|
||||||
const queryClient = useQueryClient();
|
|
||||||
return useQuery(
|
return useQuery(
|
||||||
["webhook_setting", setting_id],
|
["webhook_setting", setting_id],
|
||||||
() => fetch_(`${config.BACKEND_HOST}/api/webhook/setting/${setting_id}`),
|
() => fetch_(`${config.BACKEND_HOST}/api/webhook/setting/${setting_id}`),
|
||||||
{
|
{
|
||||||
enabled: !!setting_id,
|
enabled: !!setting_id,
|
||||||
onSuccess: (res) => {
|
|
||||||
if(res)
|
|
||||||
queryClient.setQueryData(["webhook_setting_path_id", res.path_id], res);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useWebhookSettingByPathId = (pathId) => {
|
|
||||||
const config = useConfig();
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
return useQuery(
|
|
||||||
["webhook_setting_path_id", pathId],
|
|
||||||
() => fetch_(`${config.BACKEND_HOST}/api/webhook/setting/path/${pathId}`),
|
|
||||||
{
|
|
||||||
enabled: !!pathId,
|
|
||||||
onSuccess: (res) => {
|
|
||||||
if(res)
|
|
||||||
queryClient.setQueryData(["webhook_setting", res.id], res);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useCreateWebhookSetting = () => {
|
export const useCreateWebhookSetting = () => {
|
||||||
const config = useConfig();
|
const config = useConfig();
|
||||||
@@ -126,7 +106,6 @@ export const useCreateWebhookSetting = () => {
|
|||||||
}),{
|
}),{
|
||||||
onSuccess: (res) => {
|
onSuccess: (res) => {
|
||||||
queryClient.invalidateQueries(["webhook_setting", res.id]);
|
queryClient.invalidateQueries(["webhook_setting", res.id]);
|
||||||
queryClient.invalidateQueries(["webhook_setting_path_id", res.path_id]);
|
|
||||||
queryClient.invalidateQueries("webhook_setting");
|
queryClient.invalidateQueries("webhook_setting");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,7 +122,6 @@ export const useUpdateWebhookSetting = () => {
|
|||||||
}),{
|
}),{
|
||||||
onSuccess: (res, variables) => {
|
onSuccess: (res, variables) => {
|
||||||
queryClient.invalidateQueries(["webhook_setting", variables.id]);
|
queryClient.invalidateQueries(["webhook_setting", variables.id]);
|
||||||
queryClient.invalidateQueries(["webhook_setting_path_id", variables.path_id]);
|
|
||||||
queryClient.invalidateQueries("webhook_setting");
|
queryClient.invalidateQueries("webhook_setting");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,7 +139,6 @@ export const useDeleteWebhookSetting = () => {
|
|||||||
{
|
{
|
||||||
onSuccess: (res, variables) => {
|
onSuccess: (res, variables) => {
|
||||||
queryClient.invalidateQueries(["webhook_setting", variables.id]);
|
queryClient.invalidateQueries(["webhook_setting", variables.id]);
|
||||||
queryClient.invalidateQueries(["webhook_setting_path_id", variables.path_id]);
|
|
||||||
queryClient.invalidateQueries("webhook_setting");
|
queryClient.invalidateQueries("webhook_setting");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user