Fixed workflow filter initialization (#16471)

This PR fixes https://github.com/twentyhq/twenty/issues/16165.

The bug was due to a wrong initialization of a record filter, which was
using another object metadata item than the filtered one.

As we can see in the original issue : 

```
...
"fieldMetadataId": "f12697bf-1eba-4061-bdd4-3e8a81172b79"
...
"fieldMetadataId": "658c531c-0c2e-43a1-8f70-4d6266c3841f",
...
```

The fix was to update the hook that returned the default field metadata
item to use for a new filter, and force the caller to tell which object
metadata item to use.
This commit is contained in:
Lucas Bordeau
2025-12-10 16:43:20 +01:00
committed by GitHub
parent b17e45f272
commit 3648fa064c
3 changed files with 54 additions and 48 deletions
@@ -1,7 +1,8 @@
import { ActionButton } from '@/action-menu/actions/display/components/ActionButton';
import { useChildRecordFiltersAndRecordFilterGroups } from '@/object-record/advanced-filter/hooks/useChildRecordFiltersAndRecordFilterGroups';
import { useDefaultFieldMetadataItemForFilter } from '@/object-record/advanced-filter/hooks/useDefaultFieldMetadataItemForFilter';
import { useGetDefaultFieldMetadataItemForFilter } from '@/object-record/advanced-filter/hooks/useGetDefaultFieldMetadataItemForFilter';
import { useSetRecordFilterUsedInAdvancedFilterDropdownRow } from '@/object-record/advanced-filter/hooks/useSetRecordFilterUsedInAdvancedFilterDropdownRow';
import { AdvancedFilterContext } from '@/object-record/advanced-filter/states/context/AdvancedFilterContext';
import { getAdvancedFilterAddFilterRuleSelectDropdownId } from '@/object-record/advanced-filter/utils/getAdvancedFilterAddFilterRuleSelectDropdownId';
import { useUpsertRecordFilterGroup } from '@/object-record/record-filter-group/hooks/useUpsertRecordFilterGroup';
import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
@@ -14,6 +15,7 @@ import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { useContext } from 'react';
import { RecordFilterGroupLogicalOperator } from 'twenty-shared/types';
import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils';
import { IconLibraryPlus, IconPlus } from 'twenty-ui/display';
@@ -45,13 +47,18 @@ export const AdvancedFilterAddFilterRuleSelect = ({
const { closeDropdown } = useCloseDropdown();
const { defaultFieldMetadataItemForFilter } =
useDefaultFieldMetadataItemForFilter();
const { getDefaultFieldMetadataItemForFilter } =
useGetDefaultFieldMetadataItemForFilter();
const { setRecordFilterUsedInAdvancedFilterDropdownRow } =
useSetRecordFilterUsedInAdvancedFilterDropdownRow();
const { objectMetadataItem } = useContext(AdvancedFilterContext);
const handleAddFilter = () => {
const { defaultFieldMetadataItemForFilter } =
getDefaultFieldMetadataItemForFilter(objectMetadataItem);
if (!isDefined(defaultFieldMetadataItemForFilter)) {
throw new Error('Missing default field metadata item for filter');
}
@@ -86,6 +93,9 @@ export const AdvancedFilterAddFilterRuleSelect = ({
};
const handleAddFilterGroup = () => {
const { defaultFieldMetadataItemForFilter } =
getDefaultFieldMetadataItemForFilter(objectMetadataItem);
closeDropdown(dropdownId);
if (!isDefined(defaultFieldMetadataItemForFilter)) {
@@ -1,45 +0,0 @@
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForFilterFamilySelector';
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { useRecoilValue } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
export const useDefaultFieldMetadataItemForFilter = () => {
const { currentView } = useGetCurrentViewOnly();
const { activeObjectMetadataItems } = useFilteredObjectMetadataItems();
const objectMetadataId =
currentView?.objectMetadataId ?? activeObjectMetadataItems[0]?.id;
if (!isDefined(objectMetadataId)) {
throw new Error('Could not find default object metadata item for filter');
}
const { objectMetadataItem } = useObjectMetadataItemById({
objectId: objectMetadataId,
});
const availableFieldMetadataItemsForFilter = useRecoilValue(
availableFieldMetadataItemsForFilterFamilySelector({
objectMetadataItemId: objectMetadataId,
}),
);
const fieldMetadataItemForLabelIdentifier =
availableFieldMetadataItemsForFilter.find(
(fieldMetadataItem) =>
fieldMetadataItem.id ===
objectMetadataItem?.labelIdentifierFieldMetadataId,
);
const firstFieldMetadataItem = availableFieldMetadataItemsForFilter?.[0] as
| FieldMetadataItem
| undefined;
const defaultFieldMetadataItemForFilter =
fieldMetadataItemForLabelIdentifier ?? firstFieldMetadataItem;
return { defaultFieldMetadataItemForFilter };
};
@@ -0,0 +1,41 @@
import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForFilterFamilySelector';
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
import { useRecoilCallback } from 'recoil';
export const useGetDefaultFieldMetadataItemForFilter = () => {
const getDefaultFieldMetadataItemForFilter = useRecoilCallback(
({ snapshot }) =>
(objectMetadataItem: ObjectMetadataItem) => {
const availableFieldMetadataItemsForFilter = getSnapshotValue(
snapshot,
availableFieldMetadataItemsForFilterFamilySelector({
objectMetadataItemId: objectMetadataItem.id,
}),
);
const fieldMetadataItemForLabelIdentifier =
availableFieldMetadataItemsForFilter.find(
(fieldMetadataItem) =>
fieldMetadataItem.id ===
objectMetadataItem?.labelIdentifierFieldMetadataId,
);
const firstFieldMetadataItem =
availableFieldMetadataItemsForFilter?.[0] as
| FieldMetadataItem
| undefined;
const defaultFieldMetadataItemForFilter =
fieldMetadataItemForLabelIdentifier ?? firstFieldMetadataItem;
return { defaultFieldMetadataItemForFilter };
},
[],
);
return {
getDefaultFieldMetadataItemForFilter,
};
};