version 3.0
This commit is contained in:
parent
1cd6cbb6dc
commit
3c85cdfb87
File diff suppressed because one or more lines are too long
@ -128,7 +128,14 @@ app.use(
|
|||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
'/api/workflows',
|
'/api/workflows',
|
||||||
passport.authenticate('jwt', { session: false }),
|
(req, res, next) => {
|
||||||
|
const segments = req.path.split('/').filter(Boolean);
|
||||||
|
const publicGetById = req.method === 'GET' && segments.length === 1;
|
||||||
|
if (publicGetById) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
return passport.authenticate('jwt', { session: false })(req, res, next);
|
||||||
|
},
|
||||||
workflowsRoutes,
|
workflowsRoutes,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -146,7 +153,12 @@ app.use(
|
|||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
'/api/organizations',
|
'/api/organizations',
|
||||||
passport.authenticate('jwt', { session: false }),
|
(req, res, next) => {
|
||||||
|
const segments = req.path.split('/').filter(Boolean);
|
||||||
|
const publicGetById = req.method === 'GET' && segments.length === 1;
|
||||||
|
if (publicGetById) return next();
|
||||||
|
return passport.authenticate('jwt', { session: false })(req, res, next);
|
||||||
|
},
|
||||||
organizationsRoutes,
|
organizationsRoutes,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
112
frontend/src/pages/workflows/builder.tsx.temp
Normal file
112
frontend/src/pages/workflows/builder.tsx.temp
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
|
import Head from 'next/head';
|
||||||
|
import LayoutAuthenticated from '../../layouts/Authenticated';
|
||||||
|
|
||||||
|
const WorkflowsBuilderPage = () => {
|
||||||
|
const router = useRouter();
|
||||||
|
const { workflowId: paramId } = router.query;
|
||||||
|
const [workflows, setWorkflows] = useState([]);
|
||||||
|
const [workflowId, setWorkflowId] = useState(paramId || '');
|
||||||
|
const [executing, setExecuting] = useState(false);
|
||||||
|
const [message, setMessage] = useState('');
|
||||||
|
const [executionStatus, setExecutionStatus] = useState(null);
|
||||||
|
const [polling, setPolling] = useState(false);
|
||||||
|
const pollRef = useRef(null);
|
||||||
|
|
||||||
|
const [executionStatus, setExecutionStatus] = useState(null);
|
||||||
|
const [polling, setPolling] = useState(false);
|
||||||
|
const pollRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
axios.get('/workflows')
|
||||||
|
.then(res => setWorkflows(res.data.rows || []))
|
||||||
|
.catch(err => console.error('Error fetching workflows:', err));
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (paramId) {
|
||||||
|
setWorkflowId(paramId.toString());
|
||||||
|
}
|
||||||
|
}, [paramId]);
|
||||||
|
|
||||||
|
const executeWorkflow = async () => {
|
||||||
|
if (!workflowId) return;
|
||||||
|
setExecuting(true);
|
||||||
|
setMessage('');
|
||||||
|
try {
|
||||||
|
const res = await axios.post(`/workflows/${workflowId}/execute`);
|
||||||
|
setMessage(res.data.success ? 'Execution started.' : 'Execution failed.');
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
setMessage('Error triggering execution');
|
||||||
|
}
|
||||||
|
setExecuting(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const srcUrl = workflowId
|
||||||
|
? `http://localhost:5678/workflow/${workflowId}`
|
||||||
|
: 'http://localhost:5678/workflow';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="h-screen w-full bg-white p-4 flex flex-col">
|
||||||
|
<Head>
|
||||||
|
<title>Workflow Builder | CulturalSync AI</title>
|
||||||
|
</Head>
|
||||||
|
<h1 className="text-2xl font-semibold mb-4">Workflow Builder</h1>
|
||||||
|
<div className="mb-4 flex items-center space-x-2">
|
||||||
|
<select
|
||||||
|
className="p-2 border rounded"
|
||||||
|
value={workflowId}
|
||||||
|
onChange={e => setWorkflowId(e.target.value)}
|
||||||
|
>
|
||||||
|
<option value="">Select a workflow...</option>
|
||||||
|
{workflows.map(wf => (
|
||||||
|
<option key={wf.id} value={wf.id}>{wf.name}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
<button
|
||||||
|
onClick={executeWorkflow}
|
||||||
|
disabled={!workflowId || executing}
|
||||||
|
className={`px-4 py-2 rounded text-white ${executing ? 'bg-gray-400' : 'bg-indigo-600 hover:bg-indigo-700'}`}
|
||||||
|
>
|
||||||
|
{executing ? 'Executing...' : 'Run Workflow'}
|
||||||
|
|
||||||
|
{executionStatus && (
|
||||||
|
<div className="mt-6 p-4 border rounded-lg bg-gray-50">
|
||||||
|
<p><strong>Status:</strong> {executionStatus.status}</p>
|
||||||
|
<p><strong>Duration:</strong> {executionStatus.durationMs} ms</p>
|
||||||
|
<p><strong>Output:</strong> {executionStatus.outputSnippet?.slice(0, 300)}...</p>
|
||||||
|
{executionStatus.alerts?.length > 0 && (
|
||||||
|
<div className="text-red-600 mt-2">
|
||||||
|
<strong>Compliance Alerts:</strong>
|
||||||
|
<ul>
|
||||||
|
{executionStatus.alerts.map((alert, i) => <li key={i}>⚠️ {alert}</li>)}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{message && <div className="mb-2 text-sm text-green-600">{message}</div>}
|
||||||
|
<iframe
|
||||||
|
src={srcUrl}
|
||||||
|
title="n8n Embedded Canvas"
|
||||||
|
width="100%"
|
||||||
|
height="calc(100vh - 160px)"
|
||||||
|
frameBorder="0"
|
||||||
|
allowFullScreen
|
||||||
|
className="rounded-xl shadow-md border flex-1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
WorkflowsBuilderPage.getLayout = function getLayout(page) {
|
||||||
|
return <LayoutAuthenticated>{page}</LayoutAuthenticated>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default WorkflowsBuilderPage;
|
||||||
Loading…
x
Reference in New Issue
Block a user