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