refactor: unify dashboard/terminal selector into single strip, default to dashboard
Remove separate Chat/SE tab toggle. Dashboard is now a button in the terminal strip alongside T1-T5. Chat only renders when a specific terminal route is active (/transcript-debug/:n).
This commit is contained in:
@@ -4,7 +4,7 @@ import { useRoute, useRouter } from 'vue-router'
|
||||
import { useTranscriptDebug } from '@/composables/transcript-debug'
|
||||
import { useVoiceInput } from '@/composables/useVoiceInput'
|
||||
import { useSessionState } from '@/stores/session-state'
|
||||
import { ChatContainer, AquaticBackground, AgentBadge, NewSessionModal } from '@/components/transcript-debug'
|
||||
import { ChatContainer, AquaticBackground, AgentBadge, NewSessionModal, SyncEnginePanel } from '@/components/transcript-debug'
|
||||
import type { AgentName } from '@/types/transcript-debug'
|
||||
import { isTauri, isMobileTauri, getTauriWindow } from '@/lib/tauri'
|
||||
import { usePipWindow } from '@/composables/usePipWindow'
|
||||
@@ -63,6 +63,9 @@ const showSelector = ref(false)
|
||||
const showNewSessionModal = ref(false)
|
||||
const isPipWindow = computed(() => route.query.pip === '1')
|
||||
|
||||
// Dashboard vs terminal view — driven by route
|
||||
const isDashboard = computed(() => !route.params.terminalIndex)
|
||||
|
||||
// Readability overlay
|
||||
const savedOverlay = localStorage.getItem('transcript-overlay-opacity')
|
||||
const overlayOpacity = ref(savedOverlay !== null ? parseFloat(savedOverlay) : 0.55)
|
||||
@@ -136,6 +139,10 @@ async function handleModalCreateNew(agent: AgentName, initialPrompt: string) {
|
||||
}
|
||||
}
|
||||
|
||||
function goToDashboard() {
|
||||
router.push({ name: 'transcript-debug' })
|
||||
}
|
||||
|
||||
function handleTerminalSwitch(sessionId: string) {
|
||||
const idx = sessionState.terminalRegistry.findIndex(
|
||||
e => e.transcriptSessionId === sessionId
|
||||
@@ -219,6 +226,15 @@ onMounted(async () => {
|
||||
await init()
|
||||
await voice.init()
|
||||
syncTerminalFromRoute()
|
||||
|
||||
// Signal to the parent window that this PiP page is ready to show
|
||||
if (isTauri && route.query.pip === '1') {
|
||||
try {
|
||||
const { getCurrentWebviewWindow } = await import('@tauri-apps/api/webviewWindow')
|
||||
const { emitTo } = await import('@tauri-apps/api/event')
|
||||
await emitTo('main', 'pip:ready', getCurrentWebviewWindow().label)
|
||||
} catch {}
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
@@ -252,13 +268,23 @@ onBeforeUnmount(() => {
|
||||
<!-- Terminal selector strip (hidden in PiP) -->
|
||||
<div v-if="!isPipWindow" class="terminal-strip">
|
||||
<div class="strip-left">
|
||||
<button
|
||||
:class="['strip-terminal-btn', 'strip-dashboard-btn', { active: isDashboard }]"
|
||||
@click="goToDashboard"
|
||||
title="Dashboard"
|
||||
>
|
||||
<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
|
||||
<rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/>
|
||||
<rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
v-for="(entry, idx) in sessionState.terminalRegistry"
|
||||
:key="entry.transcriptSessionId"
|
||||
:class="[
|
||||
'strip-terminal-btn',
|
||||
{
|
||||
active: String(idx + 1) === route.params.terminalIndex || (!route.params.terminalIndex && entry.transcriptSessionId === activeTerminalSessionId),
|
||||
active: String(idx + 1) === route.params.terminalIndex,
|
||||
dead: !entry.alive
|
||||
}
|
||||
]"
|
||||
@@ -360,6 +386,8 @@ onBeforeUnmount(() => {
|
||||
</div>
|
||||
</Transition>
|
||||
|
||||
<!-- Terminal chat (only when a specific terminal is selected) -->
|
||||
<template v-if="!isDashboard">
|
||||
<ChatContainer
|
||||
ref="chatRef"
|
||||
v-if="conversation"
|
||||
@@ -410,6 +438,10 @@ onBeforeUnmount(() => {
|
||||
<small v-if="!sessionState.terminalRegistry.length">No terminals registered</small>
|
||||
<small v-else>Select a terminal above to begin</small>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Dashboard (default view) -->
|
||||
<SyncEnginePanel v-if="isDashboard" />
|
||||
</div>
|
||||
|
||||
<!-- New session modal -->
|
||||
@@ -499,6 +531,16 @@ onBeforeUnmount(() => {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.strip-dashboard-btn {
|
||||
gap: 0;
|
||||
}
|
||||
.strip-dashboard-btn svg {
|
||||
opacity: 0.7;
|
||||
}
|
||||
.strip-dashboard-btn.active svg {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.realtime-dot {
|
||||
color: var(--text-muted);
|
||||
opacity: 0.4;
|
||||
@@ -641,6 +683,13 @@ onBeforeUnmount(() => {
|
||||
ChatContainer glass-transparent overrides (mirrored from FloatingTranscriptDebug)
|
||||
══════════════════════════════════════════════════════════════════════════════ */
|
||||
|
||||
.content-area :deep(.sync-engine-panel) {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.content-area :deep(.chat-container) {
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
|
||||
Reference in New Issue
Block a user