77 lines
2.3 KiB
TypeScript
77 lines
2.3 KiB
TypeScript
import { useState } from 'react';
|
|
|
|
import { useEnvironmentId } from '@/react/hooks/useEnvironmentId';
|
|
import { baseHref } from '@/portainer/helpers/pathHelper';
|
|
import { terminalClose } from '@/portainer/services/terminal-window';
|
|
import { EnvironmentId } from '@/react/portainer/environments/types';
|
|
|
|
import { Alert } from '@@/Alert';
|
|
import { Button } from '@@/buttons';
|
|
import { Terminal, LINUX_SHELL_INIT_COMMANDS } from '@@/Terminal/Terminal';
|
|
import type { ShellState } from '@@/Terminal/Terminal';
|
|
|
|
export function KubectlShellView() {
|
|
const environmentId = useEnvironmentId();
|
|
const [shellState, setShellState] = useState<ShellState>('idle');
|
|
|
|
return (
|
|
<div className="fixed bottom-0 left-0 right-0 top-0 z-[10000] bg-black text-white">
|
|
{shellState === 'connecting' && (
|
|
<div className="px-4 pt-2">Loading Terminal...</div>
|
|
)}
|
|
{shellState === 'disconnected' && (
|
|
<div className="p-4">
|
|
<Alert color="info" title="Console disconnected">
|
|
<div className="mt-4 flex items-center gap-2">
|
|
<Button
|
|
onClick={() => window.location.reload()}
|
|
data-cy="k8sShell-reloadButton"
|
|
>
|
|
Reload
|
|
</Button>
|
|
<Button
|
|
onClick={() => window.close()}
|
|
color="default"
|
|
data-cy="k8sShell-closeButton"
|
|
>
|
|
Close
|
|
</Button>
|
|
</div>
|
|
</Alert>
|
|
</div>
|
|
)}
|
|
<Terminal
|
|
url={buildUrl(environmentId)}
|
|
connect
|
|
onStateChange={onStateChange}
|
|
initialCommands={LINUX_SHELL_INIT_COMMANDS}
|
|
/>
|
|
</div>
|
|
);
|
|
|
|
function onStateChange(state: ShellState) {
|
|
if (state === 'disconnected') {
|
|
terminalClose();
|
|
}
|
|
setShellState(state);
|
|
}
|
|
|
|
function buildUrl(environmentId: EnvironmentId) {
|
|
const params = {
|
|
endpointId: environmentId,
|
|
};
|
|
|
|
const wsProtocol =
|
|
window.location.protocol === 'https:' ? 'wss://' : 'ws://';
|
|
const path = `${baseHref()}api/websocket/kubernetes-shell`;
|
|
const base = path.startsWith('http')
|
|
? path.replace(/^https?:\/\//i, '')
|
|
: window.location.host + path;
|
|
|
|
const queryParams = Object.entries(params)
|
|
.map(([k, v]) => `${k}=${v}`)
|
|
.join('&');
|
|
return `${wsProtocol}${base}?${queryParams}`;
|
|
}
|
|
}
|