diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowDropdownStepOutputItems.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowDropdownStepOutputItems.tsx
new file mode 100644
index 0000000000..6b6130ff06
--- /dev/null
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowDropdownStepOutputItems.tsx
@@ -0,0 +1,238 @@
+import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
+import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
+import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
+import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
+import { type StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema';
+
+import { useGetFieldMetadataItemByIdOrThrow } from '@/object-metadata/hooks/useGetFieldMetadataItemById';
+import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
+import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
+import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
+import { useWorkflowVersionIdOrThrow } from '@/workflow/hooks/useWorkflowVersionIdOrThrow';
+import { stepsOutputSchemaFamilySelector } from '@/workflow/states/selectors/stepsOutputSchemaFamilySelector';
+import { useUpsertStepFilterSettings } from '@/workflow/workflow-steps/workflow-actions/filter-action/hooks/useUpsertStepFilterSettings';
+import { getStepFilterOperands } from '@/workflow/workflow-steps/workflow-actions/filter-action/utils/getStepFilterOperands';
+import { useVariableDropdown } from '@/workflow/workflow-variables/hooks/useVariableDropdown';
+import { extractRawVariableNamePart } from '@/workflow/workflow-variables/utils/extractRawVariableNamePart';
+import { getCurrentSubStepFromPath } from '@/workflow/workflow-variables/utils/getCurrentSubStepFromPath';
+import { getStepHeaderLabel } from '@/workflow/workflow-variables/utils/getStepHeaderLabel';
+import { getVariableTemplateFromPath } from '@/workflow/workflow-variables/utils/getVariableTemplateFromPath';
+import { isRecordOutputSchema } from '@/workflow/workflow-variables/utils/isRecordOutputSchema';
+import { searchVariableThroughOutputSchema } from '@/workflow/workflow-variables/utils/searchVariableThroughOutputSchema';
+import { useLingui } from '@lingui/react/macro';
+import { useRecoilCallback } from 'recoil';
+import { type StepFilter } from 'twenty-shared/types';
+import { isDefined } from 'twenty-shared/utils';
+import {
+ IconChevronLeft,
+ OverflowingTextWithTooltip,
+ useIcons,
+} from 'twenty-ui/display';
+import { MenuItemSelect } from 'twenty-ui/navigation';
+
+type WorkflowDropdownStepOutputItemsProps = {
+ stepFilter: StepFilter;
+ step: StepOutputSchema;
+ onSelect: () => void;
+ onBack: () => void;
+};
+
+export const WorkflowDropdownStepOutputItems = ({
+ stepFilter,
+ step,
+ onSelect,
+ onBack,
+}: WorkflowDropdownStepOutputItemsProps) => {
+ const { t } = useLingui();
+ const { getIcon } = useIcons();
+
+ const { upsertStepFilterSettings } = useUpsertStepFilterSettings();
+ const { getFieldMetadataItemByIdOrThrow } =
+ useGetFieldMetadataItemByIdOrThrow();
+
+ const workflowVersionId = useWorkflowVersionIdOrThrow();
+
+ const updateStepFilter = useRecoilCallback(
+ ({ snapshot }) =>
+ ({
+ rawVariableName,
+ isFullRecord,
+ }: {
+ rawVariableName: string;
+ isFullRecord: boolean;
+ }) => {
+ const stepId = extractRawVariableNamePart({
+ rawVariableName,
+ part: 'stepId',
+ });
+ const [currentStepOutputSchema] = snapshot
+ .getLoadable(
+ stepsOutputSchemaFamilySelector({
+ workflowVersionId,
+ stepIds: [stepId],
+ }),
+ )
+ .getValue();
+
+ const { variableType, fieldMetadataId, compositeFieldSubFieldName } =
+ searchVariableThroughOutputSchema({
+ stepOutputSchema: currentStepOutputSchema,
+ rawVariableName,
+ isFullRecord: false,
+ });
+
+ const { fieldMetadataItem: filterFieldMetadataItem } = isDefined(
+ fieldMetadataId,
+ )
+ ? getFieldMetadataItemByIdOrThrow(fieldMetadataId)
+ : { fieldMetadataItem: undefined };
+
+ const filterType = isDefined(fieldMetadataId)
+ ? (filterFieldMetadataItem?.type ?? 'unknown')
+ : variableType;
+
+ const availableOperandsForFilter = getStepFilterOperands({
+ filterType,
+ subFieldName: compositeFieldSubFieldName,
+ });
+ const defaultOperand = availableOperandsForFilter[0];
+
+ upsertStepFilterSettings({
+ stepFilterToUpsert: {
+ ...stepFilter,
+ stepOutputKey: rawVariableName,
+ isFullRecord,
+ type: filterType ?? 'unknown',
+ value: '',
+ fieldMetadataId,
+ compositeFieldSubFieldName,
+ operand: defaultOperand,
+ },
+ });
+ },
+ [
+ workflowVersionId,
+ getFieldMetadataItemByIdOrThrow,
+ upsertStepFilterSettings,
+ stepFilter,
+ ],
+ );
+
+ const handleStepFilterFieldSelect = (key: string) => {
+ updateStepFilter({
+ rawVariableName: key,
+ isFullRecord: false,
+ });
+ onSelect();
+ };
+
+ const {
+ searchInputValue,
+ setSearchInputValue,
+ handleSelectField,
+ goBack,
+ filteredOptions,
+ currentPath,
+ } = useVariableDropdown({
+ step,
+ onSelect: handleStepFilterFieldSelect,
+ onBack,
+ });
+
+ const getDisplayedSubStepObject = () => {
+ const currentSubStep = getCurrentSubStepFromPath(step, currentPath);
+
+ if (!isRecordOutputSchema(currentSubStep)) {
+ return;
+ }
+
+ return currentSubStep.object;
+ };
+
+ const handleSelectObject = () => {
+ const currentSubStep = getCurrentSubStepFromPath(step, currentPath);
+
+ if (!isRecordOutputSchema(currentSubStep)) {
+ return;
+ }
+
+ updateStepFilter({
+ rawVariableName: getVariableTemplateFromPath({
+ stepId: step.id,
+ path: [...currentPath, currentSubStep.object.fieldIdName],
+ }),
+ isFullRecord: true,
+ });
+ onSelect();
+ };
+
+ const displayedSubStepObject = getDisplayedSubStepObject();
+
+ const shouldDisplaySubStepObject = searchInputValue
+ ? displayedSubStepObject?.label &&
+ displayedSubStepObject.label
+ .toLowerCase()
+ .includes(searchInputValue.toLowerCase())
+ : true;
+
+ const shouldDisplayObject =
+ shouldDisplaySubStepObject && displayedSubStepObject?.label;
+ const nameSingular = displayedSubStepObject?.nameSingular;
+
+ return (
+
+
+ }
+ >
+
+
+ setSearchInputValue(event.target.value)}
+ />
+
+
+ {shouldDisplayObject && (
+
+ )}
+ {filteredOptions.length > 0 && shouldDisplayObject && (
+
+ )}
+ {filteredOptions.map(([key, subStep]) => (
+ handleSelectField(key)}
+ text={subStep.label || key}
+ hasSubMenu={!subStep.isLeaf}
+ LeftIcon={subStep.icon ? getIcon(subStep.icon) : undefined}
+ contextualText={
+ subStep.isLeaf ? subStep?.value?.toString() : undefined
+ }
+ />
+ ))}
+
+
+ );
+};
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterAddFilterRuleSelect.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterAddFilterRuleSelect.tsx
index abe0877f9e..cb019d8222 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterAddFilterRuleSelect.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterAddFilterRuleSelect.tsx
@@ -137,7 +137,6 @@ export const WorkflowStepFilterAddFilterRuleSelect = ({
}
- dropdownOffset={{ y: 8, x: 0 }}
dropdownPlacement="bottom-start"
/>
);
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 d02ac2544a..251d4e25fc 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
@@ -1,19 +1,18 @@
import { useFieldMetadataItemById } from '@/object-metadata/hooks/useFieldMetadataItemById';
-import { useGetFieldMetadataItemByIdOrThrow } from '@/object-metadata/hooks/useGetFieldMetadataItemById';
import { SelectControl } from '@/ui/input/components/SelectControl';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
-import { useWorkflowVersionIdOrThrow } from '@/workflow/hooks/useWorkflowVersionIdOrThrow';
-import { stepsOutputSchemaFamilySelector } from '@/workflow/states/selectors/stepsOutputSchemaFamilySelector';
-import { useUpsertStepFilterSettings } from '@/workflow/workflow-steps/workflow-actions/filter-action/hooks/useUpsertStepFilterSettings';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
+import { WorkflowDropdownStepOutputItems } from '@/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowDropdownStepOutputItems';
import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/workflow-actions/filter-action/states/context/WorkflowStepFilterContext';
-import { getViewFilterOperands } from '@/workflow/workflow-steps/workflow-actions/filter-action/utils/getStepFilterOperands';
-import { WorkflowVariablesDropdown } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdown';
+import { WorkflowVariablesDropdownWorkflowStepItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownWorkflowStepItems';
import { useAvailableVariablesInWorkflowStep } from '@/workflow/workflow-variables/hooks/useAvailableVariablesInWorkflowStep';
+import { useSearchVariable } from '@/workflow/workflow-variables/hooks/useSearchVariable';
+
+import { type StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema';
import { extractRawVariableNamePart } from '@/workflow/workflow-variables/utils/extractRawVariableNamePart';
-import { searchVariableThroughOutputSchema } from '@/workflow/workflow-variables/utils/searchVariableThroughOutputSchema';
+import { useTheme } from '@emotion/react';
import { useLingui } from '@lingui/react/macro';
-import { useContext } from 'react';
-import { useRecoilCallback, useRecoilValue } from 'recoil';
+import { useContext, useState } from 'react';
import { type StepFilter } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { useIcons } from 'twenty-ui/display';
@@ -34,139 +33,76 @@ export const WorkflowStepFilterFieldSelect = ({
stepFilter,
}: WorkflowStepFilterFieldSelectProps) => {
const { readonly } = useContext(WorkflowStepFilterContext);
- const shouldDisplayRecordFields = true;
- const shouldDisplayRecordObjects = true;
-
- const { upsertStepFilterSettings } = useUpsertStepFilterSettings();
-
const { t } = useLingui();
- const workflowVersionId = useWorkflowVersionIdOrThrow();
+ const theme = useTheme();
+ const { closeDropdown } = useCloseDropdown();
+ const { getIcon } = useIcons();
+
+ const availableVariablesInWorkflowStep = useAvailableVariablesInWorkflowStep({
+ shouldDisplayRecordFields: true,
+ shouldDisplayRecordObjects: true,
+ fieldTypesToExclude: NON_SELECTABLE_FIELD_TYPES,
+ });
+ const noAvailableVariables = availableVariablesInWorkflowStep.length === 0;
+
+ const initialStep =
+ availableVariablesInWorkflowStep.length === 1
+ ? availableVariablesInWorkflowStep[0]
+ : undefined;
+
+ const [selectedStep, setSelectedStep] = useState<
+ StepOutputSchema | undefined
+ >(initialStep);
const stepId = extractRawVariableNamePart({
rawVariableName: stepFilter.stepOutputKey,
part: 'stepId',
});
- const stepsOutputSchema = useRecoilValue(
- stepsOutputSchemaFamilySelector({
- workflowVersionId,
- stepIds: [stepId],
- }),
- );
-
- const { getIcon } = useIcons();
+ const { variableLabel } = useSearchVariable({
+ stepId,
+ rawVariableName: stepFilter.stepOutputKey,
+ isFullRecord: stepFilter.isFullRecord ?? false,
+ });
const {
fieldMetadataItem: filterFieldMetadataItem,
objectMetadataItem: filterObjectMetadataItem,
} = useFieldMetadataItemById(stepFilter.fieldMetadataId ?? '');
- const { getFieldMetadataItemByIdOrThrow } =
- useGetFieldMetadataItemByIdOrThrow();
+ const dropdownId = `step-filter-field-${stepFilter.id}`;
- const availableVariablesInWorkflowStep = useAvailableVariablesInWorkflowStep({
- shouldDisplayRecordFields,
- shouldDisplayRecordObjects,
- });
+ const handleStepSelect = (stepId: string) => {
+ setSelectedStep(
+ availableVariablesInWorkflowStep.find((step) => step.id === stepId),
+ );
+ };
- const noAvailableVariables = availableVariablesInWorkflowStep.length === 0;
+ const handleSubItemSelect = () => {
+ setSelectedStep(initialStep);
+ closeDropdown(dropdownId);
+ };
- const handleChange = useRecoilCallback(
- ({ snapshot }) =>
- (variableName: string) => {
- const stepId = extractRawVariableNamePart({
- rawVariableName: variableName,
- part: 'stepId',
- });
- const [currentStepOutputSchema] = snapshot
- .getLoadable(
- stepsOutputSchemaFamilySelector({
- workflowVersionId,
- stepIds: [stepId],
- }),
- )
- .getValue();
-
- const {
- variableLabel,
- variableType,
- fieldMetadataId,
- compositeFieldSubFieldName,
- } = searchVariableThroughOutputSchema({
- stepOutputSchema: currentStepOutputSchema,
- rawVariableName: variableName,
- isFullRecord: false,
- });
-
- const {
- fieldMetadataItem: filterFieldMetadataItem,
- objectMetadataItem: filterObjectMetadataItem,
- } = isDefined(fieldMetadataId)
- ? getFieldMetadataItemByIdOrThrow(fieldMetadataId)
- : { fieldMetadataItem: undefined, objectMetadataItem: undefined };
-
- const filterType = isDefined(fieldMetadataId)
- ? (filterFieldMetadataItem?.type ?? 'unknown')
- : variableType;
-
- const isFullRecord =
- filterFieldMetadataItem?.name === 'id' &&
- isDefined(filterObjectMetadataItem?.labelSingular);
-
- upsertStepFilterSettings({
- stepFilterToUpsert: {
- ...stepFilter,
- stepOutputKey: variableName,
- displayValue: isFullRecord
- ? filterObjectMetadataItem.labelSingular
- : (variableLabel ?? ''),
- type: filterType ?? 'unknown',
- value: '',
- fieldMetadataId,
- compositeFieldSubFieldName,
- operand: getViewFilterOperands({
- filterType,
- subFieldName: compositeFieldSubFieldName,
- })?.[0],
- },
- });
- },
- [
- workflowVersionId,
- getFieldMetadataItemByIdOrThrow,
- upsertStepFilterSettings,
- stepFilter,
- ],
- );
-
- if (!isDefined(stepId)) {
- return null;
- }
-
- const isFullRecord =
- filterFieldMetadataItem?.name === 'id' &&
- isDefined(filterObjectMetadataItem?.labelSingular);
-
- const { variableLabel } = searchVariableThroughOutputSchema({
- stepOutputSchema: stepsOutputSchema?.[0],
- rawVariableName: stepFilter.stepOutputKey,
- isFullRecord,
- });
+ const handleBack = () => {
+ setSelectedStep(undefined);
+ };
const isSelectedFieldNotFound = !isDefined(variableLabel);
const label = isSelectedFieldNotFound
? t`Select a field from a previous step`
: variableLabel;
- const icon = isFullRecord
+ const icon = stepFilter.isFullRecord
? getIcon(filterObjectMetadataItem?.icon)
: filterFieldMetadataItem?.icon
? getIcon(filterFieldMetadataItem.icon)
: undefined;
- const dropdownId = `step-filter-field-${stepFilter.id}`;
+ if (readonly || noAvailableVariables) {
+ const disabledLabel = noAvailableVariables
+ ? t`No available fields to select`
+ : label;
- if (noAvailableVariables) {
return (
- }
- dropdownComponents={[]}
- />
- );
- }
-
- if (readonly === true) {
- return (
-
-
+ }
+ dropdownComponents={
+ !isDefined(selectedStep) ? (
+
- }
- shouldDisplayRecordFields={shouldDisplayRecordFields}
- shouldDisplayRecordObjects={shouldDisplayRecordObjects}
- shouldEnableSelectRelationObject={true}
- fieldTypesToExclude={NON_SELECTABLE_FIELD_TYPES}
- />
- >
+ ) : (
+
+ )
+ }
+ dropdownPlacement="bottom-end"
+ dropdownOffset={{
+ x: parseInt(theme.spacing(0.5), 10),
+ y: parseInt(theme.spacing(1), 10),
+ }}
+ />
);
};
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterOperandSelect.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterOperandSelect.tsx
index 1a8c02be77..fc0c85c55b 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterOperandSelect.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterOperandSelect.tsx
@@ -4,7 +4,7 @@ import { Select } from '@/ui/input/components/Select';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useUpsertStepFilterSettings } from '@/workflow/workflow-steps/workflow-actions/filter-action/hooks/useUpsertStepFilterSettings';
import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/workflow-actions/filter-action/states/context/WorkflowStepFilterContext';
-import { getViewFilterOperands } from '@/workflow/workflow-steps/workflow-actions/filter-action/utils/getStepFilterOperands';
+import { getStepFilterOperands } from '@/workflow/workflow-steps/workflow-actions/filter-action/utils/getStepFilterOperands';
import { useContext } from 'react';
import { type StepFilter, type ViewFilterOperand } from 'twenty-shared/types';
@@ -18,7 +18,7 @@ export const WorkflowStepFilterOperandSelect = ({
const { readonly } = useContext(WorkflowStepFilterContext);
const { upsertStepFilterSettings } = useUpsertStepFilterSettings();
- const operands = getViewFilterOperands({
+ const operands = getStepFilterOperands({
filterType: stepFilter.type,
subFieldName: stepFilter.compositeFieldSubFieldName,
});
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterValueInput.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterValueInput.tsx
index f28a0bf4c2..14783f24cd 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterValueInput.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterValueInput.tsx
@@ -102,7 +102,8 @@ export const WorkflowStepFilterValueInput = ({
variableType === FieldMetadataType.SELECT;
const isFullRecord =
- selectedFieldMetadataItem?.name === 'id' &&
+ isDefined(stepFilter.isFullRecord) &&
+ stepFilter.isFullRecord &&
isDefined(objectMetadataItem?.nameSingular);
const isDateField =
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/__stories__/WorkflowStepFilterColumn.stories.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/__stories__/WorkflowStepFilterColumn.stories.tsx
index 61521351ef..b7f2dd744f 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/__stories__/WorkflowStepFilterColumn.stories.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/__stories__/WorkflowStepFilterColumn.stories.tsx
@@ -24,9 +24,7 @@ const TEXT_STEP_FILTER: StepFilter = {
id: 'filter-1',
stepFilterGroupId: 'filter-group-1',
stepOutputKey: 'company.name',
- displayValue: 'Company Name',
type: 'text',
- label: 'Company Name',
value: 'Acme',
operand: ViewFilterOperand.Contains,
};
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/__stories__/WorkflowStepFilterFieldSelect.stories.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/__stories__/WorkflowStepFilterFieldSelect.stories.tsx
index 1514bbe52d..f96aa94121 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/__stories__/WorkflowStepFilterFieldSelect.stories.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/__stories__/WorkflowStepFilterFieldSelect.stories.tsx
@@ -13,9 +13,7 @@ const DEFAULT_STEP_FILTER: StepFilter = {
id: 'filter-1',
stepFilterGroupId: 'filter-group-1',
stepOutputKey: '',
- displayValue: '',
type: 'text',
- label: 'New Filter',
operand: ViewFilterOperand.Is,
value: '',
positionInStepFilterGroup: 0,
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/__stories__/WorkflowStepFilterOperandSelect.stories.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/__stories__/WorkflowStepFilterOperandSelect.stories.tsx
index 99226499cc..23e02faec1 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/__stories__/WorkflowStepFilterOperandSelect.stories.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/__stories__/WorkflowStepFilterOperandSelect.stories.tsx
@@ -14,9 +14,7 @@ const DEFAULT_STEP_FILTER: StepFilter = {
id: 'filter-1',
stepFilterGroupId: 'filter-group-1',
stepOutputKey: 'company.name',
- displayValue: 'Company Name',
type: 'text',
- label: 'Company Name',
operand: ViewFilterOperand.Contains,
value: '',
positionInStepFilterGroup: 0,
@@ -26,9 +24,7 @@ const GREATER_THAN_FILTER: StepFilter = {
id: 'filter-1',
stepFilterGroupId: 'filter-group-1',
stepOutputKey: 'company.employees',
- displayValue: 'Employee Count',
type: 'number',
- label: 'Employee Count',
operand: ViewFilterOperand.GreaterThanOrEqual,
value: '100',
positionInStepFilterGroup: 0,
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/__stories__/WorkflowStepFilterValueInput.stories.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/__stories__/WorkflowStepFilterValueInput.stories.tsx
index a7a91c42bc..7ef34351ad 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/__stories__/WorkflowStepFilterValueInput.stories.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/components/__stories__/WorkflowStepFilterValueInput.stories.tsx
@@ -14,9 +14,7 @@ const TEXT_FILTER: StepFilter = {
id: 'filter-1',
stepFilterGroupId: 'filter-group-1',
stepOutputKey: 'company.name',
- displayValue: 'Company Name',
type: 'text',
- label: 'Company Name',
operand: ViewFilterOperand.Contains,
value: 'Acme',
positionInStepFilterGroup: 0,
@@ -26,9 +24,7 @@ const NUMBER_FILTER: StepFilter = {
id: 'filter-2',
stepFilterGroupId: 'filter-group-1',
stepOutputKey: 'company.employees',
- displayValue: 'Employee Count',
type: 'number',
- label: 'Employee Count',
operand: ViewFilterOperand.GreaterThanOrEqual,
value: '100',
positionInStepFilterGroup: 0,
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/hooks/useAddRootStepFilter.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/hooks/useAddRootStepFilter.ts
index 774be2619a..c80e9f41df 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/hooks/useAddRootStepFilter.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/hooks/useAddRootStepFilter.ts
@@ -49,10 +49,8 @@ export const useAddRootStepFilter = () => {
const newStepFilter: StepFilter = {
id: v4(),
type: 'unknown',
- label: 'New Filter',
value: '',
operand: ViewFilterOperand.Is,
- displayValue: '',
stepFilterGroupId: newStepFilterGroup.id,
stepOutputKey: '',
positionInStepFilterGroup: 0,
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/utils/getStepFilterOperands.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/utils/getStepFilterOperands.ts
index f48d7d58f6..4e288605b1 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/utils/getStepFilterOperands.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/filter-action/utils/getStepFilterOperands.ts
@@ -85,7 +85,7 @@ export const COMPOSITE_FIELD_FILTER_OPERANDS_MAP = {
},
};
-export const getViewFilterOperands = ({
+export const getStepFilterOperands = ({
filterType,
subFieldName,
}: {
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 340cf9ac66..3f066846b5 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
@@ -39,7 +39,6 @@ export const WorkflowVariablesDropdown = ({
shouldDisplayRecordFields,
shouldDisplayRecordObjects,
fieldTypesToExclude,
- shouldEnableSelectRelationObject,
multiline,
clickableComponent,
}: {
@@ -48,7 +47,6 @@ export const WorkflowVariablesDropdown = ({
shouldDisplayRecordFields: boolean;
shouldDisplayRecordObjects: boolean;
fieldTypesToExclude?: InputSchemaPropertyType[];
- shouldEnableSelectRelationObject?: boolean;
disabled?: boolean;
multiline?: boolean;
clickableComponent?: React.ReactNode;
@@ -134,7 +132,6 @@ export const WorkflowVariablesDropdown = ({
step={selectedStep}
onSelect={handleSubItemSelect}
onBack={handleBack}
- shouldEnableSelectRelationObject={shouldEnableSelectRelationObject}
/>
) : (
void;
onBack: () => void;
- shouldEnableSelectRelationObject?: boolean;
};
export const WorkflowVariablesDropdownAllItems = ({
step,
onSelect,
onBack,
- shouldEnableSelectRelationObject,
}: WorkflowVariablesDropdownAllItemsProps) => {
const { t } = useLingui();
const { getIcon } = useIcons();
@@ -65,25 +63,12 @@ export const WorkflowVariablesDropdownAllItems = ({
return;
}
- const isRelationField = currentSubStep.object.isRelationField ?? false;
- const isRelationObjectSelectable =
- shouldEnableSelectRelationObject ?? false;
-
- if (isRelationField && isRelationObjectSelectable) {
- onSelect(
- getVariableTemplateFromPath({
- stepId: step.id,
- path: currentPath,
- }),
- );
- } else {
- onSelect(
- getVariableTemplateFromPath({
- stepId: step.id,
- path: [...currentPath, currentSubStep.object.fieldIdName],
- }),
- );
- }
+ onSelect(
+ getVariableTemplateFromPath({
+ stepId: step.id,
+ path: [...currentPath, currentSubStep.object.fieldIdName],
+ }),
+ );
};
const displayedSubStepObject = getDisplayedSubStepObject();
diff --git a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type.ts b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type.ts
index e614b4c5a9..1651c8c884 100644
--- a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type.ts
+++ b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type.ts
@@ -37,10 +37,8 @@ export type FieldOutputSchema =
export type RecordOutputSchema = {
object: {
- nameSingular: string;
fieldIdName: string;
objectMetadataId: string;
- isRelationField?: boolean;
} & Leaf;
fields: Record;
_outputSchemaType: 'RECORD';
diff --git a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/__tests__/generate-fake-form-response.spec.ts b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/__tests__/generate-fake-form-response.spec.ts
index 3785f60fab..80466fd0c8 100644
--- a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/__tests__/generate-fake-form-response.spec.ts
+++ b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/__tests__/generate-fake-form-response.spec.ts
@@ -116,7 +116,6 @@ describe('generateFakeFormResponse', () => {
icon: 'test-company-icon',
isLeaf: true,
label: 'Company',
- nameSingular: 'company',
objectMetadataId: '20202020-c03c-45d6-a4b0-04afe1357c5c',
value: 'A company',
},
diff --git a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/__tests__/generate-fake-object-record-event.spec.ts b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/__tests__/generate-fake-object-record-event.spec.ts
index 5fad881942..38beaf878d 100644
--- a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/__tests__/generate-fake-object-record-event.spec.ts
+++ b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/__tests__/generate-fake-object-record-event.spec.ts
@@ -61,7 +61,6 @@ describe('generateFakeObjectRecordEvent', () => {
icon: 'test-company-icon',
label: 'Company',
value: 'A company',
- nameSingular: 'company',
fieldIdName: 'properties.after.id',
objectMetadataId: '20202020-c03c-45d6-a4b0-04afe1357c5c',
},
@@ -93,7 +92,6 @@ describe('generateFakeObjectRecordEvent', () => {
icon: 'test-company-icon',
label: 'Company',
value: 'A company',
- nameSingular: 'company',
fieldIdName: 'properties.after.id',
objectMetadataId: '20202020-c03c-45d6-a4b0-04afe1357c5c',
},
@@ -125,7 +123,6 @@ describe('generateFakeObjectRecordEvent', () => {
icon: 'test-company-icon',
label: 'Company',
value: 'A company',
- nameSingular: 'company',
fieldIdName: 'properties.before.id',
objectMetadataId: '20202020-c03c-45d6-a4b0-04afe1357c5c',
},
@@ -157,7 +154,6 @@ describe('generateFakeObjectRecordEvent', () => {
icon: 'test-company-icon',
label: 'Company',
value: 'A company',
- nameSingular: 'company',
fieldIdName: 'properties.before.id',
objectMetadataId: '20202020-c03c-45d6-a4b0-04afe1357c5c',
},
diff --git a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/__tests__/generate-fake-object-record.spec.ts b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/__tests__/generate-fake-object-record.spec.ts
index 4eb175dc41..d0b8eaa4a3 100644
--- a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/__tests__/generate-fake-object-record.spec.ts
+++ b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/__tests__/generate-fake-object-record.spec.ts
@@ -41,7 +41,6 @@ describe('generateFakeObjectRecord', () => {
icon: 'test-company-icon',
label: 'Company',
value: 'A company',
- nameSingular: 'company',
fieldIdName: 'id',
objectMetadataId: '20202020-c03c-45d6-a4b0-04afe1357c5c',
},
diff --git a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record-event.ts b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record-event.ts
index 4496013bf9..8a243c3905 100644
--- a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record-event.ts
+++ b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record-event.ts
@@ -30,8 +30,6 @@ const generateFakeObjectRecordEventWithPrefix = ({
objectMetadataInfo.objectMetadataItemWithFieldsMaps.icon ?? undefined,
label: objectMetadataInfo.objectMetadataItemWithFieldsMaps.labelSingular,
value: objectMetadataInfo.objectMetadataItemWithFieldsMaps.description,
- nameSingular:
- objectMetadataInfo.objectMetadataItemWithFieldsMaps.nameSingular,
fieldIdName: `${prefix}.id`,
objectMetadataId: objectMetadataInfo.objectMetadataItemWithFieldsMaps.id,
},
diff --git a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record.ts b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record.ts
index 8b0a5353a9..1dcc8118fb 100644
--- a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record.ts
+++ b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record.ts
@@ -5,11 +5,9 @@ import { generateObjectRecordFields } from 'src/modules/workflow/workflow-builde
export const generateFakeObjectRecord = ({
objectMetadataInfo,
depth = 0,
- isRelationField,
}: {
objectMetadataInfo: ObjectMetadataInfo;
depth?: number;
- isRelationField?: boolean;
}): RecordOutputSchema => {
return {
object: {
@@ -18,11 +16,8 @@ export const generateFakeObjectRecord = ({
objectMetadataInfo.objectMetadataItemWithFieldsMaps.icon ?? undefined,
label: objectMetadataInfo.objectMetadataItemWithFieldsMaps.labelSingular,
value: objectMetadataInfo.objectMetadataItemWithFieldsMaps.description,
- nameSingular:
- objectMetadataInfo.objectMetadataItemWithFieldsMaps.nameSingular,
fieldIdName: 'id',
objectMetadataId: objectMetadataInfo.objectMetadataItemWithFieldsMaps.id,
- isRelationField,
},
fields: generateObjectRecordFields({
objectMetadataInfo,
diff --git a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/generate-object-record-fields.ts b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/generate-object-record-fields.ts
index 69c9959d43..59bf3fa9d6 100644
--- a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/generate-object-record-fields.ts
+++ b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/generate-object-record-fields.ts
@@ -60,7 +60,6 @@ export const generateObjectRecordFields = ({
objectMetadataMaps: objectMetadataInfo.objectMetadataMaps,
},
depth: depth + 1,
- isRelationField: true,
}),
};
}
diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/__tests__/evaluate-filter-conditions.util.spec.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/__tests__/evaluate-filter-conditions.util.spec.ts
index 779b9fc9b0..7a5b518b7a 100644
--- a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/__tests__/evaluate-filter-conditions.util.spec.ts
+++ b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/__tests__/evaluate-filter-conditions.util.spec.ts
@@ -21,10 +21,8 @@ describe('evaluateFilterConditions', () => {
): ResolvedFilter => ({
id: 'filter1',
type: type,
- label: 'Test Filter',
rightOperand,
operand,
- displayValue: String(rightOperand),
stepFilterGroupId: 'group1',
leftOperand,
});
@@ -784,10 +782,8 @@ describe('evaluateFilterConditions', () => {
const filter: ResolvedFilter = {
id: 'filter1',
type: 'CURRENCY',
- label: 'Currency Filter',
rightOperand: 'USD',
operand: ViewFilterOperand.Is,
- displayValue: 'USD',
stepFilterGroupId: 'group1',
leftOperand: 'USD',
compositeFieldSubFieldName: 'currencyCode',
@@ -800,10 +796,8 @@ describe('evaluateFilterConditions', () => {
const filter: ResolvedFilter = {
id: 'filter1',
type: 'CURRENCY',
- label: 'Currency Filter',
rightOperand: 100,
operand: ViewFilterOperand.GreaterThanOrEqual,
- displayValue: '100',
stepFilterGroupId: 'group1',
leftOperand: 150,
compositeFieldSubFieldName: 'amountMicros',
@@ -1215,20 +1209,16 @@ describe('evaluateFilterConditions', () => {
{
id: 'filter1',
type: 'RELATION',
- label: 'Name Filter',
rightOperand: 'John',
operand: ViewFilterOperand.Is,
- displayValue: 'John',
stepFilterGroupId: 'group1',
leftOperand: 'John',
},
{
id: 'filter2',
type: 'NUMBER',
- label: 'Age Filter',
rightOperand: 25,
operand: ViewFilterOperand.GreaterThanOrEqual,
- displayValue: '25',
stepFilterGroupId: 'group1',
leftOperand: 30,
},
@@ -1244,20 +1234,16 @@ describe('evaluateFilterConditions', () => {
{
id: 'filter1',
type: 'RELATION',
- label: 'Name Filter',
rightOperand: 'John',
operand: ViewFilterOperand.Is,
- displayValue: 'John',
stepFilterGroupId: 'group1',
leftOperand: 'John',
},
{
id: 'filter2',
type: 'NUMBER',
- label: 'Age Filter',
rightOperand: 25,
operand: ViewFilterOperand.GreaterThanOrEqual,
- displayValue: '25',
stepFilterGroupId: 'group1',
leftOperand: 20, // This will fail
},
@@ -1283,20 +1269,16 @@ describe('evaluateFilterConditions', () => {
{
id: 'filter1',
type: 'RELATION',
- label: 'Name Filter',
rightOperand: 'John',
operand: ViewFilterOperand.Is,
- displayValue: 'John',
stepFilterGroupId: 'group1',
leftOperand: 'John',
},
{
id: 'filter2',
type: 'NUMBER',
- label: 'Age Filter',
rightOperand: 25,
operand: ViewFilterOperand.GreaterThanOrEqual,
- displayValue: '25',
stepFilterGroupId: 'group1',
leftOperand: 30,
},
@@ -1319,20 +1301,16 @@ describe('evaluateFilterConditions', () => {
{
id: 'filter1',
type: 'RELATION',
- label: 'Name Filter',
rightOperand: 'John',
operand: ViewFilterOperand.Is,
- displayValue: 'John',
stepFilterGroupId: 'group1',
leftOperand: 'Jane', // This will fail
},
{
id: 'filter2',
type: 'NUMBER',
- label: 'Age Filter',
rightOperand: 25,
operand: ViewFilterOperand.GreaterThanOrEqual,
- displayValue: '25',
stepFilterGroupId: 'group1',
leftOperand: 30,
},
@@ -1357,20 +1335,16 @@ describe('evaluateFilterConditions', () => {
{
id: 'filter1',
type: 'RELATION',
- label: 'Name Filter',
rightOperand: 'John',
operand: ViewFilterOperand.Is,
- displayValue: 'John',
stepFilterGroupId: 'group1',
leftOperand: 'Jane', // This will fail
},
{
id: 'filter2',
type: 'NUMBER',
- label: 'Age Filter',
rightOperand: 25,
operand: ViewFilterOperand.GreaterThanOrEqual,
- displayValue: '25',
stepFilterGroupId: 'group1',
leftOperand: 30, // This will pass
},
@@ -1393,20 +1367,16 @@ describe('evaluateFilterConditions', () => {
{
id: 'filter1',
type: 'RELATION',
- label: 'Name Filter',
rightOperand: 'John',
operand: ViewFilterOperand.Is,
- displayValue: 'John',
stepFilterGroupId: 'group1',
leftOperand: 'Jane', // This will fail
},
{
id: 'filter2',
type: 'NUMBER',
- label: 'Age Filter',
rightOperand: 25,
operand: ViewFilterOperand.GreaterThanOrEqual,
- displayValue: '25',
stepFilterGroupId: 'group1',
leftOperand: 20, // This will fail
},
@@ -1435,20 +1405,16 @@ describe('evaluateFilterConditions', () => {
{
id: 'filter1',
type: 'RELATION',
- label: 'Name Filter',
rightOperand: 'John',
operand: ViewFilterOperand.Is,
- displayValue: 'John',
stepFilterGroupId: 'group1',
leftOperand: 'John',
},
{
id: 'filter2',
type: 'NUMBER',
- label: 'Age Filter',
rightOperand: 25,
operand: ViewFilterOperand.GreaterThanOrEqual,
- displayValue: '25',
stepFilterGroupId: 'group2',
leftOperand: 30,
},
@@ -1485,30 +1451,24 @@ describe('evaluateFilterConditions', () => {
{
id: 'filter1',
type: 'RELATION',
- label: 'Filter 1',
rightOperand: 'John',
operand: ViewFilterOperand.Is,
- displayValue: 'John',
stepFilterGroupId: 'child1',
leftOperand: 'Jane', // This will fail
},
{
id: 'filter2',
type: 'RELATION',
- label: 'Filter 2',
rightOperand: 'Smith',
operand: ViewFilterOperand.Is,
- displayValue: 'Smith',
stepFilterGroupId: 'child1',
leftOperand: 'Smith', // This will pass (OR group passes)
},
{
id: 'filter3',
type: 'NUMBER',
- label: 'Filter 3',
rightOperand: 25,
operand: ViewFilterOperand.GreaterThanOrEqual,
- displayValue: '25',
stepFilterGroupId: 'child2',
leftOperand: 30, // This will pass (AND group passes)
},
@@ -1548,10 +1508,8 @@ describe('evaluateFilterConditions', () => {
{
id: 'filter1',
type: 'RELATION',
- label: 'Name Filter',
rightOperand: 'John',
operand: ViewFilterOperand.Is,
- displayValue: 'John',
stepFilterGroupId: 'nonexistent',
leftOperand: 'John',
},
diff --git a/packages/twenty-server/src/modules/workflow/workflow-trigger/utils/__tests__/assert-form-step-is-valid.util.spec.ts b/packages/twenty-server/src/modules/workflow/workflow-trigger/utils/__tests__/assert-form-step-is-valid.util.spec.ts
index 2e0567da36..372beafe74 100644
--- a/packages/twenty-server/src/modules/workflow/workflow-trigger/utils/__tests__/assert-form-step-is-valid.util.spec.ts
+++ b/packages/twenty-server/src/modules/workflow/workflow-trigger/utils/__tests__/assert-form-step-is-valid.util.spec.ts
@@ -49,7 +49,6 @@ const settings: WorkflowFormActionSettings = {
value: 'A company',
isLeaf: true,
fieldIdName: 'id',
- nameSingular: 'company',
objectMetadataId: '123e4567-e89b-12d3-a456-426614174000',
},
_outputSchemaType: 'RECORD',
diff --git a/packages/twenty-shared/src/types/StepFilters.ts b/packages/twenty-shared/src/types/StepFilters.ts
index bc8549f64d..145a276bc0 100644
--- a/packages/twenty-shared/src/types/StepFilters.ts
+++ b/packages/twenty-shared/src/types/StepFilters.ts
@@ -15,13 +15,12 @@ export type StepFilterGroup = {
export type StepFilter = {
id: string;
type: string;
- label: string;
stepOutputKey: string;
operand: ViewFilterOperand;
value: string;
- displayValue: string;
stepFilterGroupId: string;
positionInStepFilterGroup?: number;
fieldMetadataId?: string;
compositeFieldSubFieldName?: string;
+ isFullRecord?: boolean;
};