Skip to content

Commit

Permalink
Fix logic in file system
Browse files Browse the repository at this point in the history
The exist file in the workspace are just dummy folders that don't exist in the runtime.
  • Loading branch information
akhatua2 committed Nov 22, 2024
1 parent 0ab65a2 commit a05ff89
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 42 deletions.
107 changes: 96 additions & 11 deletions examples/experimental/nodes/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ChatInterface } from './components/ChatInterface/ChatInterface';
import { Browser } from './components/Browser/Browser';
import { Sidebar } from './components/Sidebar/Sidebar';
import { SceneContext } from './components/Sidebar/SceneContext';
import { FileSystemState, FileNode } from './types/FileSystem';

const socket = io('http://localhost:8000', {
transports: ['websocket'],
Expand All @@ -29,14 +30,45 @@ type FilesType = {
type PanelOption = 'fileSystem' | 'sceneContext';

const App: React.FC = () => {
const [files, setFiles] = useState<FilesType>({
"/workspace/index.html": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Document</title>\n</head>\n<body>\n <h1>Hello World</h1>\n</body>\n</html>",
"/workspace/style.css": "body {\n background-color: #f0f0f0;\n font-family: Arial, sans-serif;\n}",
"/workspace/script.js": "console.log('Hello, World!');",
"/workspace/interview.py": "# Python code here"
const [fileSystem, setFileSystem] = useState<FileSystemState>({
tree: [
{
name: 'workspace',
type: 'folder',
path: '/workspace',
children: [
{
name: 'index.html',
type: 'file',
path: '/workspace/index.html',
},
{
name: 'style.css',
type: 'file',
path: '/workspace/style.css',
},
{
name: 'script.js',
type: 'file',
path: '/workspace/script.js',
},
{
name: 'main.py',
type: 'file',
path: '/workspace/main.py',
}
]
}
],
files: {
'/workspace/index.html': '<!DOCTYPE html>\n<html lang="en">...',
'/workspace/style.css': 'body {\n background-color: #f0f0f0;...',
'/workspace/script.js': 'console.log("Hello, World!");',
'/workspace/main.py': '# Python code here'
}
});

const [currentFile, setCurrentFile] = useState("/workspace/interview.py");
const [currentFile, setCurrentFile] = useState("/workspace/main.py");
const [messages, setMessages] = useState<Array<{text: string, type: 'message' | 'status'}>>([]);
const [terminalMessages, setTerminalMessages] = useState<string[]>([]);
const [activeTab, setActiveTab] = useState<'editor' | 'browser'>('editor');
Expand Down Expand Up @@ -75,6 +107,51 @@ const App: React.FC = () => {
};
}, []);

const addFile = (path: string, content: string) => {
setFileSystem(prev => {
// Split path into parts
const parts = path.split('/').filter(Boolean);
const fileName = parts[parts.length - 1];

// Create new file node
const newFile: FileNode = {
name: fileName,
type: 'file',
path: path
};

// Update tree structure
const newTree = [...prev.tree];
let currentLevel = newTree;
for (let i = 0; i < parts.length - 1; i++) {
const folder = currentLevel.find(node =>
node.type === 'folder' && node.name === parts[i]
);
if (folder && folder.children) {
currentLevel = folder.children;
}
}

// Add new file to appropriate level if it doesn't exist
if (!currentLevel.find(node => node.path === path)) {
currentLevel.push(newFile);
}

// Update files content
return {
tree: newTree,
files: {
...prev.files,
[path]: content
}
};
});

// Automatically switch to the new/updated file
setCurrentFile(path);
setActiveTab('editor');
};

const handleAgentAction = (messageData: any) => {
const actionType = messageData.data.action_type;
const agentName = messageData.data.agent_name;
Expand All @@ -94,8 +171,7 @@ const App: React.FC = () => {
case "write":
const filePath = messageData.data.path;
const fileContent = messageData.data.argument;
setFiles(prev => ({ ...prev, [filePath]: fileContent }));
setActiveTab('editor');
addFile(filePath, fileContent);
setMessages(prev => [...prev, {
text: `${agentName} is writing code...`,
type: 'status' as const
Expand Down Expand Up @@ -142,7 +218,10 @@ const App: React.FC = () => {
<div id="ide-container">
{activePanel === 'fileSystem' && (
<div id="file-explorer">
<FileSystem onFileSelect={setCurrentFile} />
<FileSystem
fileSystem={fileSystem.tree}
onFileSelect={(path) => setCurrentFile(path)}
/>
</div>
)}
{activePanel === 'sceneContext' && (
Expand All @@ -168,9 +247,15 @@ const App: React.FC = () => {
{activeTab === 'editor' ? (
<div id="code-editor">
<CodeEditor
code={files[currentFile]}
code={fileSystem.files[currentFile]}
onChange={(newCode) =>
setFiles(prevFiles => ({ ...prevFiles, [currentFile]: newCode }))
setFileSystem(prevFiles => ({
...prevFiles,
files: {
...prevFiles.files,
[currentFile]: newCode
}
}))
}
filename={currentFile}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ import { githubDark } from '@uiw/codemirror-theme-github';
import './CodeEditor.css'; // Import the CSS file

interface CodeEditorProps {
code: string;
code: string | undefined;
onChange: (value: string) => void;
filename: string;
}

const CodeEditor: React.FC<CodeEditorProps> = ({ code, onChange, filename }) => {
// Add empty lines to fill the editor
const fillEmptyLines = (content: string) => {
const fillEmptyLines = (content: string | undefined) => {
if (!content) return '\n'.repeat(50); // Return 50 empty lines if no content

const lines = content.split('\n');
const currentLines = lines.length;
if (currentLines < 50) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,13 @@ import {
SiTypescript, SiJson, SiMarkdown
} from 'react-icons/si';
import './FileSystem.css'; // Import the CSS file

const files = [
{ name: 'workspace', type: 'folder', children: [
{ name: 'index.html', type: 'file' },
{ name: 'style.css', type: 'file' },
{ name: 'script.js', type: 'file' },
{ name: 'interview.py', type: 'file' },
]},
];
import { FileNode } from '../../types/FileSystem';

interface FileSystemProps {
onFileSelect: (fileName: string) => void;
fileSystem: FileNode[];
onFileSelect: (path: string) => void;
}


const getFileIcon = (fileName: string) => {
const ext = fileName.split('.').pop()?.toLowerCase();
switch (ext) {
Expand All @@ -35,8 +27,8 @@ const getFileIcon = (fileName: string) => {
}
};

export const FileSystem: React.FC<FileSystemProps> = ({ onFileSelect }) => {
const [expandedFolders, setExpandedFolders] = useState<Set<string>>(new Set(['workspace']));
export const FileSystem: React.FC<FileSystemProps> = ({ fileSystem, onFileSelect }) => {
const [expandedFolders, setExpandedFolders] = useState<Set<string>>(new Set(['/workspace']));

const toggleFolder = (folderName: string, e: React.MouseEvent) => {
e.stopPropagation();
Expand All @@ -51,19 +43,19 @@ export const FileSystem: React.FC<FileSystemProps> = ({ onFileSelect }) => {
});
};

const renderItem = (item: any, depth: number = 0) => {
const isExpanded = expandedFolders.has(item.name);
const renderItem = (item: FileNode, depth: number = 0) => {
const isExpanded = expandedFolders.has(item.path);

return (
<div
key={item.name}
key={item.path}
className="file-item"
style={{ paddingLeft: `${depth * 16 + (item.type === 'file' ? 20 : 12)}px` }}
onClick={() => item.type === 'file' && onFileSelect(`/workspace/${item.name}`)}
onClick={() => item.type === 'file' && onFileSelect(item.path)}
>
{item.type === 'folder' ? (
<>
<span className="folder-arrow" onClick={(e) => toggleFolder(item.name, e)}>
<span className="folder-arrow" onClick={(e) => toggleFolder(item.path, e)}>
{isExpanded ? <ChevronDown size={14} /> : <ChevronRight size={14} />}
</span>
</>
Expand All @@ -75,12 +67,12 @@ export const FileSystem: React.FC<FileSystemProps> = ({ onFileSelect }) => {
);
};

const renderFolder = (folder: any, depth: number = 0) => (
<div key={folder.name}>
const renderFolder = (folder: FileNode, depth: number = 0) => (
<div key={folder.path}>
{renderItem(folder, depth)}
{expandedFolders.has(folder.name) && folder.children && (
{expandedFolders.has(folder.path) && folder.children && (
<div className="folder-children">
{folder.children.map((child: any) =>
{folder.children.map((child: FileNode) =>
child.type === 'folder' ?
renderFolder(child, depth + 1) :
renderItem(child, depth + 1)
Expand All @@ -92,13 +84,12 @@ export const FileSystem: React.FC<FileSystemProps> = ({ onFileSelect }) => {

return (
<>
<div id="file-explorer-header">Folders</div>
<div className="file-explorer">
{files.map(file => file.type === 'folder' ?
renderFolder(file) :
renderItem(file)
)}
</div>
<div id="file-explorer-header">Folders</div>
<div className="file-explorer">
{fileSystem.map(node =>
node.type === 'folder' ? renderFolder(node) : renderItem(node)
)}
</div>
</>
);
};
14 changes: 14 additions & 0 deletions examples/experimental/nodes/frontend/src/types/FileSystem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export interface FileNode {
name: string;
type: 'file' | 'folder';
path: string;
content?: string;
children?: FileNode[];
}

export interface FileSystemState {
tree: FileNode[];
files: {
[path: string]: string; // path -> content mapping
};
}

0 comments on commit a05ff89

Please sign in to comment.