50 lines
1.4 KiB
Vue
50 lines
1.4 KiB
Vue
<script setup lang="ts">
|
|
import { ref, onMounted, onBeforeUnmount } from 'vue'
|
|
import { useTerminal } from '~/composables/useTerminal'
|
|
import { useSessionStore } from '~/stores/session.store'
|
|
|
|
const props = defineProps<{
|
|
sessionId: string // may be a pending-XXX id initially
|
|
hostId: number
|
|
hostName: string
|
|
color: string | null
|
|
}>()
|
|
|
|
const termContainer = ref<HTMLElement | null>(null)
|
|
const sessions = useSessionStore()
|
|
const { createTerminal, connectToHost, disconnect } = useTerminal()
|
|
|
|
let termInstance: ReturnType<typeof createTerminal> | null = null
|
|
// Track the real backend sessionId once connected (replaces pending-XXX)
|
|
let realSessionId: string | null = null
|
|
|
|
onMounted(() => {
|
|
if (!termContainer.value) return
|
|
|
|
termInstance = createTerminal(termContainer.value)
|
|
const { term, fitAddon } = termInstance
|
|
|
|
// Connect — useTerminal will call sessions.addSession with the real backend sessionId.
|
|
// Remove the pending placeholder first to avoid duplicate entries.
|
|
sessions.removeSession(props.sessionId)
|
|
|
|
connectToHost(props.hostId, props.hostName, 'ssh', props.color, term, fitAddon)
|
|
})
|
|
|
|
onBeforeUnmount(() => {
|
|
if (termInstance) {
|
|
termInstance.resizeObserver.disconnect()
|
|
termInstance.term.dispose()
|
|
}
|
|
if (realSessionId) {
|
|
disconnect(realSessionId)
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div class="w-full h-full bg-[#0a0a0f]">
|
|
<div ref="termContainer" class="w-full h-full" />
|
|
</div>
|
|
</template>
|