diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterFieldSelect.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterFieldSelect.tsx index d860bcae1a..862a8dfad0 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterFieldSelect.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterFieldSelect.tsx @@ -15,11 +15,17 @@ import { useContext } from 'react'; import { useRecoilCallback, useRecoilValue } from 'recoil'; import { StepFilter } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; +import { FieldMetadataType } from '~/generated-metadata/graphql'; type WorkflowStepFilterFieldSelectProps = { stepFilter: StepFilter; }; +const NON_SELECTABLE_FIELD_TYPES = [ + FieldMetadataType.ACTOR, + FieldMetadataType.RICH_TEXT_V2, +]; + export const WorkflowStepFilterFieldSelect = ({ stepFilter, }: WorkflowStepFilterFieldSelectProps) => { @@ -163,6 +169,7 @@ export const WorkflowStepFilterFieldSelect = ({ shouldDisplayRecordFields={shouldDisplayRecordFields} shouldDisplayRecordObjects={shouldDisplayRecordObjects} shouldEnableSelectRelationObject={true} + fieldTypesToExclude={NON_SELECTABLE_FIELD_TYPES} /> ); }; diff --git a/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdown.tsx b/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdown.tsx index f43cfde282..0913b6e54d 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdown.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdown.tsx @@ -3,6 +3,7 @@ import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/S import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; +import { InputSchemaPropertyType } from '@/workflow/types/InputSchema'; import { WorkflowVariablesDropdownAllItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownAllItems'; import { WorkflowVariablesDropdownFieldItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownFieldItems'; import { WorkflowVariablesDropdownWorkflowStepItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownWorkflowStepItems'; @@ -37,6 +38,7 @@ export const WorkflowVariablesDropdown = ({ disabled, shouldDisplayRecordFields, shouldDisplayRecordObjects, + fieldTypesToExclude, shouldEnableSelectRelationObject, multiline, clickableComponent, @@ -45,6 +47,7 @@ export const WorkflowVariablesDropdown = ({ onVariableSelect: (variableName: string) => void; shouldDisplayRecordFields: boolean; shouldDisplayRecordObjects: boolean; + fieldTypesToExclude?: InputSchemaPropertyType[]; shouldEnableSelectRelationObject?: boolean; disabled?: boolean; multiline?: boolean; @@ -61,6 +64,7 @@ export const WorkflowVariablesDropdown = ({ const availableVariablesInWorkflowStep = useAvailableVariablesInWorkflowStep({ shouldDisplayRecordFields, shouldDisplayRecordObjects, + fieldTypesToExclude, }); const noAvailableVariables = availableVariablesInWorkflowStep.length === 0; diff --git a/packages/twenty-front/src/modules/workflow/workflow-variables/hooks/useAvailableVariablesInWorkflowStep.ts b/packages/twenty-front/src/modules/workflow/workflow-variables/hooks/useAvailableVariablesInWorkflowStep.ts index 7444754b4f..2b0fbff7cb 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-variables/hooks/useAvailableVariablesInWorkflowStep.ts +++ b/packages/twenty-front/src/modules/workflow/workflow-variables/hooks/useAvailableVariablesInWorkflowStep.ts @@ -1,5 +1,6 @@ import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow'; import { stepsOutputSchemaFamilySelector } from '@/workflow/states/selectors/stepsOutputSchemaFamilySelector'; +import { InputSchemaPropertyType } from '@/workflow/types/InputSchema'; import { useWorkflowSelectedNodeOrThrow } from '@/workflow/workflow-diagram/hooks/useWorkflowSelectedNodeOrThrow'; import { getPreviousSteps } from '@/workflow/workflow-steps/utils/getWorkflowPreviousSteps'; import { TRIGGER_STEP_ID } from '@/workflow/workflow-trigger/constants/TriggerStepId'; @@ -15,9 +16,11 @@ import { isEmptyObject } from '~/utils/isEmptyObject'; export const useAvailableVariablesInWorkflowStep = ({ shouldDisplayRecordFields, shouldDisplayRecordObjects, + fieldTypesToExclude, }: { shouldDisplayRecordFields: boolean; shouldDisplayRecordObjects: boolean; + fieldTypesToExclude?: InputSchemaPropertyType[]; }): StepOutputSchema[] => { const workflowSelectedNode = useWorkflowSelectedNodeOrThrow(); const flow = useFlowOrThrow(); @@ -41,6 +44,7 @@ export const useAvailableVariablesInWorkflowStep = ({ shouldDisplayRecordFields, shouldDisplayRecordObjects, outputSchema: stepOutputSchema.outputSchema, + fieldTypesToExclude, }) as OutputSchema; if (!isDefined(outputSchema) || isEmptyObject(outputSchema)) { diff --git a/packages/twenty-front/src/modules/workflow/workflow-variables/utils/__tests__/filterOutputSchema.test.ts b/packages/twenty-front/src/modules/workflow/workflow-variables/utils/__tests__/filterOutputSchema.test.ts index dfeee661ac..086671d128 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-variables/utils/__tests__/filterOutputSchema.test.ts +++ b/packages/twenty-front/src/modules/workflow/workflow-variables/utils/__tests__/filterOutputSchema.test.ts @@ -225,4 +225,44 @@ describe('filterOutputSchema', () => { ).toBeUndefined(); }); }); + + describe('fieldTypesToExclude', () => { + it('should filter out the types', () => { + const inputSchema = createRecordSchema('person', { + name: { isLeaf: true, type: undefined, value: 'toto' }, + age: { isLeaf: true, type: FieldMetadataType.NUMBER }, + id: { isLeaf: true, type: FieldMetadataType.UUID }, + }); + + const expectedSchema = createRecordSchema('person', { + name: { isLeaf: true, type: undefined, value: 'toto' }, + age: { isLeaf: true, type: FieldMetadataType.NUMBER }, + }); + + expect( + filterOutputSchema({ + shouldDisplayRecordFields: true, + shouldDisplayRecordObjects: false, + outputSchema: inputSchema, + fieldTypesToExclude: [FieldMetadataType.UUID], + }), + ).toEqual(expectedSchema); + }); + + it('should return the same schema if no types to filter', () => { + const inputSchema = createRecordSchema('person', { + name: { isLeaf: true, value: 'string' }, + id: { isLeaf: true, type: FieldMetadataType.UUID }, + }); + + expect( + filterOutputSchema({ + shouldDisplayRecordFields: true, + shouldDisplayRecordObjects: false, + outputSchema: inputSchema, + fieldTypesToExclude: [], + }), + ).toEqual(inputSchema); + }); + }); }); diff --git a/packages/twenty-front/src/modules/workflow/workflow-variables/utils/filterOutputSchema.ts b/packages/twenty-front/src/modules/workflow/workflow-variables/utils/filterOutputSchema.ts index db96e53838..188fb04ab7 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-variables/utils/filterOutputSchema.ts +++ b/packages/twenty-front/src/modules/workflow/workflow-variables/utils/filterOutputSchema.ts @@ -1,3 +1,4 @@ +import { InputSchemaPropertyType } from '@/workflow/types/InputSchema'; import { BaseOutputSchema, OutputSchema, @@ -128,20 +129,55 @@ const filterBaseOutputSchema = ({ return undefined; }; +const filterRecordOutputSchemaFieldsByType = ({ + outputSchema, + fieldTypesToExclude, +}: { + outputSchema: RecordOutputSchema; + fieldTypesToExclude: InputSchemaPropertyType[]; +}) => { + const filteredFields: BaseOutputSchema = {}; + + for (const key in outputSchema.fields) { + const field = outputSchema.fields[key]; + + if (isDefined(field.type) && fieldTypesToExclude.includes(field.type)) { + continue; + } + + filteredFields[key] = field; + } + + return { + ...outputSchema, + // Relations could be filtered recursively but this util requires a global simplification first + fields: filteredFields, + }; +}; + export const filterOutputSchema = ({ shouldDisplayRecordFields, shouldDisplayRecordObjects, outputSchema, + fieldTypesToExclude, }: { shouldDisplayRecordFields: boolean; shouldDisplayRecordObjects: boolean; outputSchema?: OutputSchema; + fieldTypesToExclude?: InputSchemaPropertyType[]; }): OutputSchema | undefined => { - if ( - !shouldDisplayRecordObjects || - shouldDisplayRecordFields || - !outputSchema - ) { + if (!isDefined(outputSchema)) { + return undefined; + } + + if (!shouldDisplayRecordObjects || shouldDisplayRecordFields) { + if (isRecordOutputSchema(outputSchema) && isDefined(fieldTypesToExclude)) { + return filterRecordOutputSchemaFieldsByType({ + outputSchema, + fieldTypesToExclude, + }); + } + return outputSchema; }