@@ -56,8 +56,10 @@ export const FileExplorer: React.FC<FileExplorerProps> = ({
|
||||
};
|
||||
|
||||
const filteredFiles = store.searchQuery
|
||||
? filterTree(files, store.searchQuery)
|
||||
: files;
|
||||
? (files.children || [])
|
||||
.map((child) => filterTree(child, store.searchQuery))
|
||||
.filter((child): child is FileNode => child !== null)
|
||||
: files.children || [];
|
||||
|
||||
useEffect(() => {
|
||||
if (store.searchQuery && files) {
|
||||
@@ -185,29 +187,6 @@ export const FileExplorer: React.FC<FileExplorerProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
padding: "6px 12px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "6px",
|
||||
borderBottom: "1px solid #3e3e42",
|
||||
}}
|
||||
>
|
||||
<FiFolder size={14} color="#858585" />
|
||||
<span
|
||||
style={{
|
||||
color: "#cccccc",
|
||||
fontWeight: 600,
|
||||
fontSize: "11px",
|
||||
letterSpacing: "0.3px",
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
{files.name}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{showSearch && (
|
||||
<div style={{ padding: "6px 8px", borderBottom: "1px solid #3e3e42" }}>
|
||||
<div
|
||||
@@ -262,19 +241,21 @@ export const FileExplorer: React.FC<FileExplorerProps> = ({
|
||||
)}
|
||||
|
||||
<div style={{ flex: 1, overflowY: "auto" }}>
|
||||
{filteredFiles ? (
|
||||
<FileTreeItem
|
||||
node={filteredFiles}
|
||||
level={0}
|
||||
onFileSelect={store.selectFile}
|
||||
selectedFile={store.activeFile?.path || null}
|
||||
onContextMenu={handleNodeContextMenu}
|
||||
expandedFolders={store.expandedFolders}
|
||||
onToggleFolder={store.toggleFolder}
|
||||
onDelete={store.handleDeleteNode}
|
||||
isRoot
|
||||
searchQuery={store.searchQuery}
|
||||
/>
|
||||
{filteredFiles.length > 0 ? (
|
||||
filteredFiles.map((child, idx) => (
|
||||
<FileTreeItem
|
||||
key={idx}
|
||||
node={child}
|
||||
level={0}
|
||||
onFileSelect={store.selectFile}
|
||||
selectedFile={store.activeFile?.path || null}
|
||||
onContextMenu={handleNodeContextMenu}
|
||||
expandedFolders={store.expandedFolders}
|
||||
onToggleFolder={store.toggleFolder}
|
||||
onDelete={store.handleDeleteNode}
|
||||
searchQuery={store.searchQuery}
|
||||
/>
|
||||
))
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
|
||||
@@ -60,7 +60,9 @@ export const FilePicker: React.FC<FilePickerProps> = ({ files }) => {
|
||||
backgroundColor: "var(--bg-primary)",
|
||||
}}
|
||||
>
|
||||
<FilePickerTree node={files} level={0} />
|
||||
{(files.children || []).map((child, idx) => (
|
||||
<FilePickerTree key={idx} node={child} level={0} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -442,6 +442,7 @@ export const useIDEStore = create<IDEState>((set, get) => ({
|
||||
return;
|
||||
}
|
||||
|
||||
// Определяем родительский путь
|
||||
let parentPath: string;
|
||||
if (!dialog.node) {
|
||||
parentPath = "";
|
||||
@@ -453,17 +454,44 @@ export const useIDEStore = create<IDEState>((set, get) => ({
|
||||
parentPath = pathParts.join("/");
|
||||
}
|
||||
|
||||
const fullPath = parentPath ? `${parentPath}/${value}` : value;
|
||||
// Проверяем наличие расширения
|
||||
const hasExtension =
|
||||
value.includes(".") && value.split(".").pop() !== value;
|
||||
let finalName = value;
|
||||
let isFile = false;
|
||||
|
||||
// Если диалог создания файла
|
||||
if (dialog.type === "newFile") {
|
||||
isFile = true;
|
||||
// Если нет расширения — добавляем .txt
|
||||
if (!hasExtension) {
|
||||
finalName = `${value}.txt`;
|
||||
}
|
||||
} else if (dialog.type === "newFolder") {
|
||||
// Если диалог создания папки — но имя с расширением, считаем файлом
|
||||
if (hasExtension) {
|
||||
isFile = true;
|
||||
}
|
||||
}
|
||||
|
||||
const fullPath = parentPath ? `${parentPath}/${finalName}` : finalName;
|
||||
|
||||
// Сохраняем раскрытые папки ДО перезагрузки дерева
|
||||
const savedExpandedFolders = new Set(get().expandedFolders);
|
||||
|
||||
try {
|
||||
const result = await scriptsApi.createScript({
|
||||
content: "",
|
||||
interpreter_id: 0,
|
||||
interpreter_id: 1,
|
||||
path: fullPath,
|
||||
});
|
||||
|
||||
await get().fetchTree();
|
||||
|
||||
// Восстанавливаем раскрытые папки
|
||||
set({ expandedFolders: savedExpandedFolders });
|
||||
|
||||
// Собираем все пути от корня до родительской папки
|
||||
const allParentPaths: string[] = [];
|
||||
let current = parentPath;
|
||||
while (current) {
|
||||
@@ -472,17 +500,14 @@ export const useIDEStore = create<IDEState>((set, get) => ({
|
||||
parts.pop();
|
||||
current = parts.join("/");
|
||||
}
|
||||
allParentPaths.forEach((p) => {
|
||||
if (!get().expandedFolders.has(p)) {
|
||||
toggleFolder(p);
|
||||
}
|
||||
});
|
||||
|
||||
// Раскрываем родительскую цепочку
|
||||
autoExpandPaths(new Set(allParentPaths));
|
||||
|
||||
if (dialog.type === "newFile") {
|
||||
if (isFile) {
|
||||
const createdNode: FileNode = {
|
||||
id: result.id,
|
||||
name: value,
|
||||
name: finalName,
|
||||
type: "file",
|
||||
content: result.content,
|
||||
path: result.path,
|
||||
|
||||
Reference in New Issue
Block a user