Skip to content

Commit 61648cb

Browse files
committed
add support for web terminal
1 parent 438b7a6 commit 61648cb

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

site/src/api/api.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import type dayjs from "dayjs";
2424
import userAgentParser from "ua-parser-js";
2525
import { delay } from "../utils/delay";
2626
import * as TypesGen from "./typesGenerated";
27+
import { PostWorkspaceUsageRequest } from "./typesGenerated";
2728

2829
const getMissingParameters = (
2930
oldBuildParameters: TypesGen.WorkspaceBuildParameter[],
@@ -1879,6 +1880,15 @@ class ApiMethods {
18791880
throw error;
18801881
}
18811882
};
1883+
1884+
postWorkspaceUsage = async (workspaceID: string, options: PostWorkspaceUsageRequest) => {
1885+
const response = await this.axios.post(
1886+
`/api/v2/workspaces/${workspaceID}/usage`,
1887+
options,
1888+
);
1889+
1890+
return response.data;
1891+
};
18821892
}
18831893

18841894
// This is a hard coded CSRF token/cookie pair for local development. In prod,

site/src/api/queries/workspaces.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { type DeleteWorkspaceOptions, API } from "api/api";
88
import type {
99
CreateWorkspaceRequest,
1010
ProvisionerLogLevel,
11+
UsageAppName,
1112
Workspace,
1213
WorkspaceBuild,
1314
WorkspaceBuildParameter,
@@ -16,6 +17,7 @@ import type {
1617
} from "api/typesGenerated";
1718
import { disabledRefetchOptions } from "./util";
1819
import { workspaceBuildsKey } from "./workspaceBuilds";
20+
import { Terminal } from "xterm";
1921

2022
export const workspaceByOwnerAndNameKey = (owner: string, name: string) => [
2123
"workspace",
@@ -313,3 +315,35 @@ export const agentLogs = (workspaceId: string, agentId: string) => {
313315
...disabledRefetchOptions,
314316
};
315317
};
318+
319+
// workspace usage options
320+
export interface WorkspaceUsageOptions {
321+
usageApp: UsageAppName;
322+
terminal: Terminal | undefined;
323+
workspaceId: string | undefined;
324+
agentId: string | undefined;
325+
}
326+
327+
export const workspaceUsage = (options: WorkspaceUsageOptions) => {
328+
return {
329+
queryKey: [
330+
"workspaces", options.workspaceId,
331+
"agents", options.agentId,
332+
"usage", options.usageApp,
333+
],
334+
enabled: options.terminal !== undefined && options.workspaceId !== undefined && options.agentId !== undefined,
335+
queryFn: () => {
336+
if (options.terminal === undefined || options.workspaceId === undefined || options.agentId === undefined) {
337+
return Promise.reject();
338+
}
339+
340+
return API.postWorkspaceUsage(options.workspaceId, {
341+
agent_id: options.agentId,
342+
app_name: options.usageApp,
343+
})
344+
},
345+
// ...disabledRefetchOptions,
346+
refetchInterval: 60000,
347+
refetchIntervalInBackground: true,
348+
};
349+
}

site/src/pages/TerminalPage/TerminalPage.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { Unicode11Addon } from "xterm-addon-unicode11";
1212
import { WebLinksAddon } from "xterm-addon-web-links";
1313
import { WebglAddon } from "xterm-addon-webgl";
1414
import { deploymentConfig } from "api/queries/deployment";
15-
import { workspaceByOwnerAndName } from "api/queries/workspaces";
15+
import { workspaceByOwnerAndName, workspaceUsage } from "api/queries/workspaces";
1616
import { useProxy } from "contexts/ProxyContext";
1717
import { ThemeOverride } from "contexts/ThemeProvider";
1818
import themes from "theme";
@@ -67,6 +67,16 @@ const TerminalPage: FC = () => {
6767
const config = useQuery(deploymentConfig());
6868
const renderer = config.data?.config.web_terminal_renderer;
6969

70+
// Periodically report workspace usage.
71+
useQuery(
72+
workspaceUsage({
73+
usageApp: "reconnecting-pty",
74+
terminal,
75+
workspaceId: workspace.data?.id,
76+
agentId: workspaceAgent?.id,
77+
})
78+
);
79+
7080
// handleWebLink handles opening of URLs in the terminal!
7181
const handleWebLink = useCallback(
7282
(uri: string) => {

0 commit comments

Comments
 (0)