Refactored object filter dropdown states (#9507)

Refactored object filter dropdown states while keeping the existing
structure to avoid creating a big PR.

The goal is to extract each sub hook returned by the useFilterDropdown
hook and create a PR for each function and the associated refactor for
the dependent zones in the code, so that we proceed by small increments.
This commit is contained in:
Lucas Bordeau
2025-01-09 18:18:27 +01:00
committed by GitHub
parent 524962a3d8
commit f44d99d2ff
18 changed files with 104 additions and 96 deletions

View File

@ -313,7 +313,7 @@ describe('useFilterDropdown', () => {
}); });
}); });
it('should handle scopeId undefined on initial values', () => { it('should handle componentInstanceId undefined on initial values', () => {
global.console.error = jest.fn(); global.console.error = jest.fn();
const renderFunction = () => { const renderFunction = () => {
@ -322,16 +322,16 @@ describe('useFilterDropdown', () => {
expect(renderFunction).toThrow(Error); expect(renderFunction).toThrow(Error);
expect(renderFunction).toThrow( expect(renderFunction).toThrow(
'Scope id is not provided and cannot be found in context.', 'Instance id is not provided and cannot be found in context.',
); );
}); });
it('should scopeId have been defined on initial values', () => { it('should componentInstanceId have been defined on initial values', () => {
const { result } = renderHook( const { result } = renderHook(
() => useFilterDropdown({ filterDropdownId }), () => useFilterDropdown({ filterDropdownId }),
renderHookConfig, renderHookConfig,
); );
expect(result.current.scopeId).toBeDefined(); expect(result.current.componentInstanceId).toBeDefined();
}); });
}); });

View File

@ -1,25 +1,24 @@
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 { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
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 { 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 { useUpsertCombinedViewFilters } from '@/views/hooks/useUpsertCombinedViewFilters';
import { isDefined } from 'twenty-ui'; import { isDefined } from 'twenty-ui';
import { ObjectFilterDropdownScopeInternalContext } from '../scopes/scope-internal-context/ObjectFilterDropdownScopeInternalContext';
import { Filter } from '../types/Filter'; import { Filter } from '../types/Filter';
type UseFilterDropdownProps = { type UseFilterDropdownProps = {
filterDropdownId?: string; filterDropdownId?: string;
advancedFilterViewFilterId?: string;
}; };
export const useFilterDropdown = (props?: UseFilterDropdownProps) => { export const useFilterDropdown = (props?: UseFilterDropdownProps) => {
const scopeId = useAvailableScopeIdOrThrow( const componentInstanceId = useAvailableComponentInstanceIdOrThrow(
ObjectFilterDropdownScopeInternalContext, ObjectFilterDropdownComponentInstanceContext,
props?.filterDropdownId, props?.filterDropdownId,
); );
@ -33,7 +32,7 @@ export const useFilterDropdown = (props?: UseFilterDropdownProps) => {
onFilterSelectState, onFilterSelectState,
advancedFilterViewFilterGroupIdState, advancedFilterViewFilterGroupIdState,
advancedFilterViewFilterIdState, advancedFilterViewFilterIdState,
} = useFilterDropdownStates(scopeId); } = useFilterDropdownStates(componentInstanceId);
const { upsertCombinedViewFilter } = useUpsertCombinedViewFilters(); const { upsertCombinedViewFilter } = useUpsertCombinedViewFilters();
@ -129,7 +128,7 @@ export const useFilterDropdown = (props?: UseFilterDropdownProps) => {
); );
return { return {
scopeId, componentInstanceId,
selectFilter, selectFilter,
resetFilter, resetFilter,
setSelectedFilter, setSelectedFilter,

View File

@ -7,53 +7,50 @@ import { objectFilterDropdownSelectedRecordIdsComponentState } from '@/object-re
import { onFilterSelectComponentState } from '@/object-record/object-filter-dropdown/states/onFilterSelectComponentState'; import { onFilterSelectComponentState } from '@/object-record/object-filter-dropdown/states/onFilterSelectComponentState';
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState'; import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState'; import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
export const useFilterDropdownStates = (scopeId: string) => { export const useFilterDropdownStates = (componentInstanceId: string) => {
const filterDefinitionUsedInDropdownState = extractComponentState( const filterDefinitionUsedInDropdownState =
filterDefinitionUsedInDropdownComponentState, filterDefinitionUsedInDropdownComponentState.atomFamily({
scopeId, instanceId: componentInstanceId,
); });
const objectFilterDropdownSearchInputState = extractComponentState( const objectFilterDropdownSearchInputState =
objectFilterDropdownSearchInputComponentState, objectFilterDropdownSearchInputComponentState.atomFamily({
scopeId, instanceId: componentInstanceId,
); });
const objectFilterDropdownSelectedRecordIdsState = extractComponentState( const objectFilterDropdownSelectedRecordIdsState =
objectFilterDropdownSelectedRecordIdsComponentState, objectFilterDropdownSelectedRecordIdsComponentState.atomFamily({
scopeId, instanceId: componentInstanceId,
); });
const objectFilterDropdownSelectedOptionValuesState = extractComponentState( const objectFilterDropdownSelectedOptionValuesState =
objectFilterDropdownSelectedOptionValuesComponentState, objectFilterDropdownSelectedOptionValuesComponentState.atomFamily({
scopeId, instanceId: componentInstanceId,
); });
const selectedFilterState = extractComponentState( const selectedFilterState = selectedFilterComponentState.atomFamily({
selectedFilterComponentState, instanceId: componentInstanceId,
scopeId, });
);
const selectedOperandInDropdownState = extractComponentState( const selectedOperandInDropdownState =
selectedOperandInDropdownComponentState, selectedOperandInDropdownComponentState.atomFamily({
scopeId, instanceId: componentInstanceId,
); });
const onFilterSelectState = extractComponentState( const onFilterSelectState = onFilterSelectComponentState.atomFamily({
onFilterSelectComponentState, instanceId: componentInstanceId,
scopeId, });
);
const advancedFilterViewFilterGroupIdState = extractComponentState( const advancedFilterViewFilterGroupIdState =
advancedFilterViewFilterGroupIdComponentState, advancedFilterViewFilterGroupIdComponentState.atomFamily({
scopeId, instanceId: componentInstanceId,
); });
const advancedFilterViewFilterIdState = extractComponentState( const advancedFilterViewFilterIdState =
advancedFilterViewFilterIdComponentState, advancedFilterViewFilterIdComponentState.atomFamily({
scopeId, instanceId: componentInstanceId,
); });
return { return {
filterDefinitionUsedInDropdownState, filterDefinitionUsedInDropdownState,

View File

@ -1,16 +1,19 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { filterDefinitionUsedInDropdownComponentState } from '../states/filterDefinitionUsedInDropdownComponentState'; import { filterDefinitionUsedInDropdownComponentState } from '../states/filterDefinitionUsedInDropdownComponentState';
import { FilterDefinition } from '../types/FilterDefinition'; import { FilterDefinition } from '../types/FilterDefinition';
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
export const useSetFilterDefinitionUsedInDropdownInScope = () => { export const useSetFilterDefinitionUsedInDropdownInScope = () => {
const setFilterDefinitionUsedInDropdownInScope = useRecoilCallback( const setFilterDefinitionUsedInDropdownInScope = useRecoilCallback(
({ set }) => ({ set }) =>
(scopeId: string, filterDefinition: FilterDefinition | null) => { (
const filterDefinitionUsedInDropdownState = extractComponentState( componentInstanceId: string,
filterDefinitionUsedInDropdownComponentState, filterDefinition: FilterDefinition | null,
scopeId, ) => {
); const filterDefinitionUsedInDropdownState =
filterDefinitionUsedInDropdownComponentState.atomFamily({
instanceId: componentInstanceId,
});
set(filterDefinitionUsedInDropdownState, filterDefinition); set(filterDefinitionUsedInDropdownState, filterDefinition);
}, },
[], [],

View File

@ -1,7 +1,6 @@
import { ReactNode } from 'react'; import { ReactNode } from 'react';
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext'; import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { ObjectFilterDropdownScopeInternalContext } from './scope-internal-context/ObjectFilterDropdownScopeInternalContext';
type ObjectFilterDropdownScopeProps = { type ObjectFilterDropdownScopeProps = {
children: ReactNode; children: ReactNode;
@ -16,11 +15,7 @@ export const ObjectFilterDropdownScope = ({
<ObjectFilterDropdownComponentInstanceContext.Provider <ObjectFilterDropdownComponentInstanceContext.Provider
value={{ instanceId: filterScopeId }} value={{ instanceId: filterScopeId }}
> >
<ObjectFilterDropdownScopeInternalContext.Provider {children}
value={{ scopeId: filterScopeId }}
>
{children}
</ObjectFilterDropdownScopeInternalContext.Provider>
</ObjectFilterDropdownComponentInstanceContext.Provider> </ObjectFilterDropdownComponentInstanceContext.Provider>
); );
}; };

View File

@ -1,7 +0,0 @@
import { createScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/utils/createScopeInternalContext';
import { RecoilComponentStateKey } from '@/ui/utilities/state/component-state/types/RecoilComponentStateKey';
type ObjectFilterDropdownScopeInternalContextProps = RecoilComponentStateKey;
export const ObjectFilterDropdownScopeInternalContext =
createScopeInternalContext<ObjectFilterDropdownScopeInternalContextProps>();

View File

@ -1,7 +1,9 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
export const advancedFilterViewFilterGroupIdComponentState = export const advancedFilterViewFilterGroupIdComponentState =
createComponentState<string | undefined>({ createComponentStateV2<string | undefined>({
key: 'advancedFilterViewFilterGroupIdComponentState', key: 'advancedFilterViewFilterGroupIdComponentState',
defaultValue: undefined, defaultValue: undefined,
componentInstanceContext: ObjectFilterDropdownComponentInstanceContext,
}); });

View File

@ -1,8 +1,10 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
export const advancedFilterViewFilterIdComponentState = createComponentState< export const advancedFilterViewFilterIdComponentState = createComponentStateV2<
string | undefined string | undefined
>({ >({
key: 'advancedFilterViewFilterIdComponentState', key: 'advancedFilterViewFilterIdComponentState',
defaultValue: undefined, defaultValue: undefined,
componentInstanceContext: ObjectFilterDropdownComponentInstanceContext,
}); });

View File

@ -1,9 +1,11 @@
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition'; import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition';
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
export const availableFilterDefinitionsComponentState = createComponentState< export const availableFilterDefinitionsComponentState = createComponentStateV2<
FilterDefinition[] FilterDefinition[]
>({ >({
key: 'availableFilterDefinitionsComponentState', key: 'availableFilterDefinitionsComponentState',
defaultValue: [], defaultValue: [],
componentInstanceContext: ObjectFilterDropdownComponentInstanceContext,
}); });

View File

@ -1,9 +1,10 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
import { FilterDefinition } from '../types/FilterDefinition'; import { FilterDefinition } from '../types/FilterDefinition';
export const filterDefinitionUsedInDropdownComponentState = export const filterDefinitionUsedInDropdownComponentState =
createComponentState<FilterDefinition | null>({ createComponentStateV2<FilterDefinition | null>({
key: 'filterDefinitionUsedInDropdownComponentState', key: 'filterDefinitionUsedInDropdownComponentState',
defaultValue: null, defaultValue: null,
componentInstanceContext: ObjectFilterDropdownComponentInstanceContext,
}); });

View File

@ -1,7 +1,9 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
export const isObjectFilterDropdownOperandSelectUnfoldedComponentState = export const isObjectFilterDropdownOperandSelectUnfoldedComponentState =
createComponentState<boolean>({ createComponentStateV2<boolean>({
key: 'isObjectFilterDropdownOperandSelectUnfoldedComponentState', key: 'isObjectFilterDropdownOperandSelectUnfoldedComponentState',
defaultValue: false, defaultValue: false,
componentInstanceContext: ObjectFilterDropdownComponentInstanceContext,
}); });

View File

@ -1,7 +1,9 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
export const isObjectFilterDropdownUnfoldedComponentState = export const isObjectFilterDropdownUnfoldedComponentState =
createComponentState<boolean>({ createComponentStateV2<boolean>({
key: 'isObjectFilterDropdownUnfoldedScopedState', key: 'isObjectFilterDropdownUnfoldedComponentState',
defaultValue: false, defaultValue: false,
componentInstanceContext: ObjectFilterDropdownComponentInstanceContext,
}); });

View File

@ -1,7 +1,9 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
export const objectFilterDropdownSearchInputComponentState = export const objectFilterDropdownSearchInputComponentState =
createComponentState<string>({ createComponentStateV2<string>({
key: 'objectFilterDropdownSearchInputComponentState', key: 'objectFilterDropdownSearchInputComponentState',
defaultValue: '', defaultValue: '',
componentInstanceContext: ObjectFilterDropdownComponentInstanceContext,
}); });

View File

@ -1,7 +1,9 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
export const objectFilterDropdownSelectedOptionValuesComponentState = export const objectFilterDropdownSelectedOptionValuesComponentState =
createComponentState<string[]>({ createComponentStateV2<string[]>({
key: 'objectFilterDropdownSelectedOptionValuesComponentState', key: 'objectFilterDropdownSelectedOptionValuesComponentState',
defaultValue: [], defaultValue: [],
componentInstanceContext: ObjectFilterDropdownComponentInstanceContext,
}); });

View File

@ -1,7 +1,9 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
export const objectFilterDropdownSelectedRecordIdsComponentState = export const objectFilterDropdownSelectedRecordIdsComponentState =
createComponentState<string[]>({ createComponentStateV2<string[]>({
key: 'objectFilterDropdownSelectedRecordIdsComponentState', key: 'objectFilterDropdownSelectedRecordIdsComponentState',
defaultValue: [], defaultValue: [],
componentInstanceContext: ObjectFilterDropdownComponentInstanceContext,
}); });

View File

@ -1,10 +1,11 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
import { Filter } from '../types/Filter'; import { Filter } from '../types/Filter';
export const onFilterSelectComponentState = createComponentState< export const onFilterSelectComponentState = createComponentStateV2<
((filter: Filter | null) => void) | undefined ((filter: Filter | null) => void) | undefined
>({ >({
key: 'onFilterSelectComponentState', key: 'onFilterSelectComponentState',
defaultValue: undefined, defaultValue: undefined,
componentInstanceContext: ObjectFilterDropdownComponentInstanceContext,
}); });

View File

@ -1,10 +1,11 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
import { Filter } from '../types/Filter'; import { Filter } from '../types/Filter';
export const selectedFilterComponentState = createComponentState< export const selectedFilterComponentState = createComponentStateV2<
Filter | undefined | null Filter | undefined | null
>({ >({
key: 'selectedFilterComponentState', key: 'selectedFilterComponentState',
defaultValue: undefined, defaultValue: undefined,
componentInstanceContext: ObjectFilterDropdownComponentInstanceContext,
}); });

View File

@ -1,8 +1,10 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand'; import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
export const selectedOperandInDropdownComponentState = export const selectedOperandInDropdownComponentState =
createComponentState<ViewFilterOperand | null>({ createComponentStateV2<ViewFilterOperand | null>({
key: 'selectedOperandInDropdownComponentState', key: 'selectedOperandInDropdownComponentState',
defaultValue: null, defaultValue: null,
componentInstanceContext: ObjectFilterDropdownComponentInstanceContext,
}); });