Search record action - allow to search more than 1 record (#14769)

https://github.com/user-attachments/assets/426da6af-6c6b-4d49-9034-0aa041cb331f
This commit is contained in:
Thomas Trompette
2025-09-30 12:07:25 +02:00
committed by GitHub
parent 4b87908752
commit b7cdf9183a
9 changed files with 177 additions and 47 deletions
@@ -1,7 +1,8 @@
import type { Leaf } from '@/workflow/workflow-variables/types/BaseOutputSchemaV2';
import { type RecordNode } from '@/workflow/workflow-variables/types/RecordNode';
export type FindRecordsOutputSchema = {
first: RecordNode;
last: RecordNode;
totalCount: number;
all: Leaf | undefined;
totalCount: Leaf;
};
@@ -36,12 +36,18 @@ describe('searchVariableThroughFindRecordsOutputSchema', () => {
label: 'First',
value: mockRecordSchema,
},
last: {
isLeaf: false,
label: 'Last',
value: mockRecordSchema,
all: {
isLeaf: true,
label: 'All',
value: 'Returns an array of records',
type: 'array',
},
totalCount: {
isLeaf: true,
label: 'Total Count',
value: 42,
type: 'number',
},
totalCount: 42,
};
it('should handle totalCount variable correctly', () => {
@@ -76,20 +82,18 @@ describe('searchVariableThroughFindRecordsOutputSchema', () => {
});
});
it('should handle last record field access correctly', () => {
it('should handle all records access correctly', () => {
const result = searchVariableThroughFindRecordsOutputSchema({
stepName: 'Find Companies',
searchRecordOutputSchema: mockSearchRecordSchema,
rawVariableName: '{{step1.last.revenue}}',
rawVariableName: '{{step1.all}}',
isFullRecord: false,
});
expect(result).toEqual({
variableLabel: 'Revenue',
variablePathLabel: 'Find Companies > Last > Revenue',
variableType: FieldMetadataType.NUMBER,
fieldMetadataId: 'company-revenue-metadata-id',
compositeFieldSubFieldName: undefined,
variableLabel: 'All',
variablePathLabel: 'Find Companies > All',
variableType: FieldMetadataType.ARRAY,
});
});
@@ -5,7 +5,7 @@ import { FieldMetadataType } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { CAPTURE_ALL_VARIABLE_TAG_INNER_REGEX } from 'twenty-shared/workflow';
type SearchResultKey = 'first' | 'last' | 'totalCount';
type SearchResultKey = 'first' | 'all' | 'totalCount';
/**
* Parses a variable name to extract its components for SearchRecord outputs
@@ -68,15 +68,7 @@ export const searchVariableThroughFindRecordsOutputSchema = ({
};
}
if (searchResultKey === 'totalCount') {
return {
variableLabel: 'Total Count',
variablePathLabel: `${stepName} > Total Count`,
variableType: FieldMetadataType.NUMBER,
};
}
if (searchResultKey === 'first' || searchResultKey === 'last') {
if (searchResultKey === 'first') {
const recordSchema = searchRecordOutputSchema[searchResultKey]?.value;
if (!isDefined(recordSchema) || !isDefined(fieldName)) {
@@ -87,7 +79,7 @@ export const searchVariableThroughFindRecordsOutputSchema = ({
}
return searchRecordOutputSchemaUtil({
stepName: `${stepName} > ${searchResultKey === 'first' ? 'First' : 'Last'}`,
stepName: `${stepName} > ${searchRecordOutputSchema[searchResultKey]?.label ?? 'First'}`,
recordOutputSchema: recordSchema,
selectedField: fieldName,
path: pathSegments,
@@ -95,6 +87,24 @@ export const searchVariableThroughFindRecordsOutputSchema = ({
});
}
if (searchResultKey === 'totalCount') {
return {
variableLabel:
searchRecordOutputSchema[searchResultKey]?.label ?? 'Total Count',
variablePathLabel: `${stepName} > ${searchRecordOutputSchema[searchResultKey]?.label ?? 'Total Count'}`,
variableType: FieldMetadataType.NUMBER,
};
}
if (searchResultKey === 'all') {
return {
variableLabel:
searchRecordOutputSchema[searchResultKey]?.label ?? 'All Records',
variablePathLabel: `${stepName} > ${searchRecordOutputSchema[searchResultKey]?.label ?? 'All Records'}`,
variableType: FieldMetadataType.ARRAY,
};
}
return {
variableLabel: undefined,
variablePathLabel: undefined,
@@ -76,6 +76,14 @@ export const searchVariableThroughIteratorOutputSchema = ({
if (iteratorResultKey === 'currentItem') {
const schema = iteratorOutputSchema.currentItem.value;
if (!isDefined(schema)) {
return {
variableLabel: undefined,
variablePathLabel: undefined,
};
}
if (isRecordOutputSchemaV2(schema) && isDefined(fieldName)) {
return searchRecordOutputSchema({
stepName: `${stepName} > Current Item`,