Files
mindforge/Mindforge.Web/src/components/FileTreeComponent.tsx
2026-03-26 19:36:25 -03:00

83 lines
2.6 KiB
TypeScript

import { useState, useEffect } from 'preact/hooks';
import { MindforgeApiService, type FileTreeNode } from '../services/MindforgeApiService';
import './FileTreeComponent.css';
interface FileTreeComponentProps {
selectedPaths: string[];
onSelectionChange: (paths: string[]) => void;
}
interface FolderNodeProps {
node: FileTreeNode;
selectedPaths: string[];
onToggle: (path: string) => void;
}
function FolderNode({ node, selectedPaths, onToggle }: FolderNodeProps) {
const [expanded, setExpanded] = useState(true);
if (node.type === 'file') {
return (
<div className="tree-file">
<label className="tree-file-label">
<input
type="checkbox"
checked={selectedPaths.includes(node.path)}
onChange={() => onToggle(node.path)}
/>
<span className="tree-file-name">{node.name}</span>
</label>
</div>
);
}
return (
<div className="tree-folder">
<div className="tree-folder-header" onClick={() => setExpanded(e => !e)}>
<span className="tree-folder-arrow">{expanded ? '▾' : '▸'}</span>
<span className="tree-folder-name">{node.name}</span>
</div>
{expanded && node.children && (
<div className="tree-folder-children">
{node.children.map(child => (
<FolderNode key={child.path} node={child} selectedPaths={selectedPaths} onToggle={onToggle} />
))}
</div>
)}
</div>
);
}
export function FileTreeComponent({ selectedPaths, onSelectionChange }: FileTreeComponentProps) {
const [tree, setTree] = useState<FileTreeNode[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
MindforgeApiService.getRepositoryTree()
.then(setTree)
.catch(err => setError(err.message))
.finally(() => setLoading(false));
}, []);
const togglePath = (path: string) => {
if (selectedPaths.includes(path)) {
onSelectionChange(selectedPaths.filter(p => p !== path));
} else {
onSelectionChange([...selectedPaths, path]);
}
};
if (loading) return <div className="tree-loading">Carregando repositório...</div>;
if (error) return <div className="tree-error">Erro ao carregar repositório: {error}</div>;
if (tree.length === 0) return <div className="tree-empty">Nenhum arquivo encontrado no repositório.</div>;
return (
<div className="file-tree">
{tree.map(node => (
<FolderNode key={node.path} node={node} selectedPaths={selectedPaths} onToggle={togglePath} />
))}
</div>
);
}