mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-01 08:13:37 +00:00
feat: enhance terminal functionality and settings
- Added new endpoints for terminal settings: GET and PUT /settings to retrieve and update terminal configurations. - Implemented session limit checks during session creation, returning a 429 status when the limit is reached. - Introduced a new TerminalSection in settings view for customizing terminal appearance and behavior, including font family, default font size, line height, and screen reader mode. - Added support for new terminal features such as search functionality and improved error handling with a TerminalErrorBoundary component. - Updated terminal layout persistence to include session IDs for reconnection and enhanced terminal state management. - Introduced new keyboard shortcuts for terminal actions, including creating new terminal tabs. - Enhanced UI with scrollbar theming for terminal components.
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
import React, { Component, ErrorInfo } from "react";
|
||||
import { AlertCircle, RefreshCw } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode;
|
||||
sessionId: string;
|
||||
onRestart?: () => void;
|
||||
}
|
||||
|
||||
interface State {
|
||||
hasError: boolean;
|
||||
error: Error | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* BUG-06 fix: Error boundary for terminal components
|
||||
* Catches xterm.js errors (WebGL context loss, canvas errors, etc.)
|
||||
* and displays a friendly recovery UI instead of crashing the app.
|
||||
*/
|
||||
export class TerminalErrorBoundary extends Component<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.state = { hasError: false, error: null };
|
||||
}
|
||||
|
||||
static getDerivedStateFromError(error: Error): State {
|
||||
return { hasError: true, error };
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
||||
console.error("[TerminalErrorBoundary] Terminal crashed:", {
|
||||
sessionId: this.props.sessionId,
|
||||
error: error.message,
|
||||
stack: error.stack,
|
||||
componentStack: errorInfo.componentStack,
|
||||
});
|
||||
}
|
||||
|
||||
handleRestart = () => {
|
||||
this.setState({ hasError: false, error: null });
|
||||
this.props.onRestart?.();
|
||||
};
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-col items-center justify-center h-full w-full",
|
||||
"bg-background/95 backdrop-blur-sm",
|
||||
"p-6 text-center gap-4"
|
||||
)}
|
||||
>
|
||||
<div className="w-12 h-12 rounded-full bg-destructive/10 flex items-center justify-center">
|
||||
<AlertCircle className="w-6 h-6 text-destructive" />
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<h3 className="text-lg font-semibold text-foreground">
|
||||
Terminal Crashed
|
||||
</h3>
|
||||
<p className="text-sm text-muted-foreground max-w-sm">
|
||||
{this.state.error?.message?.includes("WebGL")
|
||||
? "WebGL context was lost. This can happen with GPU driver issues."
|
||||
: "An unexpected error occurred in the terminal."}
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={this.handleRestart}
|
||||
className="gap-2"
|
||||
>
|
||||
<RefreshCw className="w-4 h-4" />
|
||||
Restart Terminal
|
||||
</Button>
|
||||
{this.state.error && (
|
||||
<details className="text-xs text-muted-foreground max-w-md">
|
||||
<summary className="cursor-pointer hover:text-foreground">
|
||||
Technical details
|
||||
</summary>
|
||||
<pre className="mt-2 p-2 bg-muted/50 rounded text-left overflow-auto max-h-32">
|
||||
{this.state.error.message}
|
||||
</pre>
|
||||
</details>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user