This is an automated email from the ASF dual-hosted git repository.
hsluoyz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/casbin-gateway.git
The following commit(s) were added to refs/heads/master by this push:
new 83ca53f fix(ui): dismiss the confirm dialog after confirming
83ca53f is described below
commit 83ca53f1d231545f982970f37b6c0b93378982c0
Author: Yang Luo <[email protected]>
AuthorDate: Fri Sep 4 00:31:54 2026 +0800
fix(ui): dismiss the confirm dialog after confirming
---
web/src/components/shared/confirm-dialog.tsx | 18 +++++++++++++-----
web/src/pages/AgentDetailPage.tsx | 14 ++++++++++----
web/src/pages/AgentsPage.tsx | 5 ++++-
3 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/web/src/components/shared/confirm-dialog.tsx
b/web/src/components/shared/confirm-dialog.tsx
index 8fad78a..637fbbf 100644
--- a/web/src/components/shared/confirm-dialog.tsx
+++ b/web/src/components/shared/confirm-dialog.tsx
@@ -61,23 +61,31 @@ export function ConfirmDialog({
onOpenChange?: (open: boolean) => void;
}) {
const [pending, setPending] = React.useState(false);
+ const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);
+ const isOpen = open ?? uncontrolledOpen;
+
+ const setOpen = (next: boolean) => {
+ if (open === undefined) {
+ setUncontrolledOpen(next);
+ }
+ onOpenChange?.(next);
+ };
const handleConfirm = async(event: React.MouseEvent) => {
- // The dialog closes itself on action; awaiting first would let it close
- // before an async handler reports a failure, so errors are surfaced by the
- // handler's own toast instead.
+ // Hold the dialog open while an async handler runs, then close it here,
so a
+ // failure surfaces (through the handler's own toast) before it disappears.
event.preventDefault();
setPending(true);
try {
await onConfirm();
} finally {
setPending(false);
- onOpenChange?.(false);
+ setOpen(false);
}
};
return (
- <AlertDialog open={open} onOpenChange={onOpenChange}>
+ <AlertDialog open={isOpen} onOpenChange={setOpen}>
<AlertDialogTrigger asChild disabled={disabled}>
{children}
</AlertDialogTrigger>
diff --git a/web/src/pages/AgentDetailPage.tsx
b/web/src/pages/AgentDetailPage.tsx
index 19f3260..f4aee80 100644
--- a/web/src/pages/AgentDetailPage.tsx
+++ b/web/src/pages/AgentDetailPage.tsx
@@ -14,7 +14,7 @@
import * as React from "react";
import {Link, useParams, useSearchParams} from "react-router-dom";
-import {ArrowLeft, Bot, ChevronRight, CircleX, Copy, RefreshCw} from
"lucide-react";
+import {ArrowLeft, Bot, ChevronRight, CircleX, Copy, Eye, EyeOff, RefreshCw}
from "lucide-react";
import copy from "copy-to-clipboard";
import i18next from "i18next";
@@ -84,6 +84,7 @@ function MonitoringCard({
onToggle: () => void;
}) {
const action = i18next.t(`agent:${agent.patched ? "Unpatch" : "Patch"}`);
+ const Icon = agent.patched ? EyeOff : Eye;
const note = [agent.notice, agent.followup].filter(Boolean).join(" ");
return (
@@ -113,13 +114,18 @@ function MonitoringCard({
variant={agent.patched ? "destructive" : "default"}
onConfirm={onToggle}
>
- <Button variant={agent.patched ? "outline" : "default"}
disabled={busy}>
- {busy ? <AiDots size="small" /> : null}
+ <Button
+ size="sm"
+ variant={agent.patched ? "outline" : "default"}
+ loading={busy}
+ >
+ <Icon />
{action}
</Button>
</ConfirmDialog>
) : (
- <Button variant="outline" disabled>
+ <Button size="sm" variant="outline" disabled>
+ <Eye />
{i18next.t("agent:Patch")}
</Button>
)}
diff --git a/web/src/pages/AgentsPage.tsx b/web/src/pages/AgentsPage.tsx
index 5285313..32c4482 100644
--- a/web/src/pages/AgentsPage.tsx
+++ b/web/src/pages/AgentsPage.tsx
@@ -13,7 +13,7 @@
// limitations under the License.
import {Link} from "react-router-dom";
-import {ArrowLeft, Bot, Container, RefreshCw} from "lucide-react";
+import {ArrowLeft, Bot, Container, Eye, EyeOff, RefreshCw} from "lucide-react";
import i18next from "i18next";
import * as Setting from "@/Setting";
@@ -195,12 +195,14 @@ export default function AgentsPage({account}: {account:
Account}) {
if (!record.supported) {
return (
<Button size="sm" variant="outline" disabled>
+ <Eye />
{i18next.t("agent:Patch")}
</Button>
);
}
const action = i18next.t(`agent:${record.patched ? "Unpatch" : "Patch"}`);
+ const Icon = record.patched ? EyeOff : Eye;
const note = [record.notice, record.followup].filter(Boolean).join(" ");
return (
<ConfirmDialog
@@ -215,6 +217,7 @@ export default function AgentsPage({account}: {account:
Account}) {
variant={record.patched ? "outline" : "default"}
loading={busyKey === agentKey(record)}
>
+ <Icon />
{action}
</Button>
</ConfirmDialog>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]