Skip to content

Commit 699800e

Browse files
committed
Add hooks
1 parent f259799 commit 699800e

5 files changed

Lines changed: 92 additions & 46 deletions

File tree

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/note-block/note-block.tsx

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ import type { NodeProps } from 'reactflow'
44
import remarkGfm from 'remark-gfm'
55
import { cn } from '@/lib/utils'
66
import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider'
7-
import { usePanelEditorStore } from '@/stores/panel-new/editor/store'
87
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
98
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
10-
import { useCurrentWorkflow } from '../../hooks'
11-
import { useBlockDimensions } from '../../hooks/use-block-dimensions'
9+
import {
10+
useBlockDimensions,
11+
useBlockFocus,
12+
useBlockRingStyles,
13+
useCurrentWorkflow,
14+
} from '../../hooks'
1215
import { ActionBar } from '../workflow-block/components'
1316
import { useBlockState } from '../workflow-block/hooks'
1417
import type { WorkflowBlockProps } from '../workflow-block/types'
@@ -92,9 +95,7 @@ const NoteMarkdown = memo(function NoteMarkdown({ content }: { content: string }
9295
export const NoteBlock = memo(function NoteBlock({ id, data }: NodeProps<NoteBlockNodeData>) {
9396
const { type, config, name } = data
9497

95-
const setCurrentBlockId = usePanelEditorStore((state) => state.setCurrentBlockId)
96-
const currentBlockId = usePanelEditorStore((state) => state.currentBlockId)
97-
const isFocused = currentBlockId === id
98+
const { isFocused, handleClick } = useBlockFocus(id)
9899

99100
const currentWorkflow = useCurrentWorkflow()
100101
const { isEnabled, isActive, diffStatus, isDeletedBlock } = useBlockState(
@@ -161,24 +162,20 @@ export const NoteBlock = memo(function NoteBlock({ id, data }: NodeProps<NoteBlo
161162
dependencies: [isEmpty],
162163
})
163164

164-
const hasRing =
165-
isActive || isFocused || diffStatus === 'new' || diffStatus === 'edited' || isDeletedBlock
166-
const ringStyles = cn(
167-
hasRing && 'ring-[1.75px]',
168-
isActive && 'ring-[#8C10FF] animate-pulse-ring',
169-
isFocused && 'ring-[#33B4FF]',
170-
diffStatus === 'new' && 'ring-[#22C55F]',
171-
diffStatus === 'edited' && 'ring-[#FF6600]',
172-
isDeletedBlock && 'ring-[#EF4444]'
173-
)
165+
const { hasRing, ringStyles } = useBlockRingStyles({
166+
isActive,
167+
isFocused,
168+
diffStatus,
169+
isDeletedBlock,
170+
})
174171

175172
return (
176173
<div className='group relative'>
177174
<div
178175
className={cn(
179176
'relative z-[20] w-[250px] cursor-default select-none rounded-[8px] bg-[#232323]'
180177
)}
181-
onClick={() => setCurrentBlockId(id)}
178+
onClick={handleClick}
182179
>
183180
<ActionBar blockId={id} blockType={type} disabled={!userPermissions.canEdit} />
184181

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,14 @@ import type { SubBlockConfig } from '@/blocks/types'
1111
import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
1212
import { useCredentialDisplay } from '@/hooks/use-credential-display'
1313
import { useDisplayName } from '@/hooks/use-display-name'
14-
import { usePanelEditorStore } from '@/stores/panel-new/editor/store'
1514
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
1615
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
17-
import { useBlockDimensions, useCurrentWorkflow } from '../../hooks'
16+
import {
17+
useBlockDimensions,
18+
useBlockFocus,
19+
useBlockRingStyles,
20+
useCurrentWorkflow,
21+
} from '../../hooks'
1822
import { ActionBar, Connections } from './components'
1923
import {
2024
useBlockProperties,
@@ -367,9 +371,7 @@ export const WorkflowBlock = memo(function WorkflowBlock({
367371
}, [id, collaborativeSetSubblockValue])
368372

369373
const activeWorkflowId = useWorkflowRegistry((state) => state.activeWorkflowId)
370-
const setCurrentBlockId = usePanelEditorStore((state) => state.setCurrentBlockId)
371-
const currentBlockId = usePanelEditorStore((state) => state.currentBlockId)
372-
const isFocused = currentBlockId === id
374+
const { isFocused, handleClick } = useBlockFocus(id)
373375
const currentStoreBlock = currentWorkflow.getBlockById(id)
374376

375377
const isStarterBlock = type === 'starter'
@@ -638,35 +640,19 @@ export const WorkflowBlock = memo(function WorkflowBlock({
638640
const userPermissions = useUserPermissionsContext()
639641
const isWorkflowSelector = type === 'workflow' || type === 'workflow_input'
640642

641-
/**
642-
* Determine the ring styling based on block state priority:
643-
* 1. Active (executing) - purple ring with pulse animation
644-
* 2. Pending (next step) - orange ring
645-
* 3. Focused (selected in editor) - blue ring
646-
* 4. Diff status (version comparison) - green/orange/red ring
647-
*/
648-
const hasRing =
649-
isActive ||
650-
isPending ||
651-
isFocused ||
652-
diffStatus === 'new' ||
653-
diffStatus === 'edited' ||
654-
isDeletedBlock
655-
const ringStyles = cn(
656-
hasRing && 'ring-[1.75px]',
657-
isActive && 'ring-[#8C10FF] animate-pulse-ring',
658-
isPending && 'ring-[#FF6600]',
659-
isFocused && 'ring-[#33B4FF]',
660-
diffStatus === 'new' && 'ring-[#22C55F]',
661-
diffStatus === 'edited' && 'ring-[#FF6600]',
662-
isDeletedBlock && 'ring-[#EF4444]'
663-
)
643+
const { hasRing, ringStyles } = useBlockRingStyles({
644+
isActive,
645+
isFocused,
646+
isPending,
647+
diffStatus,
648+
isDeletedBlock,
649+
})
664650

665651
return (
666652
<div className='group relative'>
667653
<div
668654
ref={contentRef}
669-
onClick={() => setCurrentBlockId(id)}
655+
onClick={handleClick}
670656
className={cn(
671657
'relative z-[20] w-[250px] cursor-default select-none rounded-[8px] bg-[#232323]'
672658
)}

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
export { useAutoLayout } from './use-auto-layout'
22
export { useBlockDimensions } from './use-block-dimensions'
3+
export { useBlockFocus } from './use-block-focus'
4+
export { useBlockRingStyles } from './use-block-ring-styles'
35
export { type CurrentWorkflow, useCurrentWorkflow } from './use-current-workflow'
46
export { useNodeUtilities } from './use-node-utilities'
57
export { useScrollManagement } from './use-scroll-management'
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { useCallback } from 'react'
2+
import { usePanelEditorStore } from '@/stores/panel-new/editor/store'
3+
4+
/**
5+
* Shared hook for managing block focus state and interactions.
6+
*/
7+
export function useBlockFocus(blockId: string) {
8+
const setCurrentBlockId = usePanelEditorStore((state) => state.setCurrentBlockId)
9+
const currentBlockId = usePanelEditorStore((state) => state.currentBlockId)
10+
const isFocused = currentBlockId === blockId
11+
12+
const handleClick = useCallback(() => {
13+
setCurrentBlockId(blockId)
14+
}, [blockId, setCurrentBlockId])
15+
16+
return { isFocused, handleClick }
17+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { useMemo } from 'react'
2+
import { cn } from '@/lib/utils'
3+
4+
interface UseBlockRingStylesOptions {
5+
isActive: boolean
6+
isFocused: boolean
7+
isPending?: boolean
8+
diffStatus?: 'new' | 'edited' | null
9+
isDeletedBlock: boolean
10+
}
11+
12+
/**
13+
* Shared hook for computing ring styles across block types.
14+
* Handles visual states: active, pending, focused, diff status, deleted.
15+
*/
16+
export function useBlockRingStyles({
17+
isActive,
18+
isFocused,
19+
isPending = false,
20+
diffStatus,
21+
isDeletedBlock,
22+
}: UseBlockRingStylesOptions) {
23+
return useMemo(() => {
24+
const hasRing =
25+
isActive ||
26+
isPending ||
27+
isFocused ||
28+
diffStatus === 'new' ||
29+
diffStatus === 'edited' ||
30+
isDeletedBlock
31+
32+
const ringStyles = cn(
33+
hasRing && 'ring-[1.75px]',
34+
isActive && 'ring-[#8C10FF] animate-pulse-ring',
35+
isPending && 'ring-[#FF6600]',
36+
isFocused && 'ring-[#33B4FF]',
37+
diffStatus === 'new' && 'ring-[#22C55F]',
38+
diffStatus === 'edited' && 'ring-[#FF6600]',
39+
isDeletedBlock && 'ring-[#EF4444]'
40+
)
41+
42+
return { hasRing, ringStyles }
43+
}, [isActive, isPending, isFocused, diffStatus, isDeletedBlock])
44+
}

0 commit comments

Comments
 (0)