fix: terminal never appears — pending session removed before WS connects
Root cause: TerminalInstance.onMounted() called sessions.removeSession() on the pending session, dropping sessions.length to 0. SessionContainer's v-if="hasSessions" went false, unmounting the entire terminal UI before the WebSocket could establish and add the real session. Fix: Added replaceSession() to session store. TerminalInstance no longer removes the pending session — instead passes its ID to connectToHost(), which swaps it in-place when the backend responds with the real session ID. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
6759327ee3
commit
d74bb28960
@ -24,11 +24,8 @@ onMounted(() => {
|
|||||||
termInstance = createTerminal(termContainer.value)
|
termInstance = createTerminal(termContainer.value)
|
||||||
const { term, fitAddon } = termInstance
|
const { term, fitAddon } = termInstance
|
||||||
|
|
||||||
// Connect — useTerminal will call sessions.addSession with the real backend sessionId.
|
// Connect — useTerminal will replace the pending session with the real backend sessionId
|
||||||
// Remove the pending placeholder first to avoid duplicate entries.
|
connectToHost(props.hostId, props.hostName, 'ssh', props.color, props.sessionId, term, fitAddon)
|
||||||
sessions.removeSession(props.sessionId)
|
|
||||||
|
|
||||||
connectToHost(props.hostId, props.hostName, 'ssh', props.color, term, fitAddon)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
|
|||||||
@ -55,7 +55,7 @@ export function useTerminal() {
|
|||||||
return { term, fitAddon, searchAddon, resizeObserver }
|
return { term, fitAddon, searchAddon, resizeObserver }
|
||||||
}
|
}
|
||||||
|
|
||||||
function connectToHost(hostId: number, hostName: string, protocol: 'ssh', color: string | null, term: Terminal, fitAddon: FitAddon) {
|
function connectToHost(hostId: number, hostName: string, protocol: 'ssh', color: string | null, pendingSessionId: string, term: Terminal, fitAddon: FitAddon) {
|
||||||
const wsUrl = `${location.protocol === 'https:' ? 'wss' : 'ws'}://${location.host}/ws/terminal?token=${auth.token}`
|
const wsUrl = `${location.protocol === 'https:' ? 'wss' : 'ws'}://${location.host}/ws/terminal?token=${auth.token}`
|
||||||
ws = new WebSocket(wsUrl)
|
ws = new WebSocket(wsUrl)
|
||||||
|
|
||||||
@ -67,7 +67,8 @@ export function useTerminal() {
|
|||||||
const msg = JSON.parse(event.data)
|
const msg = JSON.parse(event.data)
|
||||||
switch (msg.type) {
|
switch (msg.type) {
|
||||||
case 'connected':
|
case 'connected':
|
||||||
sessions.addSession({ id: msg.sessionId, hostId, hostName, protocol, color, active: true })
|
// Replace the pending placeholder with the real backend session
|
||||||
|
sessions.replaceSession(pendingSessionId, { id: msg.sessionId, hostId, hostName, protocol, color, active: true })
|
||||||
// Send initial terminal size
|
// Send initial terminal size
|
||||||
ws!.send(JSON.stringify({ type: 'resize', sessionId: msg.sessionId, cols: term.cols, rows: term.rows }))
|
ws!.send(JSON.stringify({ type: 'resize', sessionId: msg.sessionId, cols: term.cols, rows: term.rows }))
|
||||||
break
|
break
|
||||||
|
|||||||
@ -29,6 +29,15 @@ export const useSessionStore = defineStore('sessions', {
|
|||||||
this.activeSessionId = this.sessions.length ? this.sessions[this.sessions.length - 1].id : null
|
this.activeSessionId = this.sessions.length ? this.sessions[this.sessions.length - 1].id : null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
replaceSession(oldId: string, newSession: Session) {
|
||||||
|
const idx = this.sessions.findIndex(s => s.id === oldId)
|
||||||
|
if (idx !== -1) {
|
||||||
|
this.sessions[idx] = newSession
|
||||||
|
} else {
|
||||||
|
this.sessions.push(newSession)
|
||||||
|
}
|
||||||
|
this.activeSessionId = newSession.id
|
||||||
|
},
|
||||||
setActive(id: string) {
|
setActive(id: string) {
|
||||||
this.activeSessionId = id
|
this.activeSessionId = id
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user