client/web: add visual indication for exit node pending approval (#10532)

Add visual indication when running as an exit node prior to receiving
admin approval.

Updates https://github.com/tailscale/tailscale/issues/10261

Signed-off-by: Mario Minardi <mario@tailscale.com>
Co-authored-by: Sonia Appasamy <sonia@tailscale.com>
This commit is contained in:
Mario Minardi
2023-12-11 13:40:29 -07:00
committed by GitHub
parent e9f203d747
commit 763b9daa84
4 changed files with 42 additions and 8 deletions

View File

@@ -14,6 +14,7 @@ import useExitNodes, {
import { ExitNode, NodeData } from "src/types"
import Popover from "src/ui/popover"
import SearchInput from "src/ui/search-input"
import { useSWRConfig } from "swr"
export default function ExitNodeSelector({
className,
@@ -27,7 +28,14 @@ export default function ExitNodeSelector({
const api = useAPI()
const [open, setOpen] = useState<boolean>(false)
const [selected, setSelected] = useState<ExitNode>(toSelectedExitNode(node))
const [pending, setPending] = useState<boolean>(false)
const { mutate } = useSWRConfig() // allows for global mutation
useEffect(() => setSelected(toSelectedExitNode(node)), [node])
useEffect(() => {
setPending(
node.AdvertisingExitNode && node.AdvertisingExitNodeApproved === false
)
}, [node])
const handleSelect = useCallback(
(n: ExitNode) => {
@@ -35,9 +43,18 @@ export default function ExitNodeSelector({
if (n.ID === selected.ID) {
return // no update
}
// Eager clear of pending state to avoid UI oddities
if (n.ID !== runAsExitNode.ID) {
setPending(false)
}
api({ action: "update-exit-node", data: n })
// refresh data after short timeout to pick up any pending approval updates
setTimeout(() => {
mutate("/data")
}, 1000)
},
[api, selected]
[api, mutate, selected.ID]
)
const [
@@ -52,7 +69,7 @@ export default function ExitNodeSelector({
selected.ID !== noExitNode.ID && selected.ID !== runAsExitNode.ID,
!selected.Online,
],
[selected]
[selected.ID, selected.Online]
)
return (
@@ -61,6 +78,7 @@ export default function ExitNodeSelector({
"rounded-md",
{
"bg-red-600": offline,
"bg-yellow-400": pending,
},
className
)}
@@ -160,6 +178,12 @@ export default function ExitNodeSelector({
blocked until you disable the exit node or select a different one.
</p>
)}
{pending && (
<p className="text-white p-3">
Pending approval to run as exit node. This device won't be usable as
an exit node until then.
</p>
)}
</div>
)
}