Skip to content

Commit 5b42604

Browse files
committed
fix: generate, mcp, ring
1 parent cbe63a3 commit 5b42604

File tree

6 files changed

+101
-69
lines changed

6 files changed

+101
-69
lines changed

apps/sim/app/_styles/globals.css

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -77,24 +77,6 @@
7777
cursor: grabbing !important;
7878
}
7979

80-
/**
81-
* Selected node ring indicator
82-
* Uses a pseudo-element overlay to match the original behavior (absolute inset-0 z-40)
83-
*/
84-
.react-flow__node.selected > div > div {
85-
position: relative;
86-
}
87-
88-
.react-flow__node.selected > div > div::after {
89-
content: "";
90-
position: absolute;
91-
inset: 0;
92-
z-index: 40;
93-
border-radius: 8px;
94-
box-shadow: 0 0 0 1.75px var(--brand-secondary);
95-
pointer-events: none;
96-
}
97-
9880
/**
9981
* Color tokens - single source of truth for all colors
10082
* Light mode: Warm theme

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/mcp-dynamic-args/mcp-dynamic-args.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { RefObject } from 'react'
12
import { useCallback, useMemo, useRef, useState } from 'react'
23
import { createLogger } from '@sim/logger'
34
import { useParams } from 'next/navigation'
@@ -143,7 +144,7 @@ function McpInputWithTags({
143144
setShowTags(false)
144145
setActiveSourceBlockId(null)
145146
}}
146-
inputRef={inputRef}
147+
inputRef={inputRef as RefObject<HTMLInputElement>}
147148
/>
148149
</div>
149150
)
@@ -269,7 +270,7 @@ function McpTextareaWithTags({
269270
setShowTags(false)
270271
setActiveSourceBlockId(null)
271272
}}
272-
inputRef={textareaRef}
273+
inputRef={textareaRef as RefObject<HTMLTextAreaElement>}
273274
/>
274275
</div>
275276
)

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/sub-block.tsx

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { type JSX, type MouseEvent, memo, useRef, useState } from 'react'
2-
import { AlertTriangle } from 'lucide-react'
2+
import { AlertTriangle, ArrowUp } from 'lucide-react'
33
import { Button, Input, Label, Tooltip } from '@/components/emcn/components'
44
import { cn } from '@/lib/core/utils/cn'
55
import type { FieldDiffStatus } from '@/lib/workflows/diff/types'
@@ -191,7 +191,10 @@ const renderLabel = (
191191
const showWand = wandState?.isWandEnabled && !wandState.isPreview && !wandState.disabled
192192

193193
return (
194-
<Label className='flex items-center justify-between gap-[6px] pl-[2px]'>
194+
<Label
195+
className='flex items-center justify-between gap-[6px] pl-[2px]'
196+
onClick={(e) => e.preventDefault()}
197+
>
195198
<div className='flex items-center gap-[6px] whitespace-nowrap'>
196199
{config.title}
197200
{required && <span className='ml-0.5'>*</span>}
@@ -222,25 +225,42 @@ const renderLabel = (
222225
Generate
223226
</Button>
224227
) : (
225-
<Input
226-
ref={wandState.searchInputRef}
227-
value={wandState.isStreaming ? 'Generating...' : wandState.searchQuery}
228-
onChange={(e) => wandState.onSearchChange(e.target.value)}
229-
onBlur={wandState.onSearchBlur}
230-
onKeyDown={(e) => {
231-
if (e.key === 'Enter' && wandState.searchQuery.trim() && !wandState.isStreaming) {
228+
<div className='-my-1 flex items-center gap-[4px]'>
229+
<Input
230+
ref={wandState.searchInputRef}
231+
value={wandState.isStreaming ? 'Generating...' : wandState.searchQuery}
232+
onChange={(e) => wandState.onSearchChange(e.target.value)}
233+
onBlur={wandState.onSearchBlur}
234+
onKeyDown={(e) => {
235+
if (e.key === 'Enter' && wandState.searchQuery.trim() && !wandState.isStreaming) {
236+
wandState.onSearchSubmit()
237+
} else if (e.key === 'Escape') {
238+
wandState.onSearchCancel()
239+
}
240+
}}
241+
disabled={wandState.isStreaming}
242+
className={cn(
243+
'h-5 max-w-[200px] flex-1 text-[11px]',
244+
wandState.isStreaming && 'text-muted-foreground'
245+
)}
246+
placeholder='Generate...'
247+
/>
248+
<Button
249+
variant='tertiary'
250+
disabled={!wandState.searchQuery.trim() || wandState.isStreaming}
251+
onMouseDown={(e) => {
252+
e.preventDefault()
253+
e.stopPropagation()
254+
}}
255+
onClick={(e) => {
256+
e.stopPropagation()
232257
wandState.onSearchSubmit()
233-
} else if (e.key === 'Escape') {
234-
wandState.onSearchCancel()
235-
}
236-
}}
237-
disabled={wandState.isStreaming}
238-
className={cn(
239-
'-my-1 h-5 max-w-[200px] flex-1 text-[11px]',
240-
wandState.isStreaming && 'text-muted-foreground'
241-
)}
242-
placeholder='Describe what you want to generate...'
243-
/>
258+
}}
259+
className='h-[20px] w-[20px] flex-shrink-0 p-0'
260+
>
261+
<ArrowUp className='h-[12px] w-[12px]' />
262+
</Button>
263+
</div>
244264
)}
245265
</>
246266
)}

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-block-visual.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { WorkflowBlockProps } from '@/app/workspace/[workspaceId]/w/[workfl
44
import { useCurrentWorkflow } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-current-workflow'
55
import { getBlockRingStyles } from '@/app/workspace/[workspaceId]/w/[workflowId]/utils/block-ring-utils'
66
import { useExecutionStore } from '@/stores/execution'
7-
import { usePanelEditorStore } from '@/stores/panel'
7+
import { usePanelEditorStore, usePanelStore } from '@/stores/panel'
88
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
99

1010
/**
@@ -21,7 +21,8 @@ interface UseBlockVisualProps {
2121

2222
/**
2323
* Provides visual state and interaction handlers for workflow blocks.
24-
* Computes ring styling based on execution, diff, deletion, and run path states.
24+
* Computes ring styling based on editor open state, execution, diff, deletion, and run path states.
25+
* Ring is shown only when the editor panel is open for this block, not during selection/dragging.
2526
* In preview mode, uses isPreviewSelected for selection highlighting.
2627
*
2728
* @param props - The hook properties
@@ -36,13 +37,15 @@ export function useBlockVisual({ blockId, data, isPending = false }: UseBlockVis
3637

3738
const {
3839
isEnabled,
39-
isActive: blockIsActive,
40+
isActive: isExecuting,
4041
diffStatus,
4142
isDeletedBlock,
4243
} = useBlockState(blockId, currentWorkflow, data)
4344

44-
// In preview mode, use isPreviewSelected for selection state
45-
const isActive = isPreview ? isPreviewSelected : blockIsActive
45+
// Check if the editor panel is open for this block
46+
const currentBlockId = usePanelEditorStore((state) => state.currentBlockId)
47+
const activeTab = usePanelStore((state) => state.activeTab)
48+
const isEditorOpen = !isPreview && currentBlockId === blockId && activeTab === 'editor'
4649

4750
const lastRunPath = useExecutionStore((state) => state.lastRunPath)
4851
const runPathStatus = isPreview ? undefined : lastRunPath.get(blockId)
@@ -58,14 +61,24 @@ export function useBlockVisual({ blockId, data, isPending = false }: UseBlockVis
5861
const { hasRing, ringClassName: ringStyles } = useMemo(
5962
() =>
6063
getBlockRingStyles({
61-
isActive,
64+
isExecuting: isPreview ? false : isExecuting,
65+
isEditorOpen: isPreview ? isPreviewSelected : isEditorOpen,
6266
isPending: isPreview ? false : isPending,
6367
isDeletedBlock: isPreview ? false : isDeletedBlock,
6468
diffStatus: isPreview ? undefined : diffStatus,
6569
runPathStatus,
6670
isPreviewSelection: isPreview && isPreviewSelected,
6771
}),
68-
[isActive, isPending, isDeletedBlock, diffStatus, runPathStatus, isPreview, isPreviewSelected]
72+
[
73+
isExecuting,
74+
isEditorOpen,
75+
isPending,
76+
isDeletedBlock,
77+
diffStatus,
78+
runPathStatus,
79+
isPreview,
80+
isPreviewSelected,
81+
]
6982
)
7083

7184
return {

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/block-ring-utils.ts

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ export type BlockDiffStatus = 'new' | 'edited' | null | undefined
55
export type BlockRunPathStatus = 'success' | 'error' | undefined
66

77
export interface BlockRingOptions {
8-
isActive: boolean
8+
/** Whether the block is executing (shows green pulsing ring) */
9+
isExecuting: boolean
10+
/** Whether the editor panel is open for this block (shows blue ring) */
11+
isEditorOpen: boolean
912
isPending: boolean
1013
isDeletedBlock: boolean
1114
diffStatus: BlockDiffStatus
@@ -15,55 +18,67 @@ export interface BlockRingOptions {
1518

1619
/**
1720
* Derives visual ring visibility and class names for workflow blocks
18-
* based on execution, diff, deletion, and run-path states.
21+
* based on editor open state, execution, diff, deletion, and run-path states.
1922
*/
2023
export function getBlockRingStyles(options: BlockRingOptions): {
2124
hasRing: boolean
2225
ringClassName: string
2326
} {
24-
const { isActive, isPending, isDeletedBlock, diffStatus, runPathStatus, isPreviewSelection } =
25-
options
27+
const {
28+
isExecuting,
29+
isEditorOpen,
30+
isPending,
31+
isDeletedBlock,
32+
diffStatus,
33+
runPathStatus,
34+
isPreviewSelection,
35+
} = options
2636

2737
const hasRing =
28-
isActive ||
38+
isExecuting ||
39+
isEditorOpen ||
2940
isPending ||
3041
diffStatus === 'new' ||
3142
diffStatus === 'edited' ||
3243
isDeletedBlock ||
3344
!!runPathStatus
3445

3546
const ringClassName = cn(
36-
// Preview selection: static blue ring (standard thickness, no animation)
37-
isActive && isPreviewSelection && 'ring-[1.75px] ring-[var(--brand-secondary)]',
38-
// Executing block: pulsing success ring with prominent thickness
39-
isActive &&
40-
!isPreviewSelection &&
41-
'ring-[3.5px] ring-[var(--border-success)] animate-ring-pulse',
47+
// Executing block: pulsing success ring with prominent thickness (highest priority)
48+
isExecuting && 'ring-[3.5px] ring-[var(--border-success)] animate-ring-pulse',
49+
// Editor open or preview selection: static blue ring
50+
!isExecuting &&
51+
(isEditorOpen || isPreviewSelection) &&
52+
'ring-[1.75px] ring-[var(--brand-secondary)]',
4253
// Non-active states use standard ring utilities
43-
!isActive && hasRing && 'ring-[1.75px]',
54+
!isExecuting && !isEditorOpen && !isPreviewSelection && hasRing && 'ring-[1.75px]',
4455
// Pending state: warning ring
45-
!isActive && isPending && 'ring-[var(--warning)]',
56+
!isExecuting && !isEditorOpen && isPending && 'ring-[var(--warning)]',
4657
// Deleted state (highest priority after active/pending)
47-
!isActive && !isPending && isDeletedBlock && 'ring-[var(--text-error)]',
58+
!isExecuting && !isEditorOpen && !isPending && isDeletedBlock && 'ring-[var(--text-error)]',
4859
// Diff states
49-
!isActive &&
60+
!isExecuting &&
61+
!isEditorOpen &&
5062
!isPending &&
5163
!isDeletedBlock &&
5264
diffStatus === 'new' &&
5365
'ring-[var(--brand-tertiary-2)]',
54-
!isActive &&
66+
!isExecuting &&
67+
!isEditorOpen &&
5568
!isPending &&
5669
!isDeletedBlock &&
5770
diffStatus === 'edited' &&
5871
'ring-[var(--warning)]',
5972
// Run path states (lowest priority - only show if no other states active)
60-
!isActive &&
73+
!isExecuting &&
74+
!isEditorOpen &&
6175
!isPending &&
6276
!isDeletedBlock &&
6377
!diffStatus &&
6478
runPathStatus === 'success' &&
6579
'ring-[var(--border-success)]',
66-
!isActive &&
80+
!isExecuting &&
81+
!isEditorOpen &&
6782
!isPending &&
6883
!isDeletedBlock &&
6984
!diffStatus &&

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/context-menu/context-menu.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import { useCallback, useEffect, useMemo, useState } from 'react'
44
import { Check } from 'lucide-react'
55
import {
6+
Button,
67
Popover,
78
PopoverAnchor,
89
PopoverBackButton,
@@ -368,17 +369,17 @@ export function ContextMenu({
368369
onClick={(e) => e.stopPropagation()}
369370
className='h-[20px] min-w-0 flex-1 rounded-[4px] bg-[#363636] px-[6px] text-[11px] text-white uppercase caret-white focus:outline-none'
370371
/>
371-
<button
372-
type='button'
372+
<Button
373+
variant='tertiary'
373374
disabled={!canSubmitHex}
374375
onClick={(e) => {
375376
e.stopPropagation()
376377
handleHexSubmit()
377378
}}
378-
className='flex h-[20px] w-[20px] flex-shrink-0 items-center justify-center rounded-[4px] bg-[var(--brand-tertiary-2)] text-white disabled:opacity-40'
379+
className='h-[20px] w-[20px] flex-shrink-0 p-0'
379380
>
380381
<Check className='h-[12px] w-[12px]' />
381-
</button>
382+
</Button>
382383
</div>
383384
</div>
384385
</PopoverFolder>

0 commit comments

Comments
 (0)