@@ -50,6 +50,12 @@ import { useSubBlockStore } from '@/stores/workflows/subblock/store'
5050/** Stable empty object to avoid creating new references */
5151const EMPTY_SUBBLOCK_VALUES = { } as Record < string , any >
5252
53+ /** Shared style for dashed divider lines */
54+ const DASHED_DIVIDER_STYLE = {
55+ backgroundImage :
56+ 'repeating-linear-gradient(to right, var(--border) 0px, var(--border) 6px, transparent 6px, transparent 12px)' ,
57+ } as const
58+
5359/**
5460 * Icon component for rendering block icons.
5561 *
@@ -89,31 +95,23 @@ export function Editor() {
8995 const blockConfig = currentBlock ? getBlock ( currentBlock . type ) : null
9096 const title = currentBlock ?. name || 'Editor'
9197
92- // Check if selected block is a subflow (loop or parallel)
9398 const isSubflow =
9499 currentBlock && ( currentBlock . type === 'loop' || currentBlock . type === 'parallel' )
95100
96- // Get subflow display properties from configs
97101 const subflowConfig = isSubflow ? ( currentBlock . type === 'loop' ? LoopTool : ParallelTool ) : null
98102
99- // Check if selected block is a workflow block
100103 const isWorkflowBlock =
101104 currentBlock && ( currentBlock . type === 'workflow' || currentBlock . type === 'workflow_input' )
102105
103- // Get workspace ID from params
104106 const params = useParams ( )
105107 const workspaceId = params . workspaceId as string
106108
107- // Refs for resize functionality
108109 const subBlocksRef = useRef < HTMLDivElement > ( null )
109110
110- // Get user permissions
111111 const userPermissions = useUserPermissionsContext ( )
112112
113- // Get active workflow ID
114113 const activeWorkflowId = useWorkflowRegistry ( ( state ) => state . activeWorkflowId )
115114
116- // Get block properties (advanced/trigger modes)
117115 const { advancedMode, triggerMode } = useEditorBlockProperties (
118116 currentBlockId ,
119117 currentWorkflow . isSnapshotView
@@ -145,22 +143,19 @@ export function Editor() {
145143 [ subBlocksForCanonical ]
146144 )
147145 const canonicalModeOverrides = currentBlock ?. data ?. canonicalModes
148- const advancedValuesPresent = hasAdvancedValues (
149- subBlocksForCanonical ,
150- blockSubBlockValues ,
151- canonicalIndex
146+ const advancedValuesPresent = useMemo (
147+ ( ) => hasAdvancedValues ( subBlocksForCanonical , blockSubBlockValues , canonicalIndex ) ,
148+ [ subBlocksForCanonical , blockSubBlockValues , canonicalIndex ]
152149 )
153150 const displayAdvancedOptions = userPermissions . canEdit
154151 ? advancedMode
155152 : advancedMode || advancedValuesPresent
156153
157154 const hasAdvancedOnlyFields = useMemo ( ( ) => {
158155 for ( const subBlock of subBlocksForCanonical ) {
159- // Must be standalone advanced (mode: 'advanced' without canonicalParamId)
160156 if ( subBlock . mode !== 'advanced' ) continue
161157 if ( canonicalIndex . canonicalIdBySubBlockId [ subBlock . id ] ) continue
162158
163- // Check condition - skip if condition not met for current values
164159 if (
165160 subBlock . condition &&
166161 ! evaluateSubBlockCondition ( subBlock . condition , blockSubBlockValues )
@@ -173,7 +168,6 @@ export function Editor() {
173168 return false
174169 } , [ subBlocksForCanonical , canonicalIndex . canonicalIdBySubBlockId , blockSubBlockValues ] )
175170
176- // Get subblock layout using custom hook
177171 const { subBlocks, stateToUse : subBlockState } = useEditorSubblockLayout (
178172 blockConfig || ( { } as any ) ,
179173 currentBlockId || '' ,
@@ -206,31 +200,34 @@ export function Editor() {
206200 return { regularSubBlocks : regular , advancedOnlySubBlocks : advancedOnly }
207201 } , [ subBlocks , canonicalIndex . canonicalIdBySubBlockId ] )
208202
209- // Get block connections
210203 const { incomingConnections, hasIncomingConnections } = useBlockConnections ( currentBlockId || '' )
211204
212- // Connections resize hook
213205 const { handleMouseDown : handleConnectionsResizeMouseDown , isResizing } = useConnectionsResize ( {
214206 subBlocksRef,
215207 } )
216208
217- // Collaborative actions
218209 const {
219210 collaborativeSetBlockCanonicalMode,
220211 collaborativeUpdateBlockName,
221212 collaborativeToggleBlockAdvancedMode,
222213 } = useCollaborativeWorkflow ( )
223214
224- // Advanced mode toggle handler
225215 const handleToggleAdvancedMode = useCallback ( ( ) => {
226216 if ( ! currentBlockId || ! userPermissions . canEdit ) return
227217 collaborativeToggleBlockAdvancedMode ( currentBlockId )
228218 } , [ currentBlockId , userPermissions . canEdit , collaborativeToggleBlockAdvancedMode ] )
229219
230- // Rename state
231220 const [ isRenaming , setIsRenaming ] = useState ( false )
232221 const [ editedName , setEditedName ] = useState ( '' )
233- const nameInputRef = useRef < HTMLInputElement > ( null )
222+
223+ /**
224+ * Ref callback that auto-selects the input text when mounted.
225+ */
226+ const nameInputRefCallback = useCallback ( ( element : HTMLInputElement | null ) => {
227+ if ( element ) {
228+ element . select ( )
229+ }
230+ } , [ ] )
234231
235232 /**
236233 * Handles starting the rename process.
@@ -251,7 +248,6 @@ export function Editor() {
251248 if ( trimmedName && trimmedName !== currentBlock ?. name ) {
252249 const result = collaborativeUpdateBlockName ( currentBlockId , trimmedName )
253250 if ( ! result . success ) {
254- // Keep rename mode open on error so user can correct the name
255251 return
256252 }
257253 }
@@ -266,14 +262,6 @@ export function Editor() {
266262 setEditedName ( '' )
267263 } , [ ] )
268264
269- // Focus input when entering rename mode
270- useEffect ( ( ) => {
271- if ( isRenaming && nameInputRef . current ) {
272- nameInputRef . current . select ( )
273- }
274- } , [ isRenaming ] )
275-
276- // Trigger rename mode when signaled from context menu
277265 useEffect ( ( ) => {
278266 if ( shouldFocusRename && currentBlock ) {
279267 handleStartRename ( )
@@ -284,17 +272,13 @@ export function Editor() {
284272 /**
285273 * Handles opening documentation link in a new secure tab.
286274 */
287- const handleOpenDocs = ( ) => {
275+ const handleOpenDocs = useCallback ( ( ) => {
288276 const docsLink = isSubflow ? subflowConfig ?. docsLink : blockConfig ?. docsLink
289- if ( docsLink ) {
290- window . open ( docsLink , '_blank' , 'noopener,noreferrer' )
291- }
292- }
277+ window . open ( docsLink || 'https://docs.sim.ai/quick-reference' , '_blank' , 'noopener,noreferrer' )
278+ } , [ isSubflow , subflowConfig ?. docsLink , blockConfig ?. docsLink ] )
293279
294- // Get child workflow ID for workflow blocks
295280 const childWorkflowId = isWorkflowBlock ? blockSubBlockValues ?. workflowId : null
296281
297- // Fetch child workflow state for preview (only for workflow blocks with a selected workflow)
298282 const { data : childWorkflowState , isLoading : isLoadingChildWorkflow } =
299283 useWorkflowState ( childWorkflowId )
300284
@@ -307,7 +291,6 @@ export function Editor() {
307291 }
308292 } , [ childWorkflowId , workspaceId ] )
309293
310- // Determine if connections are at minimum height (collapsed state)
311294 const isConnectionsAtMinHeight = connectionsHeight <= 35
312295
313296 return (
@@ -328,7 +311,7 @@ export function Editor() {
328311 ) }
329312 { isRenaming ? (
330313 < input
331- ref = { nameInputRef }
314+ ref = { nameInputRefCallback }
332315 type = 'text'
333316 value = { editedName }
334317 onChange = { ( e ) => setEditedName ( e . target . value ) }
@@ -399,23 +382,21 @@ export function Editor() {
399382 </Tooltip.Content>
400383 </Tooltip.Root>
401384 )} */ }
402- { currentBlock && ( isSubflow ? subflowConfig ?. docsLink : blockConfig ?. docsLink ) && (
403- < Tooltip . Root >
404- < Tooltip . Trigger asChild >
405- < Button
406- variant = 'ghost'
407- className = 'p-0'
408- onClick = { handleOpenDocs }
409- aria-label = 'Open documentation'
410- >
411- < BookOpen className = 'h-[14px] w-[14px]' />
412- </ Button >
413- </ Tooltip . Trigger >
414- < Tooltip . Content side = 'top' >
415- < p > Open docs</ p >
416- </ Tooltip . Content >
417- </ Tooltip . Root >
418- ) }
385+ < Tooltip . Root >
386+ < Tooltip . Trigger asChild >
387+ < Button
388+ variant = 'ghost'
389+ className = 'p-0'
390+ onClick = { handleOpenDocs }
391+ aria-label = 'Open documentation'
392+ >
393+ < BookOpen className = 'h-[14px] w-[14px]' />
394+ </ Button >
395+ </ Tooltip . Trigger >
396+ < Tooltip . Content side = 'top' >
397+ < p > Open docs</ p >
398+ </ Tooltip . Content >
399+ </ Tooltip . Root >
419400 </ div >
420401 </ div >
421402
@@ -495,13 +476,7 @@ export function Editor() {
495476 </ div >
496477 </ div >
497478 < div className = 'subblock-divider px-[2px] pt-[16px] pb-[13px]' >
498- < div
499- className = 'h-[1.25px]'
500- style = { {
501- backgroundImage :
502- 'repeating-linear-gradient(to right, var(--border) 0px, var(--border) 6px, transparent 6px, transparent 12px)' ,
503- } }
504- />
479+ < div className = 'h-[1.25px]' style = { DASHED_DIVIDER_STYLE } />
505480 </ div >
506481 </ >
507482 ) }
@@ -566,13 +541,7 @@ export function Editor() {
566541 />
567542 { showDivider && (
568543 < div className = 'subblock-divider px-[2px] pt-[16px] pb-[13px]' >
569- < div
570- className = 'h-[1.25px]'
571- style = { {
572- backgroundImage :
573- 'repeating-linear-gradient(to right, var(--border) 0px, var(--border) 6px, transparent 6px, transparent 12px)' ,
574- } }
575- />
544+ < div className = 'h-[1.25px]' style = { DASHED_DIVIDER_STYLE } />
576545 </ div >
577546 ) }
578547 </ div >
@@ -581,13 +550,7 @@ export function Editor() {
581550
582551 { hasAdvancedOnlyFields && userPermissions . canEdit && (
583552 < div className = 'flex items-center gap-[10px] px-[2px] pt-[14px] pb-[12px]' >
584- < div
585- className = 'h-[1.25px] flex-1'
586- style = { {
587- backgroundImage :
588- 'repeating-linear-gradient(to right, var(--border) 0px, var(--border) 6px, transparent 6px, transparent 12px)' ,
589- } }
590- />
553+ < div className = 'h-[1.25px] flex-1' style = { DASHED_DIVIDER_STYLE } />
591554 < button
592555 type = 'button'
593556 onClick = { handleToggleAdvancedMode }
@@ -600,13 +563,7 @@ export function Editor() {
600563 className = { `h-[14px] w-[14px] transition-transform duration-200 ${ displayAdvancedOptions ? 'rotate-180' : '' } ` }
601564 />
602565 </ button >
603- < div
604- className = 'h-[1.25px] flex-1'
605- style = { {
606- backgroundImage :
607- 'repeating-linear-gradient(to right, var(--border) 0px, var(--border) 6px, transparent 6px, transparent 12px)' ,
608- } }
609- />
566+ < div className = 'h-[1.25px] flex-1' style = { DASHED_DIVIDER_STYLE } />
610567 </ div >
611568 ) }
612569
@@ -630,13 +587,7 @@ export function Editor() {
630587 />
631588 { index < advancedOnlySubBlocks . length - 1 && (
632589 < div className = 'subblock-divider px-[2px] pt-[16px] pb-[13px]' >
633- < div
634- className = 'h-[1.25px]'
635- style = { {
636- backgroundImage :
637- 'repeating-linear-gradient(to right, var(--border) 0px, var(--border) 6px, transparent 6px, transparent 12px)' ,
638- } }
639- />
590+ < div className = 'h-[1.25px]' style = { DASHED_DIVIDER_STYLE } />
640591 </ div >
641592 ) }
642593 </ div >
0 commit comments