fix: Display multipicker on Created By source filter (#10543)

fix: #9674 

When the selected filter is Is and the field type is ACTOR, we now show
ObjectFilterDropdownSourceSelect instead of a text input. This ensures
proper selection for actor-based filters. Also previously, when a user
changed the selected option, all default values were getting wiped out
so i have made some changes in updatedSelectedItems

Loom video:
https://www.loom.com/share/8b80a78d5e8c4a5192d69cab96f0c838?sid=5bd76fff-7cd4-4e3c-8c48-d1c9e4e95651

---------

Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
Paribesh Nepal
2025-04-02 13:26:32 +05:30
committed by GitHub
parent 3357f93415
commit 44d4e4efaf
5 changed files with 48 additions and 64 deletions

View File

@ -73,6 +73,7 @@ export const ObjectFilterDropdownOperandSelect = () => {
value: '',
type: getFilterTypeFromFieldType(fieldMetadataItemUsedInDropdown.type),
label: fieldMetadataItemUsedInDropdown.label,
subFieldName: subFieldNameUsedInDropdown,
});
return;
}
@ -100,6 +101,7 @@ export const ObjectFilterDropdownOperandSelect = () => {
value,
type: filterType,
label: fieldMetadataItemUsedInDropdown.label,
subFieldName: subFieldNameUsedInDropdown,
});
}
};

View File

@ -12,28 +12,26 @@ import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordF
import { EditableFilterDropdownButtonEffect } from '@/views/components/EditableFilterDropdownButtonEffect';
type EditableFilterDropdownButtonProps = {
viewFilterDropdownId: string;
viewFilter: RecordFilter;
recordFilter: RecordFilter;
hotkeyScope: HotkeyScope;
};
export const EditableFilterDropdownButton = ({
viewFilterDropdownId,
viewFilter,
recordFilter,
hotkeyScope,
}: EditableFilterDropdownButtonProps) => {
const { closeDropdown } = useDropdown(viewFilterDropdownId);
const { closeDropdown } = useDropdown(recordFilter.id);
const { removeRecordFilter } = useRemoveRecordFilter();
const handleRemove = () => {
closeDropdown();
removeRecordFilter({ recordFilterId: viewFilter.id });
removeRecordFilter({ recordFilterId: recordFilter.id });
};
const handleDropdownClickOutside = useCallback(() => {
const { value, operand } = viewFilter;
const { value, operand } = recordFilter;
if (
!value &&
![
@ -44,24 +42,24 @@ export const EditableFilterDropdownButton = ({
RecordFilterOperand.IsToday,
].includes(operand)
) {
removeRecordFilter({ recordFilterId: viewFilter.id });
removeRecordFilter({ recordFilterId: recordFilter.id });
}
}, [viewFilter, removeRecordFilter]);
}, [recordFilter, removeRecordFilter]);
return (
<>
<EditableFilterDropdownButtonEffect
viewFilterDropdownId={viewFilterDropdownId}
viewFilter={viewFilter}
/>
<EditableFilterDropdownButtonEffect recordFilter={recordFilter} />
<Dropdown
dropdownId={viewFilterDropdownId}
dropdownId={recordFilter.id}
clickableComponent={
<EditableFilterChip viewFilter={viewFilter} onRemove={handleRemove} />
<EditableFilterChip
viewFilter={recordFilter}
onRemove={handleRemove}
/>
}
dropdownComponents={
<ObjectFilterOperandSelectAndInput
filterDropdownId={viewFilterDropdownId}
filterDropdownId={recordFilter.id}
/>
}
dropdownHotkeyScope={hotkeyScope}

View File

@ -2,21 +2,21 @@ import { useEffect } from 'react';
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
import { objectFilterDropdownSelectedRecordIdsComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsComponentState';
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
import { useFilterableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext';
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
import { isDefined } from 'twenty-shared/utils';
type EditableFilterDropdownButtonEffectProps = {
viewFilterDropdownId: string;
viewFilter: RecordFilter;
recordFilter: RecordFilter;
};
export const EditableFilterDropdownButtonEffect = ({
viewFilterDropdownId,
viewFilter,
recordFilter,
}: EditableFilterDropdownButtonEffectProps) => {
const setFieldMetadataItemIdUsedInDropdown = useSetRecoilComponentStateV2(
fieldMetadataItemIdUsedInDropdownComponentState,
@ -24,12 +24,22 @@ export const EditableFilterDropdownButtonEffect = ({
const setSelectedOperandInDropdown = useSetRecoilComponentStateV2(
selectedOperandInDropdownComponentState,
viewFilterDropdownId,
recordFilter.id,
);
const setSubFieldNameUsedInDropdown = useSetRecoilComponentStateV2(
subFieldNameUsedInDropdownComponentState,
recordFilter.id,
);
const setSelectedFilter = useSetRecoilComponentStateV2(
selectedFilterComponentState,
viewFilterDropdownId,
recordFilter.id,
);
const setObjectFilterDropdownSelectedRecordIds = useSetRecoilComponentStateV2(
objectFilterDropdownSelectedRecordIdsComponentState,
recordFilter.id,
);
const { filterableFieldMetadataItems } =
@ -38,7 +48,7 @@ export const EditableFilterDropdownButtonEffect = ({
useEffect(() => {
const fieldMetadataItem = filterableFieldMetadataItems.find(
(fieldMetadataItem) =>
fieldMetadataItem.id === viewFilter.fieldMetadataId,
fieldMetadataItem.id === recordFilter.fieldMetadataId,
);
if (!isDefined(fieldMetadataItem)) {
@ -46,15 +56,25 @@ export const EditableFilterDropdownButtonEffect = ({
}
setFieldMetadataItemIdUsedInDropdown(fieldMetadataItem.id);
setSelectedOperandInDropdown(viewFilter.operand);
setSelectedFilter(viewFilter);
setSelectedOperandInDropdown(recordFilter.operand);
setSelectedFilter(recordFilter);
setSubFieldNameUsedInDropdown(recordFilter.subFieldName);
try {
const selectedOptions = JSON.parse(recordFilter.value);
setObjectFilterDropdownSelectedRecordIds(selectedOptions);
} catch {
setObjectFilterDropdownSelectedRecordIds([]);
}
}, [
filterableFieldMetadataItems,
setFieldMetadataItemIdUsedInDropdown,
viewFilter,
recordFilter,
setSelectedOperandInDropdown,
setSelectedFilter,
viewFilterDropdownId,
setSubFieldNameUsedInDropdown,
setObjectFilterDropdownSelectedRecordIds,
]);
return null;

View File

@ -1,35 +0,0 @@
import { useIcons } from 'twenty-ui';
import { useFieldMetadataItemById } from '@/object-metadata/hooks/useFieldMetadataItemById';
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import { SortOrFilterChip } from '@/views/components/SortOrFilterChip';
type RecordFilterChipProps = {
recordFilter: RecordFilter;
};
export const RecordFilterChip = ({ recordFilter }: RecordFilterChipProps) => {
const { fieldMetadataItem } = useFieldMetadataItemById(
recordFilter.fieldMetadataId,
);
const { removeRecordFilter } = useRemoveRecordFilter();
const { getIcon } = useIcons();
const FieldMetadataItemIcon = getIcon(fieldMetadataItem.icon);
const handleRemoveClick = () => {
removeRecordFilter({ recordFilterId: recordFilter.id });
};
return (
<SortOrFilterChip
testId={recordFilter.fieldMetadataId}
labelValue={recordFilter.label ?? ''}
Icon={FieldMetadataItemIcon}
onRemove={handleRemoveClick}
/>
);
};

View File

@ -233,11 +233,10 @@ export const ViewBarDetails = ({
<DropdownScope dropdownScopeId={recordFilter.id}>
<ViewBarFilterEffect filterDropdownId={recordFilter.id} />
<EditableFilterDropdownButton
viewFilter={recordFilter}
recordFilter={recordFilter}
hotkeyScope={{
scope: recordFilter.id,
}}
viewFilterDropdownId={recordFilter.id}
/>
</DropdownScope>
</ObjectFilterDropdownComponentInstanceContext.Provider>