@ -1,6 +1,6 @@
"use client" ;
"use client" ;
import { useState , useRef , use Memo , useCallback } from "react" ;
import { useState , useMemo , useCallback } from "react" ;
import { useWorkflowStore , WorkflowFile } from "@/store/workflowStore" ;
import { useWorkflowStore , WorkflowFile } from "@/store/workflowStore" ;
import { useShallow } from "zustand/shallow" ;
import { useShallow } from "zustand/shallow" ;
import { ProjectSetupModal } from "./ProjectSetupModal" ;
import { ProjectSetupModal } from "./ProjectSetupModal" ;
@ -93,7 +93,6 @@ export function Header() {
const [ showProjectModal , setShowProjectModal ] = useState ( false ) ;
const [ showProjectModal , setShowProjectModal ] = useState ( false ) ;
const [ projectModalMode , setProjectModalMode ] = useState < "new" | "settings" > ( "new" ) ;
const [ projectModalMode , setProjectModalMode ] = useState < "new" | "settings" > ( "new" ) ;
const fileInputRef = useRef < HTMLInputElement > ( null ) ;
const isProjectConfigured = ! ! workflowName ;
const isProjectConfigured = ! ! workflowName ;
const canSave = ! ! ( workflowId && workflowName && saveDirectoryPath ) ;
const canSave = ! ! ( workflowId && workflowName && saveDirectoryPath ) ;
@ -115,31 +114,36 @@ export function Header() {
setShowProjectModal ( true ) ;
setShowProjectModal ( true ) ;
} ;
} ;
const handleOpenFile = ( ) = > {
const handleOpenFile = async ( ) = > {
fileInputRef . current ? . click ( ) ;
try {
} ;
// Open native OS directory picker
const browseRes = await fetch ( "/api/browse-directory" ) ;
const browseResult = await browseRes . json ( ) ;
const handleFileChange = ( e : React.ChangeEvent < HTMLInputElement > ) = > {
if ( ! browseResult . success || browseResult . cancelled || ! browseResult . path ) {
const file = e . target . files ? . [ 0 ] ;
if ( ! browseResult . success && ! browseResult . cancelled ) {
if ( ! file ) return ;
alert ( browseResult . error || "Failed to open directory picker" ) ;
const reader = new FileReader ( ) ;
reader . onload = async ( event ) = > {
try {
const workflow = JSON . parse ( event . target ? . result as string ) as WorkflowFile ;
if ( workflow . version && workflow . nodes && workflow . edges ) {
await loadWorkflow ( workflow ) ;
} else {
alert ( "Invalid workflow file format" ) ;
}
}
} catch {
return ;
alert ( "Failed to parse workflow file" ) ;
}
}
} ;
reader . readAsText ( file ) ;
// Reset input so same file can be loaded again
const dirPath = browseResult . path ;
e . target . value = "" ;
// Load workflow JSON from that directory
const loadRes = await fetch ( ` /api/workflow?path= ${ encodeURIComponent ( dirPath ) } &load=true ` ) ;
const loadResult = await loadRes . json ( ) ;
if ( ! loadResult . success ) {
alert ( loadResult . error || "No workflow file found in directory" ) ;
return ;
}
const workflow = loadResult . workflow as WorkflowFile ;
await loadWorkflow ( workflow , dirPath ) ;
} catch ( error ) {
console . error ( "Failed to open workflow:" , error ) ;
alert ( "Failed to open workflow. Please try again." ) ;
}
} ;
} ;
const handleProjectSave = async ( id : string , name : string , path : string ) = > {
const handleProjectSave = async ( id : string , name : string , path : string ) = > {
@ -226,13 +230,6 @@ export function Header() {
onSave = { handleProjectSave }
onSave = { handleProjectSave }
mode = { projectModalMode }
mode = { projectModalMode }
/ >
/ >
< input
ref = { fileInputRef }
type = "file"
accept = ".json"
onChange = { handleFileChange }
className = "hidden"
/ >
< header className = "h-11 bg-neutral-900 border-b border-neutral-800 flex items-center justify-between px-4 shrink-0" >
< header className = "h-11 bg-neutral-900 border-b border-neutral-800 flex items-center justify-between px-4 shrink-0" >
< div className = "flex items-center gap-2" >
< div className = "flex items-center gap-2" >
< button
< button