added expand buttons for middle and side pane and fixed issue with moving new chat to side pane

This commit is contained in:
Arjun 2026-05-27 23:17:25 +05:30
parent d981fa9206
commit f78f1380eb
2 changed files with 32 additions and 45 deletions

View file

@ -5,7 +5,7 @@ import { RunEvent, ListRunsResponse } from '@x/shared/src/runs.js';
import type { LanguageModelUsage, ToolUIPart } from 'ai'; import type { LanguageModelUsage, ToolUIPart } from 'ai';
import './App.css' import './App.css'
import z from 'zod'; import z from 'zod';
import { CheckIcon, LoaderIcon, PanelLeftIcon, ArrowRight, MessageSquare, ChevronLeftIcon, ChevronRightIcon, Plus, HistoryIcon, X } from 'lucide-react'; import { CheckIcon, LoaderIcon, PanelLeftIcon, ArrowRight, MessageSquare, ChevronLeftIcon, ChevronRightIcon, Plus, HistoryIcon } from 'lucide-react';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
import { MarkdownEditor, type MarkdownEditorHandle } from './components/markdown-editor'; import { MarkdownEditor, type MarkdownEditorHandle } from './components/markdown-editor';
import { ChatSidebar } from './components/chat-sidebar'; import { ChatSidebar } from './components/chat-sidebar';
@ -3391,8 +3391,10 @@ function App() {
setIsMeetingsOpen(false); setIsLiveNotesOpen(false); setIsBgTasksOpen(false); setIsEmailOpen(false); setIsWorkspaceOpen(false); setIsKnowledgeViewOpen(false); setIsChatHistoryOpen(false); setIsHomeOpen(false) setIsMeetingsOpen(false); setIsLiveNotesOpen(false); setIsBgTasksOpen(false); setIsEmailOpen(false); setIsWorkspaceOpen(false); setIsKnowledgeViewOpen(false); setIsChatHistoryOpen(false); setIsHomeOpen(false)
}, [selectedPath, isGraphOpen, isSuggestedTopicsOpen, isMeetingsOpen, isLiveNotesOpen, isBgTasksOpen, isEmailOpen, isWorkspaceOpen, isKnowledgeViewOpen, isChatHistoryOpen, dismissBrowserOverlay]) }, [selectedPath, isGraphOpen, isSuggestedTopicsOpen, isMeetingsOpen, isLiveNotesOpen, isBgTasksOpen, isEmailOpen, isWorkspaceOpen, isKnowledgeViewOpen, isChatHistoryOpen, dismissBrowserOverlay])
const handleCloseFullScreenChat = useCallback(() => { const handleCloseFullScreenChat = useCallback((): boolean => {
let restored = false
if (expandedFrom) { if (expandedFrom) {
restored = true
if (expandedFrom.graph) { if (expandedFrom.graph) {
setIsGraphOpen(true) setIsGraphOpen(true)
setIsSuggestedTopicsOpen(false) setIsSuggestedTopicsOpen(false)
@ -3434,10 +3436,16 @@ function App() {
setIsSuggestedTopicsOpen(false) setIsSuggestedTopicsOpen(false)
setIsMeetingsOpen(false); setIsLiveNotesOpen(false); setIsBgTasksOpen(false); setIsEmailOpen(false); setIsWorkspaceOpen(false); setIsKnowledgeViewOpen(false); setIsChatHistoryOpen(false); setIsHomeOpen(false) setIsMeetingsOpen(false); setIsLiveNotesOpen(false); setIsBgTasksOpen(false); setIsEmailOpen(false); setIsWorkspaceOpen(false); setIsKnowledgeViewOpen(false); setIsChatHistoryOpen(false); setIsHomeOpen(false)
setSelectedPath(expandedFrom.path) setSelectedPath(expandedFrom.path)
} else {
// expandedFrom was captured from a view this restorer doesn't track
// (e.g. Home): there's nothing to re-open, so report it and let the
// caller fall back instead of leaving a blank full-screen chat.
restored = false
} }
setExpandedFrom(null) setExpandedFrom(null)
setIsRightPaneMaximized(false) setIsRightPaneMaximized(false)
} }
return restored
}, [expandedFrom]) }, [expandedFrom])
const currentViewState = React.useMemo<ViewState>(() => { const currentViewState = React.useMemo<ViewState>(() => {
@ -3885,12 +3893,13 @@ function App() {
const pushChatToSidePane = useCallback(() => { const pushChatToSidePane = useCallback(() => {
setIsRightPaneMaximized(false) setIsRightPaneMaximized(false)
setIsChatSidebarOpen(true) setIsChatSidebarOpen(true)
if (expandedFrom) { // Restore the view we expanded from; if there was nothing to restore
handleCloseFullScreenChat() // (e.g. the chat was started fresh from Home), fall back to Home so a
} else { // single click always docks the chat instead of needing two.
if (!handleCloseFullScreenChat()) {
void navigateToView({ type: 'home' }) void navigateToView({ type: 'home' })
} }
}, [expandedFrom, handleCloseFullScreenChat, navigateToView]) }, [handleCloseFullScreenChat, navigateToView])
const navigateBack = useCallback(async () => { const navigateBack = useCallback(async () => {
const { back, forward } = historyRef.current const { back, forward } = historyRef.current
@ -5375,7 +5384,7 @@ function App() {
: (viewOpen && !isChatSidebarOpen) : (viewOpen && !isChatSidebarOpen)
? { onClick: openChatSidePane, icon: <MessageSquare className="size-5" />, label: 'Open chat' } ? { onClick: openChatSidePane, icon: <MessageSquare className="size-5" />, label: 'Open chat' }
: (viewOpen && isChatSidebarOpen && !isRightPaneMaximized) : (viewOpen && isChatSidebarOpen && !isRightPaneMaximized)
? { onClick: toggleRightPaneMaximize, icon: <X className="size-5" />, label: 'Expand chat' } ? { onClick: () => setIsChatSidebarOpen(false), icon: <ArrowRight className="size-5" />, label: 'Expand pane' }
: null : null
return ( return (
<Tooltip> <Tooltip>
@ -5899,7 +5908,6 @@ function App() {
}} }}
onOpenChatHistory={() => void navigateToView({ type: 'chat-history' })} onOpenChatHistory={() => void navigateToView({ type: 'chat-history' })}
onOpenFullScreen={toggleRightPaneMaximize} onOpenFullScreen={toggleRightPaneMaximize}
onCloseChat={() => { setIsRightPaneMaximized(false); setIsChatSidebarOpen(false) }}
conversation={conversation} conversation={conversation}
currentAssistantMessage={currentAssistantMessage} currentAssistantMessage={currentAssistantMessage}
chatTabStates={chatViewStateByTab} chatTabStates={chatViewStateByTab}

View file

@ -1,5 +1,5 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { ArrowRight, X } from 'lucide-react' import { ArrowLeft, ArrowRight } from 'lucide-react'
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
@ -125,7 +125,6 @@ interface ChatSidebarProps {
onSelectRun?: (runId: string) => void onSelectRun?: (runId: string) => void
onOpenChatHistory?: () => void onOpenChatHistory?: () => void
onOpenFullScreen?: () => void onOpenFullScreen?: () => void
onCloseChat?: () => void
conversation: ConversationItem[] conversation: ConversationItem[]
currentAssistantMessage: string currentAssistantMessage: string
chatTabStates?: Record<string, ChatTabViewState> chatTabStates?: Record<string, ChatTabViewState>
@ -183,7 +182,6 @@ export function ChatSidebar({
onSelectRun, onSelectRun,
onOpenChatHistory, onOpenChatHistory,
onOpenFullScreen, onOpenFullScreen,
onCloseChat,
conversation, conversation,
currentAssistantMessage, currentAssistantMessage,
chatTabStates = {}, chatTabStates = {},
@ -515,40 +513,21 @@ export function ChatSidebar({
onSelectRun={onSelectRun} onSelectRun={onSelectRun}
onOpenChatHistory={onOpenChatHistory} onOpenChatHistory={onOpenChatHistory}
/> />
{isMaximized ? ( {onOpenFullScreen && (
onOpenFullScreen && ( <Tooltip>
<Tooltip> <TooltipTrigger asChild>
<TooltipTrigger asChild> <Button
<Button variant="ghost"
variant="ghost" size="icon"
size="icon" onClick={onOpenFullScreen}
onClick={onOpenFullScreen} className="titlebar-no-drag my-1 mr-2 h-8 w-8 shrink-0 text-muted-foreground hover:text-foreground"
className="titlebar-no-drag my-1 mr-2 h-8 w-8 shrink-0 text-muted-foreground hover:text-foreground" aria-label={isMaximized ? 'Dock chat to side pane' : 'Expand chat'}
aria-label="Dock chat to side pane" >
> {isMaximized ? <ArrowRight className="size-5" /> : <ArrowLeft className="size-5" />}
<ArrowRight className="size-5" /> </Button>
</Button> </TooltipTrigger>
</TooltipTrigger> <TooltipContent side="bottom">{isMaximized ? 'Dock to side pane' : 'Expand chat'}</TooltipContent>
<TooltipContent side="bottom">Dock to side pane</TooltipContent> </Tooltip>
</Tooltip>
)
) : (
onCloseChat && (
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
onClick={onCloseChat}
className="titlebar-no-drag my-1 mr-2 h-8 w-8 shrink-0 text-muted-foreground hover:text-foreground"
aria-label="Close chat"
>
<X className="size-5" />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom">Close chat</TooltipContent>
</Tooltip>
)
)} )}
</header> </header>