Skip to content

Commit b2e3efb

Browse files
committed
Some basic selector for proxies
1 parent 1daa32f commit b2e3efb

File tree

3 files changed

+119
-92
lines changed

3 files changed

+119
-92
lines changed

site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyPage.tsx

+33-10
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import { FC, PropsWithChildren } from "react"
1+
import { FC, PropsWithChildren, useState } from "react"
22
import { Section } from "components/SettingsLayout/Section"
33
import { WorkspaceProxyPageView } from "./WorkspaceProxyView"
44
import makeStyles from "@material-ui/core/styles/makeStyles"
55
import { useTranslation, Trans } from "react-i18next"
66
import { useWorkspaceProxiesData } from "./hooks"
7+
import { Region } from "api/typesGenerated"
8+
import { displayError } from "components/GlobalSnackbar/utils"
79
// import { ConfirmDeleteDialog } from "./components"
810
// import { Stack } from "components/Stack/Stack"
911
// import Button from "@material-ui/core/Button"
@@ -23,9 +25,7 @@ export const WorkspaceProxyPage: FC<PropsWithChildren<unknown>> = () => {
2325
</Trans>
2426
)
2527

26-
// const [tokenToDelete, setTokenToDelete] = useState<
27-
// APIKeyWithOwner | undefined
28-
// >(undefined)
28+
const [preferred, setPreffered] = useState(getPreferredProxy())
2929

3030
const {
3131
data: response,
@@ -47,16 +47,17 @@ export const WorkspaceProxyPage: FC<PropsWithChildren<unknown>> = () => {
4747
isLoading={isFetching}
4848
hasLoaded={isFetched}
4949
getWorkspaceProxiesError={getProxiesError}
50+
preferredProxy={preferred}
5051
onSelect={(proxy) => {
51-
console.log("selected", proxy)
52+
if (!proxy.healthy) {
53+
displayError("Please select a healthy workspace proxy.")
54+
return
55+
}
56+
savePreferredProxy(proxy)
57+
setPreffered(proxy)
5258
}}
5359
/>
5460
</Section>
55-
{/* <ConfirmDeleteDialog
56-
queryKey={queryKey}
57-
token={tokenToDelete}
58-
setToken={setTokenToDelete}
59-
/> */}
6061
</>
6162
)
6263
}
@@ -77,3 +78,25 @@ const useStyles = makeStyles((theme) => ({
7778
}))
7879

7980
export default WorkspaceProxyPage
81+
82+
83+
// Exporting to be used in the tests
84+
export const savePreferredProxy = (proxy: Region): void => {
85+
window.localStorage.setItem("preferred-proxy", JSON.stringify(proxy))
86+
}
87+
88+
export const getPreferredProxy = (): Region | undefined => {
89+
const str = localStorage.getItem("preferred-proxy")
90+
if (str === undefined || str === null) {
91+
return undefined
92+
}
93+
const proxy = JSON.parse(str)
94+
if (proxy.id === undefined || proxy.id === null) {
95+
return undefined
96+
}
97+
return proxy
98+
}
99+
100+
export const clearPreferredProxy = (): void => {
101+
localStorage.removeItem("preferred-proxy")
102+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { Region } from "api/typesGenerated"
2+
import { AvatarData } from "components/AvatarData/AvatarData"
3+
import { Avatar } from "components/Avatar/Avatar"
4+
import { useClickableTableRow } from "hooks/useClickableTableRow"
5+
import TableCell from "@material-ui/core/TableCell"
6+
import TableRow from "@material-ui/core/TableRow"
7+
import { FC } from "react"
8+
import { HealthyBadge, NotHealthyBadge } from "components/DeploySettingsLayout/Badges"
9+
import { makeStyles } from "@material-ui/core/styles"
10+
import { combineClasses } from "utils/combineClasses"
11+
12+
13+
export const ProxyRow: FC<{
14+
proxy: Region
15+
onSelectRegion: (proxy: Region) => void
16+
preferred: boolean
17+
}> = ({ proxy, onSelectRegion, preferred }) => {
18+
const styles = useStyles()
19+
20+
const clickable = useClickableTableRow(() => {
21+
onSelectRegion(proxy)
22+
})
23+
24+
const classes = [
25+
clickable.className,
26+
]
27+
28+
if (preferred) {
29+
classes.push(styles.preferredrow)
30+
}
31+
32+
return <TableRow
33+
key={proxy.name}
34+
data-testid={`${proxy.name}`}
35+
{...clickable}
36+
// Make sure to include our classname here.
37+
className={combineClasses(classes)}
38+
>
39+
<TableCell>
40+
<AvatarData
41+
title={
42+
proxy.display_name && proxy.display_name.length > 0
43+
? proxy.display_name
44+
: proxy.name
45+
}
46+
avatar={
47+
proxy.icon_url !== "" && <Avatar src={proxy.icon_url} variant="square" fitImage />
48+
}
49+
/>
50+
</TableCell>
51+
52+
<TableCell>{proxy.path_app_url}</TableCell>
53+
<TableCell><ProxyStatus proxy={proxy} /></TableCell>
54+
</TableRow>
55+
}
56+
57+
const ProxyStatus: FC<{
58+
proxy: Region
59+
}> = ({ proxy }) => {
60+
let icon = <NotHealthyBadge />
61+
if (proxy.healthy) {
62+
icon = <HealthyBadge />
63+
}
64+
65+
return icon
66+
}
67+
68+
const useStyles = makeStyles((theme) => ({
69+
preferredrow: {
70+
// TODO: What color should I put here?
71+
backgroundColor: theme.palette.secondary.main,
72+
outline: `3px solid ${theme.palette.secondary.light}`,
73+
outlineOffset: -3,
74+
},
75+
}))

site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.tsx

+11-82
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,9 @@ import { TableEmpty } from "components/TableEmpty/TableEmpty"
1111
import { TableLoader } from "components/TableLoader/TableLoader"
1212
import { FC } from "react"
1313
import { AlertBanner } from "components/AlertBanner/AlertBanner"
14-
import IconButton from "@material-ui/core/IconButton/IconButton"
1514
import { useTranslation } from "react-i18next"
1615
import { Region } from "api/typesGenerated"
17-
import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';
18-
import { Avatar } from "components/Avatar/Avatar"
19-
import { AvatarData } from "components/AvatarData/AvatarData"
20-
import { HealthyBadge, NotHealthyBadge } from "components/DeploySettingsLayout/Badges"
16+
import { ProxyRow } from "./WorkspaceProxyRow"
2117

2218

2319

@@ -27,6 +23,7 @@ export interface WorkspaceProxyPageViewProps {
2723
isLoading: boolean
2824
hasLoaded: boolean
2925
onSelect: (proxy: Region) => void
26+
preferredProxy?: Region
3027
selectProxyError?: Error | unknown
3128
}
3229

@@ -39,8 +36,8 @@ export const WorkspaceProxyPageView: FC<
3936
hasLoaded,
4037
onSelect,
4138
selectProxyError,
39+
preferredProxy,
4240
}) => {
43-
const theme = useTheme()
4441
const { t } = useTranslation("proxyPage")
4542

4643
return (
@@ -58,7 +55,6 @@ export const WorkspaceProxyPageView: FC<
5855
<TableCell width="40%">{t("table.icon")}</TableCell>
5956
<TableCell width="30%">{t("table.url")}</TableCell>
6057
<TableCell width="10%">{t("table.status")}</TableCell>
61-
<TableCell width="0%"></TableCell>
6258
</TableRow>
6359
</TableHead>
6460
<TableBody>
@@ -70,67 +66,14 @@ export const WorkspaceProxyPageView: FC<
7066
<TableEmpty message={t("emptyState")} />
7167
</Cond>
7268
<Cond>
73-
{proxies?.map((proxy) => {
74-
return (
75-
<TableRow
76-
key={proxy.name}
77-
data-testid={`${proxy.name}`}
78-
tabIndex={0}
79-
>
80-
<TableCell>
81-
<AvatarData
82-
title={
83-
proxy.display_name && proxy.display_name.length > 0
84-
? proxy.display_name
85-
: proxy.name
86-
}
87-
// subtitle={proxy.description}
88-
avatar={
89-
proxy.icon_url !== "" && <Avatar src={proxy.icon_url} variant="square" fitImage />
90-
}
91-
/>
92-
</TableCell>
93-
94-
{/* <TableCell>
95-
<span style={{ color: theme.palette.text.secondary }}>
96-
{proxy.name}
97-
</span>
98-
</TableCell> */}
99-
100-
<TableCell>{proxy.path_app_url}</TableCell>
101-
{/* <TableCell>{lastUsedOrNever(token.last_used)}</TableCell> */}
102-
{/* <TableCell>{proxy.wildcard_hostname}</TableCell> */}
103-
{/* <TableCell>
104-
<span
105-
style={{ color: theme.palette.text.secondary }}
106-
data-chromatic="ignore"
107-
>
108-
{dayjs(token.expires_at).fromNow()}
109-
</span>
110-
</TableCell> */}
111-
<TableCell><ProxyStatus proxy={proxy} /></TableCell>
112-
{/* <TableCell>
113-
<span style={{ color: theme.palette.text.secondary }}>
114-
{dayjs(token.created_at).fromNow()}
115-
</span>
116-
</TableCell> */}
117-
118-
<TableCell>
119-
<span style={{ color: theme.palette.text.secondary }}>
120-
<IconButton
121-
onClick={() => {
122-
onSelect(proxy)
123-
}}
124-
size="medium"
125-
aria-label={t("proxyActions.selectProxy.select")}
126-
>
127-
<CheckBoxOutlineBlankIcon />
128-
</IconButton>
129-
</span>
130-
</TableCell>
131-
</TableRow>
132-
)
133-
})}
69+
{proxies?.map((proxy) => (
70+
<ProxyRow
71+
key={proxy.id}
72+
proxy={proxy}
73+
onSelectRegion={onSelect}
74+
preferred={preferredProxy ? proxy.id === preferredProxy.id : false}
75+
/>
76+
))}
13477
</Cond>
13578
</ChooseOne>
13679
</TableBody>
@@ -139,17 +82,3 @@ export const WorkspaceProxyPageView: FC<
13982
</Stack>
14083
)
14184
}
142-
143-
144-
export interface WorkspaceProxyStatusProps {
145-
proxy: Region
146-
}
147-
148-
const ProxyStatus: FC<React.PropsWithChildren<WorkspaceProxyStatusProps>> = ({ proxy }) => {
149-
let icon = <NotHealthyBadge />
150-
if (proxy.healthy) {
151-
icon = <HealthyBadge />
152-
}
153-
154-
return icon
155-
}

0 commit comments

Comments
 (0)