From 659ed6b080b3ed849eeda71678124d94e0315ac6 Mon Sep 17 00:00:00 2001
From: Lucky Goyal <74194341+LuckyGoyal039@users.noreply.github.com>
Date: Wed, 17 Dec 2025 15:43:10 +0530
Subject: [PATCH] feat: add full path label tooltip for workflow filter field
(#16580)
# Closes Issue: Can't distinguish between fields with identical names
(#16285)
There was a UX bug in the workflow filter interface where **two
variables coming from different steps but sharing the same field name**
were displayed identically. This made it difficult for users to tell
them apart when used in a filter group, leading to confusion when
building workflows.
---
# Fix: Add Full Path Label Tooltip for Workflow Filter Field
- Adds a **tooltip/label showing the complete path** so users can
distinguish fields from different workflow steps even if they share the
same name.
## UX Improvements
---
.../ui/input/components/SelectControl.tsx | 1 +
.../WorkflowStepFilterFieldSelect.tsx | 4 +++-
.../hooks/useStepsOutputSchema.ts | 2 ++
.../types/StepOutputSchemaV2.ts | 1 +
...hVariableThroughFindRecordsOutputSchema.ts | 20 +++++++++++++++----
.../searchVariableThroughOutputSchemaV2.ts | 1 +
...searchVariableThroughRecordOutputSchema.ts | 9 ++++++++-
.../twenty-ui/src/input/types/SelectOption.ts | 1 +
8 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/packages/twenty-front/src/modules/ui/input/components/SelectControl.tsx b/packages/twenty-front/src/modules/ui/input/components/SelectControl.tsx
index baa521b0bb..2208921676 100644
--- a/packages/twenty-front/src/modules/ui/input/components/SelectControl.tsx
+++ b/packages/twenty-front/src/modules/ui/input/components/SelectControl.tsx
@@ -84,6 +84,7 @@ export const SelectControl = ({
selectSizeVariant={selectSizeVariant}
textAccent={textAccent}
hasRightElement={hasRightElement}
+ title={selectedOption.fullLabel}
>
{isDefined(selectedOption?.Icon) ? (
{
type: step.type,
icon: getActionIcon(step.type),
outputSchema: (outputSchema ?? {}) as OutputSchemaV2,
+ objectName: (step.settings?.input as { objectName?: string })
+ ?.objectName,
};
set(stepsOutputSchemaFamilyState(stepKey), stepOutputSchema);
diff --git a/packages/twenty-front/src/modules/workflow/workflow-variables/types/StepOutputSchemaV2.ts b/packages/twenty-front/src/modules/workflow/workflow-variables/types/StepOutputSchemaV2.ts
index 8cdeb33e13..f64e2ede4b 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-variables/types/StepOutputSchemaV2.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-variables/types/StepOutputSchemaV2.ts
@@ -25,4 +25,5 @@ export type StepOutputSchemaV2 = {
type: WorkflowTriggerType | WorkflowActionType;
icon?: string;
outputSchema: OutputSchemaV2;
+ objectName?: string;
};
diff --git a/packages/twenty-front/src/modules/workflow/workflow-variables/utils/searchVariableThroughFindRecordsOutputSchema.ts b/packages/twenty-front/src/modules/workflow/workflow-variables/utils/searchVariableThroughFindRecordsOutputSchema.ts
index 7f8d5200f3..cd8b157d2e 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-variables/utils/searchVariableThroughFindRecordsOutputSchema.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-variables/utils/searchVariableThroughFindRecordsOutputSchema.ts
@@ -45,11 +45,13 @@ export const searchVariableThroughFindRecordsOutputSchema = ({
searchRecordOutputSchema,
rawVariableName,
isFullRecord = false,
+ stepNameLabel,
}: {
stepName: string;
searchRecordOutputSchema: FindRecordsOutputSchema;
rawVariableName: string;
isFullRecord?: boolean;
+ stepNameLabel?: string;
}): VariableSearchResult => {
if (!isDefined(searchRecordOutputSchema)) {
return {
@@ -84,23 +86,33 @@ export const searchVariableThroughFindRecordsOutputSchema = ({
selectedField: fieldName,
path: pathSegments,
isFullRecord,
+ stepNameLabel,
});
}
if (searchResultKey === 'totalCount') {
+ const label =
+ searchRecordOutputSchema[searchResultKey]?.label ?? 'Total Count';
+ const basePath = `${stepName} > ${label}`;
return {
- variableLabel:
- searchRecordOutputSchema[searchResultKey]?.label ?? 'Total Count',
- variablePathLabel: `${stepName} > ${searchRecordOutputSchema[searchResultKey]?.label ?? 'Total Count'}`,
+ variableLabel: label,
+ variablePathLabel: stepNameLabel
+ ? `${basePath} (${stepNameLabel})`
+ : basePath,
variableType: FieldMetadataType.NUMBER,
};
}
if (searchResultKey === 'all') {
+ const label =
+ searchRecordOutputSchema[searchResultKey]?.label ?? 'All Records';
+ const basePath = `${stepName} > ${label}`;
return {
variableLabel:
searchRecordOutputSchema[searchResultKey]?.label ?? 'All Records',
- variablePathLabel: `${stepName} > ${searchRecordOutputSchema[searchResultKey]?.label ?? 'All Records'}`,
+ variablePathLabel: stepNameLabel
+ ? `${basePath} (${stepNameLabel})`
+ : basePath,
variableType: FieldMetadataType.ARRAY,
};
}
diff --git a/packages/twenty-front/src/modules/workflow/workflow-variables/utils/searchVariableThroughOutputSchemaV2.ts b/packages/twenty-front/src/modules/workflow/workflow-variables/utils/searchVariableThroughOutputSchemaV2.ts
index 41415dcc4a..a5c3a259b8 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-variables/utils/searchVariableThroughOutputSchemaV2.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-variables/utils/searchVariableThroughOutputSchemaV2.ts
@@ -66,6 +66,7 @@ export const searchVariableThroughOutputSchemaV2 = ({
searchRecordOutputSchema: stepOutputSchema.outputSchema,
rawVariableName,
isFullRecord,
+ stepNameLabel: stepOutputSchema.objectName,
});
}
diff --git a/packages/twenty-front/src/modules/workflow/workflow-variables/utils/searchVariableThroughRecordOutputSchema.ts b/packages/twenty-front/src/modules/workflow/workflow-variables/utils/searchVariableThroughRecordOutputSchema.ts
index f53af8cb51..6c14f57ee0 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-variables/utils/searchVariableThroughRecordOutputSchema.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-variables/utils/searchVariableThroughRecordOutputSchema.ts
@@ -77,6 +77,7 @@ const buildVariableResult = (
targetSchema: RecordFieldNodeValue,
targetFieldName: string,
isFullRecord: boolean,
+ stepNameLabel?: string,
): VariableSearchResult => {
const targetField = getFieldFromSchema(targetFieldName, targetSchema);
// Determine the variable label based on whether we want the full record or a specific field
@@ -97,7 +98,10 @@ const buildVariableResult = (
// Build the full path: stepName > field1 > field2 > targetField
const fullPathSegments = [stepName, ...pathLabels, variableLabel];
- const variablePathLabel = fullPathSegments.join(' > ');
+ const basePath = fullPathSegments.join(' > ');
+ const variablePathLabel = stepNameLabel
+ ? `${basePath} (${stepNameLabel})`
+ : basePath;
return {
variableLabel,
@@ -117,12 +121,14 @@ export const searchRecordOutputSchema = ({
path,
selectedField,
isFullRecord,
+ stepNameLabel,
}: {
stepName: string;
recordOutputSchema: RecordOutputSchemaV2;
path: string[];
selectedField: string;
isFullRecord: boolean;
+ stepNameLabel?: string;
}): VariableSearchResult => {
const navigationResult = navigateToTargetField(recordOutputSchema, path);
@@ -140,6 +146,7 @@ export const searchRecordOutputSchema = ({
navigationResult.schema,
selectedField,
isFullRecord,
+ stepNameLabel,
);
};
diff --git a/packages/twenty-ui/src/input/types/SelectOption.ts b/packages/twenty-ui/src/input/types/SelectOption.ts
index 9cf4d7f6d3..949eae8771 100644
--- a/packages/twenty-ui/src/input/types/SelectOption.ts
+++ b/packages/twenty-ui/src/input/types/SelectOption.ts
@@ -6,6 +6,7 @@ export type SelectOption<
> = {
Icon?: IconComponent | null;
label: string;
+ fullLabel?: string;
value: Value;
disabled?: boolean;
color?: ThemeColor | 'transparent';