mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-19 08:51:24 +00:00
Shell: Integrate Cloudshell to existing shells (#2098)
* first draft * refactored code * ux fix * add custom header support and fix ui * minor changes * hide last command also * remove logger * bug fixes * updated loick file * fix tests * moved files * update readme * documentation update * fix compilationerror * undefined check handle * format fix * format fix * fix lints * format fix * fix unrelatred test * code refator * fix format * ut fix * cgmanifest * Revert "cgmanifest" This reverts commit 2e76a6926ee0d3d4e0510f2e04e03446c2ca8c47. * fix snap * test fix * formatting code * updated xterm * include username in command * cloudshell add exit * fix test * format fix * tets fix * fix multiple open cloudshell calls * socket time out after 20 min * remove unused code * 120 min * Addressed comments
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import { FitAddon } from "@xterm/addon-fit";
|
||||
import { Terminal } from "@xterm/xterm";
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import "xterm/css/xterm.css";
|
||||
import { DatabaseAccount } from "../../../Contracts/DataModels";
|
||||
import { TerminalKind } from "../../../Contracts/ViewModels";
|
||||
import { startCloudShellTerminal } from "./CloudShellTerminalCore";
|
||||
|
||||
export interface CloudShellTerminalComponentProps {
|
||||
databaseAccount: DatabaseAccount;
|
||||
tabId: string;
|
||||
username?: string;
|
||||
shellType?: TerminalKind;
|
||||
}
|
||||
|
||||
export const CloudShellTerminalComponent: React.FC<CloudShellTerminalComponentProps> = (props) => {
|
||||
const terminalRef = useRef(null); // Reference for terminal container
|
||||
const xtermRef = useRef(null); // Reference for XTerm instance
|
||||
const socketRef = useRef(null); // Reference for WebSocket
|
||||
|
||||
useEffect(() => {
|
||||
// Initialize XTerm instance
|
||||
const terminal = new Terminal({
|
||||
cursorBlink: true,
|
||||
cursorStyle: "bar",
|
||||
fontFamily: "monospace",
|
||||
fontSize: 11,
|
||||
theme: {
|
||||
background: "#1e1e1e",
|
||||
foreground: "#d4d4d4",
|
||||
cursor: "#ffcc00",
|
||||
},
|
||||
scrollback: 1000,
|
||||
});
|
||||
|
||||
const fitAddon = new FitAddon();
|
||||
terminal.loadAddon(fitAddon);
|
||||
// Attach terminal to the DOM
|
||||
if (terminalRef.current) {
|
||||
terminal.open(terminalRef.current);
|
||||
xtermRef.current = terminal;
|
||||
}
|
||||
|
||||
// Defer terminal sizing until after DOM rendering is complete
|
||||
setTimeout(() => {
|
||||
fitAddon.fit();
|
||||
}, 0);
|
||||
|
||||
// Use ResizeObserver instead of window resize
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
const container = terminalRef.current;
|
||||
if (container && container.offsetWidth > 0 && container.offsetHeight > 0) {
|
||||
try {
|
||||
fitAddon.fit();
|
||||
} catch (e) {
|
||||
console.warn("Fit failed on resize:", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
resizeObserver.observe(terminalRef.current);
|
||||
|
||||
socketRef.current = startCloudShellTerminal(terminal, props.shellType);
|
||||
|
||||
// Cleanup function to close WebSocket and dispose terminal
|
||||
return () => {
|
||||
if (!socketRef.current) {
|
||||
return;
|
||||
}
|
||||
if (socketRef.current && socketRef.current.readyState && socketRef.current.readyState === WebSocket.OPEN) {
|
||||
socketRef.current.close(); // Close WebSocket connection
|
||||
}
|
||||
if (resizeObserver && terminalRef.current) {
|
||||
resizeObserver.unobserve(terminalRef.current);
|
||||
}
|
||||
terminal.dispose(); // Clean up XTerm instance
|
||||
};
|
||||
}, []);
|
||||
|
||||
return <div ref={terminalRef} style={{ width: "100%", height: "500px" }} />;
|
||||
};
|
||||
Reference in New Issue
Block a user