Add project templates

This commit is contained in:
ramnique 2025-02-03 23:03:44 +05:30
parent c3d9036d63
commit 4534a77416
11 changed files with 584 additions and 173 deletions

View file

@ -9,16 +9,15 @@ import { cloneWorkflow, createWorkflow, fetchPublishedWorkflowId, fetchWorkflow,
export function App({
projectId,
startWithWorkflowId,
}: {
projectId: string;
startWithWorkflowId: string | null;
}) {
const [selectorKey, setSelectorKey] = useState(0);
const [workflow, setWorkflow] = useState<WithStringId<z.infer<typeof Workflow>> | null>(null);
const [publishedWorkflowId, setPublishedWorkflowId] = useState<string | null>(null);
const [dataSources, setDataSources] = useState<WithStringId<z.infer<typeof DataSource>>[] | null>(null);
const [loading, setLoading] = useState(false);
const [autoSelectIfOnlyOneWorkflow, setAutoSelectIfOnlyOneWorkflow] = useState(true);
const handleSelect = useCallback(async (workflowId: string) => {
setLoading(true);
@ -36,6 +35,7 @@ export function App({
function handleShowSelector() {
// clear the last workflow id from local storage
localStorage.removeItem(`lastWorkflowId_${projectId}`);
setAutoSelectIfOnlyOneWorkflow(false);
setWorkflow(null);
}
@ -74,17 +74,12 @@ export function App({
// Add this useEffect for initial load
useEffect(() => {
// if startWithWorkflowId is provided, use it
if (startWithWorkflowId) {
handleSelect(startWithWorkflowId);
return;
}
// Check localStorage first, fall back to lastWorkflowId prop
const storedWorkflowId = localStorage.getItem(`lastWorkflowId_${projectId}`);
if (storedWorkflowId) {
handleSelect(storedWorkflowId);
}
}, [handleSelect, projectId, startWithWorkflowId]);
}, [handleSelect, projectId]);
// if workflow is null, show the selector
// else show workflow editor
@ -98,6 +93,7 @@ export function App({
key={selectorKey}
handleSelect={handleSelect}
handleCreateNewVersion={handleCreateNewVersion}
autoSelectIfOnlyOneWorkflow={autoSelectIfOnlyOneWorkflow}
/>}
{!loading && workflow && (dataSources !== null) && <WorkflowEditor
key={workflow._id}

View file

@ -1,7 +1,5 @@
import { Metadata } from "next";
import { agentWorkflowsCollection, dataSourcesCollection, projectsCollection } from "@/app/lib/mongodb";
import { App } from "./app";
import { baseWorkflow } from "@/app/lib/utils";
export const metadata: Metadata = {
title: "Workflow"
@ -12,40 +10,7 @@ export default async function Page({
}: {
params: { projectId: string };
}) {
let startWithWorkflowId = null;
const count = await agentWorkflowsCollection.countDocuments({
projectId: params.projectId,
});
if (count === 0) {
// get the next workflow number
const doc = await projectsCollection.findOneAndUpdate({
_id: params.projectId,
}, {
$inc: {
nextWorkflowNumber: 1,
},
}, {
returnDocument: 'after'
});
if (!doc) {
throw new Error('Project not found');
}
const nextWorkflowNumber = doc.nextWorkflowNumber;
// create the workflow
const workflow = {
...baseWorkflow,
projectId: params.projectId,
createdAt: new Date().toISOString(),
lastUpdatedAt: new Date().toISOString(),
name: `Version ${nextWorkflowNumber}`,
};
const { insertedId } = await agentWorkflowsCollection.insertOne(workflow);
startWithWorkflowId = insertedId.toString();
}
return <App
projectId={params.projectId}
startWithWorkflowId={startWithWorkflowId}
/>;
}

View file

@ -38,10 +38,12 @@ export function WorkflowSelector({
projectId,
handleSelect,
handleCreateNewVersion,
autoSelectIfOnlyOneWorkflow,
}: {
projectId: string;
handleSelect: (workflowId: string) => void;
handleCreateNewVersion: () => void;
autoSelectIfOnlyOneWorkflow: boolean;
}) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
@ -76,6 +78,10 @@ export function WorkflowSelector({
setTotalPages(Math.ceil(total / pageSize));
setPublishedWorkflowId(publishedWorkflowId);
setError(null);
if (autoSelectIfOnlyOneWorkflow && workflows.length === 1) {
handleSelect(workflows[0]._id);
}
} catch (e) {
setError('Failed to load workflows');
} finally {
@ -90,7 +96,7 @@ export function WorkflowSelector({
return () => {
ignore = true;
}
}, [projectId, currentPage, retryCount]);
}, [projectId, currentPage, retryCount, autoSelectIfOnlyOneWorkflow, handleSelect]);
return <div className="flex flex-col gap-2 max-w-[768px] mx-auto w-full border border-gray-200 rounded-lg p-4">
<div className="flex items-center gap-2 justify-between">