228 lines
6.7 KiB
JavaScript
228 lines
6.7 KiB
JavaScript
// DOM elements
|
|
const createFlowBtn = document.getElementById("create-flow-btn");
|
|
const flowNameInput = document.getElementById("flow-name");
|
|
const flowDescriptionInput = document.getElementById("flow-description");
|
|
const flowSelect = document.getElementById("flow-select");
|
|
const actionTypeSelect = document.getElementById("action-type");
|
|
const taskInput = document.getElementById("task-input");
|
|
const orderIndexInput = document.getElementById("order-index");
|
|
const addTaskBtn = document.getElementById("add-task-btn");
|
|
const flowDetails = document.getElementById("flow-details");
|
|
const executeFlowSelect = document.getElementById("execute-flow-select");
|
|
const executePayloadInput = document.getElementById("execute-payload");
|
|
const executeBtn = document.getElementById("execute-btn");
|
|
const webhookBtn = document.getElementById("webhook-btn");
|
|
const executionResults = document.getElementById("execution-results");
|
|
|
|
let currentFlows = [];
|
|
|
|
// Create new flow
|
|
async function createFlow() {
|
|
const name = flowNameInput.value.trim();
|
|
const description = flowDescriptionInput.value.trim();
|
|
|
|
if (!name) {
|
|
alert("Flow name is required");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch("/flow", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ name, description }),
|
|
});
|
|
|
|
if (response.ok) {
|
|
const flow = await response.json();
|
|
alert(`Flow "${flow.name}" created successfully!`);
|
|
flowNameInput.value = "";
|
|
flowDescriptionInput.value = "";
|
|
loadFlows();
|
|
} else {
|
|
const error = await response.json();
|
|
alert(`Error: ${error.error}`);
|
|
}
|
|
} catch (err) {
|
|
alert("Failed to create flow");
|
|
}
|
|
}
|
|
|
|
// Load all flows
|
|
async function loadFlows() {
|
|
try {
|
|
const response = await fetch("/flows");
|
|
const flows = await response.json();
|
|
currentFlows = flows;
|
|
|
|
// Update flow selects
|
|
flowSelect.innerHTML = '<option value="">Select Flow</option>';
|
|
executeFlowSelect.innerHTML =
|
|
'<option value="">Select Flow to Execute</option>';
|
|
|
|
flows.forEach((flow) => {
|
|
flowSelect.innerHTML += `<option value="${flow.id}">${flow.name}</option>`;
|
|
executeFlowSelect.innerHTML += `<option value="${flow.id}">${flow.name}</option>`;
|
|
});
|
|
} catch (err) {
|
|
console.error("Failed to load flows");
|
|
}
|
|
}
|
|
|
|
// Add task to flow
|
|
async function addTask() {
|
|
const flowId = flowSelect.value;
|
|
const actionType = actionTypeSelect.value;
|
|
const inputData = taskInput.value.trim();
|
|
const orderIndex = parseInt(orderIndexInput.value);
|
|
|
|
if (!flowId || !actionType || !inputData || isNaN(orderIndex)) {
|
|
alert("All fields are required");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(`/flow/${flowId}/task`, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({
|
|
action_type: actionType,
|
|
input_data: inputData,
|
|
order_index: orderIndex,
|
|
}),
|
|
});
|
|
|
|
if (response.ok) {
|
|
const task = await response.json();
|
|
alert(`Task "${task.action_type}" added successfully!`);
|
|
taskInput.value = "";
|
|
orderIndexInput.value = "";
|
|
loadFlowDetails(flowId);
|
|
} else {
|
|
const error = await response.json();
|
|
alert(`Error: ${error.error}`);
|
|
}
|
|
} catch (err) {
|
|
alert("Failed to add task");
|
|
}
|
|
}
|
|
|
|
// Load flow details
|
|
async function loadFlowDetails(flowId) {
|
|
if (!flowId) return;
|
|
|
|
try {
|
|
const response = await fetch(`/flow/${flowId}`);
|
|
const data = await response.json();
|
|
|
|
flowDetails.innerHTML = `
|
|
<div class="border rounded p-4">
|
|
<h3 class="font-semibold text-lg">${data.flow.name}</h3>
|
|
<p class="text-gray-600">${
|
|
data.flow.description || "No description"
|
|
}</p>
|
|
<div class="mt-4">
|
|
<h4 class="font-medium">Tasks:</h4>
|
|
<div class="space-y-2 mt-2">
|
|
${data.tasks
|
|
.map(
|
|
(task) => `
|
|
<div class="bg-gray-100 p-2 rounded">
|
|
<div class="font-medium">${task.action_type}</div>
|
|
<div class="text-sm text-gray-600">Input: ${task.input_data}</div>
|
|
<div class="text-xs text-gray-500">Order: ${task.order_index}</div>
|
|
</div>
|
|
`
|
|
)
|
|
.join("")}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
} catch (err) {
|
|
console.error("Failed to load flow details");
|
|
}
|
|
}
|
|
|
|
// Execute flow
|
|
async function executeFlow() {
|
|
const flowId = executeFlowSelect.value;
|
|
const payload = executePayloadInput.value.trim();
|
|
|
|
if (!flowId) {
|
|
alert("Please select a flow to execute");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(`/flow/${flowId}/execute`, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ payload }),
|
|
});
|
|
|
|
if (response.ok) {
|
|
const result = await response.json();
|
|
showExecutionResults(result);
|
|
} else {
|
|
const error = await response.json();
|
|
alert(`Error: ${error.error}`);
|
|
}
|
|
} catch (err) {
|
|
alert("Failed to execute flow");
|
|
}
|
|
}
|
|
|
|
// Show execution results
|
|
function showExecutionResults(result) {
|
|
executionResults.innerHTML = `
|
|
<h4 class="font-semibold mb-2">Execution Results:</h4>
|
|
<div class="space-y-2">
|
|
${result.results
|
|
.map(
|
|
(r) => `
|
|
<div class="p-2 ${
|
|
r.status === "success" ? "bg-green-100" : "bg-red-100"
|
|
} rounded">
|
|
<div class="font-medium">Task ${r.task_id}</div>
|
|
<div class="text-sm">${r.result}</div>
|
|
<div class="text-xs text-gray-600">Status: ${r.status}</div>
|
|
</div>
|
|
`
|
|
)
|
|
.join("")}
|
|
</div>
|
|
`;
|
|
executionResults.classList.remove("hidden");
|
|
}
|
|
|
|
// Get webhook URL
|
|
function getWebhookUrl() {
|
|
const flowId = executeFlowSelect.value;
|
|
|
|
if (!flowId) {
|
|
alert("Please select a flow");
|
|
return;
|
|
}
|
|
|
|
const webhookUrl = `${window.location.origin}/flow/${flowId}/trigger?payload=test@example.com`;
|
|
alert(
|
|
`Webhook URL:\n${webhookUrl}\n\nCopy this URL to trigger the flow via webhook.`
|
|
);
|
|
}
|
|
|
|
// Event listeners
|
|
createFlowBtn.addEventListener("click", createFlow);
|
|
addTaskBtn.addEventListener("click", addTask);
|
|
executeBtn.addEventListener("click", executeFlow);
|
|
webhookBtn.addEventListener("click", getWebhookUrl);
|
|
|
|
flowSelect.addEventListener("change", (e) => {
|
|
if (e.target.value) {
|
|
loadFlowDetails(e.target.value);
|
|
}
|
|
});
|
|
|
|
// Initialize
|
|
loadFlows();
|