diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRelationValueInputClickableSelect.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRelationValueInputClickableSelect.tsx
new file mode 100644
index 0000000000..61fcf935cc
--- /dev/null
+++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRelationValueInputClickableSelect.tsx
@@ -0,0 +1,23 @@
+import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
+import { SelectControl } from '@/ui/input/components/SelectControl';
+import { useComputeRecordRelationFilterDisplayValue } from '@/views/hooks/useComputeRecordRelationFilterDisplayValue';
+
+type AdvancedFilterRelationValueInputClickableSelectProps = {
+ recordFilter: RecordFilter;
+};
+
+export const AdvancedFilterRelationValueInputClickableSelect = ({
+ recordFilter,
+}: AdvancedFilterRelationValueInputClickableSelectProps) => {
+ const { displayValue } = useComputeRecordRelationFilterDisplayValue({
+ recordFilter,
+ });
+
+ return (
+
+ );
+};
diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterValueInputDropdownButtonClickableSelect.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterValueInputDropdownButtonClickableSelect.tsx
index cdb62c0635..f65735041a 100644
--- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterValueInputDropdownButtonClickableSelect.tsx
+++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterValueInputDropdownButtonClickableSelect.tsx
@@ -1,3 +1,4 @@
+import { AdvancedFilterRelationValueInputClickableSelect } from '@/object-record/advanced-filter/components/AdvancedFilterRelationValueInputClickableSelect';
import { getAdvancedFilterInputPlaceholderText } from '@/object-record/advanced-filter/utils/getAdvancedFilterInputPlacedholderText';
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { SelectControl } from '@/ui/input/components/SelectControl';
@@ -70,6 +71,18 @@ export const AdvancedFilterValueInputDropdownButtonClickableSelect = ({
const isDateTimeType =
recordFilter?.type === 'DATE' || recordFilter?.type === 'DATE_TIME';
+ if (
+ recordFilter?.type === 'RELATION' &&
+ !shouldUsePlaceholder &&
+ isDefined(recordFilter.fieldMetadataId)
+ ) {
+ return (
+
+ );
+ }
+
return isDateTimeType ? (
{advancedFilterInputText}
) : (
diff --git a/packages/twenty-front/src/modules/views/hooks/useComputeRecordRelationFilterDisplayValue.tsx b/packages/twenty-front/src/modules/views/hooks/useComputeRecordRelationFilterDisplayValue.tsx
new file mode 100644
index 0000000000..2cc1ec4a8a
--- /dev/null
+++ b/packages/twenty-front/src/modules/views/hooks/useComputeRecordRelationFilterDisplayValue.tsx
@@ -0,0 +1,96 @@
+import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
+import { getRelationObjectMetadataNameSingular } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
+import { getFieldMetadataItemByIdOrThrow } from '@/object-metadata/utils/getFieldMetadataItemByIdOrThrow';
+import { MAX_RECORDS_TO_DISPLAY } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordSelect';
+import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
+import { useRecordsForSelect } from '@/object-record/select/hooks/useRecordsForSelect';
+
+import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons';
+import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
+import { t } from '@lingui/core/macro';
+import {
+ arrayOfUuidOrVariableSchema,
+ isDefined,
+ jsonRelationFilterValueSchema,
+} from 'twenty-shared/utils';
+
+type UseComputeRecordRelationFilterDisplayValueParams = {
+ recordFilter: RecordFilter;
+};
+
+// The stored displayValue is deprecated and empty for filters created without one, so compute the label at runtime.
+export const useComputeRecordRelationFilterDisplayValue = ({
+ recordFilter,
+}: UseComputeRecordRelationFilterDisplayValueParams) => {
+ const allowRequestsToTwentyIcons = useAtomStateValue(
+ allowRequestsToTwentyIconsState,
+ );
+
+ const { objectMetadataItems } = useObjectMetadataItems();
+
+ if (!isDefined(recordFilter.fieldMetadataId)) {
+ throw new Error('recordFilter.fieldMetadataId is not defined');
+ }
+
+ // Nested relation filters resolve records from the leaf relation's target object, direct filters from the source.
+ const { fieldMetadataItem } = getFieldMetadataItemByIdOrThrow({
+ fieldMetadataId:
+ recordFilter.relationTargetFieldMetadataId ??
+ recordFilter.fieldMetadataId,
+ objectMetadataItems,
+ });
+
+ const relationObjectMetadataNameSingular =
+ getRelationObjectMetadataNameSingular({
+ field: fieldMetadataItem,
+ });
+
+ if (!isDefined(relationObjectMetadataNameSingular)) {
+ throw new Error('relationObjectMetadataNameSingular is not defined');
+ }
+
+ const relationObjectMetadataItem = objectMetadataItems.find(
+ (objectMetadataItem) =>
+ objectMetadataItem.nameSingular === relationObjectMetadataNameSingular,
+ );
+
+ if (!isDefined(relationObjectMetadataItem)) {
+ throw new Error('relationObjectMetadataItem is not defined');
+ }
+
+ const relationObjectLabelPlural = relationObjectMetadataItem.labelPlural;
+
+ const { isCurrentWorkspaceMemberSelected, selectedRecordIds } =
+ jsonRelationFilterValueSchema
+ .catch({
+ isCurrentWorkspaceMemberSelected: false,
+ selectedRecordIds: arrayOfUuidOrVariableSchema.parse(
+ recordFilter.value,
+ ),
+ })
+ .parse(recordFilter.value);
+
+ const { selectedRecords, loading } = useRecordsForSelect({
+ searchFilterText: '',
+ selectedIds: selectedRecordIds,
+ objectNameSingular: relationObjectMetadataNameSingular,
+ limit: 10,
+ allowRequestsToTwentyIcons,
+ });
+
+ if (loading) {
+ return { displayValue: t`Loading...`, loading };
+ }
+
+ const labelValueItems = [
+ ...(isCurrentWorkspaceMemberSelected ? [t`Me`] : []),
+ ...selectedRecords.map((record) => record.name),
+ ];
+
+ const displayValue =
+ labelValueItems.length > MAX_RECORDS_TO_DISPLAY
+ ? `${labelValueItems.length} ${relationObjectLabelPlural.toLowerCase()}`
+ : labelValueItems.join(', ');
+
+ return { displayValue, loading };
+};
diff --git a/packages/twenty-front/src/modules/views/hooks/useComputeRecordRelationFilterLabelValue.tsx b/packages/twenty-front/src/modules/views/hooks/useComputeRecordRelationFilterLabelValue.tsx
index eee38bff62..f25b383f59 100644
--- a/packages/twenty-front/src/modules/views/hooks/useComputeRecordRelationFilterLabelValue.tsx
+++ b/packages/twenty-front/src/modules/views/hooks/useComputeRecordRelationFilterLabelValue.tsx
@@ -1,19 +1,9 @@
-import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
-import { getRelationObjectMetadataNameSingular } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
-import { getFieldMetadataItemByIdOrThrow } from '@/object-metadata/utils/getFieldMetadataItemByIdOrThrow';
-import { MAX_RECORDS_TO_DISPLAY } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordSelect';
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
-import { useRecordsForSelect } from '@/object-record/select/hooks/useRecordsForSelect';
+import { useComputeRecordRelationFilterDisplayValue } from '@/views/hooks/useComputeRecordRelationFilterDisplayValue';
import { useGetRecordFilterChipLabelValue } from '@/views/hooks/useGetRecordFilterChipLabelValue';
+import { isNonEmptyString } from '@sniptt/guards';
import { t } from '@lingui/core/macro';
-import {
- arrayOfUuidOrVariableSchema,
- isDefined,
- jsonRelationFilterValueSchema,
-} from 'twenty-shared/utils';
-import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons';
-import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
type ObjectFilterDropdownRecordSelectProps = {
recordFilter: RecordFilter;
@@ -23,86 +13,26 @@ type ObjectFilterDropdownRecordSelectProps = {
export const useComputeRecordRelationFilterLabelValue = ({
recordFilter,
}: ObjectFilterDropdownRecordSelectProps) => {
- const allowRequestsToTwentyIcons = useAtomStateValue(
- allowRequestsToTwentyIconsState,
- );
-
- const { objectMetadataItems } = useObjectMetadataItems();
-
const { getRecordFilterChipLabelValue } = useGetRecordFilterChipLabelValue();
- if (!isDefined(recordFilter.fieldMetadataId)) {
- throw new Error('fieldMetadataItemUsedInFilterDropdown is not defined');
- }
-
- const { fieldMetadataItem } = getFieldMetadataItemByIdOrThrow({
- fieldMetadataId: recordFilter.fieldMetadataId,
- objectMetadataItems,
- });
-
- const relationObjectMetadataNameSingular =
- getRelationObjectMetadataNameSingular({
- field: fieldMetadataItem,
- });
-
- if (!isDefined(relationObjectMetadataNameSingular)) {
- throw new Error('relationObjectMetadataNameSingular is not defined');
- }
-
- const relationObjectMetadataItem = objectMetadataItems.find(
- (objectMetadataItem) =>
- objectMetadataItem.nameSingular === relationObjectMetadataNameSingular,
- );
-
- if (!isDefined(relationObjectMetadataItem)) {
- throw new Error('relationObjectMetadataItem is not defined');
- }
-
- const relationObjectLabelPlural = relationObjectMetadataItem.labelPlural;
-
- const { isCurrentWorkspaceMemberSelected, selectedRecordIds } =
- jsonRelationFilterValueSchema
- .catch({
- isCurrentWorkspaceMemberSelected: false,
- selectedRecordIds: arrayOfUuidOrVariableSchema.parse(
- recordFilter.value,
- ),
- })
- .parse(recordFilter.value);
-
- const { selectedRecords, loading } = useRecordsForSelect({
- searchFilterText: '',
- selectedIds: selectedRecordIds,
- objectNameSingular: relationObjectMetadataNameSingular,
- limit: 10,
- allowRequestsToTwentyIcons,
+ const { displayValue, loading } = useComputeRecordRelationFilterDisplayValue({
+ recordFilter,
});
if (loading) {
return { labelValue: t`: Loading...` };
}
- const labelValueItems = [
- ...(isCurrentWorkspaceMemberSelected ? [t`Me`] : []),
- ...selectedRecords.map((record) => record.name),
- ];
-
- const filterDisplayValue =
- labelValueItems.length > MAX_RECORDS_TO_DISPLAY
- ? `${labelValueItems.length} ${relationObjectLabelPlural.toLowerCase()}`
- : labelValueItems.join(', ');
-
return {
- labelValue:
- labelValueItems.length > 0
- ? getRecordFilterChipLabelValue({
- recordFilter: {
- ...recordFilter,
- displayValue: filterDisplayValue,
- },
- })
- : getRecordFilterChipLabelValue({
- recordFilter,
- }),
+ labelValue: isNonEmptyString(displayValue)
+ ? getRecordFilterChipLabelValue({
+ recordFilter: {
+ ...recordFilter,
+ displayValue,
+ },
+ })
+ : getRecordFilterChipLabelValue({
+ recordFilter,
+ }),
};
};