client/web: add device details view
Initial addition of device details view on the frontend. A little more backend piping work to come to fill all of the detail fields, for now using placeholders. Updates tailscale/corp#14335 Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This commit is contained in:
committed by
Sonia Appasamy
parent
3e9026efda
commit
d73e923b73
@@ -0,0 +1,107 @@
|
||||
import React from "react"
|
||||
import { NodeData } from "src/hooks/node-data"
|
||||
import ProfilePic from "src/ui/profile-pic"
|
||||
|
||||
export default function DeviceDetailsView({ node }: { node: NodeData }) {
|
||||
return (
|
||||
<div>
|
||||
<h1 className="mb-10">Device details</h1>
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="card">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<h1>{node.DeviceName}</h1>
|
||||
{/* TODO: connected status */}
|
||||
<div className="w-2.5 h-2.5 bg-emerald-500 rounded-full" />
|
||||
</div>
|
||||
<button className="px-3 py-2 bg-stone-50 rounded shadow border border-stone-200 text-neutral-800 text-sm font-medium">
|
||||
Log out…
|
||||
</button>
|
||||
</div>
|
||||
<hr className="my-5" />
|
||||
<div className="text-neutral-500 text-sm leading-tight mb-1">
|
||||
Managed by
|
||||
</div>
|
||||
<div className="flex">
|
||||
{/* TODO: tags display */}
|
||||
<ProfilePic size="small" url={node.Profile.ProfilePicURL} />
|
||||
<div className="ml-2 text-neutral-800 text-sm leading-tight">
|
||||
{node.Profile.LoginName}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card">
|
||||
<h2 className="mb-2">General</h2>
|
||||
<table>
|
||||
<tbody>
|
||||
{/* TODO: pipe through these values */}
|
||||
<tr>
|
||||
<td>Creator</td>
|
||||
<td>{node.Profile.DisplayName}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Managed by</td>
|
||||
<td>{node.Profile.DisplayName}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Machine name</td>
|
||||
<td>{node.DeviceName}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>OS</td>
|
||||
<td>MacOS</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ID</td>
|
||||
<td>nPKyyg3CNTRL</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tailscale version</td>
|
||||
<td>{node.IPNVersion}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Key expiry</td>
|
||||
<td>3 months from now</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div className="card">
|
||||
<h2 className="mb-2">Addresses</h2>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Tailscale IPv4</td>
|
||||
<td>{node.IP}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tailscale IPv6</td>
|
||||
<td>fd7a:115c:a1e0:ab12:4843:cd96:627a:f179</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Short domain</td>
|
||||
<td>{node.DeviceName}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Full domain</td>
|
||||
<td>{node.DeviceName}.corp.ts.net</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p className="text-neutral-500 text-sm leading-tight text-center">
|
||||
Want even more details? Visit{" "}
|
||||
<a
|
||||
// TODO: pipe control serve url from backend
|
||||
href="https://login.tailscale.com/admin"
|
||||
target="_blank"
|
||||
className="text-indigo-700 text-sm"
|
||||
>
|
||||
this device’s page
|
||||
</a>{" "}
|
||||
in the admin console.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -4,30 +4,18 @@ import { NodeData } from "src/hooks/node-data"
|
||||
import { ReactComponent as ArrowRight } from "src/icons/arrow-right.svg"
|
||||
import { ReactComponent as ChevronDown } from "src/icons/chevron-down.svg"
|
||||
import { ReactComponent as ConnectedDeviceIcon } from "src/icons/connected-device.svg"
|
||||
import { ReactComponent as TailscaleIcon } from "src/icons/tailscale-icon.svg"
|
||||
import ProfilePic from "src/ui/profile-pic"
|
||||
import { Link } from "wouter"
|
||||
|
||||
export default function ManagementClientView(props: NodeData) {
|
||||
return (
|
||||
<div className="px-5 mb-12 w-full">
|
||||
<div className="flex justify-between mb-12">
|
||||
<TailscaleIcon />
|
||||
<div className="flex">
|
||||
<p className="mr-2">{props.Profile.LoginName}</p>
|
||||
<ProfilePic url={props.Profile.ProfilePicURL} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 className="mb-3">This device</h1>
|
||||
|
||||
<div className="mb-12 w-full">
|
||||
<h2 className="mb-3">This device</h2>
|
||||
<div className="-mx-5 card mb-9">
|
||||
<div className="flex justify-between items-center text-lg mb-5">
|
||||
<div className="flex items-center">
|
||||
<ConnectedDeviceIcon />
|
||||
<div className="ml-3">
|
||||
<p className="text-neutral-800 text-lg font-medium leading-snug">
|
||||
{props.DeviceName}
|
||||
</p>
|
||||
<h1>{props.DeviceName}</h1>
|
||||
{/* TODO(sonia): display actual status */}
|
||||
<p className="text-neutral-500 text-sm">Connected</p>
|
||||
</div>
|
||||
@@ -37,23 +25,28 @@ export default function ManagementClientView(props: NodeData) {
|
||||
</p>
|
||||
</div>
|
||||
<ExitNodeSelector className="mb-5" />
|
||||
<a className="text-indigo-500 font-medium leading-snug">
|
||||
<Link
|
||||
className="text-indigo-500 font-medium leading-snug"
|
||||
to="/details"
|
||||
>
|
||||
View device details →
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<h1 className="mb-3">Settings</h1>
|
||||
<h2 className="mb-3">Settings</h2>
|
||||
<SettingsCard
|
||||
link="/subnets"
|
||||
className="mb-3"
|
||||
title="Subnet router"
|
||||
body="Add devices to your tailnet without installing Tailscale on them."
|
||||
/>
|
||||
<SettingsCard
|
||||
link="/ssh"
|
||||
className="mb-3"
|
||||
title="Tailscale SSH server"
|
||||
body="Run a Tailscale SSH server on this device and allow other devices in your tailnet to SSH into it."
|
||||
/>
|
||||
<SettingsCard
|
||||
link="/serve"
|
||||
title="Share local content"
|
||||
body="Share local ports, services, and content to your Tailscale network or to the broader internet."
|
||||
/>
|
||||
@@ -79,15 +72,18 @@ function ExitNodeSelector({ className }: { className?: string }) {
|
||||
|
||||
function SettingsCard({
|
||||
title,
|
||||
link,
|
||||
body,
|
||||
className,
|
||||
}: {
|
||||
title: string
|
||||
link: string
|
||||
body: string
|
||||
className?: string
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
<Link
|
||||
to={link}
|
||||
className={cx(
|
||||
"-mx-5 card flex justify-between items-center cursor-pointer",
|
||||
className
|
||||
@@ -102,6 +98,6 @@ function SettingsCard({
|
||||
<div>
|
||||
<ArrowRight className="ml-3" />
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user