version 3.0

This commit is contained in:
Flatlogic Bot 2025-07-06 19:39:23 +00:00
parent 1cd6cbb6dc
commit 3c85cdfb87
3 changed files with 128 additions and 3 deletions

File diff suppressed because one or more lines are too long

View File

@ -128,7 +128,14 @@ app.use(
app.use(
'/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,
);
@ -146,7 +153,12 @@ app.use(
app.use(
'/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,
);

View 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;