Skip to content

feat: add spinner to latencies when refetching #8278

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 2 commits into from
Jul 5, 2023
Merged
Show file tree
Hide file tree
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
4 changes: 2 additions & 2 deletions site/src/components/AppLink/AppLink.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ const Template: Story<AppLinkProps> = (args) => (
clearProxy: () => {
return
},
refetchProxyLatencies: () => {
return
refetchProxyLatencies: (): Date => {
return new Date()
},
}}
>
Expand Down
30 changes: 28 additions & 2 deletions site/src/components/Navbar/NavbarView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ const ProxyMenu: FC<{ proxyContextValue: ProxyContextValue }> = ({
}) => {
const buttonRef = useRef<HTMLButtonElement>(null)
const [isOpen, setIsOpen] = useState(false)
const [refetchDate, setRefetchDate] = useState<Date>()
const selectedProxy = proxyContextValue.proxy.proxy
const refreshLatencies = proxyContextValue.refetchProxyLatencies
const closeMenu = () => setIsOpen(false)
Expand All @@ -196,6 +197,26 @@ const ProxyMenu: FC<{ proxyContextValue: ProxyContextValue }> = ({
const isLoadingLatencies = Object.keys(latencies).length === 0
const isLoading = proxyContextValue.isLoading || isLoadingLatencies
const permissions = usePermissions()
const proxyLatencyLoading = (proxy: TypesGen.Region): boolean => {
if (!refetchDate) {
// Only show loading if the user manually requested a refetch
return false
}

const latency = latencies?.[proxy.id]
// Only show a loading spinner if:
// - A latency exists. This means the latency was fetched at some point, so the
// loader *should* be resolved.
// - The proxy is healthy. If it is not, the loader might never resolve.
// - The latency reported is older than the refetch date. This means the latency
// is stale and we should show a loading spinner until the new latency is
// fetched.
if (proxy.healthy && latency && latency.at < refetchDate) {
return true
}

return false
}

if (isLoading) {
return (
Expand Down Expand Up @@ -234,6 +255,7 @@ const ProxyMenu: FC<{ proxyContextValue: ProxyContextValue }> = ({
{selectedProxy.display_name}
<ProxyStatusLatency
latency={latencies?.[selectedProxy.id]?.latencyMS}
isLoading={proxyLatencyLoading(selectedProxy)}
/>
</Box>
) : (
Expand Down Expand Up @@ -277,7 +299,10 @@ const ProxyMenu: FC<{ proxyContextValue: ProxyContextValue }> = ({
/>
</Box>
{proxy.display_name}
<ProxyStatusLatency latency={latencies?.[proxy.id]?.latencyMS} />
<ProxyStatusLatency
latency={latencies?.[proxy.id]?.latencyMS}
isLoading={proxyLatencyLoading(proxy)}
/>
</Box>
</MenuItem>
))}
Expand All @@ -298,7 +323,8 @@ const ProxyMenu: FC<{ proxyContextValue: ProxyContextValue }> = ({
// Stop the menu from closing
e.stopPropagation()
// Refresh the latencies.
refreshLatencies()
const refetchDate = refreshLatencies()
setRefetchDate(refetchDate)
}}
>
Refresh Latencies
Expand Down
20 changes: 19 additions & 1 deletion site/src/components/ProxyStatusLatency/ProxyStatusLatency.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,29 @@ import Box from "@mui/material/Box"
import Tooltip from "@mui/material/Tooltip"
import { FC } from "react"
import { getLatencyColor } from "utils/latency"
import CircularProgress from "@mui/material/CircularProgress"

export const ProxyStatusLatency: FC<{ latency?: number }> = ({ latency }) => {
export const ProxyStatusLatency: FC<{
latency?: number
isLoading?: boolean
}> = ({ latency, isLoading }) => {
const theme = useTheme()
const color = getLatencyColor(theme, latency)

if (isLoading) {
return (
<Tooltip title="Loading latency...">
<CircularProgress
size="14px"
sx={{
// Always use the no latency color for loading.
color: getLatencyColor(theme, undefined),
}}
/>
</Tooltip>
)
}

if (!latency) {
return (
<Tooltip title="Latency not available">
Expand Down
4 changes: 2 additions & 2 deletions site/src/components/Resources/AgentRow.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ const TemplateFC = (
clearProxy: () => {
return
},
refetchProxyLatencies: () => {
return
refetchProxyLatencies: (): Date => {
return new Date()
},
}}
>
Expand Down
8 changes: 4 additions & 4 deletions site/src/components/Resources/ResourceCard.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ Example.args = {
clearProxy: () => {
return
},
refetchProxyLatencies: () => {
return
refetchProxyLatencies: (): Date => {
return new Date()
},
}}
>
Expand Down Expand Up @@ -106,8 +106,8 @@ BunchOfMetadata.args = {
clearProxy: () => {
return
},
refetchProxyLatencies: () => {
return
refetchProxyLatencies: (): Date => {
return new Date()
},
}}
>
Expand Down
4 changes: 2 additions & 2 deletions site/src/components/Workspace/Workspace.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ const meta: Meta<typeof Workspace> = {
setProxy: () => {
return
},
refetchProxyLatencies: () => {
return
refetchProxyLatencies: (): Date => {
return new Date()
},
}}
>
Expand Down
2 changes: 1 addition & 1 deletion site/src/contexts/ProxyContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export interface ProxyContextValue {
proxyLatencies: Record<string, ProxyLatencyReport>
// refetchProxyLatencies will trigger refreshing of the proxy latencies. By default the latencies
// are loaded once.
refetchProxyLatencies: () => void
refetchProxyLatencies: () => Date
// setProxy is a function that sets the user's selected proxy. This function should
// only be called if the user is manually selecting a proxy. This value is stored in local
// storage and will persist across reloads and tabs.
Expand Down