@@ -2,6 +2,8 @@ import React from "react";
|
|||||||
import type { FileNode } from "../types";
|
import type { FileNode } from "../types";
|
||||||
import { FilePickerItem } from "./FilePickerItem";
|
import { FilePickerItem } from "./FilePickerItem";
|
||||||
import { useFilePickerStore } from "../store/useFilePickerStore";
|
import { useFilePickerStore } from "../store/useFilePickerStore";
|
||||||
|
import { TerminalOutput } from "@/modules/terminal";
|
||||||
|
import { useTerminalStore } from "@/modules/terminal/store/useTerminalStore";
|
||||||
|
|
||||||
interface FilePickerProps {
|
interface FilePickerProps {
|
||||||
files: FileNode;
|
files: FileNode;
|
||||||
@@ -55,6 +57,9 @@ const FilePickerTree: React.FC<{
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const FilePicker: React.FC<FilePickerProps> = ({ files, onRun }) => {
|
export const FilePicker: React.FC<FilePickerProps> = ({ files, onRun }) => {
|
||||||
|
const terminalOpen = useTerminalStore((s) => s.isOpen);
|
||||||
|
const jobs = useTerminalStore((s) => s.jobs);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -63,6 +68,13 @@ export const FilePicker: React.FC<FilePickerProps> = ({ files, onRun }) => {
|
|||||||
backgroundColor: "var(--bg-primary)",
|
backgroundColor: "var(--bg-primary)",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
{/* Terminal — сверху, над списком файлов */}
|
||||||
|
{terminalOpen && jobs.length > 0 && (
|
||||||
|
<div style={{ height: 250 }}>
|
||||||
|
<TerminalOutput />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{(files.children || []).map((child, idx) => (
|
{(files.children || []).map((child, idx) => (
|
||||||
<FilePickerTree key={idx} node={child} level={0} onRun={onRun} />
|
<FilePickerTree key={idx} node={child} level={0} onRun={onRun} />
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -60,21 +60,14 @@ export const RunScriptModal: React.FC<RunScriptModalProps> = ({
|
|||||||
// 4. Ждём завершения по id
|
// 4. Ждём завершения по id
|
||||||
const jobResult = await scriptsApi.waitJob(runResult.id);
|
const jobResult = await scriptsApi.waitJob(runResult.id);
|
||||||
|
|
||||||
// 5. Обновляем джоб
|
// 5. Обновляем существующий джоб (не создаём новый!)
|
||||||
addJob({
|
const terminalStore = useTerminalStore.getState();
|
||||||
id: jobResult.id,
|
terminalStore.updateJob(runResult.id, {
|
||||||
scriptPath,
|
|
||||||
command: jobResult.command,
|
command: jobResult.command,
|
||||||
stdin: jobResult.stdin,
|
stdin: jobResult.stdin,
|
||||||
});
|
|
||||||
|
|
||||||
// Обновляем с финальным статусом
|
|
||||||
const terminalStore = useTerminalStore.getState();
|
|
||||||
terminalStore.updateJob(jobResult.id, {
|
|
||||||
status: jobResult.status,
|
status: jobResult.status,
|
||||||
stdout: jobResult.stdout,
|
stdout: jobResult.stdout,
|
||||||
stderr: jobResult.stderr,
|
stderr: jobResult.stderr,
|
||||||
stdin: jobResult.stdin,
|
|
||||||
isRunning: false,
|
isRunning: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { FiEdit3, FiPlay } from "react-icons/fi";
|
import { FiEdit3 } from "react-icons/fi";
|
||||||
import { FaSpinner } from "react-icons/fa";
|
import { FaSpinner } from "react-icons/fa";
|
||||||
import { FilePicker } from "../modules/ide";
|
import { FilePicker } from "../modules/ide";
|
||||||
import { RunScriptModal } from "../modules/ide/components/RunScriptModal";
|
import { RunScriptModal } from "../modules/ide/components/RunScriptModal";
|
||||||
import { TerminalOutput } from "../modules/terminal";
|
|
||||||
import { useTerminalStore } from "../modules/terminal/store/useTerminalStore";
|
|
||||||
import type { FileNode } from "../modules/ide";
|
import type { FileNode } from "../modules/ide";
|
||||||
import { scriptsApi } from "../modules/ide/api/scripts.api";
|
import { scriptsApi } from "../modules/ide/api/scripts.api";
|
||||||
|
|
||||||
@@ -50,9 +48,6 @@ export const TemplatesPage = () => {
|
|||||||
scriptId: number;
|
scriptId: number;
|
||||||
} | null>(null);
|
} | null>(null);
|
||||||
|
|
||||||
const terminalOpen = useTerminalStore((s) => s.isOpen);
|
|
||||||
const [terminalHeight] = useState(300);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
scriptsApi
|
scriptsApi
|
||||||
.getTree()
|
.getTree()
|
||||||
@@ -78,22 +73,21 @@ export const TemplatesPage = () => {
|
|||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
height: "100vh",
|
height: "100vh",
|
||||||
position: "relative",
|
|
||||||
backgroundColor: "var(--bg-primary)",
|
backgroundColor: "var(--bg-primary)",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* Floating header */}
|
{/* Header bar */}
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
|
||||||
top: "16px",
|
|
||||||
right: "16px",
|
|
||||||
zIndex: 10,
|
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
gap: "16px",
|
justifyContent: "flex-end",
|
||||||
|
padding: "12px 16px",
|
||||||
|
borderBottom: "1px solid var(--border)",
|
||||||
|
backgroundColor: "var(--card-bg)",
|
||||||
|
flexShrink: 0,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* Open in Editor button */}
|
{/* Open in Editor button */}
|
||||||
@@ -125,15 +119,7 @@ export const TemplatesPage = () => {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* File Picker + Terminal */}
|
{/* File Picker (terminal встроен внутрь) */}
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flex: 1,
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
overflow: "hidden",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div style={{ flex: 1, overflow: "hidden" }}>
|
<div style={{ flex: 1, overflow: "hidden" }}>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<div
|
<div
|
||||||
@@ -181,14 +167,6 @@ export const TemplatesPage = () => {
|
|||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Terminal */}
|
|
||||||
{terminalOpen && (
|
|
||||||
<div style={{ height: `${terminalHeight}px`, flexShrink: 0 }}>
|
|
||||||
<TerminalOutput />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Run Script Modal */}
|
{/* Run Script Modal */}
|
||||||
{runModal && (
|
{runModal && (
|
||||||
<RunScriptModal
|
<RunScriptModal
|
||||||
|
|||||||
Reference in New Issue
Block a user