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();
const renderFunction = () => {
@ -322,16 +322,16 @@ describe('useFilterDropdown', () => {
expect(renderFunction).toThrow(Error);
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(
() => useFilterDropdown({ filterDropdownId }),
renderHookConfig,
);
expect(result.current.scopeId).toBeDefined();
expect(result.current.componentInstanceId).toBeDefined();
});
});

View File

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

View File

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

View File

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

View File

@ -1,7 +1,6 @@
import { ReactNode } from 'react';
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { ObjectFilterDropdownScopeInternalContext } from './scope-internal-context/ObjectFilterDropdownScopeInternalContext';
type ObjectFilterDropdownScopeProps = {
children: ReactNode;
@ -16,11 +15,7 @@ export const ObjectFilterDropdownScope = ({
<ObjectFilterDropdownComponentInstanceContext.Provider
value={{ instanceId: filterScopeId }}
>
<ObjectFilterDropdownScopeInternalContext.Provider
value={{ scopeId: filterScopeId }}
>
{children}
</ObjectFilterDropdownScopeInternalContext.Provider>
{children}
</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 =
createComponentState<string | undefined>({
createComponentStateV2<string | undefined>({
key: 'advancedFilterViewFilterGroupIdComponentState',
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
>({
key: 'advancedFilterViewFilterIdComponentState',
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 { 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[]
>({
key: 'availableFilterDefinitionsComponentState',
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';
export const filterDefinitionUsedInDropdownComponentState =
createComponentState<FilterDefinition | null>({
createComponentStateV2<FilterDefinition | null>({
key: 'filterDefinitionUsedInDropdownComponentState',
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 =
createComponentState<boolean>({
createComponentStateV2<boolean>({
key: 'isObjectFilterDropdownOperandSelectUnfoldedComponentState',
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 =
createComponentState<boolean>({
key: 'isObjectFilterDropdownUnfoldedScopedState',
createComponentStateV2<boolean>({
key: 'isObjectFilterDropdownUnfoldedComponentState',
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 =
createComponentState<string>({
createComponentStateV2<string>({
key: 'objectFilterDropdownSearchInputComponentState',
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 =
createComponentState<string[]>({
createComponentStateV2<string[]>({
key: 'objectFilterDropdownSelectedOptionValuesComponentState',
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 =
createComponentState<string[]>({
createComponentStateV2<string[]>({
key: 'objectFilterDropdownSelectedRecordIdsComponentState',
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';
export const onFilterSelectComponentState = createComponentState<
export const onFilterSelectComponentState = createComponentStateV2<
((filter: Filter | null) => void) | undefined
>({
key: 'onFilterSelectComponentState',
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';
export const selectedFilterComponentState = createComponentState<
export const selectedFilterComponentState = createComponentStateV2<
Filter | undefined | null
>({
key: 'selectedFilterComponentState',
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';
export const selectedOperandInDropdownComponentState =
createComponentState<ViewFilterOperand | null>({
createComponentStateV2<ViewFilterOperand | null>({
key: 'selectedOperandInDropdownComponentState',
defaultValue: null,
componentInstanceContext: ObjectFilterDropdownComponentInstanceContext,
});