import { useState, useCallback, useEffect } from 'react';
import { useCurrentStateAndParams } from '@uirouter/react';
import { Terminal as TerminalIcon } from 'lucide-react';
import { Terminal } from 'xterm';
import { useLocalStorage } from '@/react/hooks/useLocalStorage';
import { baseHref } from '@/portainer/helpers/pathHelper';
import { notifyError } from '@/portainer/services/notifications';
import { PageHeader } from '@@/PageHeader';
import { Widget, WidgetBody } from '@@/Widget';
import { Icon } from '@@/Icon';
import { Button } from '@@/buttons';
interface StringDictionary {
[index: string]: string;
}
export function ConsoleView() {
const {
params: {
endpointId: environmentId,
container,
name: appName,
namespace,
pod: podID,
},
} = useCurrentStateAndParams();
const [jwtToken] = useLocalStorage('JWT', '');
const [command, setCommand] = useState('/bin/sh');
const [connectionStatus, setConnectionStatus] = useState('closed');
const [terminal, setTerminal] = useState(null as Terminal | null);
const [socket, setSocket] = useState(null as WebSocket | null);
const breadcrumbs = [
{
label: 'Namespaces',
link: 'kubernetes.resourcePools',
},
{
label: namespace,
link: 'kubernetes.resourcePools.resourcePool',
linkParams: { id: namespace },
},
{
label: 'Applications',
link: 'kubernetes.applications',
},
{
label: appName,
link: 'kubernetes.applications.application',
linkParams: { name: appName, namespace },
},
'Pods',
podID,
'Containers',
container,
'Console',
];
const disconnectConsole = useCallback(() => {
socket?.close();
terminal?.dispose();
setTerminal(null);
setSocket(null);
setConnectionStatus('closed');
}, [socket, terminal, setConnectionStatus]);
useEffect(() => {
if (socket) {
socket.onopen = () => {
const terminalContainer = document.getElementById('terminal-container');
if (terminalContainer) {
terminal?.open(terminalContainer);
terminal?.setOption('cursorBlink', true);
terminal?.focus();
setConnectionStatus('open');
}
};
socket.onmessage = (msg) => {
terminal?.write(msg.data);
};
socket.onerror = () => {
disconnectConsole();
notifyError('Websocket connection error');
};
socket.onclose = () => {
disconnectConsole();
};
}
}, [disconnectConsole, setConnectionStatus, socket, terminal]);
useEffect(() => {
terminal?.on('data', (data) => {
socket?.send(data);
});
}, [terminal, socket]);
return (
<>