fix: AI Assist panel as in-flow flex sibling (not fixed/overlay)

Replace fixed positioning with in-flow flex layout. The outermost div
is now a horizontal flex row: content column (flex-1 min-w-0) + panel
(w-[380px] shrink-0). When the panel opens, the content column
automatically shrinks — no padding hacks or z-index stacking needed.
This guarantees the content shifts left and stays fully visible.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-03-07 15:07:07 -05:00
parent 26cb64bdcc
commit d51cf72412
3 changed files with 43 additions and 43 deletions

View File

@@ -6,8 +6,6 @@ import { ChatTab } from './ChatTab'
import { SuggestionsTab } from './SuggestionsTab'
import type { EditorAIChatMessage, AISuggestion } from '@/types'
const PANEL_WIDTH = 380
interface EditorAIPanelProps {
isOpen: boolean
onClose: () => void
@@ -25,8 +23,6 @@ interface EditorAIPanelProps {
type Tab = 'chat' | 'suggestions'
export { PANEL_WIDTH }
export function EditorAIPanel({
isOpen,
onClose,
@@ -49,10 +45,8 @@ export function EditorAIPanel({
return (
<div
className="fixed right-0 bottom-0 z-40 flex flex-col border-l"
className="flex h-full w-[380px] shrink-0 flex-col border-l"
style={{
top: '56px',
width: `${PANEL_WIDTH}px`,
background: 'rgba(16, 17, 20, 0.95)',
backdropFilter: 'var(--glass-blur)',
WebkitBackdropFilter: 'var(--glass-blur)',

View File

@@ -10,7 +10,7 @@ import { getScheduleSummary } from '@/components/procedural-editor/scheduleUtils
import { StepList } from '@/components/procedural-editor/StepList'
import { TagInput } from '@/components/common/TagInput'
import { Spinner } from '@/components/common/Spinner'
import { EditorAIPanel, PANEL_WIDTH } from '@/components/editor-ai/EditorAIPanel'
import { EditorAIPanel } from '@/components/editor-ai/EditorAIPanel'
import { ContextMenu } from '@/components/common/ContextMenu'
import { useEditorAI } from '@/hooks/useEditorAI'
import { cn } from '@/lib/utils'
@@ -180,7 +180,9 @@ export function ProceduralEditorPage() {
}
return (
<div className="flex h-full flex-col overflow-hidden transition-[padding] duration-200" style={{ paddingRight: editorAI.isOpen ? `${PANEL_WIDTH}px` : 0 }}>
<div className="flex h-full overflow-hidden">
{/* Main content column */}
<div className="flex min-w-0 flex-1 flex-col overflow-hidden">
{/* Toolbar — sticky */}
<div className="flex shrink-0 items-center justify-between border-b border-border bg-card px-4 py-2">
<div className="flex items-center gap-3">
@@ -320,21 +322,6 @@ export function ProceduralEditorPage() {
<StepList onStepContextMenu={editorAI.openContextMenu} />
</div>
<EditorAIPanel
isOpen={editorAI.isOpen}
onClose={editorAI.closePanel}
focalNode={null}
flowName={name}
flowType={isMaintenance ? 'maintenance' : 'procedural'}
nodeCount={steps.length}
messages={editorAI.messages}
input={editorAI.input}
onInputChange={editorAI.setInput}
onSend={editorAI.sendMessage}
isLoading={editorAI.isLoading}
suggestions={editorAI.suggestions}
/>
{editorAI.contextMenu && (
<ContextMenu
position={editorAI.contextMenu.position}
@@ -363,6 +350,22 @@ export function ProceduralEditorPage() {
onClose={editorAI.closeContextMenu}
/>
)}
</div>{/* end main content column */}
<EditorAIPanel
isOpen={editorAI.isOpen}
onClose={editorAI.closePanel}
focalNode={null}
flowName={name}
flowType={isMaintenance ? 'maintenance' : 'procedural'}
nodeCount={steps.length}
messages={editorAI.messages}
input={editorAI.input}
onInputChange={editorAI.setInput}
onSend={editorAI.sendMessage}
isLoading={editorAI.isLoading}
suggestions={editorAI.suggestions}
/>
</div>
)
}

View File

@@ -17,7 +17,7 @@ import { cn, safeGetItem } from '@/lib/utils'
import { toast } from '@/lib/toast'
import { FlowAnalyticsPanel } from '@/components/analytics/FlowAnalyticsPanel'
import { ExportFlowModal } from '@/components/library/ExportFlowModal'
import { EditorAIPanel, PANEL_WIDTH } from '@/components/editor-ai/EditorAIPanel'
import { EditorAIPanel } from '@/components/editor-ai/EditorAIPanel'
import { ContextMenu } from '@/components/common/ContextMenu'
import { useEditorAI } from '@/hooks/useEditorAI'
import { findNodeInTree } from '@/store/treeEditorStore'
@@ -522,7 +522,9 @@ export function TreeEditorPage() {
}
return (
<div className="flex h-full flex-col overflow-hidden transition-[padding] duration-200" style={{ paddingRight: editorAI.isOpen ? `${PANEL_WIDTH}px` : 0 }}>
<div className="flex h-full overflow-hidden">
{/* Main content column */}
<div className="flex min-w-0 flex-1 flex-col overflow-hidden">
{/* Draft Restore Prompt */}
{showDraftPrompt && (
@@ -876,23 +878,6 @@ export function TreeEditorPage() {
/>
)}
<EditorAIPanel
isOpen={editorAI.isOpen}
onClose={handleAIPanelClose}
focalNode={editorAI.focalNodeId && treeStructure
? findNodeInTree(editorAI.focalNodeId, treeStructure)
: null}
flowName={name}
flowType="troubleshooting"
nodeCount={treeStructure ? getAllNodeIds().length : 0}
messages={editorAI.messages}
input={editorAI.input}
onInputChange={editorAI.setInput}
onSend={editorAI.sendMessage}
isLoading={editorAI.isLoading}
suggestions={editorAI.suggestions}
/>
{/* AI Context Menu */}
{editorAI.contextMenu && (
<ContextMenu
@@ -946,6 +931,24 @@ export function TreeEditorPage() {
onClose={editorAI.closeContextMenu}
/>
)}
</div>{/* end main content column */}
<EditorAIPanel
isOpen={editorAI.isOpen}
onClose={handleAIPanelClose}
focalNode={editorAI.focalNodeId && treeStructure
? findNodeInTree(editorAI.focalNodeId, treeStructure)
: null}
flowName={name}
flowType="troubleshooting"
nodeCount={treeStructure ? getAllNodeIds().length : 0}
messages={editorAI.messages}
input={editorAI.input}
onInputChange={editorAI.setInput}
onSend={editorAI.sendMessage}
isLoading={editorAI.isLoading}
suggestions={editorAI.suggestions}
/>
</div>
)
}