use standard error alert

This commit is contained in:
miloschwartz
2026-06-04 17:44:45 -07:00
parent 6b04bcb383
commit ff507f1275
3 changed files with 53 additions and 46 deletions

View File

@@ -22,6 +22,7 @@ import {
CardTitle, CardTitle,
CardDescription CardDescription
} from "@app/components/ui/card"; } from "@app/components/ui/card";
import { Alert, AlertDescription } from "@app/components/ui/alert";
import BrandedAuthSurface from "@app/components/BrandedAuthSurface"; import BrandedAuthSurface from "@app/components/BrandedAuthSurface";
import PoweredByPangolin from "@app/components/PoweredByPangolin"; import PoweredByPangolin from "@app/components/PoweredByPangolin";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
@@ -92,6 +93,7 @@ export default function RdpClient({
const [showLogin, setShowLogin] = useState(true); const [showLogin, setShowLogin] = useState(true);
const [moduleReady, setModuleReady] = useState(false); const [moduleReady, setModuleReady] = useState(false);
const [connecting, setConnecting] = useState(false); const [connecting, setConnecting] = useState(false);
const [submitError, setSubmitError] = useState<string | null>(null);
const [unicodeMode, setUnicodeMode] = useState(false); const [unicodeMode, setUnicodeMode] = useState(false);
const [cursorOverrideActive, setCursorOverrideActive] = useState(false); const [cursorOverrideActive, setCursorOverrideActive] = useState(false);
@@ -170,16 +172,13 @@ export default function RdpClient({
}; };
const startSession = async () => { const startSession = async () => {
setSubmitError(null);
setConnecting(true); setConnecting(true);
const userInteraction = userInteractionRef.current; const userInteraction = userInteractionRef.current;
const exts = extensionsRef.current; const exts = extensionsRef.current;
if (!userInteraction || !exts) { if (!userInteraction || !exts) {
setConnecting(false); setConnecting(false);
toast({ setSubmitError(t("rdpModuleInitializing"));
variant: "destructive",
title: t("rdpNotReady"),
description: t("rdpModuleInitializing")
});
return; return;
} }
@@ -241,11 +240,7 @@ export default function RdpClient({
if (!target) { if (!target) {
setConnecting(false); setConnecting(false);
toast({ setSubmitError(t("rdpNoConnectionTarget"));
variant: "destructive",
title: t("browserGatewayNoTarget"),
description: t("rdpNoConnectionTarget")
});
return; return;
} }
@@ -294,17 +289,9 @@ export default function RdpClient({
setConnecting(false); setConnecting(false);
setShowLogin(true); setShowLogin(true);
if (isIronError(err)) { if (isIronError(err)) {
toast({ setSubmitError(err.backtrace());
variant: "destructive",
title: t("rdpConnectionFailed"),
description: err.backtrace()
});
} else { } else {
toast({ setSubmitError(`${err}`);
variant: "destructive",
title: t("rdpConnectionFailed"),
description: `${err}`
});
} }
} }
}; };
@@ -331,7 +318,9 @@ export default function RdpClient({
<CardTitle>{t("rdpTitle")}</CardTitle> <CardTitle>{t("rdpTitle")}</CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<p className="text-destructive text-sm">{error}</p> <Alert variant="destructive">
<AlertDescription>{error}</AlertDescription>
</Alert>
</CardContent> </CardContent>
</Card> </Card>
</BrandedAuthSurface> </BrandedAuthSurface>
@@ -413,6 +402,14 @@ export default function RdpClient({
Enable Clipboard Enable Clipboard
</Label> </Label>
</div> */} </div> */}
{submitError && (
<Alert variant="destructive">
<AlertDescription>
{submitError}
</AlertDescription>
</Alert>
)}
<Button <Button
onClick={startSession} onClick={startSession}
disabled={!moduleReady} disabled={!moduleReady}

View File

@@ -15,7 +15,7 @@ import {
CardDescription CardDescription
} from "@app/components/ui/card"; } from "@app/components/ui/card";
import Link from "next/link"; import Link from "next/link";
import { ExternalLink, Loader2, AlertCircle } from "lucide-react"; import { ExternalLink, Loader2 } from "lucide-react";
import { Alert, AlertDescription } from "@/components/ui/alert"; import { Alert, AlertDescription } from "@/components/ui/alert";
import { HorizontalTabs } from "@app/components/HorizontalTabs"; import { HorizontalTabs } from "@app/components/HorizontalTabs";
import type { SignSshKeyResponse } from "@server/routers/ssh/types"; import type { SignSshKeyResponse } from "@server/routers/ssh/types";
@@ -352,11 +352,7 @@ export default function SshClient({
</div> </div>
)} )}
{connectError && ( {connectError && (
<Alert <Alert variant="destructive" className="w-full">
variant="destructive"
className="w-full"
>
<AlertCircle className="h-5 w-5" />
<AlertDescription> <AlertDescription>
{connectError} {connectError}
</AlertDescription> </AlertDescription>
@@ -388,7 +384,9 @@ export default function SshClient({
<CardTitle>{t("sshTitle")}</CardTitle> <CardTitle>{t("sshTitle")}</CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<p className="text-destructive text-sm">{error}</p> <Alert variant="destructive">
<AlertDescription>{error}</AlertDescription>
</Alert>
</CardContent> </CardContent>
</Card> </Card>
</BrandedAuthSurface> </BrandedAuthSurface>
@@ -447,9 +445,11 @@ export default function SshClient({
</Field> </Field>
<div className="mt-4 space-y-3"> <div className="mt-4 space-y-3">
{connectError && ( {connectError && (
<p className="text-destructive text-sm"> <Alert variant="destructive">
{connectError} <AlertDescription>
</p> {connectError}
</AlertDescription>
</Alert>
)} )}
<Button <Button
@@ -530,9 +530,11 @@ export default function SshClient({
</Field> </Field>
<div className="mt-4 space-y-3"> <div className="mt-4 space-y-3">
{connectError && ( {connectError && (
<p className="text-destructive text-sm"> <Alert variant="destructive">
{connectError} <AlertDescription>
</p> {connectError}
</AlertDescription>
</Alert>
)} )}
<Button <Button

View File

@@ -13,6 +13,7 @@ import {
CardTitle, CardTitle,
CardDescription CardDescription
} from "@app/components/ui/card"; } from "@app/components/ui/card";
import { Alert, AlertDescription } from "@app/components/ui/alert";
import BrandedAuthSurface from "@app/components/BrandedAuthSurface"; import BrandedAuthSurface from "@app/components/BrandedAuthSurface";
import PoweredByPangolin from "@app/components/PoweredByPangolin"; import PoweredByPangolin from "@app/components/PoweredByPangolin";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
@@ -44,6 +45,7 @@ export default function VncClient({
}); });
const [connected, setConnected] = useState(false); const [connected, setConnected] = useState(false);
const [connectError, setConnectError] = useState<string | null>(null);
const rfbRef = useRef<any>(null); const rfbRef = useRef<any>(null);
const screenRef = useRef<HTMLDivElement>(null); const screenRef = useRef<HTMLDivElement>(null);
@@ -66,12 +68,10 @@ export default function VncClient({
}, []); }, []);
const connect = async () => { const connect = async () => {
setConnectError(null);
if (!target) { if (!target) {
toast({ setConnectError(t("vncNoResourceTarget"));
variant: "destructive",
title: t("browserGatewayNoTarget"),
description: t("vncNoResourceTarget")
});
return; return;
} }
@@ -144,15 +144,13 @@ export default function VncClient({
rfb.addEventListener( rfb.addEventListener(
"securityfailure", "securityfailure",
(e: { detail: { status: number; reason?: string } }) => { (e: { detail: { status: number; reason?: string } }) => {
toast({ disconnect();
variant: "destructive", setConnectError(
title: t("sshErrorAuthFailed"), e.detail.reason ??
description:
e.detail.reason ??
t("vncAuthFailedStatus", { t("vncAuthFailedStatus", {
status: e.detail.status status: e.detail.status
}) })
}); );
} }
); );
@@ -168,7 +166,9 @@ export default function VncClient({
<CardTitle>{t("vncTitle")}</CardTitle> <CardTitle>{t("vncTitle")}</CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<p className="text-destructive text-sm">{error}</p> <Alert variant="destructive">
<AlertDescription>{error}</AlertDescription>
</Alert>
</CardContent> </CardContent>
</Card> </Card>
</BrandedAuthSurface> </BrandedAuthSurface>
@@ -203,6 +203,14 @@ export default function VncClient({
/> />
</Field> </Field>
{connectError && (
<Alert variant="destructive">
<AlertDescription>
{connectError}
</AlertDescription>
</Alert>
)}
<Button onClick={connect} className="w-full"> <Button onClick={connect} className="w-full">
{t("browserGatewayConnect")} {t("browserGatewayConnect")}
</Button> </Button>