Improved date filter input behavior (#12596)
Opening a date picker when creating a filter now directly applies today's date to avoid any in-between state issues. This allows the date picker and the operand selection to behave nicely when creating a date filter. Fixes https://github.com/twentyhq/core-team-issues/issues/1049
This commit is contained in:
@ -1,25 +1,10 @@
|
||||
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
||||
import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState';
|
||||
|
||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||
|
||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { FILTER_FIELD_LIST_ID } from '@/object-record/object-filter-dropdown/constants/FilterFieldListId';
|
||||
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { findDuplicateRecordFilterInNonAdvancedRecordFilters } from '@/object-record/record-filter/utils/findDuplicateRecordFilterInNonAdvancedRecordFilters';
|
||||
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
||||
import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
import { isSelectedItemIdComponentFamilySelector } from '@/ui/layout/selectable-list/states/selectors/isSelectedItemIdComponentFamilySelector';
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown } from '@/views/hooks/useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
|
||||
@ -30,14 +15,6 @@ export type ViewBarFilterDropdownFieldSelectMenuItemProps = {
|
||||
export const ViewBarFilterDropdownFieldSelectMenuItem = ({
|
||||
fieldMetadataItemToSelect,
|
||||
}: ViewBarFilterDropdownFieldSelectMenuItemProps) => {
|
||||
const setFieldMetadataItemIdUsedInDropdown = useSetRecoilComponentStateV2(
|
||||
fieldMetadataItemIdUsedInDropdownComponentState,
|
||||
);
|
||||
|
||||
const [, setObjectFilterDropdownFilterIsSelected] = useRecoilComponentStateV2(
|
||||
objectFilterDropdownFilterIsSelectedComponentState,
|
||||
);
|
||||
|
||||
const { resetSelectedItem } = useSelectableList(FILTER_FIELD_LIST_ID);
|
||||
|
||||
const isSelectedItem = useRecoilComponentFamilyValueV2(
|
||||
@ -45,58 +22,8 @@ export const ViewBarFilterDropdownFieldSelectMenuItem = ({
|
||||
fieldMetadataItemToSelect.id,
|
||||
);
|
||||
|
||||
const setSelectedOperandInDropdown = useSetRecoilComponentStateV2(
|
||||
selectedOperandInDropdownComponentState,
|
||||
);
|
||||
|
||||
const setHotkeyScope = useSetHotkeyScope();
|
||||
|
||||
const currentRecordFilters = useRecoilComponentValueV2(
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
const setObjectFilterDropdownCurrentRecordFilter =
|
||||
useSetRecoilComponentStateV2(
|
||||
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||
);
|
||||
|
||||
const handleSelectFilter = (fieldMetadataItem: FieldMetadataItem) => {
|
||||
setFieldMetadataItemIdUsedInDropdown(fieldMetadataItem.id);
|
||||
|
||||
const filterType = getFilterTypeFromFieldType(fieldMetadataItem.type);
|
||||
|
||||
if (filterType === 'RELATION' || filterType === 'SELECT') {
|
||||
setHotkeyScope(SingleRecordPickerHotkeyScope.SingleRecordPicker);
|
||||
}
|
||||
|
||||
const defaultOperand = getRecordFilterOperands({
|
||||
filterType,
|
||||
})[0];
|
||||
|
||||
setObjectFilterDropdownFilterIsSelected(true);
|
||||
|
||||
const duplicateFilterInCurrentRecordFilters =
|
||||
findDuplicateRecordFilterInNonAdvancedRecordFilters({
|
||||
recordFilters: currentRecordFilters,
|
||||
fieldMetadataItemId: fieldMetadataItem.id,
|
||||
});
|
||||
|
||||
const filterIsAlreadyInCurrentRecordFilters = isDefined(
|
||||
duplicateFilterInCurrentRecordFilters,
|
||||
);
|
||||
|
||||
if (filterIsAlreadyInCurrentRecordFilters) {
|
||||
setObjectFilterDropdownCurrentRecordFilter(
|
||||
duplicateFilterInCurrentRecordFilters,
|
||||
);
|
||||
|
||||
setSelectedOperandInDropdown(
|
||||
duplicateFilterInCurrentRecordFilters.operand,
|
||||
);
|
||||
} else {
|
||||
setSelectedOperandInDropdown(defaultOperand);
|
||||
}
|
||||
};
|
||||
const { initializeFilterOnFieldMetataItemFromViewBarFilterDropdown } =
|
||||
useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown();
|
||||
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
@ -105,7 +32,9 @@ export const ViewBarFilterDropdownFieldSelectMenuItem = ({
|
||||
const handleClick = () => {
|
||||
resetSelectedItem();
|
||||
|
||||
handleSelectFilter(fieldMetadataItemToSelect);
|
||||
initializeFilterOnFieldMetataItemFromViewBarFilterDropdown(
|
||||
fieldMetadataItemToSelect,
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@ -0,0 +1,318 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { act } from 'react';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState';
|
||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||
import { useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown } from '../useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown';
|
||||
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
|
||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
||||
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||
import { RecordFiltersComponentInstanceContext } from '@/object-record/record-filter/states/context/RecordFiltersComponentInstanceContext';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
||||
import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
||||
import { getMockPersonObjectMetadataItem } from '~/testing/mock-data/people';
|
||||
|
||||
const mockSetHotkeyScope = jest.fn();
|
||||
|
||||
jest.mock('@/ui/utilities/hotkey/hooks/useSetHotkeyScope', () => ({
|
||||
useSetHotkeyScope: () => mockSetHotkeyScope,
|
||||
}));
|
||||
|
||||
const peopleObjectMetadataItemMock = getMockPersonObjectMetadataItem();
|
||||
const personCityFieldMetadataItemMock =
|
||||
peopleObjectMetadataItemMock.fields.find((field) => field.name === 'city');
|
||||
const personCompanyFieldMetadataItemMock =
|
||||
peopleObjectMetadataItemMock.fields.find((field) => field.name === 'company');
|
||||
const personCreatedAtFieldMetadataItemMock =
|
||||
peopleObjectMetadataItemMock.fields.find(
|
||||
(field) => field.name === 'createdAt',
|
||||
);
|
||||
|
||||
const wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
<RecoilRoot
|
||||
initializeState={(snapshot) => {
|
||||
snapshot.set(objectMetadataItemsState, generatedMockObjectMetadataItems);
|
||||
}}
|
||||
>
|
||||
<ObjectFilterDropdownComponentInstanceContext.Provider
|
||||
value={{ instanceId: 'test' }}
|
||||
>
|
||||
<RecordFiltersComponentInstanceContext.Provider
|
||||
value={{ instanceId: 'test' }}
|
||||
>
|
||||
{children}
|
||||
</RecordFiltersComponentInstanceContext.Provider>
|
||||
</ObjectFilterDropdownComponentInstanceContext.Provider>
|
||||
</RecoilRoot>
|
||||
);
|
||||
|
||||
describe('useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should initialize filter for a basic text field with no existing filter', () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const { initializeFilterOnFieldMetataItemFromViewBarFilterDropdown } =
|
||||
useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown();
|
||||
|
||||
const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
|
||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
||||
);
|
||||
const objectFilterDropdownFilterIsSelected = useRecoilComponentValueV2(
|
||||
objectFilterDropdownFilterIsSelectedComponentState,
|
||||
);
|
||||
const selectedOperandInDropdown = useRecoilComponentValueV2(
|
||||
selectedOperandInDropdownComponentState,
|
||||
);
|
||||
|
||||
return {
|
||||
initializeFilterOnFieldMetataItemFromViewBarFilterDropdown,
|
||||
fieldMetadataItemUsedInDropdown,
|
||||
objectFilterDropdownFilterIsSelected,
|
||||
selectedOperandInDropdown,
|
||||
};
|
||||
},
|
||||
{
|
||||
wrapper,
|
||||
},
|
||||
);
|
||||
|
||||
if (!personCityFieldMetadataItemMock) {
|
||||
throw new Error('personCityFieldMetadataItemMock is not defined');
|
||||
}
|
||||
|
||||
const defaultOperand = getRecordFilterOperands({
|
||||
filterType: getFilterTypeFromFieldType(
|
||||
personCityFieldMetadataItemMock.type,
|
||||
),
|
||||
})?.[0];
|
||||
|
||||
act(() => {
|
||||
result.current.initializeFilterOnFieldMetataItemFromViewBarFilterDropdown(
|
||||
personCityFieldMetadataItemMock,
|
||||
);
|
||||
});
|
||||
|
||||
expect(result.current.fieldMetadataItemUsedInDropdown?.id).toBe(
|
||||
personCityFieldMetadataItemMock.id,
|
||||
);
|
||||
expect(result.current.objectFilterDropdownFilterIsSelected).toBe(true);
|
||||
expect(result.current.selectedOperandInDropdown).toBe(defaultOperand);
|
||||
expect(mockSetHotkeyScope).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should initialize filter with a relation field', () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const { initializeFilterOnFieldMetataItemFromViewBarFilterDropdown } =
|
||||
useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown();
|
||||
|
||||
const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
|
||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
||||
);
|
||||
const objectFilterDropdownFilterIsSelected = useRecoilComponentValueV2(
|
||||
objectFilterDropdownFilterIsSelectedComponentState,
|
||||
);
|
||||
const selectedOperandInDropdown = useRecoilComponentValueV2(
|
||||
selectedOperandInDropdownComponentState,
|
||||
);
|
||||
|
||||
return {
|
||||
initializeFilterOnFieldMetataItemFromViewBarFilterDropdown,
|
||||
fieldMetadataItemUsedInDropdown,
|
||||
objectFilterDropdownFilterIsSelected,
|
||||
selectedOperandInDropdown,
|
||||
};
|
||||
},
|
||||
{
|
||||
wrapper,
|
||||
},
|
||||
);
|
||||
|
||||
if (!personCompanyFieldMetadataItemMock) {
|
||||
throw new Error('personCompanyFieldMetadataItemMock is not defined');
|
||||
}
|
||||
|
||||
const defaultOperand = getRecordFilterOperands({
|
||||
filterType: getFilterTypeFromFieldType(
|
||||
personCompanyFieldMetadataItemMock.type,
|
||||
),
|
||||
})?.[0];
|
||||
|
||||
act(() => {
|
||||
result.current.initializeFilterOnFieldMetataItemFromViewBarFilterDropdown(
|
||||
personCompanyFieldMetadataItemMock,
|
||||
);
|
||||
});
|
||||
|
||||
expect(result.current.fieldMetadataItemUsedInDropdown?.id).toBe(
|
||||
personCompanyFieldMetadataItemMock.id,
|
||||
);
|
||||
expect(result.current.objectFilterDropdownFilterIsSelected).toBe(true);
|
||||
expect(result.current.selectedOperandInDropdown).toBe(defaultOperand);
|
||||
expect(mockSetHotkeyScope).toHaveBeenCalledWith(
|
||||
SingleRecordPickerHotkeyScope.SingleRecordPicker,
|
||||
);
|
||||
});
|
||||
|
||||
it('should initialize filter with a duplicate field on city', () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const { initializeFilterOnFieldMetataItemFromViewBarFilterDropdown } =
|
||||
useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown();
|
||||
|
||||
const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
|
||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
||||
);
|
||||
const objectFilterDropdownFilterIsSelected = useRecoilComponentValueV2(
|
||||
objectFilterDropdownFilterIsSelectedComponentState,
|
||||
);
|
||||
const selectedOperandInDropdown = useRecoilComponentValueV2(
|
||||
selectedOperandInDropdownComponentState,
|
||||
);
|
||||
|
||||
const objectFilterDropdownCurrentRecordFilter =
|
||||
useRecoilComponentValueV2(
|
||||
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||
);
|
||||
|
||||
const setCurrentRecordFilters = useSetRecoilComponentStateV2(
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
const currentRecordFilters = useRecoilComponentValueV2(
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
return {
|
||||
initializeFilterOnFieldMetataItemFromViewBarFilterDropdown,
|
||||
fieldMetadataItemUsedInDropdown,
|
||||
objectFilterDropdownFilterIsSelected,
|
||||
selectedOperandInDropdown,
|
||||
setCurrentRecordFilters,
|
||||
currentRecordFilters,
|
||||
objectFilterDropdownCurrentRecordFilter,
|
||||
};
|
||||
},
|
||||
{
|
||||
wrapper,
|
||||
},
|
||||
);
|
||||
|
||||
if (!personCityFieldMetadataItemMock) {
|
||||
throw new Error('personCityFieldMetadataItemMock is not defined');
|
||||
}
|
||||
|
||||
const defaultOperand = getRecordFilterOperands({
|
||||
filterType: getFilterTypeFromFieldType(
|
||||
personCityFieldMetadataItemMock.type,
|
||||
),
|
||||
})?.[0];
|
||||
|
||||
const mockExistingFilterOnCity: RecordFilter = {
|
||||
id: 'existing-filter-id',
|
||||
fieldMetadataId: personCityFieldMetadataItemMock.id,
|
||||
operand: defaultOperand,
|
||||
displayValue: 'Test City',
|
||||
label: personCityFieldMetadataItemMock.label,
|
||||
type: getFilterTypeFromFieldType(personCityFieldMetadataItemMock.type),
|
||||
value: '',
|
||||
};
|
||||
|
||||
act(() => {
|
||||
result.current.setCurrentRecordFilters([mockExistingFilterOnCity]);
|
||||
});
|
||||
|
||||
expect(result.current.currentRecordFilters.length).toBe(1);
|
||||
|
||||
act(() => {
|
||||
result.current.initializeFilterOnFieldMetataItemFromViewBarFilterDropdown(
|
||||
personCityFieldMetadataItemMock,
|
||||
);
|
||||
});
|
||||
|
||||
expect(result.current.objectFilterDropdownCurrentRecordFilter).toBe(
|
||||
mockExistingFilterOnCity,
|
||||
);
|
||||
});
|
||||
|
||||
it('should initialize filter on a date field correctly', () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const { initializeFilterOnFieldMetataItemFromViewBarFilterDropdown } =
|
||||
useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown();
|
||||
|
||||
const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
|
||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
||||
);
|
||||
const objectFilterDropdownFilterIsSelected = useRecoilComponentValueV2(
|
||||
objectFilterDropdownFilterIsSelectedComponentState,
|
||||
);
|
||||
const selectedOperandInDropdown = useRecoilComponentValueV2(
|
||||
selectedOperandInDropdownComponentState,
|
||||
);
|
||||
|
||||
const objectFilterDropdownCurrentRecordFilter =
|
||||
useRecoilComponentValueV2(
|
||||
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||
);
|
||||
|
||||
const setCurrentRecordFilters = useSetRecoilComponentStateV2(
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
const currentRecordFilters = useRecoilComponentValueV2(
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
return {
|
||||
initializeFilterOnFieldMetataItemFromViewBarFilterDropdown,
|
||||
fieldMetadataItemUsedInDropdown,
|
||||
objectFilterDropdownFilterIsSelected,
|
||||
selectedOperandInDropdown,
|
||||
setCurrentRecordFilters,
|
||||
currentRecordFilters,
|
||||
objectFilterDropdownCurrentRecordFilter,
|
||||
};
|
||||
},
|
||||
{
|
||||
wrapper,
|
||||
},
|
||||
);
|
||||
|
||||
if (!personCreatedAtFieldMetadataItemMock) {
|
||||
throw new Error('personCreatedAtFieldMetadataItemMock is not defined');
|
||||
}
|
||||
|
||||
expect(result.current.currentRecordFilters.length).toBe(0);
|
||||
|
||||
act(() => {
|
||||
result.current.initializeFilterOnFieldMetataItemFromViewBarFilterDropdown(
|
||||
personCreatedAtFieldMetadataItemMock,
|
||||
);
|
||||
});
|
||||
|
||||
expect(result.current.fieldMetadataItemUsedInDropdown?.id).toBe(
|
||||
personCreatedAtFieldMetadataItemMock.id,
|
||||
);
|
||||
|
||||
expect(
|
||||
result.current.objectFilterDropdownCurrentRecordFilter?.fieldMetadataId,
|
||||
).toBe(personCreatedAtFieldMetadataItemMock.id);
|
||||
|
||||
expect(
|
||||
result.current.objectFilterDropdownCurrentRecordFilter?.value,
|
||||
).toBeDefined();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,145 @@
|
||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { useUpsertObjectFilterDropdownCurrentFilter } from '@/object-record/object-filter-dropdown/hooks/useUpsertObjectFilterDropdownCurrentFilter';
|
||||
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
||||
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||
import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState';
|
||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { findDuplicateRecordFilterInNonAdvancedRecordFilters } from '@/object-record/record-filter/utils/findDuplicateRecordFilterInNonAdvancedRecordFilters';
|
||||
import { getDateFilterDisplayValue } from '@/object-record/record-filter/utils/getDateFilterDisplayValue';
|
||||
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
||||
import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope';
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
export const useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown =
|
||||
() => {
|
||||
const selectedOperandInDropdownCallbackState =
|
||||
useRecoilComponentCallbackStateV2(
|
||||
selectedOperandInDropdownComponentState,
|
||||
);
|
||||
|
||||
const setHotkeyScope = useSetHotkeyScope();
|
||||
|
||||
const currentRecordFiltersCallbackState = useRecoilComponentCallbackStateV2(
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
const objectFilterDropdownCurrentRecordFilterCallbackState =
|
||||
useRecoilComponentCallbackStateV2(
|
||||
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||
);
|
||||
|
||||
const fieldMetadataItemUsedInDropdownCallbackState =
|
||||
useRecoilComponentCallbackStateV2(
|
||||
fieldMetadataItemIdUsedInDropdownComponentState,
|
||||
);
|
||||
|
||||
const objectFilterDropdownFilterIsSelectedCallbackState =
|
||||
useRecoilComponentCallbackStateV2(
|
||||
objectFilterDropdownFilterIsSelectedComponentState,
|
||||
);
|
||||
|
||||
const { upsertObjectFilterDropdownCurrentFilter } =
|
||||
useUpsertObjectFilterDropdownCurrentFilter();
|
||||
|
||||
const initializeFilterOnFieldMetataItemFromViewBarFilterDropdown =
|
||||
useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
(fieldMetadataItem: FieldMetadataItem) => {
|
||||
set(
|
||||
fieldMetadataItemUsedInDropdownCallbackState,
|
||||
fieldMetadataItem.id,
|
||||
);
|
||||
|
||||
const currentRecordFilters = snapshot
|
||||
.getLoadable(currentRecordFiltersCallbackState)
|
||||
.getValue();
|
||||
|
||||
const filterType = getFilterTypeFromFieldType(
|
||||
fieldMetadataItem.type,
|
||||
);
|
||||
|
||||
if (filterType === 'RELATION' || filterType === 'SELECT') {
|
||||
setHotkeyScope(SingleRecordPickerHotkeyScope.SingleRecordPicker);
|
||||
}
|
||||
|
||||
set(objectFilterDropdownFilterIsSelectedCallbackState, true);
|
||||
|
||||
const defaultOperand = getRecordFilterOperands({
|
||||
filterType,
|
||||
})[0];
|
||||
|
||||
const duplicateFilterInCurrentRecordFilters =
|
||||
findDuplicateRecordFilterInNonAdvancedRecordFilters({
|
||||
recordFilters: currentRecordFilters,
|
||||
fieldMetadataItemId: fieldMetadataItem.id,
|
||||
});
|
||||
|
||||
const filterIsAlreadyInCurrentRecordFilters = isDefined(
|
||||
duplicateFilterInCurrentRecordFilters,
|
||||
);
|
||||
|
||||
if (filterIsAlreadyInCurrentRecordFilters) {
|
||||
set(
|
||||
objectFilterDropdownCurrentRecordFilterCallbackState,
|
||||
duplicateFilterInCurrentRecordFilters,
|
||||
);
|
||||
|
||||
set(
|
||||
selectedOperandInDropdownCallbackState,
|
||||
duplicateFilterInCurrentRecordFilters.operand,
|
||||
);
|
||||
} else {
|
||||
set(selectedOperandInDropdownCallbackState, defaultOperand);
|
||||
|
||||
if (filterType === 'DATE' || filterType === 'DATE_TIME') {
|
||||
const date = new Date();
|
||||
const value = date.toISOString();
|
||||
|
||||
const { displayValue } = getDateFilterDisplayValue(
|
||||
date,
|
||||
filterType,
|
||||
);
|
||||
|
||||
const initialDateRecordFilter: RecordFilter = {
|
||||
id: v4(),
|
||||
fieldMetadataId: fieldMetadataItem.id,
|
||||
operand: defaultOperand,
|
||||
displayValue,
|
||||
label: fieldMetadataItem.label,
|
||||
type: filterType,
|
||||
value,
|
||||
};
|
||||
|
||||
upsertObjectFilterDropdownCurrentFilter(
|
||||
initialDateRecordFilter,
|
||||
);
|
||||
|
||||
set(
|
||||
objectFilterDropdownCurrentRecordFilterCallbackState,
|
||||
initialDateRecordFilter,
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
[
|
||||
fieldMetadataItemUsedInDropdownCallbackState,
|
||||
objectFilterDropdownCurrentRecordFilterCallbackState,
|
||||
selectedOperandInDropdownCallbackState,
|
||||
setHotkeyScope,
|
||||
objectFilterDropdownFilterIsSelectedCallbackState,
|
||||
currentRecordFiltersCallbackState,
|
||||
upsertObjectFilterDropdownCurrentFilter,
|
||||
],
|
||||
);
|
||||
|
||||
return {
|
||||
initializeFilterOnFieldMetataItemFromViewBarFilterDropdown,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user