83 lines
2.6 KiB
TypeScript
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>
|
|
);
|
|
}
|