mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix(site): fix web terminal bottom overflow (#12228)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { type Interpolation, type Theme, useTheme } from "@emotion/react";
|
||||
import { type Interpolation, type Theme } from "@emotion/react";
|
||||
import { type FC, useCallback, useEffect, useRef, useState } from "react";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
|
||||
@@ -13,9 +13,6 @@ import "xterm/css/xterm.css";
|
||||
import { MONOSPACE_FONT_FAMILY } from "theme/constants";
|
||||
import { pageTitle } from "utils/page";
|
||||
import { useProxy } from "contexts/ProxyContext";
|
||||
import type { Region } from "api/typesGenerated";
|
||||
import { getLatencyColor } from "utils/latency";
|
||||
import { ProxyStatusLatency } from "components/ProxyStatusLatency/ProxyStatusLatency";
|
||||
import { openMaybePortForwardedURL } from "utils/portForward";
|
||||
import { terminalWebsocketUrl } from "utils/terminal";
|
||||
import { getMatchingAgentOrFirst } from "utils/workspace";
|
||||
@@ -28,11 +25,6 @@ import {
|
||||
import { useQuery } from "react-query";
|
||||
import { deploymentConfig } from "api/queries/deployment";
|
||||
import { workspaceByOwnerAndName } from "api/queries/workspaces";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "components/Popover/Popover";
|
||||
import { ThemeOverride } from "contexts/ThemeProvider";
|
||||
import themes from "theme";
|
||||
|
||||
@@ -57,6 +49,7 @@ const TerminalPage: FC = () => {
|
||||
"connected" | "disconnected" | "initializing"
|
||||
>("initializing");
|
||||
const [searchParams] = useSearchParams();
|
||||
const isDebugging = searchParams.has("debug");
|
||||
// The reconnection token is a unique token that identifies
|
||||
// a terminal session. It's generated by the client to reduce
|
||||
// a round-trip, and must be a UUIDv4.
|
||||
@@ -316,126 +309,36 @@ const TerminalPage: FC = () => {
|
||||
prevLifecycleState.current === "starting" && <LoadedScriptsAlert />}
|
||||
{terminalState === "disconnected" && <DisconnectedAlert />}
|
||||
<div css={styles.terminal} ref={xtermRef} data-testid="terminal" />
|
||||
{selectedProxy && latency && (
|
||||
<BottomBar proxy={selectedProxy} latency={latency.latencyMS} />
|
||||
)}
|
||||
</div>
|
||||
</ThemeOverride>
|
||||
);
|
||||
};
|
||||
|
||||
interface BottomBarProps {
|
||||
proxy: Region;
|
||||
latency?: number;
|
||||
}
|
||||
|
||||
const BottomBar: FC<BottomBarProps> = ({ proxy, latency }) => {
|
||||
const theme = useTheme();
|
||||
const color = getLatencyColor(theme, latency);
|
||||
|
||||
return (
|
||||
<div
|
||||
css={{
|
||||
padding: "0 16px",
|
||||
background: theme.palette.background.paper,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-end",
|
||||
fontSize: 12,
|
||||
borderTop: `1px solid ${theme.palette.divider}`,
|
||||
}}
|
||||
>
|
||||
<Popover mode="hover">
|
||||
<PopoverTrigger>
|
||||
<button
|
||||
aria-label="Terminal latency"
|
||||
aria-haspopup="true"
|
||||
css={{
|
||||
background: "none",
|
||||
cursor: "pointer",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 8,
|
||||
border: 0,
|
||||
padding: 8,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
css={{
|
||||
height: 6,
|
||||
width: 6,
|
||||
backgroundColor: color,
|
||||
border: 0,
|
||||
borderRadius: 3,
|
||||
}}
|
||||
/>
|
||||
<ProxyStatusLatency latency={latency} />
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
id="latency-popover"
|
||||
disableRestoreFocus
|
||||
{latency && isDebugging && (
|
||||
<span
|
||||
css={{
|
||||
pointerEvents: "none",
|
||||
"& .MuiPaper-root": {
|
||||
padding: "8px 16px",
|
||||
},
|
||||
}}
|
||||
anchorOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "right",
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: "bottom",
|
||||
horizontal: "right",
|
||||
position: "absolute",
|
||||
bottom: 24,
|
||||
right: 24,
|
||||
color: theme.palette.text.disabled,
|
||||
fontSize: 14,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
css={{
|
||||
fontSize: 13,
|
||||
color: theme.palette.text.secondary,
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
Selected proxy
|
||||
</div>
|
||||
<div
|
||||
css={{
|
||||
fontSize: 14,
|
||||
display: "flex",
|
||||
gap: 3,
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<div css={{ display: "flex", alignItems: "center", gap: 1 }}>
|
||||
<div css={{ width: 12, height: 12, lineHeight: 0 }}>
|
||||
<img
|
||||
src={proxy.icon_url}
|
||||
alt=""
|
||||
css={{ objectFit: "contain", width: "100%", height: "100%" }}
|
||||
/>
|
||||
</div>
|
||||
{proxy.display_name}
|
||||
</div>
|
||||
<ProxyStatusLatency latency={latency} />
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
Latency: {latency.latencyMS.toFixed(0)}ms
|
||||
</span>
|
||||
)}
|
||||
</ThemeOverride>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = {
|
||||
terminal: (theme) => ({
|
||||
width: "100vw",
|
||||
width: "100%",
|
||||
overflow: "hidden",
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
flex: 1,
|
||||
// These styles attempt to mimic the VS Code scrollbar.
|
||||
"& .xterm": {
|
||||
padding: 4,
|
||||
width: "100vw",
|
||||
height: "100vh",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
},
|
||||
"& .xterm-viewport": {
|
||||
// This is required to force full-width on the terminal.
|
||||
|
||||
Reference in New Issue
Block a user