Use view filters operands in step filters + migrate to twenty-shared (#13137)

Step operand will more or less be the same as view filter operand. 

This PR:
- moves `ViewFilterOperand` to twenty-shared
- use it as step operand
- check what operand should be available based on the selected field
type in filter action
- rewrite the function that evaluates filters so it uses
ViewFilterOperand instead

ViewFilterOperand may be renamed in a future PR.
This commit is contained in:
Thomas Trompette
2025-07-10 10:36:37 +02:00
committed by GitHub
parent d808cbeed9
commit 50e402af07
55 changed files with 677 additions and 665 deletions

View File

@ -14,7 +14,7 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { ViewFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
import { MenuItem } from 'twenty-ui/navigation';
type AdvancedFilterRecordFilterOperandSelectContentProps = {

View File

@ -5,7 +5,6 @@ import { selectedOperandInDropdownComponentState } from '@/object-record/object-
import { getRelativeDateDisplayValue } from '@/object-record/object-filter-dropdown/utils/getRelativeDateDisplayValue';
import { DateTimePicker } from '@/ui/input/components/internal/date/components/InternalDatePicker';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { computeVariableDateViewFilterValue } from '@/views/view-filter-value/utils/computeVariableDateViewFilterValue';
import {
resolveDateViewFilterValue,
@ -13,6 +12,7 @@ import {
VariableDateViewFilterValueUnit,
} from '@/views/view-filter-value/utils/resolveDateViewFilterValue';
import { useState } from 'react';
import { ViewFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
import { isDefined } from 'twenty-shared/utils';
import { FieldMetadataType } from '~/generated-metadata/graphql';

View File

@ -6,7 +6,7 @@ import { ObjectFilterDropdownRecordSelect } from '@/object-record/object-filter-
import { ObjectFilterDropdownSearchInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownSearchInput';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { ViewBarFilterDropdownVectorSearchInput } from '@/views/components/ViewBarFilterDropdownVectorSearchInput';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { ViewFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
import { ObjectFilterDropdownBooleanSelect } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownBooleanSelect';

View File

@ -1,6 +1,6 @@
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 'twenty-shared/src/types/ViewFilterOperand';
export const selectedOperandInDropdownComponentState =
createComponentStateV2<ViewFilterOperand | null>({

View File

@ -1,4 +1,4 @@
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { ViewFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
import { capitalize } from 'twenty-shared/utils';
import { getOperandLabel, getOperandLabelShort } from '../getOperandLabel';

View File

@ -1,4 +1,4 @@
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { ViewFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
import { isFilterOperandExpectingValue } from '../isFilterOperandExpectingValue';

View File

@ -1,4 +1,4 @@
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { ViewFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
export const configurableViewFilterOperands = new Set<ViewFilterOperand>([
ViewFilterOperand.Is,

View File

@ -1,5 +1,5 @@
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { t } from '@lingui/core/macro';
import { ViewFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
export const getOperandLabel = (
operand: ViewFilterOperand | null | undefined,

View File

@ -1,4 +1,4 @@
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { ViewFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
export const isFilterOperandExpectingValue = (operand: ViewFilterOperand) => {
switch (operand) {

View File

@ -3,8 +3,8 @@ import { renderHook } from '@testing-library/react';
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { act } from 'react';
import { ViewFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
import { useRemoveRecordFilter } from '../useRemoveRecordFilter';

View File

@ -4,7 +4,7 @@ import { act } from 'react';
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { ViewFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
import { useUpsertRecordFilter } from '../useUpsertRecordFilter';

View File

@ -1,7 +1,7 @@
import { FilterableAndTSVectorFieldType } from '@/object-record/record-filter/types/FilterableFieldType';
import { FILTER_OPERANDS_MAP } from '@/object-record/record-filter/utils/getRecordFilterOperands';
import { CompositeFieldSubFieldName } from '@/settings/data-model/types/CompositeFieldSubFieldName';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { ViewFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
export type RecordFilter = {
id: string;

View File

@ -1 +1 @@
export { ViewFilterOperand as RecordFilterOperand } from '@/views/types/ViewFilterOperand';
export { ViewFilterOperand as RecordFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';

View File

@ -3,7 +3,7 @@ import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand';
import { RecordFilterValueDependencies } from '@/object-record/record-filter/types/RecordFilterValueDependencies';
import { computeRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeRecordGqlOperationFilter';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { ViewFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { getCompaniesMock } from '~/testing/mock-data/companies';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';

View File

@ -19,8 +19,8 @@ import {
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import { computeEmptyGqlOperationFilterForEmails } from '@/object-record/record-filter/utils/compute-empty-record-gql-operation-filter/for-composite-field/computeEmptyGqlOperationFilterForEmails';
import { computeEmptyGqlOperationFilterForLinks } from '@/object-record/record-filter/utils/compute-empty-record-gql-operation-filter/for-composite-field/computeEmptyGqlOperationFilterForLinks';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { isNonEmptyString } from '@sniptt/guards';
import { ViewFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
import { Field } from '~/generated/graphql';
import { generateILikeFiltersForCompositeFields } from '~/utils/array/generateILikeFiltersForCompositeFields';

View File

@ -5,7 +5,7 @@ import {
FilterableFieldType,
} from '@/object-record/record-filter/types/FilterableFieldType';
import { CompositeFieldSubFieldName } from '@/settings/data-model/types/CompositeFieldSubFieldName';
import { ViewFilterOperand as RecordFilterOperand } from '@/views/types/ViewFilterOperand';
import { ViewFilterOperand as RecordFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
import { FieldMetadataType } from 'twenty-shared/types';
import { assertUnreachable } from 'twenty-shared/utils';

View File

@ -9,8 +9,8 @@ import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import { isSoftDeleteFilterActiveComponentState } from '@/object-record/record-table/states/isSoftDeleteFilterActiveComponentState';
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { useRecoilCallback } from 'recoil';
import { ViewFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
import { isDefined } from 'twenty-shared/utils';
type UseHandleToggleTrashColumnFilterProps = {

View File

@ -19,8 +19,8 @@ import { AppPath } from '@/types/AppPath';
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { useLingui } from '@lingui/react/macro';
import { ViewFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
import { RelationType } from '~/generated-metadata/graphql';
import { getAppPath } from '~/utils/navigation/getAppPath';

View File

@ -1,8 +1,8 @@
import { FieldMetadataItemOption } from '@/object-metadata/types/FieldMetadataItem';
import { FilterableFieldType } from '@/object-record/record-filter/types/FilterableFieldType';
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
import { ViewFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
import { RelationType } from '~/generated-metadata/graphql';
import { buildValueFromFilter } from './buildRecordInputFromFilter';

View File

@ -7,7 +7,7 @@ import {
RecordFilterToRecordInputOperand,
} from '@/object-record/record-filter/types/RecordFilter';
import { FILTER_OPERANDS_MAP } from '@/object-record/record-filter/utils/getRecordFilterOperands';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { ViewFilterOperand } from 'twenty-shared/src/types/ViewFilterOperand';
import { assertUnreachable, parseJson } from 'twenty-shared/utils';
import { RelationType } from '~/generated-metadata/graphql';