mirror of
https://github.com/tailscale/tailscale.git
synced 2025-06-12 18:58:36 +00:00

This commit makes some restructural changes to how we handle api posting from the web client frontend. Now that we're using SWR, we have less of a need for hooks like useNodeData that return a useSWR response alongside some mutation callbacks. SWR makes it easy to mutate throughout the UI without needing access to the original data state in order to reflect updates. So, we can fetch data without having to tie it to post callbacks that have to be passed around through components. In an effort to consolidate our posting endpoints, and make it easier to add more api handlers cleanly in the future, this change introduces a new `useAPI` hook that returns a single `api` callback that can make any changes from any component in the UI. The hook itself handles using SWR to mutate the relevant data keys, which get globally reflected throughout the UI. As a concurrent cleanup, node types are also moved to their own types.ts file, to consolidate data types across the app. Updates #10261 Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
58 lines
1.3 KiB
TypeScript
58 lines
1.3 KiB
TypeScript
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
import React from "react"
|
|
import { NodeData } from "src/types"
|
|
|
|
/**
|
|
* AdminContainer renders its contents only if the node's control
|
|
* server has an admin panel.
|
|
*
|
|
* TODO(sonia,will): Similarly, this could also hide the contents
|
|
* if the viewing user is a non-admin.
|
|
*/
|
|
export function AdminContainer({
|
|
node,
|
|
children,
|
|
className,
|
|
}: {
|
|
node: NodeData
|
|
children: React.ReactNode
|
|
className?: string
|
|
}) {
|
|
if (!node.ControlAdminURL.includes("tailscale.com")) {
|
|
// Admin panel only exists on Tailscale control servers.
|
|
return null
|
|
}
|
|
return <div className={className}>{children}</div>
|
|
}
|
|
|
|
/**
|
|
* AdminLink renders its contents wrapped in a link to the node's control
|
|
* server admin panel.
|
|
*
|
|
* AdminLink is meant for use only inside of a AdminContainer component,
|
|
* to avoid rendering a link when the node's control server does not have
|
|
* an admin panel.
|
|
*/
|
|
export function AdminLink({
|
|
node,
|
|
children,
|
|
path,
|
|
}: {
|
|
node: NodeData
|
|
children: React.ReactNode
|
|
path: string // admin path, e.g. "/settings/webhooks"
|
|
}) {
|
|
return (
|
|
<a
|
|
href={`${node.ControlAdminURL}${path}`}
|
|
className="link"
|
|
target="_blank"
|
|
rel="noreferrer"
|
|
>
|
|
{children}
|
|
</a>
|
|
)
|
|
}
|