Files
HellreigN/frontend/src/modules/ide/helpers/fileTree.ts
T
nikita f537f1eab9
ci-front / build (push) Successful in 2m19s
feat: IDE
2026-04-04 04:59:42 +03:00

175 lines
4.4 KiB
TypeScript

import type { FileNode } from "../types";
export const addPaths = (node: FileNode, parentPath: string = ""): FileNode => {
const currentPath = parentPath ? `${parentPath}/${node.name}` : node.name;
const newNode = { ...node, path: currentPath };
if (newNode.children) {
newNode.children = newNode.children.map((child) =>
addPaths(child, currentPath),
);
}
return newNode;
};
export const getAllFolderPaths = (node: FileNode): string[] => {
let paths: string[] = [];
if (node.type === "folder") {
paths.push(node.path || node.name);
if (node.children) {
node.children.forEach((child) => {
paths = [...paths, ...getAllFolderPaths(child)];
});
}
}
return paths;
};
export const findNode = (node: FileNode, path: string): FileNode | null => {
if (node.path === path) return node;
if (node.children) {
for (const child of node.children) {
const found = findNode(child, path);
if (found) return found;
}
}
return null;
};
export const deleteNode = (node: FileNode, path: string): FileNode | null => {
if (node.path === path) return null;
if (node.children) {
const filtered = node.children.filter((child) => child.path !== path);
const mapped = filtered
.map((child) => deleteNode(child, path))
.filter((child): child is FileNode => child !== null);
return { ...node, children: mapped };
}
return node;
};
export const addNode = (
node: FileNode,
parentPath: string,
newNode: FileNode,
): FileNode => {
if (node.path === parentPath) {
const newPath = addPaths(newNode, node.path);
return { ...node, children: [...(node.children || []), newPath] };
}
if (node.children) {
return {
...node,
children: node.children.map((child) =>
addNode(child, parentPath, newNode),
),
};
}
return node;
};
export const renameNode = (
node: FileNode,
oldPath: string,
newName: string,
): FileNode | null => {
if (node.path === oldPath) {
const pathParts = node.path?.split("/") || [];
pathParts[pathParts.length - 1] = newName;
const newPath = pathParts.join("/");
const renamedNode = { ...node, name: newName, path: newPath };
if (renamedNode.children) {
renamedNode.children = renamedNode.children.map((child) => {
const oldChildPath = child.path || "";
const newChildPath = oldChildPath.replace(oldPath, newPath);
return (
renameNode(
child,
oldChildPath,
newChildPath.split("/").pop() || "",
) || child
);
});
}
return renamedNode;
}
if (node.children) {
return {
...node,
children: node.children.map(
(child) => renameNode(child, oldPath, newName) || child,
),
};
}
return node;
};
export const filterTree = (node: FileNode, query: string): FileNode | null => {
if (!query) return node;
const lowerQuery = query.toLowerCase();
if (node.type === "file") {
if (node.name.toLowerCase().includes(lowerQuery)) return node;
return null;
}
if (node.children) {
const filteredChildren = node.children
.map((child) => filterTree(child, query))
.filter((child): child is FileNode => child !== null);
if (filteredChildren.length > 0) {
return { ...node, children: filteredChildren };
}
}
if (node.name.toLowerCase().includes(lowerQuery)) return node;
return null;
};
export const collectPathsToExpand = (
node: FileNode,
query: string,
): Set<string> => {
const paths = new Set<string>();
if (!query) return paths;
const lowerQuery = query.toLowerCase();
const search = (n: FileNode, currentPath: string) => {
if (n.name.toLowerCase().includes(lowerQuery)) {
const pathParts = currentPath.split("/");
for (let i = 1; i < pathParts.length; i++) {
paths.add(pathParts.slice(0, i).join("/"));
}
}
if (n.children) {
n.children.forEach((child) => {
const childPath = child.path || `${currentPath}/${child.name}`;
search(child, childPath);
});
}
};
search(node, node.path || node.name);
return paths;
};
export const getLanguage = (path: string) => {
const ext = path.split(".").pop();
const map: Record<string, string> = {
py: "python",
js: "javascript",
ts: "typescript",
jsx: "javascript",
tsx: "typescript",
json: "json",
md: "markdown",
css: "css",
html: "html",
};
return map[ext || ""] || "plaintext";
};