Skip to content

Commit cbc98ab

Browse files
fix(variables): display name rendering (#1915)
* fix(variables): display name rendering * cleanup * cleanup more code
1 parent 81411c7 commit cbc98ab

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

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

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { SELECTOR_TYPES_HYDRATION_REQUIRED, type SubBlockConfig } from '@/blocks
1616
import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
1717
import { useCredentialDisplay } from '@/hooks/use-credential-display'
1818
import { useDisplayName } from '@/hooks/use-display-name'
19+
import { useVariablesStore } from '@/stores/panel/variables/store'
1920
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
2021
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
2122
import { ActionBar, Connections } from './components'
@@ -77,12 +78,38 @@ const isPlainObject = (value: unknown): value is Record<string, unknown> => {
7778
return typeof value === 'object' && value !== null && !Array.isArray(value)
7879
}
7980

81+
/**
82+
* Type guard for variable assignments array
83+
*/
84+
const isVariableAssignmentsArray = (
85+
value: unknown
86+
): value is Array<{ id?: string; variableId?: string; variableName?: string; value: any }> => {
87+
return (
88+
Array.isArray(value) &&
89+
value.length > 0 &&
90+
value.every(
91+
(item) =>
92+
typeof item === 'object' &&
93+
item !== null &&
94+
('variableName' in item || 'variableId' in item)
95+
)
96+
)
97+
}
98+
8099
/**
81100
* Formats a subblock value for display, intelligently handling nested objects and arrays.
82101
*/
83102
const getDisplayValue = (value: unknown): string => {
84103
if (value == null || value === '') return '-'
85104

105+
if (isVariableAssignmentsArray(value)) {
106+
const names = value.map((a) => a.variableName).filter((name): name is string => !!name)
107+
if (names.length === 0) return '-'
108+
if (names.length === 1) return names[0]
109+
if (names.length === 2) return `${names[0]}, ${names[1]}`
110+
return `${names[0]}, ${names[1]} +${names.length - 2}`
111+
}
112+
86113
if (isTableRowArray(value)) {
87114
const nonEmptyRows = value.filter((row) => {
88115
const cellValues = Object.values(row.cells)
@@ -172,13 +199,15 @@ const SubBlockRow = ({
172199
subBlock,
173200
rawValue,
174201
workspaceId,
202+
workflowId,
175203
allSubBlockValues,
176204
}: {
177205
title: string
178206
value?: string
179207
subBlock?: SubBlockConfig
180208
rawValue?: unknown
181209
workspaceId?: string
210+
workflowId?: string
182211
allSubBlockValues?: Record<string, { value: unknown }>
183212
}) => {
184213
const getStringValue = useCallback(
@@ -235,11 +264,43 @@ const SubBlockRow = ({
235264
planId: getStringValue('planId'),
236265
})
237266

267+
// Subscribe to variables store to reactively update when variables change
268+
const allVariables = useVariablesStore((state) => state.variables)
269+
270+
// Special handling for variables-input to hydrate variable IDs to names from variables store
271+
const variablesDisplayValue = useMemo(() => {
272+
if (subBlock?.type !== 'variables-input' || !isVariableAssignmentsArray(rawValue)) {
273+
return null
274+
}
275+
276+
const workflowVariables = Object.values(allVariables).filter(
277+
(v: any) => v.workflowId === workflowId
278+
)
279+
280+
const names = rawValue
281+
.map((a) => {
282+
// Prioritize ID lookup (source of truth) over stored name
283+
if (a.variableId) {
284+
const variable = workflowVariables.find((v: any) => v.id === a.variableId)
285+
return variable?.name
286+
}
287+
if (a.variableName) return a.variableName
288+
return null
289+
})
290+
.filter((name): name is string => !!name)
291+
292+
if (names.length === 0) return null
293+
if (names.length === 1) return names[0]
294+
if (names.length === 2) return `${names[0]}, ${names[1]}`
295+
return `${names[0]}, ${names[1]} +${names.length - 2}`
296+
}, [subBlock?.type, rawValue, workflowId, allVariables])
297+
238298
const isPasswordField = subBlock?.password === true
239299
const maskedValue = isPasswordField && value && value !== '-' ? '•••' : null
240300

241301
const isSelectorType = subBlock?.type && SELECTOR_TYPES_HYDRATION_REQUIRED.includes(subBlock.type)
242-
const hydratedName = credentialName || dropdownLabel || genericDisplayName
302+
const hydratedName =
303+
credentialName || dropdownLabel || variablesDisplayValue || genericDisplayName
243304
const displayValue = maskedValue || hydratedName || (isSelectorType && value ? '-' : value)
244305

245306
return (
@@ -840,6 +901,7 @@ export const WorkflowBlock = memo(function WorkflowBlock({
840901
subBlock={subBlock}
841902
rawValue={rawValue}
842903
workspaceId={workspaceId}
904+
workflowId={currentWorkflowId}
843905
allSubBlockValues={subBlockState}
844906
/>
845907
)

apps/sim/blocks/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export const SELECTOR_TYPES_HYDRATION_REQUIRED: SubBlockType[] = [
8585
'project-selector',
8686
'knowledge-base-selector',
8787
'document-selector',
88+
'variables-input',
8889
] as const
8990

9091
export type ExtractToolOutput<T> = T extends ToolResponse ? T['output'] : never

0 commit comments

Comments
 (0)