fix: Filter Selection Icon Missing #13901 (#13950)

Fixed issue #13901



https://github.com/user-attachments/assets/4aa7d0f3-88b8-474f-85e5-b2989ed8afdd

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Kailash Rajput
2025-08-18 20:24:26 +05:30
committed by GitHub
parent 43bb8d6043
commit 5e905d3004
27 changed files with 505 additions and 2110 deletions
@@ -31,7 +31,7 @@ export type BaseOutputSchema = Record<string, Leaf | Node>;
export type FieldOutputSchema =
| ((Leaf | Node) & {
fieldMetadataId?: string;
fieldMetadataId: string;
})
| RecordOutputSchema;
@@ -10,7 +10,7 @@ const companyMockObjectMetadataItem = mockObjectMetadataItemsWithFieldMaps.find(
describe('generateFakeFormResponse', () => {
it('should generate fake responses for a form schema', async () => {
const schema: FormFieldMetadata[] = [
const formFieldMetadataItems: FormFieldMetadata[] = [
{
id: '96939213-49ac-4dee-949d-56e6c7be98e6',
name: 'name',
@@ -51,8 +51,8 @@ describe('generateFakeFormResponse', () => {
},
};
const result = await generateFakeFormResponse({
formMetadata: schema,
const result = generateFakeFormResponse({
formFieldMetadataItems,
objectMetadataMaps: mockObjectMetadataMaps,
});
@@ -1,7 +1,7 @@
import { FieldMetadataType } from 'twenty-shared/types';
import * as generateFakeValueModule from 'src/engine/utils/generate-fake-value';
import { generateFakeField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-field';
import { generateFakeRecordField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-record-field';
import * as camelToTitleCaseModule from 'src/utils/camel-to-title-case';
jest.mock('src/engine/utils/generate-fake-value');
@@ -52,7 +52,7 @@ describe('generateFakeField', () => {
it('should generate a leaf node for TEXT type', () => {
generateFakeValueSpy.mockReturnValueOnce('Fake Text');
const result = generateFakeField({
const result = generateFakeRecordField({
type: FieldMetadataType.TEXT,
label: 'Text Field',
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
@@ -74,7 +74,7 @@ describe('generateFakeField', () => {
});
it('should handle custom value', () => {
const result = generateFakeField({
const result = generateFakeRecordField({
type: FieldMetadataType.TEXT,
label: 'Text Field',
value: 'Test value',
@@ -96,7 +96,7 @@ describe('generateFakeField', () => {
it('should generate a leaf node for NUMBER type with icon', () => {
generateFakeValueSpy.mockReturnValueOnce(42);
const result = generateFakeField({
const result = generateFakeRecordField({
type: FieldMetadataType.NUMBER,
label: 'Number Field',
icon: 'IconNumber',
@@ -118,7 +118,7 @@ describe('generateFakeField', () => {
generateFakeValueSpy.mockReturnValueOnce(fakeDate);
const result = generateFakeField({
const result = generateFakeRecordField({
type: FieldMetadataType.DATE,
label: 'Date Field',
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
@@ -145,7 +145,7 @@ describe('generateFakeField', () => {
.mockReturnValueOnce('Label')
.mockReturnValueOnce('Url');
const result = generateFakeField({
const result = generateFakeRecordField({
type: FieldMetadataType.LINKS,
label: 'Links Field',
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
@@ -189,7 +189,7 @@ describe('generateFakeField', () => {
.mockReturnValueOnce('Amount')
.mockReturnValueOnce('Currency Code');
const result = generateFakeField({
const result = generateFakeRecordField({
type: FieldMetadataType.CURRENCY,
label: 'Currency Field',
icon: 'IconCurrency',
@@ -230,7 +230,7 @@ describe('generateFakeField', () => {
generateFakeValueSpy.mockReturnValueOnce('Unknown Value');
const result = generateFakeField({
const result = generateFakeRecordField({
type: unknownType,
label: 'Unknown Field',
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
@@ -249,7 +249,7 @@ describe('generateFakeField', () => {
it('should handle empty label', () => {
generateFakeValueSpy.mockReturnValueOnce('Fake Boolean');
const result = generateFakeField({
const result = generateFakeRecordField({
type: FieldMetadataType.BOOLEAN,
label: '',
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
@@ -1,12 +1,12 @@
import { FieldMetadataType } from 'twenty-shared/types';
import { generateFakeField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-field';
import { mockObjectMetadataItemsWithFieldMaps } from 'src/engine/core-modules/__mocks__/mockObjectMetadataItemsWithFieldMaps';
import { generateFakeRecordField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-record-field';
import { generateObjectRecordFields } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-object-record-fields';
import { shouldGenerateFieldFakeValue } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/should-generate-field-fake-value';
import { mockObjectMetadataItemsWithFieldMaps } from 'src/engine/core-modules/__mocks__/mockObjectMetadataItemsWithFieldMaps';
jest.mock(
'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-field',
'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-record-field',
);
jest.mock(
'src/modules/workflow/workflow-builder/workflow-schema/utils/should-generate-field-fake-value',
@@ -42,7 +42,7 @@ describe('generateObjectRecordFields', () => {
(field) => field.type !== FieldMetadataType.RELATION,
);
(generateFakeField as jest.Mock).mockImplementation(
(generateFakeRecordField as jest.Mock).mockImplementation(
({ type, label, icon }) => ({
type,
label,
@@ -69,7 +69,7 @@ describe('generateObjectRecordFields', () => {
});
expect(shouldGenerateFieldFakeValue).toHaveBeenCalledTimes(2);
expect(generateFakeField).toHaveBeenCalledTimes(2);
expect(generateFakeRecordField).toHaveBeenCalledTimes(2);
});
it('should return empty object when no valid fields', () => {
@@ -79,6 +79,6 @@ describe('generateObjectRecordFields', () => {
expect(result).toEqual({});
expect(shouldGenerateFieldFakeValue).toHaveBeenCalledTimes(2);
expect(generateFakeField).not.toHaveBeenCalled();
expect(generateFakeRecordField).not.toHaveBeenCalled();
});
});
@@ -0,0 +1,26 @@
import { type FieldMetadataType } from 'twenty-shared/types';
import { generateFakeValue } from 'src/engine/utils/generate-fake-value';
import {
type Leaf,
type Node,
} from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type';
type GenerateFakeFormFieldArgs = {
type: FieldMetadataType;
label: string;
value?: string;
};
export const generateFakeFormField = ({
type,
label,
value,
}: GenerateFakeFormFieldArgs): Leaf | Node => {
return {
isLeaf: true,
type: type,
label: label,
value: value ?? generateFakeValue(type, 'FieldMetadataType'),
};
};
@@ -6,59 +6,59 @@ import {
type Leaf,
type Node,
} from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type';
import { generateFakeField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-field';
import { generateFakeFormField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-form-field';
import { generateFakeObjectRecord } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record';
import { type FormFieldMetadata } from 'src/modules/workflow/workflow-executor/workflow-actions/form/types/workflow-form-action-settings.type';
export const generateFakeFormResponse = async ({
formMetadata,
objectMetadataMaps,
}: {
formMetadata: FormFieldMetadata[];
type GenerateFakeFormResponseArgs = {
formFieldMetadataItems: FormFieldMetadata[];
objectMetadataMaps: ObjectMetadataMaps;
}): Promise<Record<string, Leaf | Node>> => {
const result = await Promise.all(
formMetadata.map(async (formFieldMetadata) => {
if (formFieldMetadata.type === 'RECORD') {
if (!formFieldMetadata?.settings?.objectName) {
return undefined;
}
};
const objectMetadataItemWithFieldsMaps =
getObjectMetadataMapItemByNameSingular(
objectMetadataMaps,
formFieldMetadata?.settings?.objectName,
);
if (!isDefined(objectMetadataItemWithFieldsMaps)) {
throw new Error(
`Object metadata not found for object name ${formFieldMetadata?.settings?.objectName}`,
);
}
return {
[formFieldMetadata.name]: {
isLeaf: false,
label: formFieldMetadata.label,
value: generateFakeObjectRecord({
objectMetadataInfo: {
objectMetadataItemWithFieldsMaps,
objectMetadataMaps,
},
}),
},
};
} else {
return {
[formFieldMetadata.name]: generateFakeField({
type: formFieldMetadata.type,
label: formFieldMetadata.label,
value: formFieldMetadata.placeholder,
}),
};
export const generateFakeFormResponse = ({
formFieldMetadataItems,
objectMetadataMaps,
}: GenerateFakeFormResponseArgs): Record<string, Leaf | Node> => {
const result = formFieldMetadataItems.map((formFieldMetadata) => {
if (formFieldMetadata.type === 'RECORD') {
if (!formFieldMetadata?.settings?.objectName) {
return undefined;
}
}),
);
const objectMetadataItemWithFieldsMaps =
getObjectMetadataMapItemByNameSingular(
objectMetadataMaps,
formFieldMetadata?.settings?.objectName,
);
if (!isDefined(objectMetadataItemWithFieldsMaps)) {
throw new Error(
`Object metadata not found for object name ${formFieldMetadata?.settings?.objectName}`,
);
}
return {
[formFieldMetadata.name]: {
isLeaf: false,
label: formFieldMetadata.label,
value: generateFakeObjectRecord({
objectMetadataInfo: {
objectMetadataItemWithFieldsMaps,
objectMetadataMaps,
},
}),
},
};
} else {
return {
[formFieldMetadata.name]: generateFakeFormField({
type: formFieldMetadata.type,
label: formFieldMetadata.label,
value: formFieldMetadata.placeholder,
}),
};
}
});
return result.filter(isDefined).reduce(
(acc, curr) => {
@@ -8,19 +8,23 @@ import {
} from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type';
import { camelToTitleCase } from 'src/utils/camel-to-title-case';
export const generateFakeField = ({
type GenerateFakeRecordFieldArgs = {
type: FieldMetadataType;
label: string;
fieldMetadataId: string;
icon?: string;
value?: string;
};
export const generateFakeRecordField = ({
type,
label,
icon,
value,
fieldMetadataId,
}: {
type: FieldMetadataType;
label: string;
fieldMetadataId?: string;
icon?: string;
value?: string;
}): (Leaf | Node) & { fieldMetadataId?: string } => {
}: GenerateFakeRecordFieldArgs): (Leaf | Node) & {
fieldMetadataId: string;
} => {
const compositeType = compositeTypeDefinitions.get(type);
if (compositeType) {
@@ -3,8 +3,8 @@ import { isDefined } from 'twenty-shared/utils';
import { type ObjectMetadataInfo } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
import { type FieldOutputSchema } from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type';
import { generateFakeField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-field';
import { generateFakeObjectRecord } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record';
import { generateFakeRecordField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-record-field';
import { shouldGenerateFieldFakeValue } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/should-generate-field-fake-value';
const MAXIMUM_DEPTH = 1;
@@ -25,7 +25,7 @@ export const generateObjectRecordFields = ({
}
if (field.type !== FieldMetadataType.RELATION) {
acc[field.name] = generateFakeField({
acc[field.name] = generateFakeRecordField({
type: field.type,
label: field.label,
icon: field.icon ?? undefined,
@@ -73,7 +73,7 @@ export class WorkflowSchemaWorkspaceService {
});
case WorkflowActionType.FORM:
return this.computeFormActionOutputSchema({
formMetadata: step.settings.input,
formFieldMetadataItems: step.settings.input,
workspaceId,
});
case WorkflowActionType.CODE: // StepOutput schema is computed on serverlessFunction draft execution
@@ -156,10 +156,10 @@ export class WorkflowSchemaWorkspaceService {
}
private async computeFormActionOutputSchema({
formMetadata,
formFieldMetadataItems,
workspaceId,
}: {
formMetadata: FormFieldMetadata[];
formFieldMetadataItems: FormFieldMetadata[];
workspaceId: string;
}): Promise<OutputSchema> {
const objectMetadataMaps =
@@ -168,7 +168,7 @@ export class WorkflowSchemaWorkspaceService {
);
return generateFakeFormResponse({
formMetadata,
formFieldMetadataItems,
objectMetadataMaps,
});
}