Skip to content

Commit 0bf2bce

Browse files
improvement(var-resolution): resolve variables with block name check and consolidate code (#1469)
* improvement(var-resolution): resolve variables with block name check and consolidate code * fix tests * fix type error * fix var highlighting in kb tags * fix kb tags
1 parent 0d881ec commit 0bf2bce

File tree

15 files changed

+475
-141
lines changed

15 files changed

+475
-141
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { checkTagTrigger, TagDropdown } from '@/components/ui/tag-dropdown'
1010
import { createLogger } from '@/lib/logs/console/logger'
1111
import { cn } from '@/lib/utils'
1212
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/hooks/use-sub-block-value'
13+
import { useAccessibleReferencePrefixes } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-accessible-reference-prefixes'
1314
import type { SubBlockConfig } from '@/blocks/types'
1415
import { useTagSelection } from '@/hooks/use-tag-selection'
1516

@@ -60,6 +61,7 @@ export function ComboBox({
6061
const [highlightedIndex, setHighlightedIndex] = useState(-1)
6162

6263
const emitTagSelection = useTagSelection(blockId, subBlockId)
64+
const accessiblePrefixes = useAccessibleReferencePrefixes(blockId)
6365

6466
const inputRef = useRef<HTMLInputElement>(null)
6567
const overlayRef = useRef<HTMLDivElement>(null)
@@ -432,7 +434,10 @@ export function ComboBox({
432434
style={{ right: '42px' }}
433435
>
434436
<div className='w-full truncate text-foreground' style={{ scrollbarWidth: 'none' }}>
435-
{formatDisplayText(displayValue)}
437+
{formatDisplayText(displayValue, {
438+
accessiblePrefixes,
439+
highlightAll: !accessiblePrefixes,
440+
})}
436441
</div>
437442
</div>
438443
{/* Chevron button */}

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Label } from '@/components/ui/label'
55
import { checkTagTrigger, TagDropdown } from '@/components/ui/tag-dropdown'
66
import { cn } from '@/lib/utils'
77
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/hooks/use-sub-block-value'
8+
import { useAccessibleReferencePrefixes } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-accessible-reference-prefixes'
89
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
910

1011
interface InputFormatField {
@@ -152,6 +153,8 @@ export function InputMapping({
152153
setMapping(updated)
153154
}
154155

156+
const accessiblePrefixes = useAccessibleReferencePrefixes(blockId)
157+
155158
if (!selectedWorkflowId) {
156159
return (
157160
<div className='flex flex-col items-center justify-center rounded-lg border border-border/50 bg-muted/30 p-8 text-center'>
@@ -213,6 +216,7 @@ export function InputMapping({
213216
blockId={blockId}
214217
subBlockId={subBlockId}
215218
disabled={isPreview || disabled}
219+
accessiblePrefixes={accessiblePrefixes}
216220
/>
217221
)
218222
})}
@@ -229,6 +233,7 @@ function InputMappingField({
229233
blockId,
230234
subBlockId,
231235
disabled,
236+
accessiblePrefixes,
232237
}: {
233238
fieldName: string
234239
fieldType?: string
@@ -237,6 +242,7 @@ function InputMappingField({
237242
blockId: string
238243
subBlockId: string
239244
disabled: boolean
245+
accessiblePrefixes: Set<string> | undefined
240246
}) {
241247
const [showTags, setShowTags] = useState(false)
242248
const [cursorPosition, setCursorPosition] = useState(0)
@@ -318,7 +324,10 @@ function InputMappingField({
318324
className='w-full whitespace-pre'
319325
style={{ scrollbarWidth: 'none', minWidth: 'fit-content' }}
320326
>
321-
{formatDisplayText(value)}
327+
{formatDisplayText(value, {
328+
accessiblePrefixes,
329+
highlightAll: !accessiblePrefixes,
330+
})}
322331
</div>
323332
</div>
324333

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { formatDisplayText } from '@/components/ui/formatted-text'
77
import { Input } from '@/components/ui/input'
88
import { Label } from '@/components/ui/label'
99
import { checkTagTrigger, TagDropdown } from '@/components/ui/tag-dropdown'
10+
import { useAccessibleReferencePrefixes } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-accessible-reference-prefixes'
1011
import type { SubBlockConfig } from '@/blocks/types'
1112
import { useKnowledgeBaseTagDefinitions } from '@/hooks/use-knowledge-base-tag-definitions'
1213
import { useTagSelection } from '@/hooks/use-tag-selection'
@@ -55,6 +56,9 @@ export function KnowledgeTagFilters({
5556
// Use KB tag definitions hook to get available tags
5657
const { tagDefinitions, isLoading } = useKnowledgeBaseTagDefinitions(knowledgeBaseId)
5758

59+
// Get accessible prefixes for variable highlighting
60+
const accessiblePrefixes = useAccessibleReferencePrefixes(blockId)
61+
5862
// State for managing tag dropdown
5963
const [activeTagDropdown, setActiveTagDropdown] = useState<{
6064
rowIndex: number
@@ -314,7 +318,12 @@ export function KnowledgeTagFilters({
314318
className='w-full border-0 text-transparent caret-foreground placeholder:text-muted-foreground/50 focus-visible:ring-0 focus-visible:ring-offset-0'
315319
/>
316320
<div className='pointer-events-none absolute inset-0 flex items-center overflow-hidden bg-transparent px-3 text-sm'>
317-
<div className='whitespace-pre'>{formatDisplayText(cellValue)}</div>
321+
<div className='whitespace-pre'>
322+
{formatDisplayText(cellValue, {
323+
accessiblePrefixes,
324+
highlightAll: !accessiblePrefixes,
325+
})}
326+
</div>
318327
</div>
319328
</div>
320329
</td>

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { createLogger } from '@/lib/logs/console/logger'
1111
import { cn } from '@/lib/utils'
1212
import { WandPromptBar } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/wand-prompt-bar/wand-prompt-bar'
1313
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/hooks/use-sub-block-value'
14+
import { useAccessibleReferencePrefixes } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-accessible-reference-prefixes'
1415
import { useWand } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-wand'
1516
import type { SubBlockConfig } from '@/blocks/types'
1617
import { useTagSelection } from '@/hooks/use-tag-selection'
@@ -92,6 +93,7 @@ export function LongInput({
9293
const overlayRef = useRef<HTMLDivElement>(null)
9394
const [activeSourceBlockId, setActiveSourceBlockId] = useState<string | null>(null)
9495
const containerRef = useRef<HTMLDivElement>(null)
96+
const accessiblePrefixes = useAccessibleReferencePrefixes(blockId)
9597

9698
// Use preview value when in preview mode, otherwise use store value or prop value
9799
const baseValue = isPreview ? previewValue : propValue !== undefined ? propValue : storeValue
@@ -405,7 +407,10 @@ export function LongInput({
405407
height: `${height}px`,
406408
}}
407409
>
408-
{formatDisplayText(value?.toString() ?? '')}
410+
{formatDisplayText(value?.toString() ?? '', {
411+
accessiblePrefixes,
412+
highlightAll: !accessiblePrefixes,
413+
})}
409414
</div>
410415

411416
{/* Wand Button */}

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { createLogger } from '@/lib/logs/console/logger'
1111
import { cn } from '@/lib/utils'
1212
import { WandPromptBar } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/wand-prompt-bar/wand-prompt-bar'
1313
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/hooks/use-sub-block-value'
14+
import { useAccessibleReferencePrefixes } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-accessible-reference-prefixes'
1415
import { useWand } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-wand'
1516
import type { SubBlockConfig } from '@/blocks/types'
1617
import { useTagSelection } from '@/hooks/use-tag-selection'
@@ -345,6 +346,8 @@ export function ShortInput({
345346
}
346347
}
347348

349+
const accessiblePrefixes = useAccessibleReferencePrefixes(blockId)
350+
348351
return (
349352
<>
350353
<WandPromptBar
@@ -417,7 +420,10 @@ export function ShortInput({
417420
>
418421
{password && !isFocused
419422
? '•'.repeat(value?.toString().length ?? 0)
420-
: formatDisplayText(value?.toString() ?? '')}
423+
: formatDisplayText(value?.toString() ?? '', {
424+
accessiblePrefixes,
425+
highlightAll: !accessiblePrefixes,
426+
})}
421427
</div>
422428
</div>
423429

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { checkTagTrigger, TagDropdown } from '@/components/ui/tag-dropdown'
2222
import { Textarea } from '@/components/ui/textarea'
2323
import { cn } from '@/lib/utils'
2424
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/hooks/use-sub-block-value'
25+
import { useAccessibleReferencePrefixes } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-accessible-reference-prefixes'
2526

2627
interface Field {
2728
id: string
@@ -80,6 +81,7 @@ export function FieldFormat({
8081
const [cursorPosition, setCursorPosition] = useState(0)
8182
const [activeFieldId, setActiveFieldId] = useState<string | null>(null)
8283
const [activeSourceBlockId, setActiveSourceBlockId] = useState<string | null>(null)
84+
const accessiblePrefixes = useAccessibleReferencePrefixes(blockId)
8385

8486
// Use preview value when in preview mode, otherwise use store value
8587
const value = isPreview ? previewValue : storeValue
@@ -471,7 +473,10 @@ export function FieldFormat({
471473
style={{ scrollbarWidth: 'none', minWidth: 'fit-content' }}
472474
>
473475
{formatDisplayText(
474-
(localValues[field.id] ?? field.value ?? '')?.toString()
476+
(localValues[field.id] ?? field.value ?? '')?.toString(),
477+
accessiblePrefixes
478+
? { accessiblePrefixes }
479+
: { highlightAll: true }
475480
)}
476481
</div>
477482
</div>

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/tool-input/components/mcp-server-modal/mcp-server-modal.tsx

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
} from '@/components/ui/select'
2525
import { createLogger } from '@/lib/logs/console/logger'
2626
import type { McpTransport } from '@/lib/mcp/types'
27+
import { useAccessibleReferencePrefixes } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-accessible-reference-prefixes'
2728
import { useMcpServerTest } from '@/hooks/use-mcp-server-test'
2829
import { useMcpServersStore } from '@/stores/mcp-servers/store'
2930

@@ -33,6 +34,7 @@ interface McpServerModalProps {
3334
open: boolean
3435
onOpenChange: (open: boolean) => void
3536
onServerCreated?: () => void
37+
blockId: string
3638
}
3739

3840
interface McpServerFormData {
@@ -42,7 +44,12 @@ interface McpServerFormData {
4244
headers?: Record<string, string>
4345
}
4446

45-
export function McpServerModal({ open, onOpenChange, onServerCreated }: McpServerModalProps) {
47+
export function McpServerModal({
48+
open,
49+
onOpenChange,
50+
onServerCreated,
51+
blockId,
52+
}: McpServerModalProps) {
4653
const params = useParams()
4754
const workspaceId = params.workspaceId as string
4855
const [formData, setFormData] = useState<McpServerFormData>({
@@ -262,6 +269,8 @@ export function McpServerModal({ open, onOpenChange, onServerCreated }: McpServe
262269
workspaceId,
263270
])
264271

272+
const accessiblePrefixes = useAccessibleReferencePrefixes(blockId)
273+
265274
return (
266275
<Dialog open={open} onOpenChange={onOpenChange}>
267276
<DialogContent className='sm:max-w-[600px]'>
@@ -337,7 +346,10 @@ export function McpServerModal({ open, onOpenChange, onServerCreated }: McpServe
337346
className='whitespace-nowrap'
338347
style={{ transform: `translateX(-${urlScrollLeft}px)` }}
339348
>
340-
{formatDisplayText(formData.url || '')}
349+
{formatDisplayText(formData.url || '', {
350+
accessiblePrefixes,
351+
highlightAll: !accessiblePrefixes,
352+
})}
341353
</div>
342354
</div>
343355
</div>
@@ -389,7 +401,10 @@ export function McpServerModal({ open, onOpenChange, onServerCreated }: McpServe
389401
transform: `translateX(-${headerScrollLeft[`key-${index}`] || 0}px)`,
390402
}}
391403
>
392-
{formatDisplayText(key || '')}
404+
{formatDisplayText(key || '', {
405+
accessiblePrefixes,
406+
highlightAll: !accessiblePrefixes,
407+
})}
393408
</div>
394409
</div>
395410
</div>
@@ -417,7 +432,10 @@ export function McpServerModal({ open, onOpenChange, onServerCreated }: McpServe
417432
transform: `translateX(-${headerScrollLeft[`value-${index}`] || 0}px)`,
418433
}}
419434
>
420-
{formatDisplayText(value || '')}
435+
{formatDisplayText(value || '', {
436+
accessiblePrefixes,
437+
highlightAll: !accessiblePrefixes,
438+
})}
421439
</div>
422440
</div>
423441
</div>

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1977,6 +1977,7 @@ export function ToolInput({
19771977
// Refresh MCP tools when a new server is created
19781978
refreshTools(true)
19791979
}}
1980+
blockId={blockId}
19801981
/>
19811982
</div>
19821983
)
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { useMemo } from 'react'
2+
import { shallow } from 'zustand/shallow'
3+
import { BlockPathCalculator } from '@/lib/block-path-calculator'
4+
import { SYSTEM_REFERENCE_PREFIXES } from '@/lib/workflows/references'
5+
import { normalizeBlockName } from '@/stores/workflows/utils'
6+
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
7+
import type { Loop, Parallel } from '@/stores/workflows/workflow/types'
8+
9+
export function useAccessibleReferencePrefixes(blockId?: string | null): Set<string> | undefined {
10+
const { blocks, edges, loops, parallels } = useWorkflowStore(
11+
(state) => ({
12+
blocks: state.blocks,
13+
edges: state.edges,
14+
loops: state.loops || {},
15+
parallels: state.parallels || {},
16+
}),
17+
shallow
18+
)
19+
20+
return useMemo(() => {
21+
if (!blockId) {
22+
return undefined
23+
}
24+
25+
const graphEdges = edges.map((edge) => ({ source: edge.source, target: edge.target }))
26+
const ancestorIds = BlockPathCalculator.findAllPathNodes(graphEdges, blockId)
27+
const accessibleIds = new Set<string>(ancestorIds)
28+
accessibleIds.add(blockId)
29+
30+
const starterBlock = Object.values(blocks).find((block) => block.type === 'starter')
31+
if (starterBlock) {
32+
accessibleIds.add(starterBlock.id)
33+
}
34+
35+
const loopValues = Object.values(loops as Record<string, Loop>)
36+
loopValues.forEach((loop) => {
37+
if (!loop?.nodes) return
38+
if (loop.nodes.includes(blockId)) {
39+
loop.nodes.forEach((nodeId) => accessibleIds.add(nodeId))
40+
}
41+
})
42+
43+
const parallelValues = Object.values(parallels as Record<string, Parallel>)
44+
parallelValues.forEach((parallel) => {
45+
if (!parallel?.nodes) return
46+
if (parallel.nodes.includes(blockId)) {
47+
parallel.nodes.forEach((nodeId) => accessibleIds.add(nodeId))
48+
}
49+
})
50+
51+
const prefixes = new Set<string>()
52+
accessibleIds.forEach((id) => {
53+
prefixes.add(normalizeBlockName(id))
54+
const block = blocks[id]
55+
if (block?.name) {
56+
prefixes.add(normalizeBlockName(block.name))
57+
}
58+
})
59+
60+
SYSTEM_REFERENCE_PREFIXES.forEach((prefix) => prefixes.add(prefix))
61+
62+
return prefixes
63+
}, [blockId, blocks, edges, loops, parallels])
64+
}

0 commit comments

Comments
 (0)