feat: add file explorer with tree view and IDE layout
Backend: editor service for directory tree reading and file CRUD, editor routes at /api/editor with path traversal protection. Frontend: FileExplorer tree component with expand/collapse directories, IDELayout with sidebar + header + outlet, wired into App routing. Editor now receives state as props from App for cross-component file loading.
This commit is contained in:
@@ -12,9 +12,29 @@ async function request<T>(path: string, options?: RequestInit): Promise<T> {
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export interface FileNode {
|
||||
name: string;
|
||||
path: string;
|
||||
type: "file" | "directory";
|
||||
children?: FileNode[];
|
||||
}
|
||||
|
||||
export const api = {
|
||||
health: () => request<{ status: string; wsClients: number }>("/health"),
|
||||
|
||||
editor: {
|
||||
tree: (repo: string) => request<FileNode[]>(`/editor/tree/${repo}`),
|
||||
readFile: (repo: string, filePath: string) =>
|
||||
request<{ content: string }>(`/editor/file/${repo}/${filePath}`),
|
||||
writeFile: (repo: string, filePath: string, content: string) =>
|
||||
request(`/editor/file/${repo}/${filePath}`, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify({ content }),
|
||||
}),
|
||||
deleteFile: (repo: string, filePath: string) =>
|
||||
request(`/editor/file/${repo}/${filePath}`, { method: "DELETE" }),
|
||||
},
|
||||
|
||||
workspace: {
|
||||
getConfig: () => request<Record<string, unknown>>("/workspace/config"),
|
||||
updateConfig: (data: Record<string, unknown>) =>
|
||||
|
||||
Reference in New Issue
Block a user