feat(KB-057): add interactive terminal to dashboard
- Add backend terminal API with session management and SSE streaming - Create useTerminal hook for command execution and history navigation - Implement interactive TerminalModal with real-time output display - Add terminal button to Header for quick access - Style terminal with CSS variables and responsive design - Add keyboard shortcuts (Ctrl+C to kill, Ctrl+L to clear, arrow keys for history) - Add security validation for shell commands
This commit is contained in:
@@ -61,17 +61,6 @@ export function TerminalModal({ isOpen, onClose, initialCommand }: TerminalModal
|
||||
}
|
||||
}, [isOpen, initialCommand, executeCommand, showWelcome]);
|
||||
|
||||
// Handle escape key to close modal
|
||||
useEffect(() => {
|
||||
if (!isOpen) return;
|
||||
|
||||
const handleKey = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") onClose();
|
||||
};
|
||||
document.addEventListener("keydown", handleKey);
|
||||
return () => document.removeEventListener("keydown", handleKey);
|
||||
}, [isOpen, onClose]);
|
||||
|
||||
// Handle overlay click to close
|
||||
const handleOverlayClick = useCallback(
|
||||
(e: React.MouseEvent) => {
|
||||
@@ -130,6 +119,17 @@ export function TerminalModal({ isOpen, onClose, initialCommand }: TerminalModal
|
||||
[isRunning, killCurrentCommand, clearHistory, navigateHistoryUp, navigateHistoryDown],
|
||||
);
|
||||
|
||||
// Handle escape key to close
|
||||
useEffect(() => {
|
||||
if (!isOpen) return;
|
||||
|
||||
const handleKey = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") onClose();
|
||||
};
|
||||
document.addEventListener("keydown", handleKey);
|
||||
return () => document.removeEventListener("keydown", handleKey);
|
||||
}, [isOpen, onClose]);
|
||||
|
||||
// Handle clear button click
|
||||
const handleClear = useCallback(() => {
|
||||
clearHistory();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import { render, screen, waitFor, act, fireEvent } from "@testing-library/react";
|
||||
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
|
||||
import { TerminalModal } from "../TerminalModal";
|
||||
import * as useTerminalModule from "../../hooks/useTerminal";
|
||||
|
||||
@@ -65,7 +65,6 @@ describe("TerminalModal", () => {
|
||||
const { container } = render(
|
||||
<TerminalModal isOpen={false} onClose={mockOnClose} />
|
||||
);
|
||||
|
||||
expect(container.firstChild).toBeNull();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user