fix: remove features string from window.open to enable tab reuse

window.open(url, name, 'noopener,noreferrer') with a non-empty features
string forces a new popup window and ignores the name for tab reuse.
Remove the third parameter so the browser focuses existing named tabs.

Quality gates: tsc --noEmit pass, npm run build pass, 80/80 tests pass
This commit is contained in:
Developer
2026-06-09 12:18:28 +00:00
parent 486f3cbc44
commit e5e29aca49
3 changed files with 223 additions and 222 deletions
@@ -138,7 +138,11 @@ export function SessionCard({
)} )}
{session.url && ( {session.url && (
<p className="session-card-url"> <p className="session-card-url">
<a href={session.url} target={`session-${session.id}`} rel="noopener noreferrer"> <a
href={session.url}
target={`session-${session.id}`}
rel="noopener noreferrer"
>
{session.url} {session.url}
</a> </a>
</p> </p>
@@ -11,7 +11,10 @@ import {
} from "../../../api/sessions"; } from "../../../api/sessions";
import type { ToolType } from "../../../api/tool-types"; import type { ToolType } from "../../../api/tool-types";
import { CreateSessionForm } from "../session/create-session-form"; import { CreateSessionForm } from "../session/create-session-form";
import { listConfigProfiles, type ConfigProfile } from "../../../api/config-profiles"; import {
listConfigProfiles,
type ConfigProfile,
} from "../../../api/config-profiles";
import { listSSHKeys, type SSHKey } from "../../../api/ssh-keys"; import { listSSHKeys, type SSHKey } from "../../../api/ssh-keys";
import { useEventContext } from "../../../state/events"; import { useEventContext } from "../../../state/events";
@@ -348,16 +351,13 @@ export const InstanceList = ({
)} )}
onChange={(e) => { onChange={(e) => {
if (e.target.checked) { if (e.target.checked) {
setSelectedSshKeyIdsForAction( setSelectedSshKeyIdsForAction((prev) => [
(prev) => [...prev, key.id], ...prev,
); key.id,
]);
} else { } else {
setSelectedSshKeyIdsForAction( setSelectedSshKeyIdsForAction((prev) =>
(prev) => prev.filter((id) => id !== key.id),
prev.filter(
(id) =>
id !== key.id,
),
); );
} }
}} }}
@@ -496,16 +496,13 @@ export const InstanceList = ({
)} )}
onChange={(e) => { onChange={(e) => {
if (e.target.checked) { if (e.target.checked) {
setSelectedSshKeyIdsForAction( setSelectedSshKeyIdsForAction((prev) => [
(prev) => [...prev, key.id], ...prev,
); key.id,
]);
} else { } else {
setSelectedSshKeyIdsForAction( setSelectedSshKeyIdsForAction((prev) =>
(prev) => prev.filter((id) => id !== key.id),
prev.filter(
(id) =>
id !== key.id,
),
); );
} }
}} }}
+3 -3
View File
@@ -37,14 +37,14 @@ export function useInstanceActions(
const handleOpen = useCallback((session: Session) => { const handleOpen = useCallback((session: Session) => {
const tabName = `session-${session.id}`; const tabName = `session-${session.id}`;
if (session.url) { if (session.url) {
window.open(session.url, tabName, "noopener,noreferrer"); window.open(session.url, tabName);
return; return;
} }
if (session.tool_type_interfaces?.includes("terminal")) { if (session.tool_type_interfaces?.includes("terminal")) {
window.open(`/instances/${session.id}/terminal`, tabName, "noopener,noreferrer"); window.open(`/instances/${session.id}/terminal`, tabName);
return; return;
} }
window.open(`/projects/${session.project_id}`, tabName, "noopener,noreferrer"); window.open(`/projects/${session.project_id}`, tabName);
}, []); }, []);
const handleStart = useCallback( const handleStart = useCallback(