11'use client'
22
33import { memo , useCallback , useRef } from 'react'
4- import { Chip , cn , toast } from '@sim/emcn'
5- import { Search } from '@sim/emcn/icons'
4+ import { Chip , ChipSwitch , cn , toast } from '@sim/emcn'
65import { useParams } from 'next/navigation'
76import { ThinkingLoader } from '@/components/ui'
87import { useSession } from '@/lib/auth/auth-client'
@@ -39,9 +38,14 @@ interface PanelProps {
3938 onCloseEditor ?: ( ) => void
4039}
4140
41+ const PANEL_TABS = [
42+ { value : 'toolbar' , label : 'Toolbar' } ,
43+ { value : 'editor' , label : 'Editor' } ,
44+ ] as const
45+
4246/**
43- * Workflow header and contextual right panel. The panel automatically shows the block
44- * library when the canvas has no selection and the editor when a block is selected .
47+ * Workflow header and contextual right panel. Toolbar and Editor remain independently
48+ * available so users can browse blocks without losing their current canvas selection .
4549 *
4650 * @returns Structured workflow chrome around the canvas
4751 */
@@ -50,6 +54,7 @@ export const Panel = memo(function Panel({ onCloseEditor }: PanelProps) {
5054 const workspaceId = params . workspaceId as string
5155
5256 const panelRef = useRef < HTMLElement > ( null )
57+ const activeTab = usePanelStore ( ( state ) => state . activeTab )
5358 const setActiveTab = usePanelStore ( ( state ) => state . setActiveTab )
5459 const toolbarRef = useRef < {
5560 focusSearch : ( ) => void
@@ -60,9 +65,6 @@ export const Panel = memo(function Panel({ onCloseEditor }: PanelProps) {
6065 // Hooks
6166 const userPermissions = useUserPermissionsContext ( )
6267
63- const currentBlockId = usePanelEditorStore ( ( state ) => state . currentBlockId )
64- const showEditor = currentBlockId !== null
65-
6668 const { data : workflows = { } } = useWorkflowMap ( workspaceId )
6769 const { data : folders = { } } = useFolderMap ( workspaceId )
6870 const activeWorkflowId = useWorkflowRegistry ( ( state ) => state . activeWorkflowId )
@@ -138,7 +140,6 @@ export const Panel = memo(function Panel({ onCloseEditor }: PanelProps) {
138140 } , [ onCloseEditor , setActiveTab ] )
139141
140142 const handleFocusToolbarSearch = useCallback ( ( ) => {
141- usePanelEditorStore . getState ( ) . clearCurrentBlock ( )
142143 setActiveTab ( 'toolbar' )
143144 requestAnimationFrame ( ( ) => toolbarRef . current ?. focusSearch ( ) )
144145 } , [ setActiveTab ] )
@@ -195,25 +196,7 @@ export const Panel = memo(function Panel({ onCloseEditor }: PanelProps) {
195196 < WorkflowHistoryControls />
196197 < WorkflowControls />
197198 </ div >
198- < div
199- className = { cn (
200- 'pointer-events-none flex w-[var(--panel-width)] flex-shrink-0 items-center border-[var(--border)] border-l pr-1 pl-3.5' ,
201- showEditor ? 'justify-between bg-[var(--bg)]' : 'justify-end'
202- ) }
203- >
204- { showEditor && (
205- < button
206- type = 'button'
207- className = 'pointer-events-auto flex h-10 min-w-0 flex-1 items-center gap-2 p-0 text-left outline-none focus-visible:underline'
208- onClick = { handleFocusToolbarSearch }
209- aria-label = 'Search blocks'
210- >
211- < Search className = 'size-[14px] flex-shrink-0 text-[var(--text-muted)]' />
212- < span className = 'min-w-0 truncate text-[var(--text-muted)] text-sm' >
213- Search blocks...
214- </ span >
215- </ button >
216- ) }
199+ < div className = 'pointer-events-none flex w-[var(--panel-width)] flex-shrink-0 items-center justify-end border-[var(--border)] border-l bg-[var(--bg)] pr-1 pl-3.5' >
217200 < div className = 'pointer-events-auto flex items-center gap-1.5' >
218201 < Deploy
219202 activeWorkflowId = { activeWorkflowId }
@@ -248,35 +231,45 @@ export const Panel = memo(function Panel({ onCloseEditor }: PanelProps) {
248231 </ div >
249232 </ header >
250233
251- < div
252- className = { cn (
253- 'workflow-right-tools pointer-events-none absolute right-0 bottom-0 z-20 flex w-[var(--panel-width)] [container-type:size]' ,
254- showEditor ? 'top-[40px]' : 'top-0'
255- ) }
256- >
234+ < div className = 'workflow-right-tools pointer-events-none absolute top-[40px] right-0 bottom-0 z-20 flex w-[var(--panel-width)] [container-type:size]' >
257235 < aside
258236 ref = { panelRef }
259- className = 'panel-container pointer-events-auto relative flex h-full min-h-0 flex-col overflow-hidden border-[var(--border)] border-l bg-[var(--bg)]'
237+ className = 'panel-container pointer-events-auto relative flex h-full min-h-0 w-full flex-col overflow-hidden border-[var(--border)] border-l bg-[var(--bg)]'
260238 aria-label = 'Workflow panel'
261239 >
262240 < div className = 'flex h-full min-h-0 flex-col' >
263- < div
264- className = { cn (
265- 'min-h-0 overflow-hidden' ,
266- showEditor ? 'flex flex-1 flex-col' : 'flex-1'
267- ) }
268- >
269- { showEditor ? (
270- < div className = 'flex h-full min-h-0 flex-col overflow-hidden' >
271- < Editor onClose = { handleCloseEditor } />
272- </ div >
273- ) : (
274- < div className = 'flex h-full flex-col' >
275- < div className = 'min-h-0 flex-1' >
276- < Toolbar ref = { toolbarRef } />
277- </ div >
278- </ div >
279- ) }
241+ < div className = 'flex h-[40px] flex-shrink-0 items-center border-[var(--border)] border-b px-3' >
242+ < ChipSwitch
243+ options = { PANEL_TABS }
244+ value = { activeTab }
245+ onChange = { setActiveTab }
246+ aria-label = 'Workflow panel view'
247+ />
248+ </ div >
249+
250+ < div className = 'min-h-0 flex-1 overflow-hidden' >
251+ < div
252+ data-tab-content = 'toolbar'
253+ className = { cn (
254+ 'h-full min-h-0' ,
255+ activeTab === 'toolbar' ? 'flex flex-col' : 'hidden'
256+ ) }
257+ >
258+ < Toolbar
259+ key = { activeWorkflowId ?? 'workflow' }
260+ ref = { toolbarRef }
261+ isActive = { activeTab === 'toolbar' }
262+ />
263+ </ div >
264+ < div
265+ data-tab-content = 'editor'
266+ className = { cn (
267+ 'h-full min-h-0 flex-col overflow-hidden' ,
268+ activeTab === 'editor' ? 'flex' : 'hidden'
269+ ) }
270+ >
271+ < Editor onClose = { handleCloseEditor } />
272+ </ div >
280273 </ div >
281274 </ div >
282275
0 commit comments