mirror of
https://github.com/coder/coder.git
synced 2026-09-21 20:51:01 +08:00
feat: Add latency indicator to the UI (#3846)
With Tailscale, we now get latency of all regions.
This commit is contained in:
@@ -14,7 +14,15 @@ module.exports = {
|
||||
// addons are official and community plugins to extend Storybook.
|
||||
//
|
||||
// SEE: https://storybook.js.org/addons
|
||||
addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
|
||||
addons: [
|
||||
"@storybook/addon-links",
|
||||
{
|
||||
name: "@storybook/addon-essentials",
|
||||
options: {
|
||||
actions: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
// Storybook uses babel under the hood, while we currently use ts-loader.
|
||||
// Sometimes, you may encounter an error in a Storybook that contains syntax
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { Story } from "@storybook/react"
|
||||
import { ResourceAgentLatency, ResourceAgentLatencyProps } from "./ResourceAgentLatency"
|
||||
|
||||
export default {
|
||||
title: "components/ResourceAgentLatency",
|
||||
component: ResourceAgentLatency,
|
||||
}
|
||||
|
||||
const Template: Story<ResourceAgentLatencyProps> = (args) => <ResourceAgentLatency {...args} />
|
||||
|
||||
export const Single = Template.bind({})
|
||||
Single.args = {
|
||||
latency: {
|
||||
"Coder DERP": {
|
||||
latency_ms: 100.52,
|
||||
preferred: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export const Multiple = Template.bind({})
|
||||
Multiple.args = {
|
||||
latency: {
|
||||
Chicago: {
|
||||
latency_ms: 22.25551,
|
||||
preferred: false,
|
||||
},
|
||||
"New York": {
|
||||
latency_ms: 56.1111,
|
||||
preferred: true,
|
||||
},
|
||||
"San Francisco": {
|
||||
latency_ms: 125.11,
|
||||
preferred: false,
|
||||
},
|
||||
Tokyo: {
|
||||
latency_ms: 255,
|
||||
preferred: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import StarIcon from "@material-ui/icons/Star"
|
||||
import React from "react"
|
||||
import { WorkspaceAgent } from "../../api/typesGenerated"
|
||||
import { HelpTooltip, HelpTooltipText } from "../Tooltips/HelpTooltip"
|
||||
|
||||
export interface ResourceAgentLatencyProps {
|
||||
latency: WorkspaceAgent["latency"]
|
||||
}
|
||||
|
||||
export const ResourceAgentLatency: React.FC<ResourceAgentLatencyProps> = (props) => {
|
||||
const styles = useStyles()
|
||||
if (Object.keys(props.latency).length === 0) {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<div className={styles.title}>
|
||||
<b>Latency</b>
|
||||
<HelpTooltip size="small">
|
||||
<HelpTooltipText>
|
||||
Latency from relay servers, used when connections cannot connect peer-to-peer. Star
|
||||
indicates the preferred relay.
|
||||
</HelpTooltipText>
|
||||
</HelpTooltip>
|
||||
</div>
|
||||
{Object.keys(props.latency)
|
||||
.sort()
|
||||
.map((region) => {
|
||||
const value = props.latency[region]
|
||||
return (
|
||||
<div key={region} className={styles.region}>
|
||||
<b>{region}:</b> {Math.round(value.latency_ms * 100) / 100} ms
|
||||
{value.preferred && <StarIcon className={styles.star} />}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
root: {
|
||||
display: "grid",
|
||||
gap: 6,
|
||||
},
|
||||
title: {
|
||||
fontSize: "Something",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
// This ensures that the latency aligns with other columns in the grid.
|
||||
height: 20,
|
||||
},
|
||||
region: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
},
|
||||
star: {
|
||||
width: 14,
|
||||
height: 14,
|
||||
marginLeft: 4,
|
||||
},
|
||||
}))
|
||||
@@ -20,6 +20,7 @@ import { TerminalLink } from "../TerminalLink/TerminalLink"
|
||||
import { AgentHelpTooltip } from "../Tooltips/AgentHelpTooltip"
|
||||
import { AgentOutdatedTooltip } from "../Tooltips/AgentOutdatedTooltip"
|
||||
import { ResourcesHelpTooltip } from "../Tooltips/ResourcesHelpTooltip"
|
||||
import { ResourceAgentLatency } from "./ResourceAgentLatency"
|
||||
import { ResourceAvatarData } from "./ResourceAvatarData"
|
||||
|
||||
const Language = {
|
||||
@@ -129,6 +130,9 @@ export const Resources: FC<React.PropsWithChildren<ResourcesProps>> = ({
|
||||
<span className={styles.agentVersion}>{displayVersion}</span>
|
||||
<AgentOutdatedTooltip outdated={outdated} />
|
||||
</div>
|
||||
<div className={styles.dataRow}>
|
||||
<ResourceAgentLatency latency={agent.latency} />
|
||||
</div>
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
@@ -232,6 +236,7 @@ const useStyles = makeStyles((theme) => ({
|
||||
gridAutoFlow: "row",
|
||||
whiteSpace: "nowrap",
|
||||
gap: theme.spacing(0.75),
|
||||
height: "fit-content",
|
||||
},
|
||||
|
||||
dataRow: {
|
||||
|
||||
@@ -311,7 +311,12 @@ export const MockWorkspaceAgent: TypesGen.WorkspaceAgent = {
|
||||
status: "connected",
|
||||
updated_at: "",
|
||||
version: MockBuildInfo.version,
|
||||
latency: {},
|
||||
latency: {
|
||||
"Coder Embedded DERP": {
|
||||
latency_ms: 32.55,
|
||||
preferred: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export const MockWorkspaceAgentDisconnected: TypesGen.WorkspaceAgent = {
|
||||
@@ -320,6 +325,7 @@ export const MockWorkspaceAgentDisconnected: TypesGen.WorkspaceAgent = {
|
||||
name: "another-workspace-agent",
|
||||
status: "disconnected",
|
||||
version: "",
|
||||
latency: {},
|
||||
}
|
||||
|
||||
export const MockWorkspaceAgentOutdated: TypesGen.WorkspaceAgent = {
|
||||
@@ -328,6 +334,21 @@ export const MockWorkspaceAgentOutdated: TypesGen.WorkspaceAgent = {
|
||||
name: "an-outdated-workspace-agent",
|
||||
version: "v99.999.9998+abcdef",
|
||||
operating_system: "Windows",
|
||||
latency: {
|
||||
...MockWorkspaceAgent.latency,
|
||||
Chicago: {
|
||||
preferred: false,
|
||||
latency_ms: 95.11,
|
||||
},
|
||||
"San Francisco": {
|
||||
preferred: false,
|
||||
latency_ms: 111.55,
|
||||
},
|
||||
Paris: {
|
||||
preferred: false,
|
||||
latency_ms: 221.66,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export const MockWorkspaceAgentConnecting: TypesGen.WorkspaceAgent = {
|
||||
@@ -336,6 +357,7 @@ export const MockWorkspaceAgentConnecting: TypesGen.WorkspaceAgent = {
|
||||
name: "another-workspace-agent",
|
||||
status: "connecting",
|
||||
version: "",
|
||||
latency: {},
|
||||
}
|
||||
|
||||
export const MockWorkspaceResource: TypesGen.WorkspaceResource = {
|
||||
|
||||
Reference in New Issue
Block a user