Skip to content

Commit 332f427

Browse files
committed
fix(app): respect dialog dismissals and dedupe health polling
1 parent 81b2fc7 commit 332f427

1 file changed

Lines changed: 40 additions & 12 deletions

File tree

  • desktop/cortex-control-center/src

desktop/cortex-control-center/src/App.jsx

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1519,6 +1519,23 @@ export function App() {
15191519
const streamSessionEventCountRef = useRef(0);
15201520
const devVerificationStartedRef = useRef(false);
15211521
const permissionsEndpointAvailableRef = useRef(true);
1522+
const browserHealthProbeRef = useRef(null);
1523+
const connectionDialogAutoPromptSuppressedRef = useRef(false);
1524+
1525+
const openConnectionDialog = useCallback(() => {
1526+
connectionDialogAutoPromptSuppressedRef.current = false;
1527+
setShowConnectionDialog(true);
1528+
}, []);
1529+
1530+
const dismissConnectionDialog = useCallback(() => {
1531+
connectionDialogAutoPromptSuppressedRef.current = true;
1532+
setShowConnectionDialog(false);
1533+
}, []);
1534+
1535+
const closeConnectionDialog = useCallback(() => {
1536+
connectionDialogAutoPromptSuppressedRef.current = false;
1537+
setShowConnectionDialog(false);
1538+
}, []);
15221539

15231540
const changePanel = useCallback((nextPanel) => {
15241541
if (!PANEL_SEQUENCE_KEYS.has(nextPanel) || nextPanel === panel) {
@@ -1880,6 +1897,7 @@ export function App() {
18801897
if (invokeRef.current) {
18811898
try {
18821899
const state = { ...EMPTY_DAEMON, ...(await call("daemon_status")) };
1900+
browserHealthProbeRef.current = null;
18831901
setDaemonState(state);
18841902
return state;
18851903
} catch {
@@ -1890,8 +1908,10 @@ export function App() {
18901908
let health;
18911909
try {
18921910
health = await api("/health");
1911+
browserHealthProbeRef.current = health || null;
18931912
} catch {
18941913
// daemon unreachable is an expected state, not an error
1914+
browserHealthProbeRef.current = null;
18951915
}
18961916
if (isReachableHealthPayload(health)) {
18971917
const nextState = {
@@ -1928,11 +1948,14 @@ export function App() {
19281948
}, [api]);
19291949

19301950
const refreshHealth = useCallback(async () => {
1931-
let health;
1932-
try {
1933-
health = await api("/health");
1934-
} catch {
1935-
// daemon unreachable -- show dashes
1951+
let health = browserHealthProbeRef.current;
1952+
browserHealthProbeRef.current = null;
1953+
if (!health) {
1954+
try {
1955+
health = await api("/health");
1956+
} catch {
1957+
// daemon unreachable -- show dashes
1958+
}
19361959
}
19371960
if (!health) {
19381961
const readinessReady = await probeReadiness();
@@ -2566,11 +2589,16 @@ export function App() {
25662589
setDaemonTimeoutStaleSummary("");
25672590
clearRecoveryRetry();
25682591
setFeedbackMessage(summarizeDashboardErrors(unique));
2569-
if (!invokeRef.current && unique.every((error) => isAuthFailure(error))) {
2592+
if (
2593+
!invokeRef.current
2594+
&& unique.every((error) => isAuthFailure(error))
2595+
&& !connectionDialogAutoPromptSuppressedRef.current
2596+
) {
25702597
setShowConnectionDialog(true);
25712598
}
25722599
}
25732600
} else {
2601+
connectionDialogAutoPromptSuppressedRef.current = false;
25742602
clearRecoveryRetry();
25752603
const uniqueSecondary = [...new Set(secondaryErrors)];
25762604
if (uniqueSecondary.length) {
@@ -4007,7 +4035,7 @@ export function App() {
40074035
<span className="topbar-stat"><span className="topbar-label">DEC</span> {stats.decisions}</span>
40084036
<span className="topbar-stat"><span className="topbar-label">EVT</span> {stats.events}</span>
40094037
<span className="topbar-stat"><span className="topbar-label">AGENTS</span> {normalizedSessions.length}</span>
4010-
<span className="topbar-stat topbar-connection" onClick={() => setShowConnectionDialog(true)} title="Click to change connection">
4038+
<span className="topbar-stat topbar-connection" onClick={openConnectionDialog} title="Click to change connection">
40114039
<span className="topbar-label">HOST</span>
40124040
{hostLabel}
40134041
</span>
@@ -4082,15 +4110,15 @@ export function App() {
40824110
)}
40834111

40844112
{showConnectionDialog && (
4085-
<div className="connection-overlay" onClick={() => setShowConnectionDialog(false)}>
4113+
<div className="connection-overlay" onClick={dismissConnectionDialog}>
40864114
<div className="connection-dialog" onClick={e => e.stopPropagation()}>
40874115
<div className="connection-dialog-header">
40884116
<h2>Connection Settings</h2>
40894117
<button
40904118
type="button"
40914119
className="connection-dialog-close"
40924120
aria-label="Close connection settings"
4093-
onClick={() => setShowConnectionDialog(false)}
4121+
onClick={dismissConnectionDialog}
40944122
>
40954123
×
40964124
</button>
@@ -4106,7 +4134,7 @@ export function App() {
41064134
setCortexBase(DEFAULT_CORTEX_BASE);
41074135
tokenRef.current = "";
41084136
persistBrowserAuthToken("");
4109-
setShowConnectionDialog(false);
4137+
closeConnectionDialog();
41104138
queueMicrotask(() => refreshAllRef.current());
41114139
return;
41124140
}
@@ -4117,7 +4145,7 @@ export function App() {
41174145
setCortexBase(`http://${host}:${port}`);
41184146
tokenRef.current = token || "";
41194147
persistBrowserAuthToken(token || "");
4120-
setShowConnectionDialog(false);
4148+
closeConnectionDialog();
41214149
queueMicrotask(() => refreshAllRef.current());
41224150
}}>
41234151
<label className="connection-field">
@@ -4152,7 +4180,7 @@ export function App() {
41524180
setCortexBase(DEFAULT_CORTEX_BASE);
41534181
tokenRef.current = "";
41544182
persistBrowserAuthToken("");
4155-
setShowConnectionDialog(false);
4183+
closeConnectionDialog();
41564184
readAuthToken({ suppressFeedback: true });
41574185
queueMicrotask(() => refreshAllRef.current());
41584186
}}>Reset to Local</button>

0 commit comments

Comments
 (0)