Refactored select filter and select filter definition logic (#9519)

This PR extracts the logic to manage filter and filter definition
setting.

Previously it was ambiguous, we had the same "selectFilter" naming used
for setting filter definition in filter dropdown and for setting the
actual filter value and saving to view filter states.

This is another incremental refactor, which will allow to remove
useFilterDropdown hook.
This commit is contained in:
Lucas Bordeau
2025-01-09 18:54:34 +01:00
committed by GitHub
parent 71a4593ba4
commit 17e2e38812
16 changed files with 138 additions and 72 deletions
@@ -4,6 +4,7 @@ import { useEffect, useState } from 'react';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { useApplyRecordFilter } from '@/object-record/object-filter-dropdown/hooks/useApplyRecordFilter';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope'; import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
import { BooleanDisplay } from '@/ui/field/display/components/BooleanDisplay'; import { BooleanDisplay } from '@/ui/field/display/components/BooleanDisplay';
@@ -40,9 +41,10 @@ export const ObjectFilterDropdownBooleanSelect = () => {
filterDefinitionUsedInDropdownState, filterDefinitionUsedInDropdownState,
selectedOperandInDropdownState, selectedOperandInDropdownState,
selectedFilterState, selectedFilterState,
selectFilter,
} = useFilterDropdown(); } = useFilterDropdown();
const { applyRecordFilter } = useApplyRecordFilter();
const { closeDropdown } = useDropdown(); const { closeDropdown } = useDropdown();
const filterDefinitionUsedInDropdown = useRecoilValue( const filterDefinitionUsedInDropdown = useRecoilValue(
@@ -69,7 +71,7 @@ export const ObjectFilterDropdownBooleanSelect = () => {
return; return;
} }
selectFilter({ applyRecordFilter({
id: selectedFilter?.id ?? v4(), id: selectedFilter?.id ?? v4(),
definition: filterDefinitionUsedInDropdown, definition: filterDefinitionUsedInDropdown,
operand: selectedOperandInDropdown, operand: selectedOperandInDropdown,
@@ -1,6 +1,7 @@
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { useApplyRecordFilter } from '@/object-record/object-filter-dropdown/hooks/useApplyRecordFilter';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter'; import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
import { getRelativeDateDisplayValue } from '@/object-record/object-filter-dropdown/utils/getRelativeDateDisplayValue'; import { getRelativeDateDisplayValue } from '@/object-record/object-filter-dropdown/utils/getRelativeDateDisplayValue';
@@ -21,9 +22,10 @@ export const ObjectFilterDropdownDateInput = () => {
filterDefinitionUsedInDropdownState, filterDefinitionUsedInDropdownState,
selectedOperandInDropdownState, selectedOperandInDropdownState,
selectedFilterState, selectedFilterState,
selectFilter,
} = useFilterDropdown(); } = useFilterDropdown();
const { applyRecordFilter } = useApplyRecordFilter();
const filterDefinitionUsedInDropdown = useRecoilValue( const filterDefinitionUsedInDropdown = useRecoilValue(
filterDefinitionUsedInDropdownState, filterDefinitionUsedInDropdownState,
); );
@@ -51,7 +53,7 @@ export const ObjectFilterDropdownDateInput = () => {
if (!filterDefinitionUsedInDropdown || !selectedOperandInDropdown) return; if (!filterDefinitionUsedInDropdown || !selectedOperandInDropdown) return;
selectFilter?.({ applyRecordFilter({
id: selectedFilter?.id ? selectedFilter.id : v4(), id: selectedFilter?.id ? selectedFilter.id : v4(),
fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId, fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId,
value: newDate?.toISOString() ?? '', value: newDate?.toISOString() ?? '',
@@ -83,7 +85,7 @@ export const ObjectFilterDropdownDateInput = () => {
) )
: ''; : '';
selectFilter?.({ applyRecordFilter({
id: selectedFilter?.id ? selectedFilter.id : v4(), id: selectedFilter?.id ? selectedFilter.id : v4(),
fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId, fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId,
value, value,
@@ -7,7 +7,7 @@ import { AdvancedFilterButton } from '@/object-record/object-filter-dropdown/com
import { ObjectFilterDropdownFilterSelectMenuItem } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectMenuItem'; import { ObjectFilterDropdownFilterSelectMenuItem } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectMenuItem';
import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId'; import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { useSelectFilter } from '@/object-record/object-filter-dropdown/hooks/useSelectFilter'; import { useSelectFilterDefinitionUsedInDropdown } from '@/object-record/object-filter-dropdown/hooks/useSelectFilterDefinitionUsedInDropdown';
import { FiltersHotkeyScope } from '@/object-record/object-filter-dropdown/types/FiltersHotkeyScope'; import { FiltersHotkeyScope } from '@/object-record/object-filter-dropdown/types/FiltersHotkeyScope';
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext'; import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
import { hiddenTableColumnsComponentSelector } from '@/object-record/record-table/states/selectors/hiddenTableColumnsComponentSelector'; import { hiddenTableColumnsComponentSelector } from '@/object-record/record-table/states/selectors/hiddenTableColumnsComponentSelector';
@@ -121,7 +121,8 @@ export const ObjectFilterDropdownFilterSelect = ({
(item) => item.fieldMetadataId, (item) => item.fieldMetadataId,
); );
const { selectFilter } = useSelectFilter(); const { selectFilterDefinitionUsedInDropdown } =
useSelectFilterDefinitionUsedInDropdown();
const { resetSelectedItem } = useSelectableList(OBJECT_FILTER_DROPDOWN_ID); const { resetSelectedItem } = useSelectableList(OBJECT_FILTER_DROPDOWN_ID);
@@ -135,7 +136,11 @@ export const ObjectFilterDropdownFilterSelect = ({
} }
resetSelectedItem(); resetSelectedItem();
selectFilter({ filterDefinition: selectedFilterDefinition });
selectFilterDefinitionUsedInDropdown({
filterDefinition: selectedFilterDefinition,
});
closeAdvancedFilterDropdown(); closeAdvancedFilterDropdown();
}; };
@@ -1,4 +1,5 @@
import { useAdvancedFilterDropdown } from '@/object-record/advanced-filter/hooks/useAdvancedFilterDropdown'; import { useAdvancedFilterDropdown } from '@/object-record/advanced-filter/hooks/useAdvancedFilterDropdown';
import { useApplyRecordFilter } from '@/object-record/object-filter-dropdown/hooks/useApplyRecordFilter';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState'; import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState';
import { objectFilterDropdownFirstLevelFilterDefinitionComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFirstLevelFilterDefinitionComponentState'; import { objectFilterDropdownFirstLevelFilterDefinitionComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFirstLevelFilterDefinitionComponentState';
@@ -55,11 +56,12 @@ export const ObjectFilterDropdownFilterSelectCompositeFieldSubMenu = () => {
setFilterDefinitionUsedInDropdown, setFilterDefinitionUsedInDropdown,
setSelectedOperandInDropdown, setSelectedOperandInDropdown,
setObjectFilterDropdownSearchInput, setObjectFilterDropdownSearchInput,
selectFilter,
advancedFilterViewFilterIdState, advancedFilterViewFilterIdState,
advancedFilterViewFilterGroupIdState, advancedFilterViewFilterGroupIdState,
} = useFilterDropdown(); } = useFilterDropdown();
const { applyRecordFilter } = useApplyRecordFilter();
const advancedFilterViewFilterId = useRecoilValue( const advancedFilterViewFilterId = useRecoilValue(
advancedFilterViewFilterIdState, advancedFilterViewFilterIdState,
); );
@@ -84,7 +86,8 @@ export const ObjectFilterDropdownFilterSelectCompositeFieldSubMenu = () => {
definition.type, definition.type,
operand, operand,
); );
selectFilter({
applyRecordFilter({
id: advancedFilterViewFilterId, id: advancedFilterViewFilterId,
fieldMetadataId: definition.fieldMetadataId, fieldMetadataId: definition.fieldMetadataId,
value, value,
@@ -1,7 +1,7 @@
import { useAdvancedFilterDropdown } from '@/object-record/advanced-filter/hooks/useAdvancedFilterDropdown'; import { useAdvancedFilterDropdown } from '@/object-record/advanced-filter/hooks/useAdvancedFilterDropdown';
import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId'; import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { useSelectFilter } from '@/object-record/object-filter-dropdown/hooks/useSelectFilter'; import { useSelectFilterDefinitionUsedInDropdown } from '@/object-record/object-filter-dropdown/hooks/useSelectFilterDefinitionUsedInDropdown';
import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState'; import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState';
import { objectFilterDropdownFirstLevelFilterDefinitionComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFirstLevelFilterDefinitionComponentState'; import { objectFilterDropdownFirstLevelFilterDefinitionComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFirstLevelFilterDefinitionComponentState';
import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownIsSelectingCompositeFieldComponentState'; import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownIsSelectingCompositeFieldComponentState';
@@ -25,7 +25,8 @@ export type ObjectFilterDropdownFilterSelectMenuItemProps = {
export const ObjectFilterDropdownFilterSelectMenuItem = ({ export const ObjectFilterDropdownFilterSelectMenuItem = ({
filterDefinition, filterDefinition,
}: ObjectFilterDropdownFilterSelectMenuItemProps) => { }: ObjectFilterDropdownFilterSelectMenuItemProps) => {
const { selectFilter } = useSelectFilter(); const { selectFilterDefinitionUsedInDropdown } =
useSelectFilterDefinitionUsedInDropdown();
const [, setObjectFilterDropdownFirstLevelFilterDefinition] = const [, setObjectFilterDropdownFirstLevelFilterDefinition] =
useRecoilComponentStateV2( useRecoilComponentStateV2(
@@ -55,12 +56,8 @@ export const ObjectFilterDropdownFilterSelectMenuItem = ({
const isACompositeField = isCompositeField(filterDefinition.type); const isACompositeField = isCompositeField(filterDefinition.type);
const { const { setSelectedOperandInDropdown, advancedFilterViewFilterIdState } =
setFilterDefinitionUsedInDropdown, useFilterDropdown();
setSelectedOperandInDropdown,
setObjectFilterDropdownSearchInput,
advancedFilterViewFilterIdState,
} = useFilterDropdown();
const setHotkeyScope = useSetHotkeyScope(); const setHotkeyScope = useSetHotkeyScope();
@@ -72,11 +69,14 @@ export const ObjectFilterDropdownFilterSelectMenuItem = ({
advancedFilterViewFilterId, advancedFilterViewFilterId,
); );
const handleSelectFilter = (availableFilterDefinition: FilterDefinition) => { const handleSelectFilterDefinition = (
availableFilterDefinition: FilterDefinition,
) => {
closeAdvancedFilterDropdown(); closeAdvancedFilterDropdown();
selectFilter({ filterDefinition: availableFilterDefinition });
setFilterDefinitionUsedInDropdown(availableFilterDefinition); selectFilterDefinitionUsedInDropdown({
filterDefinition: availableFilterDefinition,
});
if ( if (
availableFilterDefinition.type === 'RELATION' || availableFilterDefinition.type === 'RELATION' ||
@@ -89,8 +89,6 @@ export const ObjectFilterDropdownFilterSelectMenuItem = ({
getOperandsForFilterDefinition(availableFilterDefinition)[0], getOperandsForFilterDefinition(availableFilterDefinition)[0],
); );
setObjectFilterDropdownSearchInput('');
setObjectFilterDropdownFilterIsSelected(true); setObjectFilterDropdownFilterIsSelected(true);
}; };
@@ -107,7 +105,7 @@ export const ObjectFilterDropdownFilterSelectMenuItem = ({
setObjectFilterDropdownFirstLevelFilterDefinition(filterDefinition); setObjectFilterDropdownFirstLevelFilterDefinition(filterDefinition);
setObjectFilterDropdownIsSelectingCompositeField(true); setObjectFilterDropdownIsSelectingCompositeField(true);
} else { } else {
handleSelectFilter(filterDefinition); handleSelectFilterDefinition(filterDefinition);
} }
}; };
@@ -2,6 +2,7 @@ import { ChangeEvent, useCallback, useState } from 'react';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { useApplyRecordFilter } from '@/object-record/object-filter-dropdown/hooks/useApplyRecordFilter';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { DropdownMenuInput } from '@/ui/layout/dropdown/components/DropdownMenuInput'; import { DropdownMenuInput } from '@/ui/layout/dropdown/components/DropdownMenuInput';
@@ -10,8 +11,10 @@ export const ObjectFilterDropdownNumberInput = () => {
selectedOperandInDropdownState, selectedOperandInDropdownState,
filterDefinitionUsedInDropdownState, filterDefinitionUsedInDropdownState,
selectedFilterState, selectedFilterState,
selectFilter,
} = useFilterDropdown(); } = useFilterDropdown();
const { applyRecordFilter } = useApplyRecordFilter();
const [hasFocused, setHasFocused] = useState(false); const [hasFocused, setHasFocused] = useState(false);
const filterDefinitionUsedInDropdown = useRecoilValue( const filterDefinitionUsedInDropdown = useRecoilValue(
@@ -48,8 +51,10 @@ export const ObjectFilterDropdownNumberInput = () => {
placeholder={filterDefinitionUsedInDropdown.label} placeholder={filterDefinitionUsedInDropdown.label}
onChange={(event: ChangeEvent<HTMLInputElement>) => { onChange={(event: ChangeEvent<HTMLInputElement>) => {
const newValue = event.target.value; const newValue = event.target.value;
setInputValue(newValue); setInputValue(newValue);
selectFilter?.({
applyRecordFilter({
id: selectedFilter?.id ? selectedFilter.id : v4(), id: selectedFilter?.id ? selectedFilter.id : v4(),
fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId, fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId,
value: newValue, value: newValue,
@@ -1,6 +1,7 @@
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { useApplyRecordFilter } from '@/object-record/object-filter-dropdown/hooks/useApplyRecordFilter';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { getInitialFilterValue } from '@/object-record/object-filter-dropdown/utils/getInitialFilterValue'; import { getInitialFilterValue } from '@/object-record/object-filter-dropdown/utils/getInitialFilterValue';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
@@ -22,9 +23,10 @@ export const ObjectFilterDropdownOperandSelect = () => {
filterDefinitionUsedInDropdownState, filterDefinitionUsedInDropdownState,
setSelectedOperandInDropdown, setSelectedOperandInDropdown,
selectedFilterState, selectedFilterState,
selectFilter,
} = useFilterDropdown(); } = useFilterDropdown();
const { applyRecordFilter } = useApplyRecordFilter();
const { closeDropdown } = useDropdown(); const { closeDropdown } = useDropdown();
const filterDefinitionUsedInDropdown = useRecoilValue( const filterDefinitionUsedInDropdown = useRecoilValue(
@@ -49,7 +51,7 @@ export const ObjectFilterDropdownOperandSelect = () => {
setSelectedOperandInDropdown(newOperand); setSelectedOperandInDropdown(newOperand);
if (isValuelessOperand && isDefined(filterDefinitionUsedInDropdown)) { if (isValuelessOperand && isDefined(filterDefinitionUsedInDropdown)) {
selectFilter?.({ applyRecordFilter({
id: v4(), id: v4(),
fieldMetadataId: filterDefinitionUsedInDropdown?.fieldMetadataId ?? '', fieldMetadataId: filterDefinitionUsedInDropdown?.fieldMetadataId ?? '',
displayValue: '', displayValue: '',
@@ -71,7 +73,7 @@ export const ObjectFilterDropdownOperandSelect = () => {
selectedFilter.displayValue, selectedFilter.displayValue,
); );
selectFilter?.({ applyRecordFilter({
id: selectedFilter.id ? selectedFilter.id : v4(), id: selectedFilter.id ? selectedFilter.id : v4(),
fieldMetadataId: selectedFilter.fieldMetadataId, fieldMetadataId: selectedFilter.fieldMetadataId,
displayValue, displayValue,
@@ -14,6 +14,7 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
import { useSelectableListStates } from '@/ui/layout/selectable-list/hooks/internal/useSelectableListStates'; import { useSelectableListStates } from '@/ui/layout/selectable-list/hooks/internal/useSelectableListStates';
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList'; import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
import { useApplyRecordFilter } from '@/object-record/object-filter-dropdown/hooks/useApplyRecordFilter';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { MenuItem, MenuItemMultiSelect } from 'twenty-ui'; import { MenuItem, MenuItemMultiSelect } from 'twenty-ui';
import { isDefined } from '~/utils/isDefined'; import { isDefined } from '~/utils/isDefined';
@@ -32,9 +33,10 @@ export const ObjectFilterDropdownOptionSelect = () => {
selectedOperandInDropdownState, selectedOperandInDropdownState,
objectFilterDropdownSelectedOptionValuesState, objectFilterDropdownSelectedOptionValuesState,
selectedFilterState, selectedFilterState,
selectFilter,
} = useFilterDropdown(); } = useFilterDropdown();
const { applyRecordFilter } = useApplyRecordFilter();
const { closeDropdown } = useDropdown(); const { closeDropdown } = useDropdown();
const { selectedItemIdState } = useSelectableListStates({ const { selectedItemIdState } = useSelectableListStates({
@@ -128,7 +130,7 @@ export const ObjectFilterDropdownOptionSelect = () => {
? JSON.stringify(selectedOptions.map((option) => option.value)) ? JSON.stringify(selectedOptions.map((option) => option.value))
: EMPTY_FILTER_VALUE; : EMPTY_FILTER_VALUE;
selectFilter({ applyRecordFilter({
id: selectedFilter?.id ? selectedFilter.id : v4(), id: selectedFilter?.id ? selectedFilter.id : v4(),
definition: filterDefinitionUsedInDropdown, definition: filterDefinitionUsedInDropdown,
operand: selectedOperandInDropdown, operand: selectedOperandInDropdown,
@@ -1,6 +1,7 @@
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { useApplyRecordFilter } from '@/object-record/object-filter-dropdown/hooks/useApplyRecordFilter';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { RATING_VALUES } from '@/object-record/record-field/meta-types/constants/RatingValues'; import { RATING_VALUES } from '@/object-record/record-field/meta-types/constants/RatingValues';
import { FieldRatingValue } from '@/object-record/record-field/types/FieldMetadata'; import { FieldRatingValue } from '@/object-record/record-field/types/FieldMetadata';
@@ -34,7 +35,6 @@ export const ObjectFilterDropdownRatingInput = () => {
selectedOperandInDropdownState, selectedOperandInDropdownState,
filterDefinitionUsedInDropdownState, filterDefinitionUsedInDropdownState,
selectedFilterState, selectedFilterState,
selectFilter,
} = useFilterDropdown(); } = useFilterDropdown();
const filterDefinitionUsedInDropdown = useRecoilValue( const filterDefinitionUsedInDropdown = useRecoilValue(
@@ -46,6 +46,8 @@ export const ObjectFilterDropdownRatingInput = () => {
const selectedFilter = useRecoilValue(selectedFilterState); const selectedFilter = useRecoilValue(selectedFilterState);
const { applyRecordFilter } = useApplyRecordFilter();
return ( return (
filterDefinitionUsedInDropdown && filterDefinitionUsedInDropdown &&
selectedOperandInDropdown && ( selectedOperandInDropdown && (
@@ -57,7 +59,7 @@ export const ObjectFilterDropdownRatingInput = () => {
return; return;
} }
selectFilter?.({ applyRecordFilter?.({
id: selectedFilter?.id ? selectedFilter.id : v4(), id: selectedFilter?.id ? selectedFilter.id : v4(),
fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId, fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId,
value: convertFieldRatingValueToNumber(newValue), value: convertFieldRatingValueToNumber(newValue),
@@ -5,6 +5,7 @@ import { v4 } from 'uuid';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { ObjectFilterDropdownRecordPinnedItems } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordPinnedItems'; import { ObjectFilterDropdownRecordPinnedItems } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordPinnedItems';
import { CURRENT_WORKSPACE_MEMBER_SELECTABLE_ITEM_ID } from '@/object-record/object-filter-dropdown/constants/CurrentWorkspaceMemberSelectableItemId'; import { CURRENT_WORKSPACE_MEMBER_SELECTABLE_ITEM_ID } from '@/object-record/object-filter-dropdown/constants/CurrentWorkspaceMemberSelectableItemId';
import { useApplyRecordFilter } from '@/object-record/object-filter-dropdown/hooks/useApplyRecordFilter';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope'; import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
import { MultipleSelectDropdown } from '@/object-record/select/components/MultipleSelectDropdown'; import { MultipleSelectDropdown } from '@/object-record/select/components/MultipleSelectDropdown';
@@ -37,9 +38,10 @@ export const ObjectFilterDropdownRecordSelect = ({
selectedOperandInDropdownState, selectedOperandInDropdownState,
selectedFilterState, selectedFilterState,
objectFilterDropdownSelectedRecordIdsState, objectFilterDropdownSelectedRecordIdsState,
selectFilter,
} = useFilterDropdown(); } = useFilterDropdown();
const { applyRecordFilter } = useApplyRecordFilter(viewComponentId);
const { currentViewWithCombinedFiltersAndSorts } = const { currentViewWithCombinedFiltersAndSorts } =
useGetCurrentView(viewComponentId); useGetCurrentView(viewComponentId);
@@ -187,7 +189,7 @@ export const ObjectFilterDropdownRecordSelect = ({
const filterId = viewFilter?.id ?? fieldId; const filterId = viewFilter?.id ?? fieldId;
selectFilter({ applyRecordFilter({
id: selectedFilter?.id ? selectedFilter.id : filterId, id: selectedFilter?.id ? selectedFilter.id : filterId,
definition: filterDefinitionUsedInDropdown, definition: filterDefinitionUsedInDropdown,
operand: selectedOperandInDropdown, operand: selectedOperandInDropdown,
@@ -2,6 +2,7 @@ import { useState } from 'react';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { useApplyRecordFilter } from '@/object-record/object-filter-dropdown/hooks/useApplyRecordFilter';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { getActorSourceMultiSelectOptions } from '@/object-record/object-filter-dropdown/utils/getActorSourceMultiSelectOptions'; import { getActorSourceMultiSelectOptions } from '@/object-record/object-filter-dropdown/utils/getActorSourceMultiSelectOptions';
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope'; import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
@@ -29,10 +30,11 @@ export const ObjectFilterDropdownSourceSelect = ({
selectedFilterState, selectedFilterState,
setObjectFilterDropdownSelectedRecordIds, setObjectFilterDropdownSelectedRecordIds,
objectFilterDropdownSelectedRecordIdsState, objectFilterDropdownSelectedRecordIdsState,
selectFilter,
emptyFilterButKeepDefinition, emptyFilterButKeepDefinition,
} = useFilterDropdown(); } = useFilterDropdown();
const { applyRecordFilter } = useApplyRecordFilter(viewComponentId);
const { deleteCombinedViewFilter } = const { deleteCombinedViewFilter } =
useDeleteCombinedViewFilters(viewComponentId); useDeleteCombinedViewFilters(viewComponentId);
@@ -108,7 +110,7 @@ export const ObjectFilterDropdownSourceSelect = ({
const filterId = viewFilter?.id ?? fieldId; const filterId = viewFilter?.id ?? fieldId;
selectFilter({ applyRecordFilter({
id: selectedFilter?.id ? selectedFilter.id : filterId, id: selectedFilter?.id ? selectedFilter.id : filterId,
definition: filterDefinitionUsedInDropdown, definition: filterDefinitionUsedInDropdown,
operand: selectedOperandInDropdown || ViewFilterOperand.Is, operand: selectedOperandInDropdown || ViewFilterOperand.Is,
@@ -2,6 +2,7 @@ import { ChangeEvent, useCallback, useState } from 'react';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { useApplyRecordFilter } from '@/object-record/object-filter-dropdown/hooks/useApplyRecordFilter';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput'; import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
@@ -12,7 +13,6 @@ export const ObjectFilterDropdownTextSearchInput = () => {
objectFilterDropdownSearchInputState, objectFilterDropdownSearchInputState,
setObjectFilterDropdownSearchInput, setObjectFilterDropdownSearchInput,
selectedFilterState, selectedFilterState,
selectFilter,
} = useFilterDropdown(); } = useFilterDropdown();
const [filterId] = useState(v4()); const [filterId] = useState(v4());
@@ -29,6 +29,8 @@ export const ObjectFilterDropdownTextSearchInput = () => {
); );
const selectedFilter = useRecoilValue(selectedFilterState); const selectedFilter = useRecoilValue(selectedFilterState);
const { applyRecordFilter } = useApplyRecordFilter();
const handleInputRef = useCallback( const handleInputRef = useCallback(
(node: HTMLInputElement | null) => { (node: HTMLInputElement | null) => {
if (Boolean(node) && !hasFocused) { if (Boolean(node) && !hasFocused) {
@@ -51,7 +53,7 @@ export const ObjectFilterDropdownTextSearchInput = () => {
onChange={(event: ChangeEvent<HTMLInputElement>) => { onChange={(event: ChangeEvent<HTMLInputElement>) => {
setObjectFilterDropdownSearchInput(event.target.value); setObjectFilterDropdownSearchInput(event.target.value);
selectFilter?.({ applyRecordFilter({
id: selectedFilter?.id ?? filterId, id: selectedFilter?.id ?? filterId,
fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId, fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId,
value: event.target.value, value: event.target.value,
@@ -2,6 +2,7 @@ import { expect } from '@storybook/test';
import { act, renderHook, waitFor } from '@testing-library/react'; import { act, renderHook, waitFor } from '@testing-library/react';
import { RecoilRoot, useRecoilState } from 'recoil'; import { RecoilRoot, useRecoilState } from 'recoil';
import { useApplyRecordFilter } from '@/object-record/object-filter-dropdown/hooks/useApplyRecordFilter';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { useFilterDropdownStates } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdownStates'; import { useFilterDropdownStates } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdownStates';
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter'; import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
@@ -261,19 +262,26 @@ describe('useFilterDropdown', () => {
it('should reset filter', async () => { it('should reset filter', async () => {
const { result } = renderHook(() => { const { result } = renderHook(() => {
const { resetFilter, selectFilter } = useFilterDropdown({ const { resetFilter } = useFilterDropdown({
filterDropdownId, filterDropdownId,
}); });
const { applyRecordFilter } = useApplyRecordFilter(filterDropdownId);
const { selectedFilterState } = useFilterDropdownStates(filterDropdownId); const { selectedFilterState } = useFilterDropdownStates(filterDropdownId);
const [selectedFilter, setSelectedFilter] = const [selectedFilter, setSelectedFilter] =
useRecoilState(selectedFilterState); useRecoilState(selectedFilterState);
return { selectedFilter, setSelectedFilter, selectFilter, resetFilter }; return {
selectedFilter,
setSelectedFilter,
applyRecordFilter,
resetFilter,
};
}, renderHookConfig); }, renderHookConfig);
act(() => { act(() => {
result.current.selectFilter(mockFilter); result.current.applyRecordFilter(mockFilter);
}); });
await waitFor(() => { await waitFor(() => {
@@ -291,12 +299,13 @@ describe('useFilterDropdown', () => {
it('should call onFilterSelect when a filter option is set', async () => { it('should call onFilterSelect when a filter option is set', async () => {
const { result } = renderHook(() => { const { result } = renderHook(() => {
const { selectFilter } = useFilterDropdown({ filterDropdownId }); const { applyRecordFilter } = useApplyRecordFilter(filterDropdownId);
const { onFilterSelectState } = useFilterDropdownStates(filterDropdownId); const { onFilterSelectState } = useFilterDropdownStates(filterDropdownId);
const [onFilterSelect, setOnFilterSelect] = const [onFilterSelect, setOnFilterSelect] =
useRecoilState(onFilterSelectState); useRecoilState(onFilterSelectState);
return { onFilterSelect, setOnFilterSelect, selectFilter }; return { onFilterSelect, setOnFilterSelect, applyRecordFilter };
}, renderHookConfig); }, renderHookConfig);
const onFilterSelectMock = jest.fn(); const onFilterSelectMock = jest.fn();
@@ -304,7 +313,7 @@ describe('useFilterDropdown', () => {
act(() => { act(() => {
result.current.setOnFilterSelect(onFilterSelectMock); result.current.setOnFilterSelect(onFilterSelectMock);
result.current.selectFilter(mockFilter); result.current.applyRecordFilter(mockFilter);
}); });
await waitFor(() => { await waitFor(() => {
@@ -0,0 +1,48 @@
import { onFilterSelectComponentState } from '@/object-record/object-filter-dropdown/states/onFilterSelectComponentState';
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
import { useUpsertCombinedViewFilters } from '@/views/hooks/useUpsertCombinedViewFilters';
import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-ui';
export const useApplyRecordFilter = (componentInstanceId?: string) => {
const { upsertCombinedViewFilter } = useUpsertCombinedViewFilters();
const selectedFilterCallbackState = useRecoilComponentCallbackStateV2(
selectedFilterComponentState,
componentInstanceId,
);
const onFilterSelectCallbackState = useRecoilComponentCallbackStateV2(
onFilterSelectComponentState,
componentInstanceId,
);
const applyRecordFilter = useRecoilCallback(
({ set, snapshot }) =>
(filter: Filter | null) => {
set(selectedFilterCallbackState, filter);
const onFilterSelect = getSnapshotValue(
snapshot,
onFilterSelectCallbackState,
);
if (isDefined(filter)) {
upsertCombinedViewFilter(filter);
}
onFilterSelect?.(filter);
},
[
selectedFilterCallbackState,
onFilterSelectCallbackState,
upsertCombinedViewFilter,
],
);
return {
applyRecordFilter,
};
};
@@ -1,16 +1,12 @@
import { useRecoilCallback, useSetRecoilState } from 'recoil'; import { useRecoilCallback, useSetRecoilState } from 'recoil';
import { useFilterDropdownStates } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdownStates'; import { useFilterDropdownStates } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdownStates';
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext'; import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState'; import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState';
import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownIsSelectingCompositeFieldComponentState'; import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownIsSelectingCompositeFieldComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow'; import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2'; import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
import { useUpsertCombinedViewFilters } from '@/views/hooks/useUpsertCombinedViewFilters';
import { isDefined } from 'twenty-ui';
import { Filter } from '../types/Filter';
type UseFilterDropdownProps = { type UseFilterDropdownProps = {
filterDropdownId?: string; filterDropdownId?: string;
@@ -34,23 +30,6 @@ export const useFilterDropdown = (props?: UseFilterDropdownProps) => {
advancedFilterViewFilterIdState, advancedFilterViewFilterIdState,
} = useFilterDropdownStates(componentInstanceId); } = useFilterDropdownStates(componentInstanceId);
const { upsertCombinedViewFilter } = useUpsertCombinedViewFilters();
const selectFilter = useRecoilCallback(
({ set, snapshot }) =>
(filter: Filter | null) => {
set(selectedFilterState, filter);
const onFilterSelect = getSnapshotValue(snapshot, onFilterSelectState);
if (isDefined(filter)) {
upsertCombinedViewFilter(filter);
}
onFilterSelect?.(filter);
},
[selectedFilterState, onFilterSelectState, upsertCombinedViewFilter],
);
const emptyFilterButKeepDefinition = useRecoilCallback( const emptyFilterButKeepDefinition = useRecoilCallback(
({ set }) => ({ set }) =>
() => { () => {
@@ -129,7 +108,6 @@ export const useFilterDropdown = (props?: UseFilterDropdownProps) => {
return { return {
componentInstanceId, componentInstanceId,
selectFilter,
resetFilter, resetFilter,
setSelectedFilter, setSelectedFilter,
setSelectedOperandInDropdown, setSelectedOperandInDropdown,
@@ -1,3 +1,4 @@
import { useApplyRecordFilter } from '@/object-record/object-filter-dropdown/hooks/useApplyRecordFilter';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition'; import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition';
import { getInitialFilterValue } from '@/object-record/object-filter-dropdown/utils/getInitialFilterValue'; import { getInitialFilterValue } from '@/object-record/object-filter-dropdown/utils/getInitialFilterValue';
@@ -12,12 +13,11 @@ type SelectFilterParams = {
filterDefinition: FilterDefinition; filterDefinition: FilterDefinition;
}; };
export const useSelectFilter = () => { export const useSelectFilterDefinitionUsedInDropdown = () => {
const { const {
setFilterDefinitionUsedInDropdown, setFilterDefinitionUsedInDropdown,
setSelectedOperandInDropdown, setSelectedOperandInDropdown,
setObjectFilterDropdownSearchInput, setObjectFilterDropdownSearchInput,
selectFilter: filterDropdownSelectFilter,
advancedFilterViewFilterGroupIdState, advancedFilterViewFilterGroupIdState,
advancedFilterViewFilterIdState, advancedFilterViewFilterIdState,
} = useFilterDropdown(); } = useFilterDropdown();
@@ -31,7 +31,11 @@ export const useSelectFilter = () => {
const setHotkeyScope = useSetHotkeyScope(); const setHotkeyScope = useSetHotkeyScope();
const selectFilter = ({ filterDefinition }: SelectFilterParams) => { const { applyRecordFilter } = useApplyRecordFilter();
const selectFilterDefinitionUsedInDropdown = ({
filterDefinition,
}: SelectFilterParams) => {
setFilterDefinitionUsedInDropdown(filterDefinition); setFilterDefinitionUsedInDropdown(filterDefinition);
if ( if (
@@ -53,7 +57,7 @@ export const useSelectFilter = () => {
const isAdvancedFilter = isDefined(advancedFilterViewFilterId); const isAdvancedFilter = isDefined(advancedFilterViewFilterId);
if (isAdvancedFilter || value !== '') { if (isAdvancedFilter || value !== '') {
filterDropdownSelectFilter({ applyRecordFilter({
id: advancedFilterViewFilterId ?? v4(), id: advancedFilterViewFilterId ?? v4(),
fieldMetadataId: filterDefinition.fieldMetadataId, fieldMetadataId: filterDefinition.fieldMetadataId,
displayValue, displayValue,
@@ -68,6 +72,6 @@ export const useSelectFilter = () => {
}; };
return { return {
selectFilter, selectFilterDefinitionUsedInDropdown,
}; };
}; };