mirror of
https://github.com/tailscale/tailscale.git
synced 2025-12-28 22:19:48 +00:00
client/web: add confirmation dialogs
Add confirmation dialogs for disconnecting and stopping advertisement of a subnet route. Updates #10261 Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This commit is contained in:
committed by
Sonia Appasamy
parent
69b56462fc
commit
a4c7b0574a
@@ -73,6 +73,11 @@ function WebClient({
|
||||
currentVersion={node.IPNVersion}
|
||||
/>
|
||||
</FeatureRoute>
|
||||
<Route path="/disconnected">
|
||||
<Card className="mt-8">
|
||||
<EmptyState description="You have been disconnected" />
|
||||
</Card>
|
||||
</Route>
|
||||
<Route>
|
||||
<Card className="mt-8">
|
||||
<EmptyState description="Page not found" />
|
||||
@@ -129,6 +134,11 @@ function Header({
|
||||
}) {
|
||||
const [loc] = useLocation()
|
||||
|
||||
if (loc === "/disconnected") {
|
||||
// No header on view presented after logout.
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-wrap gap-4 justify-between items-center mb-9 md:mb-12">
|
||||
|
||||
@@ -11,6 +11,7 @@ import { UpdateAvailableNotification } from "src/components/update-available"
|
||||
import { NodeData } from "src/types"
|
||||
import Button from "src/ui/button"
|
||||
import Card from "src/ui/card"
|
||||
import Dialog from "src/ui/dialog"
|
||||
import QuickCopy from "src/ui/quick-copy"
|
||||
import { useLocation } from "wouter"
|
||||
|
||||
@@ -21,9 +22,6 @@ export default function DeviceDetailsView({
|
||||
readonly: boolean
|
||||
node: NodeData
|
||||
}) {
|
||||
const api = useAPI()
|
||||
const [, setLocation] = useLocation()
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1 className="mb-10">Device details</h1>
|
||||
@@ -39,16 +37,7 @@ export default function DeviceDetailsView({
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
{!readonly && (
|
||||
<Button
|
||||
sizeVariant="small"
|
||||
onClick={() =>
|
||||
api({ action: "logout" }).then(() => setLocation("/"))
|
||||
}
|
||||
>
|
||||
Disconnect…
|
||||
</Button>
|
||||
)}
|
||||
{!readonly && <DisconnectDialog />}
|
||||
</div>
|
||||
</Card>
|
||||
{node.Features["auto-update"] &&
|
||||
@@ -210,3 +199,33 @@ export default function DeviceDetailsView({
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function DisconnectDialog() {
|
||||
const api = useAPI()
|
||||
const [, setLocation] = useLocation()
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
className="max-w-md"
|
||||
title="Disconnect"
|
||||
trigger={<Button sizeVariant="small">Disconnect…</Button>}
|
||||
>
|
||||
<Dialog.Form
|
||||
cancelButton
|
||||
submitButton="Disconnect"
|
||||
destructive
|
||||
onSubmit={() => {
|
||||
api({ action: "logout" })
|
||||
setLocation("/disconnected")
|
||||
}}
|
||||
>
|
||||
You are about to disconnect this device from your tailnet. To reconnect,
|
||||
you will be required to re-authenticate this device.
|
||||
<p className="mt-4 text-sm text-text-muted">
|
||||
Your connection to this web interface will end as soon as you click
|
||||
disconnect.
|
||||
</p>
|
||||
</Dialog.Form>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import * as Control from "src/components/control-components"
|
||||
import { NodeData } from "src/types"
|
||||
import Button from "src/ui/button"
|
||||
import Card from "src/ui/card"
|
||||
import Dialog from "src/ui/dialog"
|
||||
import EmptyState from "src/ui/empty-state"
|
||||
import Input from "src/ui/input"
|
||||
|
||||
@@ -139,9 +140,8 @@ export default function SubnetRouterView({
|
||||
)}
|
||||
</div>
|
||||
{!readonly && (
|
||||
<Button
|
||||
sizeVariant="small"
|
||||
onClick={() =>
|
||||
<StopAdvertisingDialog
|
||||
onSubmit={() =>
|
||||
api({
|
||||
action: "update-routes",
|
||||
data: advertisedRoutes.filter(
|
||||
@@ -149,9 +149,7 @@ export default function SubnetRouterView({
|
||||
),
|
||||
})
|
||||
}
|
||||
>
|
||||
Stop advertising…
|
||||
</Button>
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -179,3 +177,22 @@ export default function SubnetRouterView({
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function StopAdvertisingDialog({ onSubmit }: { onSubmit: () => void }) {
|
||||
return (
|
||||
<Dialog
|
||||
className="max-w-md"
|
||||
title="Stop advertising route"
|
||||
trigger={<Button sizeVariant="small">Stop advertising…</Button>}
|
||||
>
|
||||
<Dialog.Form
|
||||
cancelButton
|
||||
submitButton="Stop advertising"
|
||||
destructive
|
||||
onSubmit={onSubmit}
|
||||
>
|
||||
Any active connections between devices over this route will be broken.
|
||||
</Dialog.Form>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user