Skip to content

fix(site): fix web terminal bottom overflow #12228

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 21, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 16 additions & 113 deletions site/src/pages/TerminalPage/TerminalPage.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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";
Expand All @@ -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";

Expand All @@ -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.
Expand Down Expand Up @@ -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%",
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not use screen sizes here since the .term should fit the parent size.

},
"& .xterm-viewport": {
// This is required to force full-width on the terminal.
Expand Down