From 123ccf96ef964bb29fd143320b40ae6be1b63ed5 Mon Sep 17 00:00:00 2001 From: BUDUMURU SRINIVAS SAI SARAN TEJA Date: Sun, 28 Dec 2025 21:50:31 +0530 Subject: [PATCH 1/4] feat: enhance workflow loading logic and improve node handling in CreateWorkFlow component --- .../app/components/nodes/CreateWorkFlow.tsx | 85 ++++++++++++++++--- 1 file changed, 74 insertions(+), 11 deletions(-) diff --git a/apps/web/app/components/nodes/CreateWorkFlow.tsx b/apps/web/app/components/nodes/CreateWorkFlow.tsx index 86b9b9a..7bfb764 100644 --- a/apps/web/app/components/nodes/CreateWorkFlow.tsx +++ b/apps/web/app/components/nodes/CreateWorkFlow.tsx @@ -44,9 +44,9 @@ export const CreateWorkFlow = () => { const dispatch = useDispatch(); const userId = useAppSelector(s=>s.user.userId) const workflowId = useAppSelector(s=>s.workflow.workflow_id) - const existingTrigger = useAppSelector(s=>s.workflow.trigger?.name) + const existingTrigger = useAppSelector(s=>s.workflow.trigger) const existingNodes = useAppSelector(s=>s.workflow.nodes) - console.log(`workflow from redux, TRigger: ${existingTrigger}, Nodes: ${existingNodes}`) + // console.log(`workflow from redux, TRigger: ${existingTrigger}, Nodes: ${existingNodes}`) const [nodes, setNodes] = useState([ { @@ -149,6 +149,71 @@ export const CreateWorkFlow = () => { getWorkflowData(); },[dispatch, userId, workflowId]) + useEffect(()=>{ + async function loadWorkflow(){ + const START_X = 100; + const GAP = 250; + const Y = 200; + + const newNodes: NodeType[] = []; + const newEdges: EdgeType[] = []; + + if(existingTrigger){ + newNodes.push({ + id: `trigger-${existingTrigger.dbId}`, + type: 'trigger' as const, + position: { x: START_X, y: Y}, + data:{ + label: existingTrigger.name, + name: existingTrigger.name, + type: existingTrigger.name.split(" - ")[0], + icon: '📊', + config: existingTrigger.config, + } + }) + } + + existingNodes.forEach((node, index)=>{ + const nodeId = `action-${node.dbId}-${index}`; + + newNodes.push({ + id: nodeId, + type: 'action' as const, + position: { x: START_X + (index + 1) * GAP, y: Y}, + data:{ + label: node.name, + name: node.name, + icon: '⚙️', + type: node.name.split(" - ")[0], + config: node.config, + } + }); + }); + + const placeholderIndex = newNodes.length; + newNodes.push({ + id: `placeholder-${Date.now()}`, + type: 'placeholder' as const, + position: { x: START_X + placeholderIndex * GAP, y: Y}, + data: { label: '+' } + }); + + for(let i=0; i { nodes={nodes} edges={edges} onNodeClick={async(event, node) => { + console.log("Node clicked:", node.id, node.type, node.data); if (node.type === "placeholder") { const hasTrigger = nodes.some((n) => n.type === "trigger"); if (hasTrigger) { @@ -236,17 +302,14 @@ export const CreateWorkFlow = () => { } } if(node.type === 'action' || node.type === 'trigger'){ - if(node.data.name === 'Google Sheet' ){ - console.log("sheet called") - console.log(node.id) - // setNodeId("550e8400-e29b-41d4-a716-446655440000") - // getCredentials(node.data.type ? node.data.type : "") - // setNodeId(node.id.split("trigger-")[1] || "") - // if(cred) setLoadSheet(true) + // Check by type instead of name (more reliable) + if(node.data.type?.includes('google_sheet') || node.data.type === "Google sheet"){ + console.log("Google Sheet node clicked") + console.log("Node ID:", node.id) setNodeIDType(node.id) - setCredType(node.data.type === "google_sheet" ? "google_oauth" : "") + setCredType(node.data.type.includes("google sheet") || node.data.type.includes("google_sheet") ? "google_oauth" : "") setLoadSheet(!loadSheet) - console.log("hook called") + console.log("Form opened") } } }} From 55391cc84f4dfbcfa460ef7398c8dad11f6f08bf Mon Sep 17 00:00:00 2001 From: BUDUMURU SRINIVAS SAI SARAN TEJA Date: Mon, 29 Dec 2025 16:49:53 +0530 Subject: [PATCH 2/4] fix: refine Google Sheet node handling and streamline credential type setting --- apps/web/app/components/nodes/CreateWorkFlow.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/web/app/components/nodes/CreateWorkFlow.tsx b/apps/web/app/components/nodes/CreateWorkFlow.tsx index 7bfb764..76621b2 100644 --- a/apps/web/app/components/nodes/CreateWorkFlow.tsx +++ b/apps/web/app/components/nodes/CreateWorkFlow.tsx @@ -10,7 +10,7 @@ import ActionSideBar from "../Actions/ActionSidebar"; import ActionNode from "../Actions/ActionNode"; import { GoogleSheetFormClient } from "./GoogleSheetFormClient"; import { useDispatch } from "react-redux"; -import { workflowActions, workflowReducer } from "@/store/slices/workflowSlice"; +import { workflowActions } from "@/store/slices/workflowSlice"; import { createWorkflow, getEmptyWorkflow, getworkflowData } from "@/app/workflow/lib/config"; import { useAppSelector } from '@/app/hooks/redux'; @@ -303,11 +303,12 @@ export const CreateWorkFlow = () => { } if(node.type === 'action' || node.type === 'trigger'){ // Check by type instead of name (more reliable) - if(node.data.type?.includes('google_sheet') || node.data.type === "Google sheet"){ + const nodeType = node.data.type?.toLowerCase() || ''; + if(nodeType.includes('google_sheet') || nodeType.includes('google sheet')){ console.log("Google Sheet node clicked") console.log("Node ID:", node.id) setNodeIDType(node.id) - setCredType(node.data.type.includes("google sheet") || node.data.type.includes("google_sheet") ? "google_oauth" : "") + setCredType("google_oauth") setLoadSheet(!loadSheet) console.log("Form opened") } From 0918a6de7cede22d864decb96bfc5a1d07eef5fe Mon Sep 17 00:00:00 2001 From: BUDUMURU SRINIVAS SAI SARAN TEJA Date: Mon, 29 Dec 2025 17:02:36 +0530 Subject: [PATCH 3/4] fix: add guard to prevent rebuilding nodes/edges without stored data in CreateWorkFlow component --- apps/web/app/components/nodes/CreateWorkFlow.tsx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/apps/web/app/components/nodes/CreateWorkFlow.tsx b/apps/web/app/components/nodes/CreateWorkFlow.tsx index 76621b2..23f139b 100644 --- a/apps/web/app/components/nodes/CreateWorkFlow.tsx +++ b/apps/web/app/components/nodes/CreateWorkFlow.tsx @@ -150,14 +150,19 @@ export const CreateWorkFlow = () => { },[dispatch, userId, workflowId]) useEffect(()=>{ - async function loadWorkflow(){ + // Guard: only rebuild nodes/edges if there's actual stored data + if (existingNodes.length === 0 && !existingTrigger) { + return; // Keep the current placeholder state + } + + function loadWorkflow(){ const START_X = 100; const GAP = 250; const Y = 200; const newNodes: NodeType[] = []; const newEdges: EdgeType[] = []; - + const type = existingTrigger?.name.split(" - ")[0] if(existingTrigger){ newNodes.push({ id: `trigger-${existingTrigger.dbId}`, @@ -166,7 +171,7 @@ export const CreateWorkFlow = () => { data:{ label: existingTrigger.name, name: existingTrigger.name, - type: existingTrigger.name.split(" - ")[0], + type: type, icon: '📊', config: existingTrigger.config, } @@ -175,7 +180,7 @@ export const CreateWorkFlow = () => { existingNodes.forEach((node, index)=>{ const nodeId = `action-${node.dbId}-${index}`; - + const type = node.name.split(" - ")[0] newNodes.push({ id: nodeId, type: 'action' as const, @@ -184,7 +189,7 @@ export const CreateWorkFlow = () => { label: node.name, name: node.name, icon: '⚙️', - type: node.name.split(" - ")[0], + type: type, config: node.config, } }); From 80dc6b5e10916ed9620c04c2b4381944fd676508 Mon Sep 17 00:00:00 2001 From: BUDUMURU SRINIVAS SAI SARAN TEJA Date: Mon, 29 Dec 2025 21:52:02 +0530 Subject: [PATCH 4/4] feat: add initial data handling and document fetching in GoogleSheetFormClient component --- .../app/components/nodes/CreateWorkFlow.tsx | 17 ++- .../nodes/GoogleSheetFormClient.tsx | 100 ++++++++++++++---- 2 files changed, 95 insertions(+), 22 deletions(-) diff --git a/apps/web/app/components/nodes/CreateWorkFlow.tsx b/apps/web/app/components/nodes/CreateWorkFlow.tsx index 23f139b..7cda789 100644 --- a/apps/web/app/components/nodes/CreateWorkFlow.tsx +++ b/apps/web/app/components/nodes/CreateWorkFlow.tsx @@ -40,7 +40,8 @@ export const CreateWorkFlow = () => { const [actionSidebarOpen, setActionSidebarOpen] = useState(false); const [credType, setCredType] = useState(""); const [nodeIDType, setNodeIDType] = useState('') - const [loadSheet, setLoadSheet] = useState(false) + const [loadSheet, setLoadSheet] = useState(false) + const [selectedNodeConfig, setSelectedNodeConfig] = useState(undefined); const dispatch = useDispatch(); const userId = useAppSelector(s=>s.user.userId) const workflowId = useAppSelector(s=>s.workflow.workflow_id) @@ -314,6 +315,8 @@ export const CreateWorkFlow = () => { console.log("Node ID:", node.id) setNodeIDType(node.id) setCredType("google_oauth") + console.log("config from node: ", node.data.config) + setSelectedNodeConfig(node.data.config) setLoadSheet(!loadSheet) console.log("Form opened") } @@ -334,7 +337,17 @@ export const CreateWorkFlow = () => { /> {loadSheet && - + } ); diff --git a/apps/web/app/components/nodes/GoogleSheetFormClient.tsx b/apps/web/app/components/nodes/GoogleSheetFormClient.tsx index aab2779..94de1e2 100644 --- a/apps/web/app/components/nodes/GoogleSheetFormClient.tsx +++ b/apps/web/app/components/nodes/GoogleSheetFormClient.tsx @@ -4,7 +4,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@ import { Button } from '@workspace/ui/components/button'; import { Input } from '@workspace/ui/components/input'; import { Label } from '@workspace/ui/components/label'; -import React, { useState, useTransition } from 'react'; +import React, { useEffect, useState, useTransition } from 'react'; import Link from 'next/link'; import { toast } from 'sonner'; import { handleSaveConfig } from './actions'; @@ -13,42 +13,102 @@ import { BACKEND_URL } from '@repo/common/zod'; import { useAppSelector } from '@/app/hooks/redux'; interface GoogleSheetFormClientProps { - initialData: { - credentials: Array<{ id: string }>; - authUrl?: string; - hasCredentials: boolean; + type: string; + nodeType: string; + initialData?: { + range?: string; + operation?: string; + sheetName?: string; + spreadSheetId?: string; + credentialId?: string; }; - userId: string; - nodeId: string; } -export function GoogleSheetFormClient(type:{type: string, nodeType: string}) { - const [selectedCredential, setSelectedCredential] = useState(''); +export function GoogleSheetFormClient({ type, nodeType, initialData }: GoogleSheetFormClientProps) { + const [selectedCredential, setSelectedCredential] = useState(initialData?.credentialId || ''); const [documents, setDocuments] = useState>([]); - const [selectedDocument, setSelectedDocument] = useState(''); + const [selectedDocument, setSelectedDocument] = useState(initialData?.spreadSheetId || ''); const [sheets, setSheets] = useState>([]); - const [selectedSheet, setSelectedSheet] = useState(''); - const [operation, setOperation] = useState('read_rows'); - const [range, setRange] = useState('A1:Z100'); + const [selectedSheet, setSelectedSheet] = useState(initialData?.sheetName || ''); + const [operation, setOperation] = useState(initialData?.operation || 'read_rows'); + const [range, setRange] = useState(initialData?.range || 'A1:Z100'); const [loading, setLoading] = useState(false); const [isPending, startTransition] = useTransition(); const [result, setResult] = useState(null); - const [credId, setCredId] = useState(); + const [credId, setCredId] = useState(initialData?.credentialId || ''); // const [authUrl, setAuthUrl] = useState() + console.log('initial data: ', initialData) + console.log('initial document: ', selectedDocument) + console.log('initial sheet: ', selectedSheet) + console.log('initial range: ', range) + console.log("initial operation: ",operation) + const userId = useAppSelector(s=>s.user.userId) || "" const workflowId = useAppSelector(s=>s.workflow.workflow_id) || '' console.log(userId, 'id from client') - const credType = type.type - const nodeType = type.nodeType.split("~")[0] || "" - console.log('checking nodeType: ', nodeType); + const credType = type + const nodeTypeParsed = nodeType.split("~")[0] || "" + console.log('checking nodeType: ', nodeTypeParsed); - const nodeId = type.nodeType.split("~")[1] || "" + const nodeId = nodeType.split("~")[1] || "" console.log('checking node id: ',nodeId) const {cred: response, authUrl} = useCredentials(credType) console.log('response from form client', typeof(response)) console.log(response," response from client after hook") console.log(authUrl," authurl") + + // Fetch documents when there's initial credentialId + useEffect(() => { + const fetchInitialDocuments = async () => { + if (!initialData?.credentialId) return; + + setLoading(true); + try { + const res = await fetch(`${BACKEND_URL}/node/getDocuments/${initialData.credentialId}`, { + method: 'GET', + credentials: "include", + headers: { 'Content-Type': 'application/json' }, + }); + const data = await res.json(); + if (data.files?.length > 0) { + setDocuments(data.files); + } + } catch (error) { + console.error('Failed to fetch initial documents:', error); + } finally { + setLoading(false); + } + }; + + fetchInitialDocuments(); + }, [initialData?.credentialId]); + + // Fetch sheets when there's initial spreadSheetId + useEffect(() => { + const fetchInitialSheets = async () => { + if (!initialData?.credentialId || !initialData?.spreadSheetId) return; + + setLoading(true); + try { + const res = await fetch(`${BACKEND_URL}/node/getSheets/${initialData.credentialId}/${initialData.spreadSheetId}`, { + method: 'GET', + headers: { 'Content-Type': 'application/json' }, + credentials: "include", + }); + const data = await res.json(); + if (data.files?.data?.length > 0) { + setSheets(data.files.data); + } + } catch (error) { + console.error('Failed to fetch initial sheets:', error); + } finally { + setLoading(false); + } + }; + + fetchInitialSheets(); + }, [initialData?.credentialId, initialData?.spreadSheetId]); const openAuthWindow = (url: string) => { if (!url) return; @@ -129,8 +189,8 @@ export function GoogleSheetFormClient(type:{type: string, nodeType: string}) { userId:userId, node_Trigger:nodeId, workflowId, - type:nodeType, - name: `Google sheet - ${nodeType}`, + type:nodeTypeParsed, + name: `Google sheet - ${nodeTypeParsed}`, credentialId: selectedCredential, spreadsheetId: selectedDocument, sheetName: selectedSheet,