diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/components/DestroyMultipleRecordsAction.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/components/DestroyMultipleRecordsAction.tsx index a2443656cd..b306bc46e5 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/components/DestroyMultipleRecordsAction.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/components/DestroyMultipleRecordsAction.tsx @@ -6,13 +6,13 @@ import { contextStoreFiltersComponentState } from '@/context-store/states/contex import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters'; import { DEFAULT_QUERY_PAGE_SIZE } from '@/object-record/constants/DefaultQueryPageSize'; -import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; import { useDestroyManyRecords } from '@/object-record/hooks/useDestroyManyRecords'; import { useLazyFetchAllRecords } from '@/object-record/hooks/useLazyFetchAllRecords'; import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies'; import { useRecordIndexIdFromCurrentContextStore } from '@/object-record/record-index/hooks/useRecordIndexIdFromCurrentContextStore'; import { useResetTableRowSelection } from '@/object-record/record-table/hooks/internal/useResetTableRowSelection'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; +import { type RecordGqlOperationFilter } from 'twenty-shared/types'; export const DestroyMultipleRecordsAction = () => { const { recordIndexId, objectMetadataItem } = diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/components/RestoreMultipleRecordsAction.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/components/RestoreMultipleRecordsAction.tsx index 223da282be..4066448259 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/components/RestoreMultipleRecordsAction.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/components/RestoreMultipleRecordsAction.tsx @@ -6,13 +6,13 @@ import { contextStoreFiltersComponentState } from '@/context-store/states/contex import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters'; import { DEFAULT_QUERY_PAGE_SIZE } from '@/object-record/constants/DefaultQueryPageSize'; -import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; import { useLazyFetchAllRecords } from '@/object-record/hooks/useLazyFetchAllRecords'; import { useRestoreManyRecords } from '@/object-record/hooks/useRestoreManyRecords'; import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies'; import { useRecordIndexIdFromCurrentContextStore } from '@/object-record/record-index/hooks/useRecordIndexIdFromCurrentContextStore'; import { useResetTableRowSelection } from '@/object-record/record-table/hooks/internal/useResetTableRowSelection'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; +import { type RecordGqlOperationFilter } from 'twenty-shared/types'; export const RestoreMultipleRecordsAction = () => { const { recordIndexId, objectMetadataItem } = diff --git a/packages/twenty-front/src/modules/activities/hooks/useActivities.ts b/packages/twenty-front/src/modules/activities/hooks/useActivities.ts index 449ae2cbee..a895e37cc6 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useActivities.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useActivities.ts @@ -8,10 +8,10 @@ import { type Note } from '@/activities/types/Note'; import { type Task } from '@/activities/types/Task'; import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; import { type CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; import { type RecordGqlOperationOrderBy } from '@/object-record/graphql/types/RecordGqlOperationOrderBy'; import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; +import { type RecordGqlOperationFilter } from 'twenty-shared/types'; import { sortByAscString } from '~/utils/array/sortByAscString'; export const useActivities = ({ diff --git a/packages/twenty-front/src/modules/context-store/utils/__tests__/computeContextStoreFilters.test.ts b/packages/twenty-front/src/modules/context-store/utils/__tests__/computeContextStoreFilters.test.ts index b62850167f..6271a5516e 100644 --- a/packages/twenty-front/src/modules/context-store/utils/__tests__/computeContextStoreFilters.test.ts +++ b/packages/twenty-front/src/modules/context-store/utils/__tests__/computeContextStoreFilters.test.ts @@ -1,8 +1,10 @@ import { type ContextStoreTargetedRecordsRule } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; -import { type RecordFilterValueDependencies } from '@/object-record/record-filter/types/RecordFilterValueDependencies'; -import { ViewFilterOperand } from 'twenty-shared/types'; +import { + type RecordFilterValueDependencies, + ViewFilterOperand, +} from 'twenty-shared/types'; import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems'; describe('computeContextStoreFilters', () => { diff --git a/packages/twenty-front/src/modules/context-store/utils/computeContextStoreFilters.ts b/packages/twenty-front/src/modules/context-store/utils/computeContextStoreFilters.ts index e0d7f32b96..9b1ef96aa4 100644 --- a/packages/twenty-front/src/modules/context-store/utils/computeContextStoreFilters.ts +++ b/packages/twenty-front/src/modules/context-store/utils/computeContextStoreFilters.ts @@ -1,12 +1,14 @@ import { type ContextStoreTargetedRecordsRule } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; -import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; -import { type RecordFilterValueDependencies } from '@/object-record/record-filter/types/RecordFilterValueDependencies'; -import { computeRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeRecordGqlOperationFilter'; import { turnAnyFieldFilterIntoRecordGqlFilter } from '@/object-record/record-filter/utils/turnAnyFieldFilterIntoRecordGqlFilter'; import { makeAndFilterVariables } from '@/object-record/utils/makeAndFilterVariables'; +import { + type RecordFilterValueDependencies, + type RecordGqlOperationFilter, +} from 'twenty-shared/types'; +import { computeRecordGqlOperationFilter } from 'twenty-shared/utils'; type ComputeContextStoreFiltersProps = { contextStoreTargetedRecordsRule: ContextStoreTargetedRecordsRule; diff --git a/packages/twenty-front/src/modules/error-handler/components/AppErrorBoundary.tsx b/packages/twenty-front/src/modules/error-handler/components/AppErrorBoundary.tsx index 19da8f8396..c1c4991ecc 100644 --- a/packages/twenty-front/src/modules/error-handler/components/AppErrorBoundary.tsx +++ b/packages/twenty-front/src/modules/error-handler/components/AppErrorBoundary.tsx @@ -1,9 +1,8 @@ import { AppErrorBoundaryEffect } from '@/error-handler/components/internal/AppErrorBoundaryEffect'; -import { type CustomError } from '@/error-handler/CustomError'; import { checkIfItsAViteStaleChunkLazyLoadingError } from '@/error-handler/utils/checkIfItsAViteStaleChunkLazyLoadingError'; import { type ErrorInfo, type ReactNode } from 'react'; import { ErrorBoundary, type FallbackProps } from 'react-error-boundary'; -import { isDefined } from 'twenty-shared/utils'; +import { type CustomError, isDefined } from 'twenty-shared/utils'; type AppErrorBoundaryProps = { children: ReactNode; diff --git a/packages/twenty-front/src/modules/error-handler/components/PromiseRejectionEffect.tsx b/packages/twenty-front/src/modules/error-handler/components/PromiseRejectionEffect.tsx index db17fe8079..ef0eca92e3 100644 --- a/packages/twenty-front/src/modules/error-handler/components/PromiseRejectionEffect.tsx +++ b/packages/twenty-front/src/modules/error-handler/components/PromiseRejectionEffect.tsx @@ -1,9 +1,8 @@ import { useCallback, useEffect } from 'react'; -import { type CustomError } from '@/error-handler/CustomError'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import isEmpty from 'lodash.isempty'; -import { isDefined } from 'twenty-shared/utils'; +import { isDefined, type CustomError } from 'twenty-shared/utils'; const hasErrorCode = ( error: CustomError | any, diff --git a/packages/twenty-front/src/modules/favorites/utils/validateAndExtractFolderId.ts b/packages/twenty-front/src/modules/favorites/utils/validateAndExtractFolderId.ts index f2f2bbb697..62e774b413 100644 --- a/packages/twenty-front/src/modules/favorites/utils/validateAndExtractFolderId.ts +++ b/packages/twenty-front/src/modules/favorites/utils/validateAndExtractFolderId.ts @@ -1,5 +1,5 @@ -import { CustomError } from '@/error-handler/CustomError'; import { FAVORITE_DROPPABLE_IDS } from '@/favorites/constants/FavoriteDroppableIds'; +import { CustomError } from 'twenty-shared/utils'; export const validateAndExtractFolderId = ( droppableId: string, diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useGetObjectMetadataItemById.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useGetObjectMetadataItemById.ts index 6ae6c99c7d..df1ce4d25c 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/useGetObjectMetadataItemById.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useGetObjectMetadataItemById.ts @@ -1,8 +1,7 @@ import { useRecoilValue } from 'recoil'; -import { CustomError } from '@/error-handler/CustomError'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; -import { isDefined } from 'twenty-shared/utils'; +import { CustomError, isDefined } from 'twenty-shared/utils'; export const useGetObjectMetadataItemById = () => { const objectMetadataItems = useRecoilValue(objectMetadataItemsState); diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItemById.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItemById.ts index 6802ceb039..88c5cb6977 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItemById.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItemById.ts @@ -1,8 +1,7 @@ import { useRecoilValue } from 'recoil'; -import { CustomError } from '@/error-handler/CustomError'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; -import { isDefined } from 'twenty-shared/utils'; +import { CustomError, isDefined } from 'twenty-shared/utils'; export const useObjectMetadataItemById = ({ objectId, diff --git a/packages/twenty-front/src/modules/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions.ts b/packages/twenty-front/src/modules/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions.ts index ea8f7ef121..06c2d67351 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions.ts +++ b/packages/twenty-front/src/modules/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions.ts @@ -1,6 +1,3 @@ -import { FieldMetadataType } from '~/generated-metadata/graphql'; - -import { type FilterableAndTSVectorFieldType } from '@/object-record/record-filter/types/FilterableFieldType'; import { type ObjectMetadataItem } from '../types/ObjectMetadataItem'; export const getRelationObjectMetadataNameSingular = ({ @@ -10,50 +7,3 @@ export const getRelationObjectMetadataNameSingular = ({ }): string | undefined => { return field.relation?.targetObjectMetadata.nameSingular; }; - -export const getFilterTypeFromFieldType = ( - fieldType: FieldMetadataType, -): FilterableAndTSVectorFieldType => { - switch (fieldType) { - case FieldMetadataType.DATE_TIME: - return 'DATE_TIME'; - case FieldMetadataType.DATE: - return 'DATE'; - case FieldMetadataType.LINKS: - return 'LINKS'; - case FieldMetadataType.FULL_NAME: - return 'FULL_NAME'; - case FieldMetadataType.NUMBER: - return 'NUMBER'; - case FieldMetadataType.CURRENCY: - return 'CURRENCY'; - case FieldMetadataType.EMAILS: - return 'EMAILS'; - case FieldMetadataType.PHONES: - return 'PHONES'; - case FieldMetadataType.RELATION: - return 'RELATION'; - case FieldMetadataType.SELECT: - return 'SELECT'; - case FieldMetadataType.MULTI_SELECT: - return 'MULTI_SELECT'; - case FieldMetadataType.ADDRESS: - return 'ADDRESS'; - case FieldMetadataType.RATING: - return 'RATING'; - case FieldMetadataType.ACTOR: - return 'ACTOR'; - case FieldMetadataType.ARRAY: - return 'ARRAY'; - case FieldMetadataType.RAW_JSON: - return 'RAW_JSON'; - case FieldMetadataType.BOOLEAN: - return 'BOOLEAN'; - case FieldMetadataType.TS_VECTOR: - return 'TS_VECTOR'; - case FieldMetadataType.UUID: - return 'UUID'; - default: - return 'TEXT'; - } -}; diff --git a/packages/twenty-front/src/modules/object-metadata/utils/getFieldMetadataItemByIdOrThrow.ts b/packages/twenty-front/src/modules/object-metadata/utils/getFieldMetadataItemByIdOrThrow.ts index e35226ea12..ea546f060b 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/getFieldMetadataItemByIdOrThrow.ts +++ b/packages/twenty-front/src/modules/object-metadata/utils/getFieldMetadataItemByIdOrThrow.ts @@ -1,6 +1,5 @@ -import { CustomError } from '@/error-handler/CustomError'; import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; -import { isDefined } from 'twenty-shared/utils'; +import { CustomError, isDefined } from 'twenty-shared/utils'; type GetFieldMetadataItemByIdParams = { fieldMetadataId: string; diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterAddFilterRuleSelect.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterAddFilterRuleSelect.tsx index 257348a39d..5caaa9fe14 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterAddFilterRuleSelect.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterAddFilterRuleSelect.tsx @@ -1,12 +1,10 @@ import { ActionButton } from '@/action-menu/actions/display/components/ActionButton'; -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { useChildRecordFiltersAndRecordFilterGroups } from '@/object-record/advanced-filter/hooks/useChildRecordFiltersAndRecordFilterGroups'; import { useDefaultFieldMetadataItemForFilter } from '@/object-record/advanced-filter/hooks/useDefaultFieldMetadataItemForFilter'; import { useSetRecordFilterUsedInAdvancedFilterDropdownRow } from '@/object-record/advanced-filter/hooks/useSetRecordFilterUsedInAdvancedFilterDropdownRow'; import { getAdvancedFilterAddFilterRuleSelectDropdownId } from '@/object-record/advanced-filter/utils/getAdvancedFilterAddFilterRuleSelectDropdownId'; import { useUpsertRecordFilterGroup } from '@/object-record/record-filter-group/hooks/useUpsertRecordFilterGroup'; import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; -import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; import { getDefaultSubFieldNameForCompositeFilterableFieldType } from '@/object-record/record-filter/utils/getDefaultSubFieldNameForCompositeFilterableFieldType'; @@ -16,7 +14,8 @@ import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown'; import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly'; -import { isDefined } from 'twenty-shared/utils'; +import { RecordFilterGroupLogicalOperator } from 'twenty-shared/types'; +import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils'; import { IconLibraryPlus, IconPlus } from 'twenty-ui/display'; import { MenuItem } from 'twenty-ui/navigation'; import { v4 } from 'uuid'; diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterDropdownFilterInput.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterDropdownFilterInput.tsx index aef3e01d27..e2605500dc 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterDropdownFilterInput.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterDropdownFilterInput.tsx @@ -13,13 +13,13 @@ import { ObjectFilterDropdownDateInput } from '@/object-record/object-filter-dro import { ObjectFilterDropdownTextInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownTextInput'; import { DATE_FILTER_TYPES } from '@/object-record/object-filter-dropdown/constants/DateFilterTypes'; import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState'; -import { isExpectedSubFieldName } from '@/object-record/object-filter-dropdown/utils/isExpectedSubFieldName'; import { isFilterOnActorSourceSubField } from '@/object-record/object-filter-dropdown/utils/isFilterOnActorSourceSubField'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent'; import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { FieldMetadataType } from 'twenty-shared/types'; +import { isExpectedSubFieldName } from 'twenty-shared/utils'; type AdvancedFilterDropdownFilterInputProps = { filterDropdownId: string; diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterFieldSelectMenu.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterFieldSelectMenu.tsx index b0a6aa6f96..725f7eac50 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterFieldSelectMenu.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterFieldSelectMenu.tsx @@ -10,7 +10,6 @@ import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectab import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { AdvancedFilterFieldSelectSearchInput } from '@/object-record/advanced-filter/components/AdvancedFilterFieldSelectSearchInput'; import { useAdvancedFilterFieldSelectDropdown } from '@/object-record/advanced-filter/hooks/useAdvancedFilterFieldSelectDropdown'; import { useSelectFieldUsedInAdvancedFilterDropdown } from '@/object-record/advanced-filter/hooks/useSelectFieldUsedInAdvancedFilterDropdown'; @@ -27,6 +26,7 @@ import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/Gene import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState'; import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState'; import { useLingui } from '@lingui/react/macro'; +import { getFilterTypeFromFieldType } from 'twenty-shared/utils'; type AdvancedFilterFieldSelectMenuProps = { recordFilterId: string; diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorDropdown.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorDropdown.tsx index 1e8e79e673..0915e96e44 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorDropdown.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorDropdown.tsx @@ -2,9 +2,9 @@ import { ADVANCED_FILTER_LOGICAL_OPERATOR_OPTIONS } from '@/object-record/advanc import { DEFAULT_ADVANCED_FILTER_DROPDOWN_OFFSET } from '@/object-record/advanced-filter/constants/DefaultAdvancedFilterDropdownOffset'; import { useUpsertRecordFilterGroup } from '@/object-record/record-filter-group/hooks/useUpsertRecordFilterGroup'; import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; -import { type RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; import { Select } from '@/ui/input/components/Select'; import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth'; +import { type RecordFilterGroupLogicalOperator } from 'twenty-shared/types'; type AdvancedFilterLogicalOperatorDropdownProps = { recordFilterGroup: RecordFilterGroup; diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/constants/AdvancedFilterLogicalOperatorOptions.ts b/packages/twenty-front/src/modules/object-record/advanced-filter/constants/AdvancedFilterLogicalOperatorOptions.ts index 8d44eb01d3..c38fa00606 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/constants/AdvancedFilterLogicalOperatorOptions.ts +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/constants/AdvancedFilterLogicalOperatorOptions.ts @@ -1,4 +1,4 @@ -import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; +import { RecordFilterGroupLogicalOperator } from 'twenty-shared/types'; export const ADVANCED_FILTER_LOGICAL_OPERATOR_OPTIONS = [ { diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useSelectFieldUsedInAdvancedFilterDropdown.ts b/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useSelectFieldUsedInAdvancedFilterDropdown.ts index 6581c1e507..49e586802e 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useSelectFieldUsedInAdvancedFilterDropdown.ts +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useSelectFieldUsedInAdvancedFilterDropdown.ts @@ -1,5 +1,4 @@ import { useGetFieldMetadataItemByIdOrThrow } from '@/object-metadata/hooks/useGetFieldMetadataItemById'; -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState'; import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState'; import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState'; @@ -18,7 +17,7 @@ import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePush import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState'; -import { isDefined } from 'twenty-shared/utils'; +import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils'; type SelectFilterParams = { fieldMetadataItemId: string; diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/utils/shouldShowFilterTextInput.ts b/packages/twenty-front/src/modules/object-record/advanced-filter/utils/shouldShowFilterTextInput.ts index 72d9020f77..0a4f1f0372 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/utils/shouldShowFilterTextInput.ts +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/utils/shouldShowFilterTextInput.ts @@ -1,10 +1,10 @@ import { NUMBER_FILTER_TYPES } from '@/object-record/object-filter-dropdown/constants/NumberFilterTypes'; import { TEXT_FILTER_TYPES } from '@/object-record/object-filter-dropdown/constants/TextFilterTypes'; -import { isExpectedSubFieldName } from '@/object-record/object-filter-dropdown/utils/isExpectedSubFieldName'; -import { FieldMetadataType } from 'twenty-shared/types'; -import { type RecordFilter } from '../../record-filter/types/RecordFilter'; +import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; import { type CompositeFieldSubFieldName } from '@/settings/data-model/types/CompositeFieldSubFieldName'; +import { FieldMetadataType } from 'twenty-shared/types'; +import { isExpectedSubFieldName } from 'twenty-shared/utils'; export const shouldShowFilterTextInput = ({ recordFilter, diff --git a/packages/twenty-front/src/modules/object-record/graphql/types/RecordGqlOperationVariables.ts b/packages/twenty-front/src/modules/object-record/graphql/types/RecordGqlOperationVariables.ts index b625a8ed78..c10ecc52d7 100644 --- a/packages/twenty-front/src/modules/object-record/graphql/types/RecordGqlOperationVariables.ts +++ b/packages/twenty-front/src/modules/object-record/graphql/types/RecordGqlOperationVariables.ts @@ -1,6 +1,6 @@ -import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; import { type RecordGqlOperationOrderBy } from '@/object-record/graphql/types/RecordGqlOperationOrderBy'; import { type QueryCursorDirection } from '@/object-record/utils/generateFindManyRecordsQuery'; +import { type RecordGqlOperationFilter } from 'twenty-shared/types'; export type RecordGqlOperationVariables = { filter?: RecordGqlOperationFilter; diff --git a/packages/twenty-front/src/modules/object-record/hooks/useAggregateRecords.ts b/packages/twenty-front/src/modules/object-record/hooks/useAggregateRecords.ts index ce162d259a..f34530163c 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useAggregateRecords.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useAggregateRecords.ts @@ -3,12 +3,12 @@ import { useQuery } from '@apollo/client'; import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { type RecordGqlFieldsAggregate } from '@/object-record/graphql/types/RecordGqlFieldsAggregate'; -import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; import { type RecordGqlOperationFindManyResult } from '@/object-record/graphql/types/RecordGqlOperationFindManyResult'; import { useAggregateRecordsQuery } from '@/object-record/hooks/useAggregateRecordsQuery'; import { useObjectPermissionsForObject } from '@/object-record/hooks/useObjectPermissionsForObject'; import { type ExtendedAggregateOperations } from '@/object-record/record-table/types/ExtendedAggregateOperations'; import isEmpty from 'lodash.isempty'; +import { type RecordGqlOperationFilter } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; export type AggregateRecordsData = { diff --git a/packages/twenty-front/src/modules/object-record/hooks/useAttachRelatedRecordFromRecord.ts b/packages/twenty-front/src/modules/object-record/hooks/useAttachRelatedRecordFromRecord.ts index efbfe58437..043ee620f6 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useAttachRelatedRecordFromRecord.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useAttachRelatedRecordFromRecord.ts @@ -1,4 +1,3 @@ -import { CustomError } from '@/error-handler/CustomError'; import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; @@ -8,7 +7,7 @@ import { computeDepthOneRecordGqlFieldsFromRecord } from '@/object-record/graphq import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; -import { isDefined } from 'twenty-shared/utils'; +import { CustomError, isDefined } from 'twenty-shared/utils'; type useAttachRelatedRecordFromRecordProps = { recordObjectNameSingular: string; diff --git a/packages/twenty-front/src/modules/object-record/hooks/useFindManyRecords.ts b/packages/twenty-front/src/modules/object-record/hooks/useFindManyRecords.ts index abd26e9d4d..8967982e9c 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useFindManyRecords.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useFindManyRecords.ts @@ -15,8 +15,8 @@ import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; import { type OnFindManyRecordsCompleted } from '@/object-record/types/OnFindManyRecordsCompleted'; import { getQueryIdentifier } from '@/object-record/utils/getQueryIdentifier'; -import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; import { QUERY_DEFAULT_LIMIT_RECORDS } from 'twenty-shared/constants'; +import { type RecordGqlOperationFilter } from 'twenty-shared/types'; export type UseFindManyRecordsParams = ObjectMetadataItemIdentifier & RecordGqlOperationVariables & { diff --git a/packages/twenty-front/src/modules/object-record/hooks/useUpdateMultipleRecordsFromManyObjects.ts b/packages/twenty-front/src/modules/object-record/hooks/useUpdateMultipleRecordsFromManyObjects.ts index f3065b069f..0ba80bc018 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useUpdateMultipleRecordsFromManyObjects.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useUpdateMultipleRecordsFromManyObjects.ts @@ -1,6 +1,5 @@ import { triggerUpdateRecordOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerUpdateRecordOptimisticEffect'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; -import { CustomError } from '@/error-handler/CustomError'; import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient'; import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; import { getObjectTypename } from '@/object-record/cache/utils/getObjectTypename'; @@ -23,7 +22,7 @@ import { sanitizeRecordInput } from '@/object-record/utils/sanitizeRecordInput'; import { isNull } from '@sniptt/guards'; import { useContext } from 'react'; import { useRecoilValue } from 'recoil'; -import { isDefined } from 'twenty-shared/utils'; +import { CustomError, isDefined } from 'twenty-shared/utils'; import { buildRecordFromKeysWithSameValue } from '~/utils/array/buildRecordFromKeysWithSameValue'; type UpdateManyRecordArgs = { diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownContentWrapper.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownContentWrapper.tsx index fff046822f..d410fbb69a 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownContentWrapper.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownContentWrapper.tsx @@ -1,11 +1,10 @@ -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { DATE_FILTER_TYPES } from '@/object-record/object-filter-dropdown/constants/DateFilterTypes'; import { DATE_PICKER_DROPDOWN_CONTENT_WIDTH } from '@/object-record/object-filter-dropdown/constants/DatePickerDropdownContentWidth'; import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector'; import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent'; import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; -import { isDefined } from 'twenty-shared/utils'; +import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils'; export const ObjectFilterDropdownContentWrapper = ({ children, diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateInput.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateInput.tsx index 2ce6f8dd0a..a19e2a4ce0 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateInput.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateInput.tsx @@ -6,14 +6,13 @@ import { getRelativeDateDisplayValue } from '@/object-record/object-filter-dropd import { DateTimePicker } from '@/ui/input/components/internal/date/components/InternalDatePicker'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { computeVariableDateViewFilterValue } from '@/views/view-filter-value/utils/computeVariableDateViewFilterValue'; -import { resolveDateViewFilterValue } from '@/views/view-filter-value/utils/resolveDateViewFilterValue'; import { useState } from 'react'; import { ViewFilterOperand, type VariableDateViewFilterValueDirection, type VariableDateViewFilterValueUnit, } from 'twenty-shared/types'; -import { isDefined } from 'twenty-shared/utils'; +import { isDefined, resolveDateViewFilterValue } from 'twenty-shared/utils'; import { FieldMetadataType } from '~/generated-metadata/graphql'; export const ObjectFilterDropdownDateInput = () => { diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterInput.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterInput.tsx index 944fa61005..de09d92e73 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterInput.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterInput.tsx @@ -8,7 +8,6 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM import { ViewFilterOperand } from 'twenty-shared/types'; -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { ObjectFilterDropdownBooleanSelect } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownBooleanSelect'; import { ObjectFilterDropdownInnerSelectOperandDropdown } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownInnerSelectOperandDropdown'; import { ObjectFilterDropdownTextInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownTextInput'; @@ -19,7 +18,7 @@ import { TEXT_FILTER_TYPES } from '@/object-record/object-filter-dropdown/consta import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector'; import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; -import { isDefined } from 'twenty-shared/utils'; +import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils'; type ObjectFilterDropdownFilterInputProps = { filterDropdownId: string; diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownInnerSelectOperandDropdown.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownInnerSelectOperandDropdown.tsx index 3dce6df833..57cbdaf711 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownInnerSelectOperandDropdown.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownInnerSelectOperandDropdown.tsx @@ -1,4 +1,3 @@ -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { DATE_FILTER_TYPES } from '@/object-record/object-filter-dropdown/constants/DateFilterTypes'; import { DATE_PICKER_DROPDOWN_CONTENT_WIDTH } from '@/object-record/object-filter-dropdown/constants/DatePickerDropdownContentWidth'; import { useApplyObjectFilterDropdownOperand } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownOperand'; @@ -11,7 +10,7 @@ import { getRecordFilterOperands } from '@/object-record/record-filter/utils/get import { DropdownMenuInnerSelect } from '@/ui/layout/dropdown/components/DropdownMenuInnerSelect'; import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; -import { isDefined } from 'twenty-shared/utils'; +import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils'; import { type SelectOption } from 'twenty-ui/input'; const OBJECT_FILTER_DROPDOWN_INNER_SELECT_OPERAND_DROPDOWN_ID = diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRatingInput.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRatingInput.tsx index cffcdc911a..0e1ac9ed5c 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRatingInput.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRatingInput.tsx @@ -1,10 +1,9 @@ -import { RATING_VALUES } from '@/object-record/record-field/ui/meta-types/constants/RatingValues'; -import { type FieldRatingValue } from '@/object-record/record-field/ui/types/FieldMetadata'; -import { RatingInput } from '@/ui/field/input/components/RatingInput'; - import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue'; import { useObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useObjectFilterDropdownFilterValue'; +import { RatingInput } from '@/ui/field/input/components/RatingInput'; import styled from '@emotion/styled'; +import { RATING_VALUES } from 'twenty-shared/constants'; +import { type FieldRatingValue } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; const StyledRatingInputContainer = styled.div` diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordSelect.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordSelect.tsx index 1c300af128..550795c895 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordSelect.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordSelect.tsx @@ -14,9 +14,11 @@ import { type SelectableItem } from '@/object-record/select/types/SelectableItem import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { type RelationFilterValue } from '@/views/view-filter-value/types/RelationFilterValue'; -import { arrayOfUuidOrVariableSchema } from '@/views/view-filter-value/validation-schemas/arrayOfUuidsOrVariablesSchema'; -import { jsonRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema'; -import { isDefined } from 'twenty-shared/utils'; +import { + arrayOfUuidOrVariableSchema, + isDefined, + jsonRelationFilterValueSchema, +} from 'twenty-shared/utils'; import { IconUserCircle } from 'twenty-ui/display'; export const EMPTY_FILTER_VALUE: string = JSON.stringify({ diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/__tests__/getOperandsForFilterType.test.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/__tests__/getOperandsForFilterType.test.ts index 22472e01a5..21c705c314 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/__tests__/getOperandsForFilterType.test.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/__tests__/getOperandsForFilterType.test.ts @@ -1,8 +1,8 @@ -import { type FilterableFieldType } from '@/object-record/record-filter/types/FilterableFieldType'; import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand'; import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands'; import { type CompositeFieldSubFieldName } from '@/settings/data-model/types/CompositeFieldSubFieldName'; import { type FieldType } from '@/settings/data-model/types/FieldType'; +import { type FilterableFieldType } from 'twenty-shared/types'; describe('getOperandsForFilterType', () => { const emptyOperands = [ diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/getInitialFilterValue.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/getInitialFilterValue.ts index 046a6aae78..6b86d72acb 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/getInitialFilterValue.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/getInitialFilterValue.ts @@ -1,7 +1,7 @@ -import { type FilterableAndTSVectorFieldType } from '@/object-record/record-filter/types/FilterableFieldType'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand'; import { getDateFilterDisplayValue } from '@/object-record/record-filter/utils/getDateFilterDisplayValue'; +import { type FilterableAndTSVectorFieldType } from 'twenty-shared/types'; export const getInitialFilterValue = ( newType: FilterableAndTSVectorFieldType, diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/getSubMenuOptions.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/getSubMenuOptions.ts index 5b880be0eb..ea268d59b9 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/getSubMenuOptions.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/getSubMenuOptions.ts @@ -1,4 +1,4 @@ -import { type FilterableFieldType } from '@/object-record/record-filter/types/FilterableFieldType'; +import { type FilterableFieldType } from 'twenty-shared/types'; export const getSubMenuOptions = (subMenu: FilterableFieldType | null) => { switch (subMenu) { diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/isCompositeFilterableFieldType.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/isCompositeFilterableFieldType.ts index 06aa52721c..9067820b22 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/isCompositeFilterableFieldType.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/isCompositeFilterableFieldType.ts @@ -1,7 +1,7 @@ import { type CompositeFilterableFieldType } from '@/object-record/record-filter/types/CompositeFilterableFieldType'; -import { FILTERABLE_FIELD_TYPES } from '@/object-record/record-filter/types/FilterableFieldType'; import { COMPOSITE_FIELD_TYPES } from '@/settings/data-model/types/CompositeFieldType'; import { type FieldType } from '@/settings/data-model/types/FieldType'; +import { FILTERABLE_FIELD_TYPES } from 'twenty-shared/types'; export const isCompositeFilterableFieldType = ( type: FieldType, diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/isExpectedSubFieldName.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/isExpectedSubFieldName.ts deleted file mode 100644 index 8074ec708a..0000000000 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/isExpectedSubFieldName.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS } from '@/settings/data-model/constants/SettingsCompositeFieldTypeConfigs'; - -export const isExpectedSubFieldName = < - GivenFieldType extends keyof typeof SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS, - CompositeFieldTypeSettings extends - typeof SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS, - PossibleSubFieldsForGivenFieldType extends - CompositeFieldTypeSettings[GivenFieldType]['subFields'][number]['subFieldName'], ->( - fieldMetadataType: GivenFieldType, - subFieldName: PossibleSubFieldsForGivenFieldType, - subFieldNameToCheck: string | null | undefined, -): subFieldNameToCheck is PossibleSubFieldsForGivenFieldType => { - return ( - SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS[fieldMetadataType].subFields - .map((subField) => subField.subFieldName) - .includes(subFieldName) && subFieldName === subFieldNameToCheck - ); -}; diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/getAggregateOperationLabel.ts b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/getAggregateOperationLabel.ts index 2c70f380fb..e7e96809e3 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/getAggregateOperationLabel.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/getAggregateOperationLabel.ts @@ -1,8 +1,8 @@ -import { CustomError } from '@/error-handler/CustomError'; import { AggregateOperations } from '@/object-record/record-table/constants/AggregateOperations'; import { DateAggregateOperations } from '@/object-record/record-table/constants/DateAggregateOperations'; import { type ExtendedAggregateOperations } from '@/object-record/record-table/types/ExtendedAggregateOperations'; import { t } from '@lingui/core/macro'; +import { CustomError } from 'twenty-shared/utils'; export const getAggregateOperationLabel = ( operation: ExtendedAggregateOperations, diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/getAggregateOperationShortLabel.ts b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/getAggregateOperationShortLabel.ts index 98bc33957a..96776fefce 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/getAggregateOperationShortLabel.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/getAggregateOperationShortLabel.ts @@ -1,8 +1,8 @@ -import { CustomError } from '@/error-handler/CustomError'; import { AggregateOperations } from '@/object-record/record-table/constants/AggregateOperations'; import { DateAggregateOperations } from '@/object-record/record-table/constants/DateAggregateOperations'; import { type ExtendedAggregateOperations } from '@/object-record/record-table/types/ExtendedAggregateOperations'; import { msg } from '@lingui/core/macro'; +import { CustomError } from 'twenty-shared/utils'; export const getAggregateOperationShortLabel = ( operation: ExtendedAggregateOperations, diff --git a/packages/twenty-front/src/modules/object-record/record-calendar/month/hooks/useRecordCalendarQueryDateRangeFilter.tsx b/packages/twenty-front/src/modules/object-record/record-calendar/month/hooks/useRecordCalendarQueryDateRangeFilter.tsx index a365fd78cb..6e9e063163 100644 --- a/packages/twenty-front/src/modules/object-record/record-calendar/month/hooks/useRecordCalendarQueryDateRangeFilter.tsx +++ b/packages/twenty-front/src/modules/object-record/record-calendar/month/hooks/useRecordCalendarQueryDateRangeFilter.tsx @@ -2,9 +2,11 @@ import { useRecordCalendarContextOrThrow } from '@/object-record/record-calendar import { useRecordCalendarMonthDaysRange } from '@/object-record/record-calendar/month/hooks/useRecordCalendarMonthDaysRange'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand'; -import { computeRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeRecordGqlOperationFilter'; import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly'; -import { isDefined } from 'twenty-shared/utils'; +import { + computeRecordGqlOperationFilter, + isDefined, +} from 'twenty-shared/utils'; const DATE_RANGE_FILTER_AFTER_ID = 'DATE_RANGE_FILTER_AFTER_ID'; const DATE_RANGE_FILTER_BEFORE_ID = 'DATE_RANGE_FILTER_BEFORE_ID'; diff --git a/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationSection.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationSection.tsx index 7f9811a33f..7d9e7e1681 100644 --- a/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationSection.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationSection.tsx @@ -3,7 +3,6 @@ import { useRecoilValue } from 'recoil'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; -import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; import { useAggregateRecords } from '@/object-record/hooks/useAggregateRecords'; import { RecordDetailSectionContainer } from '@/object-record/record-field-list/record-detail-section/components/RecordDetailSectionContainer'; import { RecordDetailRelationRecordsList } from '@/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationRecordsList'; @@ -24,7 +23,11 @@ import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { coreIndexViewIdFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/coreIndexViewIdFromObjectMetadataItemFamilySelector'; import { useLingui } from '@lingui/react/macro'; -import { AppPath, ViewFilterOperand } from 'twenty-shared/types'; +import { + AppPath, + ViewFilterOperand, + type RecordGqlOperationFilter, +} from 'twenty-shared/types'; import { getAppPath } from 'twenty-shared/utils'; import { RelationType } from '~/generated-metadata/graphql'; diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/hooks/useRatingField.ts b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/hooks/useRatingField.ts index 51b1e56d80..dfe6560915 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/hooks/useRatingField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/hooks/useRatingField.ts @@ -4,8 +4,8 @@ import { useRecoilState } from 'recoil'; import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector'; import { FieldMetadataType } from '~/generated-metadata/graphql'; +import { type FieldRatingValue } from 'twenty-shared/types'; import { FieldContext } from '../../contexts/FieldContext'; -import { type FieldRatingValue } from '../../types/FieldMetadata'; import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; import { isFieldRating } from '../../types/guards/isFieldRating'; diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/hooks/useRatingFieldDisplay.ts b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/hooks/useRatingFieldDisplay.ts index 1e40956347..c1dd7e25ae 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/hooks/useRatingFieldDisplay.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/hooks/useRatingFieldDisplay.ts @@ -1,8 +1,8 @@ import { useContext } from 'react'; -import { type FieldRatingValue } from '@/object-record/record-field/ui/types/FieldMetadata'; import { useRecordFieldValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext'; +import { type FieldRatingValue } from 'twenty-shared/types'; import { FieldContext } from '../../contexts/FieldContext'; export const useRatingFieldDisplay = () => { diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/MultiItemFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/MultiItemFieldInput.tsx index 9f908128a9..cd0b98e03f 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/MultiItemFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/MultiItemFieldInput.tsx @@ -1,7 +1,6 @@ import React, { useRef, useState } from 'react'; import { Key } from 'ts-key-enum'; -import { CustomError } from '@/error-handler/CustomError'; import { MultiItemBaseInput, type MultiItemBaseInputProps, @@ -14,6 +13,7 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement'; import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside'; import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow'; +import { CustomError } from 'twenty-shared/utils'; import { IconCheck, IconPlus } from 'twenty-ui/display'; import { LightIconButton } from 'twenty-ui/input'; import { MenuItem } from 'twenty-ui/navigation'; diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/RatingFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/RatingFieldInput.tsx index 3c9714bb31..2e2cf50efd 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/RatingFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/RatingFieldInput.tsx @@ -1,9 +1,9 @@ -import { type FieldRatingValue } from '@/object-record/record-field/ui/types/FieldMetadata'; import { RatingInput } from '@/ui/field/input/components/RatingInput'; import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext'; import { FieldInputEventContext } from '@/object-record/record-field/ui/contexts/FieldInputEventContext'; import { useContext } from 'react'; +import { type FieldRatingValue } from 'twenty-shared/types'; import { useRatingField } from '../../hooks/useRatingField'; export const RatingFieldInput = () => { diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/__stories__/RatingFieldInput.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/__stories__/RatingFieldInput.stories.tsx index b576edb00d..7c4600da3a 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/__stories__/RatingFieldInput.stories.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/__stories__/RatingFieldInput.stories.tsx @@ -10,8 +10,7 @@ import { RecordFieldComponentInstanceContext } from '@/object-record/record-fiel import { RECORD_TABLE_CELL_INPUT_ID_PREFIX } from '@/object-record/record-table/constants/RecordTableCellInputIdPrefix'; import { getRecordFieldInputInstanceId } from '@/object-record/utils/getRecordFieldInputId'; import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType'; -import { FieldMetadataType } from 'twenty-shared/types'; -import { type FieldRatingValue } from '../../../../types/FieldMetadata'; +import { FieldMetadataType, type FieldRatingValue } from 'twenty-shared/types'; import { useRatingField } from '../../../hooks/useRatingField'; import { RatingFieldInput } from '../RatingFieldInput'; diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/types/FieldInputDraftValue.ts b/packages/twenty-front/src/modules/object-record/record-field/ui/types/FieldInputDraftValue.ts index 899a5a546d..ea986e6432 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/types/FieldInputDraftValue.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/types/FieldInputDraftValue.ts @@ -12,7 +12,6 @@ import { type FieldMultiSelectValue, type FieldNumberValue, type FieldPhonesValue, - type FieldRatingValue, type FieldRelationFromManyValue, type FieldRelationToOneValue, type FieldSelectValue, @@ -20,6 +19,7 @@ import { type FieldUUidValue, type PhoneRecord, } from '@/object-record/record-field/ui/types/FieldMetadata'; +import { type FieldRatingValue } from 'twenty-shared/types'; export type FieldTextDraftValue = string; export type FieldNumberDraftValue = number; diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/types/FieldMetadata.ts b/packages/twenty-front/src/modules/object-record/record-field/ui/types/FieldMetadata.ts index 29347525dc..9103fde6c2 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/types/FieldMetadata.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/types/FieldMetadata.ts @@ -1,5 +1,4 @@ import { type FieldMetadataItemRelation } from '@/object-metadata/types/FieldMetadataItemRelation'; -import { type RATING_VALUES } from '@/object-record/record-field/ui/meta-types/constants/RatingValues'; import { type ZodHelperLiteral } from '@/object-record/record-field/ui/types/ZodHelperLiteral'; import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; import { @@ -251,7 +250,6 @@ export type FieldAddressValue = { addressLat: number | null; addressLng: number | null; }; -export type FieldRatingValue = (typeof RATING_VALUES)[number] | null; export type FieldSelectValue = string | null; export type FieldMultiSelectValue = string[] | null; diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/types/guards/isFieldRatingValue.ts b/packages/twenty-front/src/modules/object-record/record-field/ui/types/guards/isFieldRatingValue.ts index c6f15fec02..8c12a1bdab 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/types/guards/isFieldRatingValue.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/types/guards/isFieldRatingValue.ts @@ -1,6 +1,5 @@ -import { RATING_VALUES } from '@/object-record/record-field/ui/meta-types/constants/RatingValues'; - -import { type FieldRatingValue } from '../FieldMetadata'; +import { RATING_VALUES } from 'twenty-shared/constants'; +import { type FieldRatingValue } from 'twenty-shared/types'; export const isFieldRatingValue = ( fieldValue: unknown, diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/utils/computeDraftValueFromString.ts b/packages/twenty-front/src/modules/object-record/record-field/ui/utils/computeDraftValueFromString.ts index 8aa3708aca..774b0d2cec 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/utils/computeDraftValueFromString.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/utils/computeDraftValueFromString.ts @@ -1,4 +1,3 @@ -import { CustomError } from '@/error-handler/CustomError'; import { CurrencyCode } from '@/object-record/record-field/ui/types/CurrencyCode'; import { type FieldDefinition } from '@/object-record/record-field/ui/types/FieldDefinition'; import { type FieldInputDraftValue } from '@/object-record/record-field/ui/types/FieldInputDraftValue'; @@ -14,6 +13,7 @@ import { isFieldPhones } from '@/object-record/record-field/ui/types/guards/isFi import { isFieldRelation } from '@/object-record/record-field/ui/types/guards/isFieldRelation'; import { isFieldText } from '@/object-record/record-field/ui/types/guards/isFieldText'; import { isFieldUuid } from '@/object-record/record-field/ui/types/guards/isFieldUuid'; +import { CustomError } from 'twenty-shared/utils'; type computeDraftValueFromStringParams = { fieldDefinition: Pick, 'type'>; diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/utils/computeEmptyDraftValue.ts b/packages/twenty-front/src/modules/object-record/record-field/ui/utils/computeEmptyDraftValue.ts index cd31119576..398fb31bf1 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/utils/computeEmptyDraftValue.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/utils/computeEmptyDraftValue.ts @@ -1,4 +1,3 @@ -import { CustomError } from '@/error-handler/CustomError'; import { CurrencyCode } from '@/object-record/record-field/ui/types/CurrencyCode'; import { type FieldDefinition } from '@/object-record/record-field/ui/types/FieldDefinition'; import { type FieldInputDraftValue } from '@/object-record/record-field/ui/types/FieldInputDraftValue'; @@ -13,6 +12,7 @@ import { isFieldRawJson } from '@/object-record/record-field/ui/types/guards/isF import { isFieldRelation } from '@/object-record/record-field/ui/types/guards/isFieldRelation'; import { isFieldText } from '@/object-record/record-field/ui/types/guards/isFieldText'; import { isFieldUuid } from '@/object-record/record-field/ui/types/guards/isFieldUuid'; +import { CustomError } from 'twenty-shared/utils'; type computeEmptyDraftValueParams = { fieldDefinition: Pick, 'type'>; diff --git a/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/__tests__/useRemoveRecordFilterGroup.test.tsx b/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/__tests__/useRemoveRecordFilterGroup.test.tsx index 1e400b09e7..18f1d71ca0 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/__tests__/useRemoveRecordFilterGroup.test.tsx +++ b/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/__tests__/useRemoveRecordFilterGroup.test.tsx @@ -2,9 +2,9 @@ import { renderHook } from '@testing-library/react'; import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState'; import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; -import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { act } from 'react'; +import { RecordFilterGroupLogicalOperator } from 'twenty-shared/types'; import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper'; import { useRemoveRecordFilterGroup } from '../useRemoveRecordFilterGroup'; import { useUpsertRecordFilterGroup } from '../useUpsertRecordFilterGroup'; diff --git a/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/__tests__/useUpsertRecordFilterGroup.test.tsx b/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/__tests__/useUpsertRecordFilterGroup.test.tsx index 28c62c7146..5758fe0a37 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/__tests__/useUpsertRecordFilterGroup.test.tsx +++ b/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/__tests__/useUpsertRecordFilterGroup.test.tsx @@ -4,8 +4,8 @@ import { act } from 'react'; import { useUpsertRecordFilterGroup } from '@/object-record/record-filter-group/hooks/useUpsertRecordFilterGroup'; import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState'; import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; -import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; +import { RecordFilterGroupLogicalOperator } from 'twenty-shared/types'; import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper'; const Wrapper = getJestMetadataAndApolloMocksWrapper({ diff --git a/packages/twenty-front/src/modules/object-record/record-filter-group/types/RecordFilterGroup.ts b/packages/twenty-front/src/modules/object-record/record-filter-group/types/RecordFilterGroup.ts index 58a21895cf..ab41b97ea1 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter-group/types/RecordFilterGroup.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter-group/types/RecordFilterGroup.ts @@ -1,4 +1,4 @@ -import { type RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; +import { type RecordFilterGroupLogicalOperator } from 'twenty-shared/types'; export type RecordFilterGroup = { id: string; diff --git a/packages/twenty-front/src/modules/object-record/record-filter/hooks/useCreateEmptyRecordFilterFromFieldMetadataItem.ts b/packages/twenty-front/src/modules/object-record/record-filter/hooks/useCreateEmptyRecordFilterFromFieldMetadataItem.ts index 45bec1f193..20cb16ae05 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/hooks/useCreateEmptyRecordFilterFromFieldMetadataItem.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/hooks/useCreateEmptyRecordFilterFromFieldMetadataItem.ts @@ -1,9 +1,9 @@ import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { getInitialFilterValue } from '@/object-record/object-filter-dropdown/utils/getInitialFilterValue'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; import { getDefaultSubFieldNameForCompositeFilterableFieldType } from '@/object-record/record-filter/utils/getDefaultSubFieldNameForCompositeFilterableFieldType'; import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands'; +import { getFilterTypeFromFieldType } from 'twenty-shared/utils'; import { v4 } from 'uuid'; export const useCreateEmptyRecordFilterFromFieldMetadataItem = () => { diff --git a/packages/twenty-front/src/modules/object-record/record-filter/hooks/useCreateRecordFilterFromObjectFilterDropdownCurrentStates.ts b/packages/twenty-front/src/modules/object-record/record-filter/hooks/useCreateRecordFilterFromObjectFilterDropdownCurrentStates.ts index 419dedab2c..a7fb151a73 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/hooks/useCreateRecordFilterFromObjectFilterDropdownCurrentStates.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/hooks/useCreateRecordFilterFromObjectFilterDropdownCurrentStates.ts @@ -1,11 +1,10 @@ -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector'; import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState'; import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState'; import { useRecoilCallback } from 'recoil'; -import { isDefined } from 'twenty-shared/utils'; +import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils'; import { v4 } from 'uuid'; export const useCreateRecordFilterFromObjectFilterDropdownCurrentStates = diff --git a/packages/twenty-front/src/modules/object-record/record-filter/hooks/useFilterValueDependencies.ts b/packages/twenty-front/src/modules/object-record/record-filter/hooks/useFilterValueDependencies.ts index 7093ccde30..dc8d5fe7d1 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/hooks/useFilterValueDependencies.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/hooks/useFilterValueDependencies.ts @@ -1,6 +1,6 @@ import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; -import { type RecordFilterValueDependencies } from '@/object-record/record-filter/types/RecordFilterValueDependencies'; import { useRecoilValue } from 'recoil'; +import { type RecordFilterValueDependencies } from 'twenty-shared/types'; export const useFilterValueDependencies = (): { filterValueDependencies: RecordFilterValueDependencies; diff --git a/packages/twenty-front/src/modules/object-record/record-filter/types/CompositeFilterableFieldType.ts b/packages/twenty-front/src/modules/object-record/record-filter/types/CompositeFilterableFieldType.ts index 77a26bcd94..688644e041 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/types/CompositeFilterableFieldType.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/types/CompositeFilterableFieldType.ts @@ -1,5 +1,5 @@ -import { type FilterableFieldType } from '@/object-record/record-filter/types/FilterableFieldType'; import { type CompositeFieldType } from '@/settings/data-model/types/CompositeFieldType'; +import { type FilterableFieldType } from 'twenty-shared/types'; export type CompositeFilterableFieldType = FilterableFieldType & CompositeFieldType; diff --git a/packages/twenty-front/src/modules/object-record/record-filter/types/RecordFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/types/RecordFilter.ts index 675b91e409..c70a76cf0c 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/types/RecordFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/types/RecordFilter.ts @@ -1,7 +1,9 @@ -import { type FilterableAndTSVectorFieldType } from '@/object-record/record-filter/types/FilterableFieldType'; import { type FILTER_OPERANDS_MAP } from '@/object-record/record-filter/utils/getRecordFilterOperands'; import { type CompositeFieldSubFieldName } from '@/settings/data-model/types/CompositeFieldSubFieldName'; -import { type ViewFilterOperand } from 'twenty-shared/types'; +import { + type FilterableAndTSVectorFieldType, + type ViewFilterOperand, +} from 'twenty-shared/types'; export type RecordFilter = { id: string; diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/combineFilters.test.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/combineFilters.test.ts index 5564913ac2..e4f96717fe 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/combineFilters.test.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/combineFilters.test.ts @@ -1,5 +1,5 @@ -import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; -import { combineFilters } from '../combineFilters'; +import { type RecordGqlOperationFilter } from 'twenty-shared/types'; +import { combineFilters } from 'twenty-shared/utils'; describe('combineFilters', () => { it('should return empty object when all filters are empty', () => { diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/computeViewRecordGqlOperationFilter.test.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/computeViewRecordGqlOperationFilter.test.ts index edb540cdc8..e172f5c6e2 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/computeViewRecordGqlOperationFilter.test.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/computeViewRecordGqlOperationFilter.test.ts @@ -1,10 +1,14 @@ import { type FieldCurrencyValue } from '@/object-record/record-field/ui/types/FieldMetadata'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand'; -import { type RecordFilterValueDependencies } from '@/object-record/record-filter/types/RecordFilterValueDependencies'; -import { computeRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeRecordGqlOperationFilter'; -import { ViewFilterOperand } from 'twenty-shared/types'; -import { isDefined } from 'twenty-shared/utils'; +import { + ViewFilterOperand, + type RecordFilterValueDependencies, +} from 'twenty-shared/types'; +import { + computeRecordGqlOperationFilter, + isDefined, +} from 'twenty-shared/utils'; import { FieldMetadataType } from '~/generated-metadata/graphql'; import { getCompaniesMock } from '~/testing/mock-data/companies'; diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/getAllRecordFilterDescendantsOfRecordFilterGroup.test.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/getAllRecordFilterDescendantsOfRecordFilterGroup.test.ts index ef3a58d5c7..15c6eaa759 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/getAllRecordFilterDescendantsOfRecordFilterGroup.test.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/getAllRecordFilterDescendantsOfRecordFilterGroup.test.ts @@ -1,7 +1,7 @@ import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; -import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand'; +import { RecordFilterGroupLogicalOperator } from 'twenty-shared/types'; import { sortByProperty } from '~/utils/array/sortByProperty'; import { getAllRecordFilterDescendantsOfRecordFilterGroup } from '../getAllRecordFilterDescendantsOfRecordFilterGroup'; diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/isMatchingCurrencyFilter.test.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/isMatchingCurrencyFilter.test.ts index 1448ded0f4..84533ddda6 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/isMatchingCurrencyFilter.test.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/isMatchingCurrencyFilter.test.ts @@ -1,5 +1,5 @@ -import { type CurrencyFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; import { isMatchingCurrencyFilter } from '@/object-record/record-filter/utils/isMatchingCurrencyFilter'; +import { type CurrencyFilter } from 'twenty-shared/types'; describe('isMatchingCurrencyFilter', () => { describe('amountMicros', () => { diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/isRecordMatchingFilter.test.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/isRecordMatchingFilter.test.ts index 4712288a59..75ba860370 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/isRecordMatchingFilter.test.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/isRecordMatchingFilter.test.ts @@ -1,4 +1,4 @@ -import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; +import { type RecordGqlOperationFilter } from 'twenty-shared/types'; import { getCompaniesMock } from '~/testing/mock-data/companies'; import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems'; diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/checkIfShouldComputeEmptinessFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/checkIfShouldComputeEmptinessFilter.ts deleted file mode 100644 index e71aca60be..0000000000 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/checkIfShouldComputeEmptinessFilter.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; -import { type FilterableAndTSVectorFieldType } from '@/object-record/record-filter/types/FilterableFieldType'; -import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; -import { isEmptinessOperand } from '@/object-record/record-filter/utils/isEmptinessOperand'; - -export const checkIfShouldComputeEmptinessFilter = ({ - recordFilter, - correspondingFieldMetadataItem, -}: { - recordFilter: RecordFilter; - correspondingFieldMetadataItem: Pick; -}) => { - const isAnEmptinessOperand = isEmptinessOperand(recordFilter.operand); - - const filterTypesThatHaveNoEmptinessOperand: FilterableAndTSVectorFieldType[] = - ['BOOLEAN', 'TS_VECTOR']; - - const filterType = getFilterTypeFromFieldType( - correspondingFieldMetadataItem.type, - ); - - const filterHasEmptinessOperands = - !filterTypesThatHaveNoEmptinessOperand.includes(filterType); - - const shouldComputeEmptinessFilter = - filterHasEmptinessOperands && isAnEmptinessOperand; - - return shouldComputeEmptinessFilter; -}; diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/getDateFilterDisplayValue.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/getDateFilterDisplayValue.ts index 7fd9aaa46d..1ac1f3f0a8 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/getDateFilterDisplayValue.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/getDateFilterDisplayValue.ts @@ -1,4 +1,4 @@ -import { type FilterableAndTSVectorFieldType } from '@/object-record/record-filter/types/FilterableFieldType'; +import { type FilterableAndTSVectorFieldType } from 'twenty-shared/types'; export const getDateFilterDisplayValue = ( value: Date, diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/getDefaultSubFieldNameForCompositeFilterableFieldType.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/getDefaultSubFieldNameForCompositeFilterableFieldType.ts index 68097bbee3..443dcae776 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/getDefaultSubFieldNameForCompositeFilterableFieldType.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/getDefaultSubFieldNameForCompositeFilterableFieldType.ts @@ -7,7 +7,7 @@ import { assertUnreachable } from 'twenty-shared/utils'; export const getDefaultSubFieldNameForCompositeFilterableFieldType = ( fieldType: FieldType, ): CompositeFieldSubFieldName | undefined => { - if (!isCompositeFilterableFieldType(fieldType as any)) { + if (!isCompositeFilterableFieldType(fieldType)) { return undefined; } diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/getRecordFilterOperands.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/getRecordFilterOperands.ts index 08f5d5bbb6..d39e9e4ad2 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/getRecordFilterOperands.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/getRecordFilterOperands.ts @@ -1,15 +1,12 @@ -import { isExpectedSubFieldName } from '@/object-record/object-filter-dropdown/utils/isExpectedSubFieldName'; import { isFilterOnActorSourceSubField } from '@/object-record/object-filter-dropdown/utils/isFilterOnActorSourceSubField'; -import { - type FilterableAndTSVectorFieldType, - type FilterableFieldType, -} from '@/object-record/record-filter/types/FilterableFieldType'; import { type CompositeFieldSubFieldName } from '@/settings/data-model/types/CompositeFieldSubFieldName'; import { FieldMetadataType, ViewFilterOperand as RecordFilterOperand, + type FilterableAndTSVectorFieldType, + type FilterableFieldType, } from 'twenty-shared/types'; -import { assertUnreachable } from 'twenty-shared/utils'; +import { assertUnreachable, isExpectedSubFieldName } from 'twenty-shared/utils'; export type GetRecordFilterOperandsParams = { filterType: FilterableAndTSVectorFieldType; @@ -168,7 +165,7 @@ export const getRecordFilterOperands = ({ FieldMetadataType.CURRENCY, 'currencyCode', subFieldName, - ) + ) === true ) { return COMPOSITE_FIELD_FILTER_OPERANDS_MAP.CURRENCY.currencyCode; } else { diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingArrayFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingArrayFilter.ts index e4fa12676c..05126e7371 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingArrayFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingArrayFilter.ts @@ -1,4 +1,4 @@ -import { type ArrayFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; +import { type ArrayFilter } from 'twenty-shared/types'; export const isMatchingArrayFilter = ({ arrayFilter, diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingBooleanFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingBooleanFilter.ts index 0acde71e2a..98cf6b9eb8 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingBooleanFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingBooleanFilter.ts @@ -1,4 +1,4 @@ -import { type BooleanFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; +import { type BooleanFilter } from 'twenty-shared/types'; export const isMatchingBooleanFilter = ({ booleanFilter, diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingCurrencyFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingCurrencyFilter.ts index 44aaa409ee..2ac8b32b1d 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingCurrencyFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingCurrencyFilter.ts @@ -1,5 +1,5 @@ -import { type CurrencyFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; import { isNonEmptyString } from '@sniptt/guards'; +import { type CurrencyFilter } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; const isMatchingCurrencyCodeFilter = ( diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingDateFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingDateFilter.ts index 55e7ccd0eb..0693a66fbe 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingDateFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingDateFilter.ts @@ -1,6 +1,5 @@ -import { parseISO, isEqual, isAfter, isBefore } from 'date-fns'; - -import { type DateFilter } from '@/object-record//graphql/types/RecordGqlOperationFilter'; +import { isAfter, isBefore, isEqual, parseISO } from 'date-fns'; +import { type DateFilter } from 'twenty-shared/types'; export const isMatchingDateFilter = ({ dateFilter, diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingFloatFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingFloatFilter.ts index 58c8083029..c3cca636f6 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingFloatFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingFloatFilter.ts @@ -1,4 +1,4 @@ -import { type FloatFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; +import { type FloatFilter } from 'twenty-shared/types'; export const isMatchingFloatFilter = ({ floatFilter, diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingMultiSelectFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingMultiSelectFilter.ts index fe3f2f24f1..ce8b3760ad 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingMultiSelectFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingMultiSelectFilter.ts @@ -1,4 +1,4 @@ -import { type MultiSelectFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; +import { type MultiSelectFilter } from 'twenty-shared/types'; export const isMatchingMultiSelectFilter = ({ multiSelectFilter, diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingRatingFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingRatingFilter.ts index 759ef8c8b1..9bf64140b2 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingRatingFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingRatingFilter.ts @@ -1,4 +1,4 @@ -import { type RatingFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; +import { type RatingFilter } from 'twenty-shared/types'; export const isMatchingRatingFilter = ({ ratingFilter, diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingRawJsonFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingRawJsonFilter.ts index 635ea0346a..ea04317bae 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingRawJsonFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingRawJsonFilter.ts @@ -1,4 +1,4 @@ -import { type RawJsonFilter } from '../../graphql/types/RecordGqlOperationFilter'; +import { type RawJsonFilter } from 'twenty-shared/types'; export const isMatchingRawJsonFilter = ({ rawJsonFilter, diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingRichTextV2Filter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingRichTextV2Filter.ts index ef21c926fa..89f3bb9c12 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingRichTextV2Filter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingRichTextV2Filter.ts @@ -1,5 +1,5 @@ -import { type RichTextV2Filter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; import escapeRegExp from 'lodash.escaperegexp'; +import { type RichTextV2Filter } from 'twenty-shared/types'; export const isMatchingRichTextV2Filter = ({ richTextV2Filter, diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingSelectFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingSelectFilter.ts index 31f4b37ed4..ac52eb6ab6 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingSelectFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingSelectFilter.ts @@ -1,4 +1,4 @@ -import { type SelectFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; +import { type SelectFilter } from 'twenty-shared/types'; export const isMatchingSelectFilter = ({ selectFilter, diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingStringFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingStringFilter.ts index 55a406c591..431732765e 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingStringFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingStringFilter.ts @@ -1,5 +1,5 @@ -import { type StringFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; import escapeRegExp from 'lodash.escaperegexp'; +import { type StringFilter } from 'twenty-shared/types'; export const isMatchingStringFilter = ({ stringFilter, diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingTSVectorFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingTSVectorFilter.ts index 0c987e61b9..89c678ccd1 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingTSVectorFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingTSVectorFilter.ts @@ -1,4 +1,4 @@ -import { type TSVectorFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; +import { type TSVectorFilter } from 'twenty-shared/types'; export const isMatchingTSVectorFilter = ({ tsVectorFilter, diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingUUIDFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingUUIDFilter.ts index 87fd891df6..af34e0bef8 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingUUIDFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingUUIDFilter.ts @@ -1,7 +1,4 @@ -import { - type UUIDFilter, - type UUIDFilterValue, -} from '@/object-record/graphql/types/RecordGqlOperationFilter'; +import { type UUIDFilter, type UUIDFilterValue } from 'twenty-shared/types'; export const isMatchingUUIDFilter = ({ uuidFilter, diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isRecordMatchingFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/isRecordMatchingFilter.ts index 2f0280db84..3993aa2d35 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isRecordMatchingFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/isRecordMatchingFilter.ts @@ -1,6 +1,19 @@ import { isObject } from '@sniptt/guards'; import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; +import { isMatchingArrayFilter } from '@/object-record/record-filter/utils/isMatchingArrayFilter'; +import { isMatchingBooleanFilter } from '@/object-record/record-filter/utils/isMatchingBooleanFilter'; +import { isMatchingCurrencyFilter } from '@/object-record/record-filter/utils/isMatchingCurrencyFilter'; +import { isMatchingDateFilter } from '@/object-record/record-filter/utils/isMatchingDateFilter'; +import { isMatchingFloatFilter } from '@/object-record/record-filter/utils/isMatchingFloatFilter'; +import { isMatchingMultiSelectFilter } from '@/object-record/record-filter/utils/isMatchingMultiSelectFilter'; +import { isMatchingRatingFilter } from '@/object-record/record-filter/utils/isMatchingRatingFilter'; +import { isMatchingRawJsonFilter } from '@/object-record/record-filter/utils/isMatchingRawJsonFilter'; +import { isMatchingRichTextV2Filter } from '@/object-record/record-filter/utils/isMatchingRichTextV2Filter'; +import { isMatchingSelectFilter } from '@/object-record/record-filter/utils/isMatchingSelectFilter'; +import { isMatchingStringFilter } from '@/object-record/record-filter/utils/isMatchingStringFilter'; +import { isMatchingTSVectorFilter } from '@/object-record/record-filter/utils/isMatchingTSVectorFilter'; +import { isMatchingUUIDFilter } from '@/object-record/record-filter/utils/isMatchingUUIDFilter'; import { type ActorFilter, type AddressFilter, @@ -26,20 +39,7 @@ import { type StringFilter, type TSVectorFilter, type UUIDFilter, -} from '@/object-record/graphql/types/RecordGqlOperationFilter'; -import { isMatchingArrayFilter } from '@/object-record/record-filter/utils/isMatchingArrayFilter'; -import { isMatchingBooleanFilter } from '@/object-record/record-filter/utils/isMatchingBooleanFilter'; -import { isMatchingCurrencyFilter } from '@/object-record/record-filter/utils/isMatchingCurrencyFilter'; -import { isMatchingDateFilter } from '@/object-record/record-filter/utils/isMatchingDateFilter'; -import { isMatchingFloatFilter } from '@/object-record/record-filter/utils/isMatchingFloatFilter'; -import { isMatchingMultiSelectFilter } from '@/object-record/record-filter/utils/isMatchingMultiSelectFilter'; -import { isMatchingRatingFilter } from '@/object-record/record-filter/utils/isMatchingRatingFilter'; -import { isMatchingRawJsonFilter } from '@/object-record/record-filter/utils/isMatchingRawJsonFilter'; -import { isMatchingRichTextV2Filter } from '@/object-record/record-filter/utils/isMatchingRichTextV2Filter'; -import { isMatchingSelectFilter } from '@/object-record/record-filter/utils/isMatchingSelectFilter'; -import { isMatchingStringFilter } from '@/object-record/record-filter/utils/isMatchingStringFilter'; -import { isMatchingTSVectorFilter } from '@/object-record/record-filter/utils/isMatchingTSVectorFilter'; -import { isMatchingUUIDFilter } from '@/object-record/record-filter/utils/isMatchingUUIDFilter'; +} from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; import { FieldMetadataType } from '~/generated-metadata/graphql'; import { isEmptyObject } from '~/utils/isEmptyObject'; diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/turnAnyFieldFilterIntoRecordGqlFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/turnAnyFieldFilterIntoRecordGqlFilter.ts index e1d221725e..bbefbce0b3 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/turnAnyFieldFilterIntoRecordGqlFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/turnAnyFieldFilterIntoRecordGqlFilter.ts @@ -1,13 +1,15 @@ import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; -import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand'; -import { turnRecordFilterIntoRecordGqlOperationFilter } from '@/object-record/record-filter/utils/compute-record-gql-operation-filter/turnRecordFilterIntoGqlOperationFilter'; import { createAnyFieldRecordFilterBaseProperties } from '@/object-record/record-filter/utils/createAnyFieldRecordFilterBaseProperties'; import { filterSelectOptionsOfFieldMetadataItem } from '@/object-record/record-filter/utils/filterSelectOptionsOfFieldMetadataItem'; import { CURRENCIES } from '@/settings/data-model/constants/Currencies'; import { isNonEmptyString } from '@sniptt/guards'; -import { isDefined } from 'twenty-shared/utils'; +import { type RecordGqlOperationFilter } from 'twenty-shared/types'; +import { + isDefined, + turnRecordFilterIntoRecordGqlOperationFilter, +} from 'twenty-shared/utils'; import { z } from 'zod'; import { FieldMetadataType } from '~/generated-metadata/graphql'; import { isNonEmptyArray } from '~/utils/isNonEmptyArray'; diff --git a/packages/twenty-front/src/modules/object-record/record-index/hooks/useFindManyRecordIndexTableParams.ts b/packages/twenty-front/src/modules/object-record/record-index/hooks/useFindManyRecordIndexTableParams.ts index e4b454ef8f..956e71b502 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/hooks/useFindManyRecordIndexTableParams.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/hooks/useFindManyRecordIndexTableParams.ts @@ -4,14 +4,15 @@ import { currentRecordFilterGroupsComponentState } from '@/object-record/record- import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies'; import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState'; import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState'; -import { combineFilters } from '@/object-record/record-filter/utils/combineFilters'; -import { computeRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeRecordGqlOperationFilter'; import { turnAnyFieldFilterIntoRecordGqlFilter } from '@/object-record/record-filter/utils/turnAnyFieldFilterIntoRecordGqlFilter'; import { useCurrentRecordGroupDefinition } from '@/object-record/record-group/hooks/useCurrentRecordGroupDefinition'; import { useRecordGroupFilter } from '@/object-record/record-group/hooks/useRecordGroupFilter'; import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; - +import { + combineFilters, + computeRecordGqlOperationFilter, +} from 'twenty-shared/utils'; export const useFindManyRecordIndexTableParams = ( objectNameSingular: string, ) => { @@ -41,9 +42,9 @@ export const useFindManyRecordIndexTableParams = ( const currentFilters = computeRecordGqlOperationFilter({ fields: objectMetadataItem?.fields ?? [], - filterValueDependencies, recordFilterGroups: currentRecordFilterGroups, recordFilters: currentRecordFilters, + filterValueDependencies, }); const anyFieldFilterValue = useRecoilComponentValue( diff --git a/packages/twenty-front/src/modules/object-record/record-index/hooks/useHandleToggleTrashColumnFilter.ts b/packages/twenty-front/src/modules/object-record/record-index/hooks/useHandleToggleTrashColumnFilter.ts index 5b015f71ba..ed3a4852a4 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/hooks/useHandleToggleTrashColumnFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/hooks/useHandleToggleTrashColumnFilter.ts @@ -3,15 +3,14 @@ import { v4 } from 'uuid'; import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; import { isSoftDeleteFilterActiveComponentState } from '@/object-record/record-table/states/isSoftDeleteFilterActiveComponentState'; import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState'; +import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils'; import { useRecoilCallback } from 'recoil'; import { ViewFilterOperand } from 'twenty-shared/types'; -import { isDefined } from 'twenty-shared/utils'; type UseHandleToggleTrashColumnFilterProps = { objectNameSingular: string; diff --git a/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexBoardColumn.ts b/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexBoardColumn.ts index 8e3e4a82a0..dbaead8be5 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexBoardColumn.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexBoardColumn.ts @@ -8,7 +8,6 @@ import { useSetRecordIdsForColumn } from '@/object-record/record-board/hooks/use import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState'; import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies'; import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState'; -import { computeRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeRecordGqlOperationFilter'; import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState'; import { useRecordBoardRecordGqlFields } from '@/object-record/record-index/hooks/useRecordBoardRecordGqlFields'; @@ -16,11 +15,14 @@ import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataIte import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState'; import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState'; -import { combineFilters } from '@/object-record/record-filter/utils/combineFilters'; import { turnAnyFieldFilterIntoRecordGqlFilter } from '@/object-record/record-filter/utils/turnAnyFieldFilterIntoRecordGqlFilter'; import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; -import { isDefined } from 'twenty-shared/utils'; +import { + combineFilters, + computeRecordGqlOperationFilter, + isDefined, +} from 'twenty-shared/utils'; type UseLoadRecordIndexBoardProps = { objectNameSingular: string; diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/useAggregateRecordsForHeader.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/useAggregateRecordsForHeader.ts index ad0b2dc29b..09543c2316 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/useAggregateRecordsForHeader.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/useAggregateRecordsForHeader.ts @@ -6,14 +6,16 @@ import { currentRecordFilterGroupsComponentState } from '@/object-record/record- import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies'; import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState'; import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState'; -import { computeRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeRecordGqlOperationFilter'; import { turnAnyFieldFilterIntoRecordGqlFilter } from '@/object-record/record-filter/utils/turnAnyFieldFilterIntoRecordGqlFilter'; import { recordIndexKanbanAggregateOperationState } from '@/object-record/record-index/states/recordIndexKanbanAggregateOperationState'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { UserContext } from '@/users/contexts/UserContext'; import { useContext } from 'react'; import { useRecoilValue } from 'recoil'; -import { isDefined } from 'twenty-shared/utils'; +import { + computeRecordGqlOperationFilter, + isDefined, +} from 'twenty-shared/utils'; import { dateLocaleState } from '~/localization/states/dateLocaleState'; type UseAggregateRecordsProps = { diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/hooks/useAggregateRecordsForRecordTableColumnFooter.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/hooks/useAggregateRecordsForRecordTableColumnFooter.tsx index 4d8d0c0c25..a2aa0c4104 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/hooks/useAggregateRecordsForRecordTableColumnFooter.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/hooks/useAggregateRecordsForRecordTableColumnFooter.tsx @@ -4,7 +4,6 @@ import { currentRecordFilterGroupsComponentState } from '@/object-record/record- import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies'; import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState'; import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState'; -import { computeRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeRecordGqlOperationFilter'; import { turnAnyFieldFilterIntoRecordGqlFilter } from '@/object-record/record-filter/utils/turnAnyFieldFilterIntoRecordGqlFilter'; import { useRecordGroupFilter } from '@/object-record/record-group/hooks/useRecordGroupFilter'; import { AggregateOperations } from '@/object-record/record-table/constants/AggregateOperations'; @@ -17,7 +16,11 @@ import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/ho import { UserContext } from '@/users/contexts/UserContext'; import { useContext } from 'react'; import { useRecoilValue } from 'recoil'; -import { isDefined, isFieldMetadataDateKind } from 'twenty-shared/utils'; +import { + computeRecordGqlOperationFilter, + isDefined, + isFieldMetadataDateKind, +} from 'twenty-shared/utils'; import { dateLocaleState } from '~/localization/states/dateLocaleState'; export const useAggregateRecordsForRecordTableColumnFooter = ( diff --git a/packages/twenty-front/src/modules/object-record/record-table/utils/buildRecordInputFromFilter.spec.ts b/packages/twenty-front/src/modules/object-record/record-table/utils/buildRecordInputFromFilter.spec.ts index 00cf376b5f..19d8c36c00 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/utils/buildRecordInputFromFilter.spec.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/utils/buildRecordInputFromFilter.spec.ts @@ -1,8 +1,10 @@ import { type FieldMetadataItemOption } from '@/object-metadata/types/FieldMetadataItem'; -import { type FilterableFieldType } from '@/object-record/record-filter/types/FilterableFieldType'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; import { type ColorScheme } from '@/workspace-member/types/WorkspaceMember'; -import { ViewFilterOperand } from 'twenty-shared/types'; +import { + type FilterableFieldType, + ViewFilterOperand, +} from 'twenty-shared/types'; import { RelationType } from '~/generated-metadata/graphql'; import { buildValueFromFilter } from './buildRecordInputFromFilter'; diff --git a/packages/twenty-front/src/modules/object-record/spreadsheet-import/utils/getSpreadSheetFieldValidationDefinitions.ts b/packages/twenty-front/src/modules/object-record/spreadsheet-import/utils/getSpreadSheetFieldValidationDefinitions.ts index a6595126d8..e36d71cb6e 100644 --- a/packages/twenty-front/src/modules/object-record/spreadsheet-import/utils/getSpreadSheetFieldValidationDefinitions.ts +++ b/packages/twenty-front/src/modules/object-record/spreadsheet-import/utils/getSpreadSheetFieldValidationDefinitions.ts @@ -1,10 +1,10 @@ -import { RATING_VALUES } from '@/object-record/record-field/ui/meta-types/constants/RatingValues'; import { isFieldRatingValue } from '@/object-record/record-field/ui/types/guards/isFieldRatingValue'; import { emailSchema } from '@/object-record/record-field/ui/validation-schemas/emailSchema'; import { type SpreadsheetImportFieldValidationDefinition } from '@/spreadsheet-import/types'; import { t } from '@lingui/core/macro'; import { isDate, isString } from '@sniptt/guards'; import { parsePhoneNumberWithError } from 'libphonenumber-js'; +import { RATING_VALUES } from 'twenty-shared/constants'; import { absoluteUrlSchema, getCountryCodesForCallingCode, diff --git a/packages/twenty-front/src/modules/object-record/utils/makeAndFilterVariables.ts b/packages/twenty-front/src/modules/object-record/utils/makeAndFilterVariables.ts index 6f653c5d18..0e93544ccc 100644 --- a/packages/twenty-front/src/modules/object-record/utils/makeAndFilterVariables.ts +++ b/packages/twenty-front/src/modules/object-record/utils/makeAndFilterVariables.ts @@ -1,4 +1,4 @@ -import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; +import { type RecordGqlOperationFilter } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; export const makeAndFilterVariables = ( diff --git a/packages/twenty-front/src/modules/object-record/utils/makeOrFilterVariables.ts b/packages/twenty-front/src/modules/object-record/utils/makeOrFilterVariables.ts index bedf68f754..33a830e7ab 100644 --- a/packages/twenty-front/src/modules/object-record/utils/makeOrFilterVariables.ts +++ b/packages/twenty-front/src/modules/object-record/utils/makeOrFilterVariables.ts @@ -1,4 +1,4 @@ -import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; +import { type RecordGqlOperationFilter } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; export const makeOrFilterVariables = ( diff --git a/packages/twenty-front/src/modules/settings/accounts/hooks/useTriggerApiOAuth.ts b/packages/twenty-front/src/modules/settings/accounts/hooks/useTriggerApiOAuth.ts index bd505adfa0..e3dced2239 100644 --- a/packages/twenty-front/src/modules/settings/accounts/hooks/useTriggerApiOAuth.ts +++ b/packages/twenty-front/src/modules/settings/accounts/hooks/useTriggerApiOAuth.ts @@ -2,7 +2,7 @@ import { useCallback } from 'react'; import { type AppPath, ConnectedAccountProvider } from 'twenty-shared/types'; import { useRedirect } from '@/domain-manager/hooks/useRedirect'; -import { CustomError } from '@/error-handler/CustomError'; +import { CustomError } from 'twenty-shared/utils'; import { REACT_APP_SERVER_BASE_URL } from '~/config'; import { type CalendarChannelVisibility, diff --git a/packages/twenty-front/src/modules/settings/admin-panel/config-variables/components/ConfigVariableDatabaseInput.tsx b/packages/twenty-front/src/modules/settings/admin-panel/config-variables/components/ConfigVariableDatabaseInput.tsx index 0a8af783c9..9b5cac6a59 100644 --- a/packages/twenty-front/src/modules/settings/admin-panel/config-variables/components/ConfigVariableDatabaseInput.tsx +++ b/packages/twenty-front/src/modules/settings/admin-panel/config-variables/components/ConfigVariableDatabaseInput.tsx @@ -1,4 +1,3 @@ -import { CustomError } from '@/error-handler/CustomError'; import { Select } from '@/ui/input/components/Select'; import { SelectControl } from '@/ui/input/components/SelectControl'; import { TextArea } from '@/ui/input/components/TextArea'; @@ -7,6 +6,7 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { type ConfigVariableValue } from 'twenty-shared/types'; +import { CustomError } from 'twenty-shared/utils'; import { MenuItemMultiSelect } from 'twenty-ui/navigation'; import { ConfigVariableType } from '~/generated/graphql'; import { type ConfigVariableOptions } from '../types/ConfigVariableOptions'; diff --git a/packages/twenty-front/src/modules/settings/admin-panel/config-variables/utils/useSourceContent.ts b/packages/twenty-front/src/modules/settings/admin-panel/config-variables/utils/useSourceContent.ts index f64457255c..8a015a5f4a 100644 --- a/packages/twenty-front/src/modules/settings/admin-panel/config-variables/utils/useSourceContent.ts +++ b/packages/twenty-front/src/modules/settings/admin-panel/config-variables/utils/useSourceContent.ts @@ -1,6 +1,6 @@ -import { CustomError } from '@/error-handler/CustomError'; import { useTheme } from '@emotion/react'; import { useLingui } from '@lingui/react/macro'; +import { CustomError } from 'twenty-shared/utils'; import { ConfigSource } from '~/generated/graphql'; diff --git a/packages/twenty-front/src/modules/settings/data-model/constants/SettingsCompositeFieldTypeConfigs.ts b/packages/twenty-front/src/modules/settings/data-model/constants/SettingsCompositeFieldTypeConfigs.ts index 438469fdf3..72d890d373 100644 --- a/packages/twenty-front/src/modules/settings/data-model/constants/SettingsCompositeFieldTypeConfigs.ts +++ b/packages/twenty-front/src/modules/settings/data-model/constants/SettingsCompositeFieldTypeConfigs.ts @@ -12,6 +12,7 @@ import { import { COMPOSITE_FIELD_SUB_FIELD_LABELS } from '@/settings/data-model/constants/CompositeFieldSubFieldLabel'; import { type SettingsFieldTypeConfig } from '@/settings/data-model/constants/SettingsNonCompositeFieldTypeConfigs'; import { type CompositeFieldType } from '@/settings/data-model/types/CompositeFieldType'; +import { COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES } from 'twenty-shared/constants'; import { ConnectedAccountProvider } from 'twenty-shared/types'; import { IllustrationIconCurrency, @@ -51,7 +52,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { Icon: IllustrationIconCurrency, subFields: [ { - subFieldName: 'amountMicros', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.CURRENCY] + .amountMicros, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.CURRENCY] .amountMicros, @@ -60,7 +63,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: false, }, { - subFieldName: 'currencyCode', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.CURRENCY] + .currencyCode, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.CURRENCY] .currencyCode, @@ -90,7 +95,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { Icon: IllustrationIconMail, subFields: [ { - subFieldName: 'primaryEmail', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.EMAILS] + .primaryEmail, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.EMAILS] .primaryEmail, @@ -99,7 +106,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: true, }, { - subFieldName: 'additionalEmails', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.EMAILS] + .additionalEmails, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.EMAILS] .additionalEmails, @@ -133,7 +142,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { Icon: IllustrationIconLink, subFields: [ { - subFieldName: 'primaryLinkUrl', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.LINKS] + .primaryLinkUrl, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.LINKS] .primaryLinkUrl, @@ -142,7 +153,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: true, }, { - subFieldName: 'primaryLinkLabel', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.LINKS] + .primaryLinkLabel, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.LINKS] .primaryLinkLabel, @@ -151,7 +164,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: false, }, { - subFieldName: 'secondaryLinks', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.LINKS] + .secondaryLinks, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.LINKS] .secondaryLinks, @@ -184,7 +199,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { Icon: IllustrationIconPhone, subFields: [ { - subFieldName: 'primaryPhoneCallingCode', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.PHONES] + .primaryPhoneCallingCode, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.PHONES] .primaryPhoneCallingCode, @@ -193,7 +210,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: false, }, { - subFieldName: 'primaryPhoneCountryCode', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.PHONES] + .primaryPhoneCountryCode, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.PHONES] .primaryPhoneCountryCode, @@ -202,7 +221,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: false, }, { - subFieldName: 'primaryPhoneNumber', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.PHONES] + .primaryPhoneNumber, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.PHONES] .primaryPhoneNumber, @@ -211,7 +232,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: true, }, { - subFieldName: 'additionalPhones', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.PHONES] + .additionalPhones, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.PHONES] .additionalPhones, @@ -252,7 +275,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { Icon: IllustrationIconUser, subFields: [ { - subFieldName: 'firstName', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.FULL_NAME] + .firstName, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.FULL_NAME] .firstName, @@ -261,7 +286,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: false, }, { - subFieldName: 'lastName', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.FULL_NAME] + .lastName, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.FULL_NAME] .lastName, @@ -282,7 +309,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { Icon: IllustrationIconMap, subFields: [ { - subFieldName: 'addressStreet1', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.ADDRESS] + .addressStreet1, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS] .addressStreet1, @@ -291,7 +320,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: false, }, { - subFieldName: 'addressStreet2', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.ADDRESS] + .addressStreet2, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS] .addressStreet2, @@ -300,7 +331,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: false, }, { - subFieldName: 'addressCity', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.ADDRESS] + .addressCity, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS] .addressCity, @@ -309,7 +342,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: false, }, { - subFieldName: 'addressState', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.ADDRESS] + .addressState, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS] .addressState, @@ -318,7 +353,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: false, }, { - subFieldName: 'addressCountry', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.ADDRESS] + .addressCountry, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS] .addressCountry, @@ -327,7 +364,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: false, }, { - subFieldName: 'addressPostcode', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.ADDRESS] + .addressPostcode, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS] .addressPostcode, @@ -336,7 +375,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: false, }, { - subFieldName: 'addressLat', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.ADDRESS] + .addressLat, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS] .addressLat, @@ -345,7 +386,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: false, }, { - subFieldName: 'addressLng', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.ADDRESS] + .addressLng, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS] .addressLng, @@ -394,7 +437,8 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { category: 'Basic', subFields: [ { - subFieldName: 'source', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.ACTOR].source, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ACTOR].source, isImportable: true, @@ -402,7 +446,8 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: false, }, { - subFieldName: 'name', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.ACTOR].name, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ACTOR].name, isImportable: true, @@ -410,7 +455,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: false, }, { - subFieldName: 'workspaceMemberId', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.ACTOR] + .workspaceMemberId, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ACTOR] .workspaceMemberId, @@ -419,7 +466,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: false, }, { - subFieldName: 'context', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.ACTOR] + .context, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ACTOR].context, isImportable: true, @@ -454,7 +503,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { category: 'Basic', subFields: [ { - subFieldName: 'blocknote', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.RICH_TEXT_V2] + .blocknote, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.RICH_TEXT_V2] .blocknote, @@ -463,7 +514,9 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { isIncludedInUniqueConstraint: false, }, { - subFieldName: 'markdown', + subFieldName: + COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[FieldMetadataType.RICH_TEXT_V2] + .markdown, subFieldLabel: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.RICH_TEXT_V2] .markdown, diff --git a/packages/twenty-front/src/modules/settings/data-model/constants/SettingsNonCompositeFieldTypeConfigs.ts b/packages/twenty-front/src/modules/settings/data-model/constants/SettingsNonCompositeFieldTypeConfigs.ts index 5eba42bcf6..6e96ae9677 100644 --- a/packages/twenty-front/src/modules/settings/data-model/constants/SettingsNonCompositeFieldTypeConfigs.ts +++ b/packages/twenty-front/src/modules/settings/data-model/constants/SettingsNonCompositeFieldTypeConfigs.ts @@ -6,7 +6,6 @@ import { type FieldJsonValue, type FieldMultiSelectValue, type FieldNumberValue, - type FieldRatingValue, type FieldRelationValue, type FieldSelectValue, type FieldTextValue, @@ -15,6 +14,7 @@ import { import { DEFAULT_DATE_VALUE } from '@/settings/data-model/constants/DefaultDateValue'; import { type SettingsFieldTypeCategoryType } from '@/settings/data-model/types/SettingsFieldTypeCategoryType'; import { type SettingsNonCompositeFieldType } from '@/settings/data-model/types/SettingsNonCompositeFieldType'; +import { type FieldRatingValue } from 'twenty-shared/types'; import { IllustrationIconArray, IllustrationIconCalendarEvent, diff --git a/packages/twenty-front/src/modules/settings/integrations/database-connection/utils/editDatabaseConnection.ts b/packages/twenty-front/src/modules/settings/integrations/database-connection/utils/editDatabaseConnection.ts index 006c89e4fa..af5e1b67eb 100644 --- a/packages/twenty-front/src/modules/settings/integrations/database-connection/utils/editDatabaseConnection.ts +++ b/packages/twenty-front/src/modules/settings/integrations/database-connection/utils/editDatabaseConnection.ts @@ -3,11 +3,11 @@ import isEmpty from 'lodash.isempty'; import pickBy from 'lodash.pickby'; import { z } from 'zod'; -import { CustomError } from '@/error-handler/CustomError'; import { settingsIntegrationPostgreSQLConnectionFormSchema, settingsIntegrationStripeConnectionFormSchema, } from '@/settings/integrations/database-connection/components/SettingsIntegrationDatabaseConnectionForm'; +import { CustomError } from 'twenty-shared/utils'; import { type RemoteServer } from '~/generated-metadata/graphql'; export const getEditionSchemaForForm = (databaseKey: string) => { diff --git a/packages/twenty-front/src/modules/settings/playground/components/PlaygroundSetupForm.tsx b/packages/twenty-front/src/modules/settings/playground/components/PlaygroundSetupForm.tsx index 103f23aaf4..fb4e79ad76 100644 --- a/packages/twenty-front/src/modules/settings/playground/components/PlaygroundSetupForm.tsx +++ b/packages/twenty-front/src/modules/settings/playground/components/PlaygroundSetupForm.tsx @@ -1,4 +1,3 @@ -import { CustomError } from '@/error-handler/CustomError'; import { SETTINGS_PLAYGROUND_FORM_SCHEMA_SELECT_OPTIONS } from '@/settings/playground/constants/SettingsPlaygroundFormSchemaSelectOptions'; import { playgroundApiKeyState } from '@/settings/playground/states/playgroundApiKeyState'; import { PlaygroundSchemas } from '@/settings/playground/types/PlaygroundSchemas'; @@ -11,6 +10,7 @@ import { useLingui } from '@lingui/react/macro'; import { Controller, useForm } from 'react-hook-form'; import { useRecoilState } from 'recoil'; import { SettingsPath } from 'twenty-shared/types'; +import { CustomError } from 'twenty-shared/utils'; import { IconApi, IconBrandGraphql } from 'twenty-ui/display'; import { Button } from 'twenty-ui/input'; import { z } from 'zod'; diff --git a/packages/twenty-front/src/modules/ui/field/input/components/RatingInput.tsx b/packages/twenty-front/src/modules/ui/field/input/components/RatingInput.tsx index 2906d70c79..672d61aa5a 100644 --- a/packages/twenty-front/src/modules/ui/field/input/components/RatingInput.tsx +++ b/packages/twenty-front/src/modules/ui/field/input/components/RatingInput.tsx @@ -2,8 +2,8 @@ import { styled } from '@linaria/react'; import { useContext, useState } from 'react'; import { useClearField } from '@/object-record/record-field/ui/hooks/useClearField'; -import { RATING_VALUES } from '@/object-record/record-field/ui/meta-types/constants/RatingValues'; -import { type FieldRatingValue } from '@/object-record/record-field/ui/types/FieldMetadata'; +import { RATING_VALUES } from 'twenty-shared/constants'; +import { type FieldRatingValue } from 'twenty-shared/types'; import { IconTwentyStarFilled } from 'twenty-ui/display'; import { THEME_COMMON, ThemeContext } from 'twenty-ui/theme'; diff --git a/packages/twenty-front/src/modules/ui/input/components/internal/date/components/RelativeDatePickerHeader.tsx b/packages/twenty-front/src/modules/ui/input/components/internal/date/components/RelativeDatePickerHeader.tsx index fcc0d7dc42..c54766402f 100644 --- a/packages/twenty-front/src/modules/ui/input/components/internal/date/components/RelativeDatePickerHeader.tsx +++ b/packages/twenty-front/src/modules/ui/input/components/internal/date/components/RelativeDatePickerHeader.tsx @@ -2,7 +2,6 @@ import { Select } from '@/ui/input/components/Select'; import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput'; import { RELATIVE_DATE_DIRECTION_SELECT_OPTIONS } from '@/ui/input/components/internal/date/constants/RelativeDateDirectionSelectOptions'; import { RELATIVE_DATE_UNITS_SELECT_OPTIONS } from '@/ui/input/components/internal/date/constants/RelativeDateUnitSelectOptions'; -import { variableDateViewFilterValuePartsSchema } from '@/views/view-filter-value/utils/resolveDateViewFilterValue'; import { type VariableDateViewFilterValueDirection, type VariableDateViewFilterValueUnit, @@ -10,6 +9,7 @@ import { import styled from '@emotion/styled'; import { useEffect, useState } from 'react'; +import { variableDateViewFilterValuePartsSchema } from 'twenty-shared/utils'; const StyledContainer = styled.div<{ noPadding: boolean }>` display: flex; @@ -92,7 +92,8 @@ export const RelativeDatePickerHeader = ( }; if ( - variableDateViewFilterValuePartsSchema.safeParse(valueParts).success + variableDateViewFilterValuePartsSchema.safeParse(valueParts) + .success === true ) { props.onChange?.(valueParts); } diff --git a/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdownAdvancedFilterButton.tsx b/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdownAdvancedFilterButton.tsx index 8cc921c0f8..99bd5ef34d 100644 --- a/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdownAdvancedFilterButton.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdownAdvancedFilterButton.tsx @@ -10,7 +10,6 @@ import { VIEW_BAR_FILTER_BOTTOM_MENU_ITEM_IDS } from '@/views/constants/ViewBarF import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId'; import { useSetRecordFilterUsedInAdvancedFilterDropdownRow } from '@/object-record/advanced-filter/hooks/useSetRecordFilterUsedInAdvancedFilterDropdownRow'; -import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; import { useCreateEmptyRecordFilterFromFieldMetadataItem } from '@/object-record/record-filter/hooks/useCreateEmptyRecordFilterFromFieldMetadataItem'; import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown'; import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown'; @@ -20,6 +19,7 @@ import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly'; import styled from '@emotion/styled'; import { useLingui } from '@lingui/react/macro'; import { useRecoilValue } from 'recoil'; +import { RecordFilterGroupLogicalOperator } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; import { Pill } from 'twenty-ui/components'; import { IconFilter } from 'twenty-ui/display'; diff --git a/packages/twenty-front/src/modules/views/hooks/__tests__/useApplyCurrentViewFiltersToCurrentRecordFilters.test.tsx b/packages/twenty-front/src/modules/views/hooks/__tests__/useApplyCurrentViewFiltersToCurrentRecordFilters.test.tsx index 875eb78002..b402584c0a 100644 --- a/packages/twenty-front/src/modules/views/hooks/__tests__/useApplyCurrentViewFiltersToCurrentRecordFilters.test.tsx +++ b/packages/twenty-front/src/modules/views/hooks/__tests__/useApplyCurrentViewFiltersToCurrentRecordFilters.test.tsx @@ -1,7 +1,6 @@ import { renderHook } from '@testing-library/react'; import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState'; -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; @@ -11,7 +10,7 @@ import { type View } from '@/views/types/View'; import { type ViewFilter } from '@/views/types/ViewFilter'; import { act } from 'react'; import { ViewFilterOperand } from 'twenty-shared/types'; -import { isDefined } from 'twenty-shared/utils'; +import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils'; import { type CoreViewFilter, ViewFilterOperand as CoreViewFilterOperand, diff --git a/packages/twenty-front/src/modules/views/hooks/__tests__/useApplyViewFiltersToCurrentRecordFilters.test.tsx b/packages/twenty-front/src/modules/views/hooks/__tests__/useApplyViewFiltersToCurrentRecordFilters.test.tsx index 2e8f2404f5..5f0ca977e1 100644 --- a/packages/twenty-front/src/modules/views/hooks/__tests__/useApplyViewFiltersToCurrentRecordFilters.test.tsx +++ b/packages/twenty-front/src/modules/views/hooks/__tests__/useApplyViewFiltersToCurrentRecordFilters.test.tsx @@ -1,12 +1,11 @@ import { act, renderHook } from '@testing-library/react'; -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { type ViewFilter } from '@/views/types/ViewFilter'; import { ViewFilterOperand } from 'twenty-shared/types'; -import { isDefined } from 'twenty-shared/utils'; +import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils'; import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper'; import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems'; import { useApplyViewFiltersToCurrentRecordFilters } from '../useApplyViewFiltersToCurrentRecordFilters'; diff --git a/packages/twenty-front/src/modules/views/hooks/__tests__/useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown.test.test.tsx b/packages/twenty-front/src/modules/views/hooks/__tests__/useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown.test.tsx similarity index 99% rename from packages/twenty-front/src/modules/views/hooks/__tests__/useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown.test.test.tsx rename to packages/twenty-front/src/modules/views/hooks/__tests__/useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown.test.tsx index 82ba633482..e2146f630a 100644 --- a/packages/twenty-front/src/modules/views/hooks/__tests__/useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown.test.test.tsx +++ b/packages/twenty-front/src/modules/views/hooks/__tests__/useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown.test.tsx @@ -7,7 +7,6 @@ import { selectedOperandInDropdownComponentState } from '@/object-record/object- 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'; @@ -19,6 +18,7 @@ import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentTyp import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState'; import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId'; +import { getFilterTypeFromFieldType } from 'twenty-shared/utils'; import { getMockPersonObjectMetadataItem } from '~/testing/mock-data/people'; import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems'; diff --git a/packages/twenty-front/src/modules/views/hooks/internal/useGetRecordIndexTotalCount.ts b/packages/twenty-front/src/modules/views/hooks/internal/useGetRecordIndexTotalCount.ts index ff07b20446..fa925b79a6 100644 --- a/packages/twenty-front/src/modules/views/hooks/internal/useGetRecordIndexTotalCount.ts +++ b/packages/twenty-front/src/modules/views/hooks/internal/useGetRecordIndexTotalCount.ts @@ -4,11 +4,11 @@ import { currentRecordFilterGroupsComponentState } from '@/object-record/record- import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies'; import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState'; import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState'; -import { computeRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeRecordGqlOperationFilter'; import { turnAnyFieldFilterIntoRecordGqlFilter } from '@/object-record/record-filter/utils/turnAnyFieldFilterIntoRecordGqlFilter'; import { AggregateOperations } from '@/object-record/record-table/constants/AggregateOperations'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { useGetViewGroupsFilters } from '@/views/hooks/useGetViewGroupsFilters'; +import { computeRecordGqlOperationFilter } from 'twenty-shared/utils'; export const useGetRecordIndexTotalCount = () => { const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow(); diff --git a/packages/twenty-front/src/modules/views/hooks/internal/useViewFromQueryParams.ts b/packages/twenty-front/src/modules/views/hooks/internal/useViewFromQueryParams.ts index b9140bbe40..670fa452a9 100644 --- a/packages/twenty-front/src/modules/views/hooks/internal/useViewFromQueryParams.ts +++ b/packages/twenty-front/src/modules/views/hooks/internal/useViewFromQueryParams.ts @@ -15,9 +15,11 @@ import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; import { generateFindManyRecordsQuery } from '@/object-record/utils/generateFindManyRecordsQuery'; import { type ViewFilter } from '@/views/types/ViewFilter'; -import { relationFilterValueSchemaObject } from '@/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema'; import { ViewFilterOperand } from 'twenty-shared/types'; -import { isDefined } from 'twenty-shared/utils'; +import { + isDefined, + relationFilterValueSchemaObject, +} from 'twenty-shared/utils'; const filterQueryParamsSchema = z.object({ viewId: z.string().optional(), diff --git a/packages/twenty-front/src/modules/views/hooks/useComputeRecordRelationFilterLabelValue.tsx b/packages/twenty-front/src/modules/views/hooks/useComputeRecordRelationFilterLabelValue.tsx index a8a0f90a41..00058f9de0 100644 --- a/packages/twenty-front/src/modules/views/hooks/useComputeRecordRelationFilterLabelValue.tsx +++ b/packages/twenty-front/src/modules/views/hooks/useComputeRecordRelationFilterLabelValue.tsx @@ -5,10 +5,12 @@ import { MAX_RECORDS_TO_DISPLAY } from '@/object-record/object-filter-dropdown/c import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; import { useRecordsForSelect } from '@/object-record/select/hooks/useRecordsForSelect'; import { getRecordFilterLabelValue } from '@/views/utils/getRecordFilterLabelValue'; -import { arrayOfUuidOrVariableSchema } from '@/views/view-filter-value/validation-schemas/arrayOfUuidsOrVariablesSchema'; -import { jsonRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema'; import { t } from '@lingui/core/macro'; -import { isDefined } from 'twenty-shared/utils'; +import { + arrayOfUuidOrVariableSchema, + isDefined, + jsonRelationFilterValueSchema, +} from 'twenty-shared/utils'; type ObjectFilterDropdownRecordSelectProps = { recordFilter: RecordFilter; diff --git a/packages/twenty-front/src/modules/views/hooks/useGetViewGroupsFilters.ts b/packages/twenty-front/src/modules/views/hooks/useGetViewGroupsFilters.ts index c7ee12c977..b983e3b414 100644 --- a/packages/twenty-front/src/modules/views/hooks/useGetViewGroupsFilters.ts +++ b/packages/twenty-front/src/modules/views/hooks/useGetViewGroupsFilters.ts @@ -1,8 +1,7 @@ -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly'; import { FieldMetadataType, ViewFilterOperand } from 'twenty-shared/types'; -import { isDefined } from 'twenty-shared/utils'; +import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils'; export const useGetViewGroupsFilters = (): RecordFilter[] => { const { currentView } = useGetCurrentViewOnly(); diff --git a/packages/twenty-front/src/modules/views/hooks/useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown.ts b/packages/twenty-front/src/modules/views/hooks/useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown.ts index 4c0efce65a..10acb7dd60 100644 --- a/packages/twenty-front/src/modules/views/hooks/useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown.ts +++ b/packages/twenty-front/src/modules/views/hooks/useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown.ts @@ -1,5 +1,4 @@ import { type 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'; @@ -15,7 +14,7 @@ import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentTyp import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState'; import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId'; import { useRecoilCallback } from 'recoil'; -import { isDefined } from 'twenty-shared/utils'; +import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils'; import { v4 } from 'uuid'; export const useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown = diff --git a/packages/twenty-front/src/modules/views/hooks/useVectorSearchFilterActions.ts b/packages/twenty-front/src/modules/views/hooks/useVectorSearchFilterActions.ts index f87942f8bf..6207223057 100644 --- a/packages/twenty-front/src/modules/views/hooks/useVectorSearchFilterActions.ts +++ b/packages/twenty-front/src/modules/views/hooks/useVectorSearchFilterActions.ts @@ -1,10 +1,9 @@ -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter'; import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter'; import { isRecordFilterConsideredEmpty } from '@/object-record/record-filter/utils/isRecordFilterConsideredEmpty'; import { useVectorSearchFieldInRecordIndexContextOrThrow } from '@/views/hooks/useVectorSearchFieldInRecordIndexContextOrThrow'; import { ViewFilterOperand } from 'twenty-shared/types'; -import { isDefined } from 'twenty-shared/utils'; +import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils'; import { v4 } from 'uuid'; import { useVectorSearchFilterState } from './useVectorSearchFilterState'; diff --git a/packages/twenty-front/src/modules/views/utils/__tests__/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator.test.ts b/packages/twenty-front/src/modules/views/utils/__tests__/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator.test.ts index d4c3a171f6..fa884b3976 100644 --- a/packages/twenty-front/src/modules/views/utils/__tests__/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator.test.ts +++ b/packages/twenty-front/src/modules/views/utils/__tests__/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator.test.ts @@ -1,6 +1,6 @@ -import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator'; import { mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator } from '@/views/utils/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator'; +import { RecordFilterGroupLogicalOperator } from 'twenty-shared/types'; describe('mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator', () => { it('should map correctly for AND', () => { diff --git a/packages/twenty-front/src/modules/views/utils/__tests__/mapRecordFilterGroupToViewFilterGroup.test.ts b/packages/twenty-front/src/modules/views/utils/__tests__/mapRecordFilterGroupToViewFilterGroup.test.ts index 2fd9d6247a..b467266542 100644 --- a/packages/twenty-front/src/modules/views/utils/__tests__/mapRecordFilterGroupToViewFilterGroup.test.ts +++ b/packages/twenty-front/src/modules/views/utils/__tests__/mapRecordFilterGroupToViewFilterGroup.test.ts @@ -1,5 +1,4 @@ import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; -import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; import { AggregateOperations } from '@/object-record/record-table/constants/AggregateOperations'; import { type View } from '@/views/types/View'; import { type ViewFilterGroup } from '@/views/types/ViewFilterGroup'; @@ -7,6 +6,7 @@ import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLog import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType'; import { ViewType } from '@/views/types/ViewType'; import { mapRecordFilterGroupToViewFilterGroup } from '@/views/utils/mapRecordFilterGroupToViewFilterGroup'; +import { RecordFilterGroupLogicalOperator } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems'; diff --git a/packages/twenty-front/src/modules/views/utils/__tests__/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator.test.ts b/packages/twenty-front/src/modules/views/utils/__tests__/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator.test.ts index f965d1516f..d4fd95b2ba 100644 --- a/packages/twenty-front/src/modules/views/utils/__tests__/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator.test.ts +++ b/packages/twenty-front/src/modules/views/utils/__tests__/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator.test.ts @@ -1,6 +1,6 @@ -import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator'; import { mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator } from '@/views/utils/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator'; +import { RecordFilterGroupLogicalOperator } from 'twenty-shared/types'; describe('mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator', () => { it('should map correctly for AND', () => { diff --git a/packages/twenty-front/src/modules/views/utils/__tests__/mapViewFilterGroupsToRecordFilterGroups.test.ts b/packages/twenty-front/src/modules/views/utils/__tests__/mapViewFilterGroupsToRecordFilterGroups.test.ts index b4ca54c011..0c0a4dc5a0 100644 --- a/packages/twenty-front/src/modules/views/utils/__tests__/mapViewFilterGroupsToRecordFilterGroups.test.ts +++ b/packages/twenty-front/src/modules/views/utils/__tests__/mapViewFilterGroupsToRecordFilterGroups.test.ts @@ -1,8 +1,8 @@ import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; -import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; import { type ViewFilterGroup } from '@/views/types/ViewFilterGroup'; import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator'; import { mapViewFilterGroupsToRecordFilterGroups } from '@/views/utils/mapViewFilterGroupsToRecordFilterGroups'; +import { RecordFilterGroupLogicalOperator } from 'twenty-shared/types'; describe('mapViewFilterGroupsToRecordFilterGroups', () => { it('should map empty array to empty array', () => { diff --git a/packages/twenty-front/src/modules/views/utils/convertCoreViewFilterToViewFilter.ts b/packages/twenty-front/src/modules/views/utils/convertCoreViewFilterToViewFilter.ts index b11ca64946..256942178e 100644 --- a/packages/twenty-front/src/modules/views/utils/convertCoreViewFilterToViewFilter.ts +++ b/packages/twenty-front/src/modules/views/utils/convertCoreViewFilterToViewFilter.ts @@ -1,5 +1,6 @@ import { type CompositeFieldSubFieldName } from '@/settings/data-model/types/CompositeFieldSubFieldName'; import { type ViewFilter } from '@/views/types/ViewFilter'; +import { convertViewFilterValueToString } from 'twenty-shared/utils'; import { type CoreViewFilter } from '~/generated/graphql'; import { convertViewFilterOperandFromCore } from '../utils/convertViewFilterOperandFromCore'; @@ -20,14 +21,8 @@ export const convertCoreViewFilterToViewFilter = ( id: coreViewFilter.id, fieldMetadataId: coreViewFilter.fieldMetadataId, operand: convertViewFilterOperandFromCore(coreViewFilter.operand), - value: - typeof coreViewFilter.value === 'string' - ? coreViewFilter.value - : JSON.stringify(coreViewFilter.value ?? ''), - displayValue: - typeof coreViewFilter.value === 'string' - ? coreViewFilter.value - : JSON.stringify(coreViewFilter.value ?? ''), + value: convertViewFilterValueToString(coreViewFilter.value), + displayValue: convertViewFilterValueToString(coreViewFilter.value), viewFilterGroupId: coreViewFilter.viewFilterGroupId, positionInViewFilterGroup: coreViewFilter.positionInViewFilterGroup, subFieldName: coreViewFilter.subFieldName as CompositeFieldSubFieldName, diff --git a/packages/twenty-front/src/modules/views/utils/getQueryVariablesFromFiltersAndSorts.ts b/packages/twenty-front/src/modules/views/utils/getQueryVariablesFromFiltersAndSorts.ts index 2bff7d8dd1..17a1bda720 100644 --- a/packages/twenty-front/src/modules/views/utils/getQueryVariablesFromFiltersAndSorts.ts +++ b/packages/twenty-front/src/modules/views/utils/getQueryVariablesFromFiltersAndSorts.ts @@ -2,9 +2,9 @@ import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataI import { turnSortsIntoOrderBy } from '@/object-record/object-sort-dropdown/utils/turnSortsIntoOrderBy'; import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; -import { type RecordFilterValueDependencies } from '@/object-record/record-filter/types/RecordFilterValueDependencies'; -import { computeRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeRecordGqlOperationFilter'; import { type RecordSort } from '@/object-record/record-sort/types/RecordSort'; +import { type RecordFilterValueDependencies } from 'twenty-shared/types'; +import { computeRecordGqlOperationFilter } from 'twenty-shared/utils'; export const getQueryVariablesFromFiltersAndSorts = ({ recordFilterGroups, diff --git a/packages/twenty-front/src/modules/views/utils/getRecordFilterLabelValue.ts b/packages/twenty-front/src/modules/views/utils/getRecordFilterLabelValue.ts index f524700ad5..0df5dfcf7d 100644 --- a/packages/twenty-front/src/modules/views/utils/getRecordFilterLabelValue.ts +++ b/packages/twenty-front/src/modules/views/utils/getRecordFilterLabelValue.ts @@ -2,9 +2,8 @@ import { type FieldMetadataItemOption } from '@/object-metadata/types/FieldMetad import { getOperandLabelShort } from '@/object-record/object-filter-dropdown/utils/getOperandLabel'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand'; -import { isEmptinessOperand } from '@/object-record/record-filter/utils/isEmptinessOperand'; import { isRecordFilterConsideredEmpty } from '@/object-record/record-filter/utils/isRecordFilterConsideredEmpty'; -import { parseJson } from 'twenty-shared/utils'; +import { isEmptinessOperand, parseJson } from 'twenty-shared/utils'; export const getRecordFilterLabelValue = ({ recordFilter, diff --git a/packages/twenty-front/src/modules/views/utils/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator.ts b/packages/twenty-front/src/modules/views/utils/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator.ts index 976a63bc91..fee1fea929 100644 --- a/packages/twenty-front/src/modules/views/utils/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator.ts +++ b/packages/twenty-front/src/modules/views/utils/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator.ts @@ -1,5 +1,5 @@ -import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator'; +import { RecordFilterGroupLogicalOperator } from 'twenty-shared/types'; export const mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator = ({ diff --git a/packages/twenty-front/src/modules/views/utils/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator.ts b/packages/twenty-front/src/modules/views/utils/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator.ts index 316b6d0858..6bf34f0ebb 100644 --- a/packages/twenty-front/src/modules/views/utils/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator.ts +++ b/packages/twenty-front/src/modules/views/utils/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator.ts @@ -1,5 +1,5 @@ -import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator'; +import { RecordFilterGroupLogicalOperator } from 'twenty-shared/types'; export const mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator = ({ diff --git a/packages/twenty-front/src/modules/views/utils/mapViewFiltersToFilters.ts b/packages/twenty-front/src/modules/views/utils/mapViewFiltersToFilters.ts index 7de909ca63..9f1dcf27cf 100644 --- a/packages/twenty-front/src/modules/views/utils/mapViewFiltersToFilters.ts +++ b/packages/twenty-front/src/modules/views/utils/mapViewFiltersToFilters.ts @@ -2,12 +2,11 @@ import { type RecordFilter } from '@/object-record/record-filter/types/RecordFil import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { isSystemSearchVectorField } from '@/object-record/utils/isSystemSearchVectorField'; import { type CompositeFieldSubFieldName } from '@/settings/data-model/types/CompositeFieldSubFieldName'; import { convertViewFilterOperandFromCore } from '@/views/utils/convertViewFilterOperandFromCore'; import { type ViewFilterOperand } from 'twenty-shared/types'; -import { isDefined } from 'twenty-shared/utils'; +import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils'; import { type CoreViewFilter } from '~/generated/graphql'; import { type ViewFilter } from '../types/ViewFilter'; diff --git a/packages/twenty-front/src/modules/views/view-filter-value/types/RelationFilterValue.ts b/packages/twenty-front/src/modules/views/view-filter-value/types/RelationFilterValue.ts index 3919e79788..0fd4807d8a 100644 --- a/packages/twenty-front/src/modules/views/view-filter-value/types/RelationFilterValue.ts +++ b/packages/twenty-front/src/modules/views/view-filter-value/types/RelationFilterValue.ts @@ -1,4 +1,4 @@ -import { type jsonRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema'; +import { type jsonRelationFilterValueSchema } from 'twenty-shared/utils'; import { type z } from 'zod'; export type RelationFilterValue = z.infer; diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowFindRecordsAddFilterButton.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowFindRecordsAddFilterButton.tsx index 3a26b3a886..b0fcbe1c95 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowFindRecordsAddFilterButton.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowFindRecordsAddFilterButton.tsx @@ -2,13 +2,13 @@ import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataIte import { AdvancedFilterContext } from '@/object-record/advanced-filter/states/context/AdvancedFilterContext'; import { rootLevelRecordFilterGroupComponentSelector } from '@/object-record/advanced-filter/states/rootLevelRecordFilterGroupComponentSelector'; import { useUpsertRecordFilterGroup } from '@/object-record/record-filter-group/hooks/useUpsertRecordFilterGroup'; -import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; import { useCreateEmptyRecordFilterFromFieldMetadataItem } from '@/object-record/record-filter/hooks/useCreateEmptyRecordFilterFromFieldMetadataItem'; import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { useSetRecoilComponentFamilyState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentFamilyState'; import { hasInitializedCurrentRecordFiltersComponentFamilyState } from '@/views/states/hasInitializedCurrentRecordFiltersComponentFamilyState'; import { useContext } from 'react'; +import { RecordFilterGroupLogicalOperator } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; import { IconFilter } from 'twenty-ui/display'; import { Button } from 'twenty-ui/input'; diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowFindRecordsFilters.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowFindRecordsFilters.tsx index d6ec563a85..00f628d971 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowFindRecordsFilters.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowFindRecordsFilters.tsx @@ -7,7 +7,6 @@ import { rootLevelRecordFilterGroupComponentSelector } from '@/object-record/adv import { isRecordFilterGroupChildARecordFilterGroup } from '@/object-record/advanced-filter/utils/isRecordFilterGroupChildARecordFilterGroup'; import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState'; import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState'; -import { computeRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeRecordGqlOperationFilter'; import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue'; @@ -17,7 +16,10 @@ import { type FindRecordsActionFilter } from '@/workflow/workflow-steps/workflow import { WorkflowFindRecordsAddFilterButton } from '@/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowFindRecordsAddFilterButton'; import styled from '@emotion/styled'; import { useRecoilCallback, useRecoilValue } from 'recoil'; -import { isDefined } from 'twenty-shared/utils'; +import { + computeRecordGqlOperationFilter, + isDefined, +} from 'twenty-shared/utils'; const StyledContainer = styled.div` align-items: start; diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/utils/shouldDisplayFormField.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/utils/shouldDisplayFormField.ts index a499275b43..2852628d75 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/utils/shouldDisplayFormField.ts +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/utils/shouldDisplayFormField.ts @@ -1,6 +1,6 @@ -import { CustomError } from '@/error-handler/CustomError'; import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { type WorkflowActionType } from '@/workflow/types/Workflow'; +import { CustomError } from 'twenty-shared/utils'; import { FieldMetadataType } from '~/generated-metadata/graphql'; const COMMON_DISPLAYABLE_FIELD_TYPES = [ diff --git a/packages/twenty-front/src/pages/settings/SettingsWorkspaceMembers.tsx b/packages/twenty-front/src/pages/settings/SettingsWorkspaceMembers.tsx index 86627cd5a0..ac0ada20b5 100644 --- a/packages/twenty-front/src/pages/settings/SettingsWorkspaceMembers.tsx +++ b/packages/twenty-front/src/pages/settings/SettingsWorkspaceMembers.tsx @@ -28,7 +28,11 @@ import { WorkspaceInviteTeam } from '@/workspace/components/WorkspaceInviteTeam' import { type ApolloError } from '@apollo/client'; import { formatDistanceToNow } from 'date-fns'; import { SettingsPath } from 'twenty-shared/types'; -import { getSettingsPath, isDefined } from 'twenty-shared/utils'; +import { + generateILikeFiltersForCompositeFields, + getSettingsPath, + isDefined, +} from 'twenty-shared/utils'; import { AppTooltip, Avatar, @@ -47,7 +51,6 @@ import { useImpersonateMutation, } from '~/generated-metadata/graphql'; -import { generateILikeFiltersForCompositeFields } from '~/utils/array/generateILikeFiltersForCompositeFields'; import { normalizeSearchText } from '~/utils/normalizeSearchText'; import { TableCell } from '../../modules/ui/layout/table/components/TableCell'; import { TableRow } from '../../modules/ui/layout/table/components/TableRow'; diff --git a/packages/twenty-front/src/testing/decorators/getFieldDecorator.tsx b/packages/twenty-front/src/testing/decorators/getFieldDecorator.tsx index eae314ce56..308fc6128e 100644 --- a/packages/twenty-front/src/testing/decorators/getFieldDecorator.tsx +++ b/packages/twenty-front/src/testing/decorators/getFieldDecorator.tsx @@ -2,14 +2,13 @@ import { type Decorator } from '@storybook/react'; import { useEffect } from 'react'; import { useRecoilCallback } from 'recoil'; -import { CustomError } from '@/error-handler/CustomError'; import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition'; import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField'; import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext'; import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/ui/states/contexts/RecordFieldComponentInstanceContext'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; -import { isDefined } from 'twenty-shared/utils'; +import { CustomError, isDefined } from 'twenty-shared/utils'; import { getCompaniesMock } from '~/testing/mock-data/companies'; import { getPeopleRecordConnectionMock } from '~/testing/mock-data/people'; import { mockedTasks } from '~/testing/mock-data/tasks'; diff --git a/packages/twenty-front/src/utils/date-utils.ts b/packages/twenty-front/src/utils/date-utils.ts index be8dcb5bd5..2046ba4187 100644 --- a/packages/twenty-front/src/utils/date-utils.ts +++ b/packages/twenty-front/src/utils/date-utils.ts @@ -13,9 +13,8 @@ import { } from 'date-fns'; import { DateFormat } from '@/localization/constants/DateFormat'; -import { isDefined } from 'twenty-shared/utils'; +import { CustomError, isDefined } from 'twenty-shared/utils'; -import { CustomError } from '@/error-handler/CustomError'; import { i18n } from '@lingui/core'; import { plural, t } from '@lingui/core/macro'; import { logError } from './logError'; diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-runner.module.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-runner.module.ts index 448f0a915e..bf805377e3 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-runner.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-runner.module.ts @@ -22,6 +22,7 @@ import { GraphqlQueryUpdateOneResolverService } from 'src/engine/api/graphql/gra import { WorkspaceQueryHookModule } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.module'; import { WorkspaceQueryRunnerModule } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module'; import { ApiKeyModule } from 'src/engine/core-modules/api-key/api-key.module'; +import { CoreViewModule } from 'src/engine/core-modules/view/view.module'; import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module'; import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity'; import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module'; @@ -52,6 +53,7 @@ const graphqlQueryResolvers = [ TypeOrmModule.forFeature([RoleTargetsEntity]), UserRoleModule, ApiKeyModule, + CoreViewModule, ], providers: [ ProcessNestedRelationsHelper, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-group-by-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-group-by-resolver.service.ts index 3b5e93389c..331e21bd38 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-group-by-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-group-by-resolver.service.ts @@ -1,5 +1,17 @@ import { Injectable } from '@nestjs/common'; +import { + CompositeFieldSubFieldName, + RecordFilterGroupLogicalOperator, +} from 'twenty-shared/types'; +import { + assertIsDefinedOrThrow, + combineFilters, + computeRecordGqlOperationFilter, + convertViewFilterValueToString, + getFilterTypeFromFieldType, +} from 'twenty-shared/utils'; + import { GraphqlQueryBaseResolverService, GraphqlQueryResolverExecutionArgs, @@ -18,7 +30,11 @@ import { GraphqlQueryRunnerExceptionCode, } from 'src/engine/api/graphql/graphql-query-runner/errors/graphql-query-runner.exception'; import { ProcessAggregateHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/process-aggregate.helper'; +import { convertViewFilterOperand } from 'src/engine/api/graphql/graphql-query-runner/utils/convert-view-filter-operands'; import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; +import { ViewFilterGroupService } from 'src/engine/core-modules/view/services/view-filter-group.service'; +import { ViewFilterService } from 'src/engine/core-modules/view/services/view-filter.service'; +import { WorkspaceNotFoundDefaultError } from 'src/engine/core-modules/workspace/workspace.exception'; import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps'; import { formatColumnNamesFromCompositeFieldAndSubfields } from 'src/engine/twenty-orm/utils/format-column-names-from-composite-field-and-subfield.util'; @@ -28,6 +44,13 @@ export class GraphqlQueryGroupByResolverService extends GraphqlQueryBaseResolver GroupByResolverArgs, IGroupByConnection>[] > { + constructor( + private readonly viewFilterService: ViewFilterService, + private readonly viewFilterGroupService: ViewFilterGroupService, + ) { + super(); + } + async resolve( executionArgs: GraphqlQueryResolverExecutionArgs, _featureFlagsMap: Record, @@ -44,6 +67,14 @@ export class GraphqlQueryGroupByResolverService extends GraphqlQueryBaseResolver let appliedFilters = executionArgs.args.filter ?? ({} as ObjectRecordFilter); + if (executionArgs.args.viewId) { + appliedFilters = await this.addFiltersFromView({ + executionArgs, + objectMetadataItemWithFieldMaps, + appliedFilters, + }); + } + executionArgs.graphqlQueryParser.applyFilterToBuilder( queryBuilder, objectMetadataNameSingular, @@ -182,6 +213,77 @@ export class GraphqlQueryGroupByResolverService extends GraphqlQueryBaseResolver return groupByFields; } + private async addFiltersFromView({ + executionArgs, + objectMetadataItemWithFieldMaps, + appliedFilters, + }: { + executionArgs: GraphqlQueryResolverExecutionArgs; + objectMetadataItemWithFieldMaps: ObjectMetadataItemWithFieldMaps; + appliedFilters: ObjectRecordFilter; + }): Promise { + assertIsDefinedOrThrow(executionArgs.args.viewId); + + const workspaceId = executionArgs.options.authContext.workspace?.id; + + assertIsDefinedOrThrow(workspaceId, WorkspaceNotFoundDefaultError); + + const viewFilters = await this.viewFilterService.findByViewId( + workspaceId, + executionArgs.args.viewId, + ); + + const viewFilterGroups = await this.viewFilterGroupService.findByViewId( + workspaceId, + executionArgs.args.viewId, + ); + + const recordFilters = viewFilters.map((viewFilter) => { + const fieldMetadataItem = + objectMetadataItemWithFieldMaps.fieldsById[viewFilter.fieldMetadataId]; + + return { + id: viewFilter.id, + fieldMetadataId: viewFilter.fieldMetadataId, + value: convertViewFilterValueToString(viewFilter.value), + type: getFilterTypeFromFieldType(fieldMetadataItem.type), + operand: convertViewFilterOperand(viewFilter.operand), + recordFilterGroupId: viewFilter.viewFilterGroupId, + positionInRecordFilterGroup: viewFilter.positionInViewFilterGroup, + subFieldName: viewFilter.subFieldName as CompositeFieldSubFieldName, + }; + }); + + const recordFilterGroups = viewFilterGroups.map((viewFilterGroup) => { + return { + id: viewFilterGroup.id, + logicalOperator: + viewFilterGroup.logicalOperator as unknown as RecordFilterGroupLogicalOperator, // TODO - https://github.com/twentyhq/twenty/issues/14746 + parentRecordFilterGroupId: viewFilterGroup.parentViewFilterGroupId, + }; + }); + + const fields = Object.values( + objectMetadataItemWithFieldMaps.fieldsById, + ).map((field) => ({ + id: field.id, + name: field.name, + type: field.type, + label: field.label, + })); + + const filtersFromView = computeRecordGqlOperationFilter({ + recordFilters, + recordFilterGroups: recordFilterGroups, + fields, + filterValueDependencies: {}, + }); + + appliedFilters = combineFilters([appliedFilters, filtersFromView]); + + return appliedFilters; + } + async validate( _args: GroupByResolverArgs, _options: WorkspaceQueryRunnerOptions, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/convert-view-filter-operands.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/convert-view-filter-operands.ts new file mode 100644 index 0000000000..a486f27576 --- /dev/null +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/convert-view-filter-operands.ts @@ -0,0 +1,44 @@ +import { ViewFilterOperand as ViewFilterOperandShared } from 'twenty-shared/types'; + +import { ViewFilterOperand } from 'src/engine/core-modules/view/enums/view-filter-operand'; + +export const convertViewFilterOperand = ( + operand: ViewFilterOperand, +): ViewFilterOperandShared => { + switch (operand) { + case ViewFilterOperand.IS: + return ViewFilterOperandShared.Is; + case ViewFilterOperand.IS_NOT_NULL: + return ViewFilterOperandShared.IsNotNull; + case ViewFilterOperand.IS_NOT: + return ViewFilterOperandShared.IsNot; + case ViewFilterOperand.LESS_THAN_OR_EQUAL: + return ViewFilterOperandShared.LessThanOrEqual; + case ViewFilterOperand.GREATER_THAN_OR_EQUAL: + return ViewFilterOperandShared.GreaterThanOrEqual; + case ViewFilterOperand.IS_BEFORE: + return ViewFilterOperandShared.IsBefore; + case ViewFilterOperand.IS_AFTER: + return ViewFilterOperandShared.IsAfter; + case ViewFilterOperand.CONTAINS: + return ViewFilterOperandShared.Contains; + case ViewFilterOperand.DOES_NOT_CONTAIN: + return ViewFilterOperandShared.DoesNotContain; + case ViewFilterOperand.IS_EMPTY: + return ViewFilterOperandShared.IsEmpty; + case ViewFilterOperand.IS_NOT_EMPTY: + return ViewFilterOperandShared.IsNotEmpty; + case ViewFilterOperand.IS_RELATIVE: + return ViewFilterOperandShared.IsRelative; + case ViewFilterOperand.IS_IN_PAST: + return ViewFilterOperandShared.IsInPast; + case ViewFilterOperand.IS_IN_FUTURE: + return ViewFilterOperandShared.IsInFuture; + case ViewFilterOperand.IS_TODAY: + return ViewFilterOperandShared.IsToday; + case ViewFilterOperand.VECTOR_SEARCH: + return ViewFilterOperandShared.VectorSearch; + default: + throw new Error(`Invalid view filter operand: ${operand}`); + } +}; diff --git a/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts b/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts index 87cba55243..07273f5109 100644 --- a/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts +++ b/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts @@ -139,7 +139,7 @@ describe('WorkspaceEntityManager', () => { IS_WORKFLOW_ITERATOR_ENABLED: false, IS_DATABASE_EVENT_TRIGGER_ENABLED: false, IS_CALENDAR_VIEW_ENABLED: false, - IS_GROUP_BY_ENABLED: false, + IS_GROUP_BY_ENABLED: true, IS_PUBLIC_DOMAIN_ENABLED: false, IS_EMAILING_DOMAIN_ENABLED: false, IS_DYNAMIC_SEARCH_FIELDS_ENABLED: false, diff --git a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/utils/seed-feature-flags.util.ts b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/utils/seed-feature-flags.util.ts index 40b5dcee23..a3e501d8c2 100644 --- a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/utils/seed-feature-flags.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/utils/seed-feature-flags.util.ts @@ -78,7 +78,7 @@ export const seedFeatureFlags = async ( { key: FeatureFlagKey.IS_GROUP_BY_ENABLED, workspaceId: workspaceId, - value: false, + value: true, }, { key: FeatureFlagKey.IS_PUBLIC_DOMAIN_ENABLED, diff --git a/packages/twenty-server/src/utils/custom-exception.ts b/packages/twenty-server/src/utils/custom-exception.ts index 24bda4faab..34300cc1e2 100644 --- a/packages/twenty-server/src/utils/custom-exception.ts +++ b/packages/twenty-server/src/utils/custom-exception.ts @@ -1,3 +1,5 @@ +import { CustomError } from 'twenty-shared/utils'; + const CommonExceptionCode = { INTERNAL_SERVER_ERROR: 'INTERNAL_SERVER_ERROR', } as const; @@ -18,7 +20,7 @@ export abstract class CustomException< ForceFriendlyMessage = false, ExceptionMessage extends string = string, ExceptionFriendlyMessage extends string = string, -> extends Error { +> extends CustomError { code: ExceptionCode; userFriendlyMessage?: ExceptionFriendlyMessage; diff --git a/packages/twenty-server/test/integration/graphql/suites/group-by-resolvers.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/group-by-resolvers.integration-spec.ts new file mode 100644 index 0000000000..3613b3c309 --- /dev/null +++ b/packages/twenty-server/test/integration/graphql/suites/group-by-resolvers.integration-spec.ts @@ -0,0 +1,239 @@ +import { randomUUID } from 'crypto'; + +import { PERSON_GQL_FIELDS } from 'test/integration/constants/person-gql-fields.constants'; +import { createOneOperationFactory } from 'test/integration/graphql/utils/create-one-operation-factory.util'; +import { createViewFilterGroupOperationFactory } from 'test/integration/graphql/utils/create-view-filter-group-operation-factory.util'; +import { createViewFilterOperationFactory } from 'test/integration/graphql/utils/create-view-filter-operation-factory.util'; +import { createViewOperationFactory } from 'test/integration/graphql/utils/create-view-operation-factory.util'; +import { deleteOneOperationFactory } from 'test/integration/graphql/utils/delete-one-operation-factory.util'; +import { groupByOperationFactory } from 'test/integration/graphql/utils/group-by-operation-factory.util'; +import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util'; +import { findManyObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/find-many-object-metadata.util'; + +import { ViewFilterOperand } from 'src/engine/core-modules/view/enums/view-filter-operand'; +import { type FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto'; +import { ViewFilterGroupLogicalOperator } from 'src/modules/view/standard-objects/view-filter-group.workspace-entity'; + +describe('group-by resolvers (integration)', () => { + describe('with viewId undefined', () => { + const testPersonId = randomUUID(); + const testPerson2Id = randomUUID(); + const testPerson3Id = randomUUID(); + + afterEach(async () => { + // cleanup created people + await makeGraphqlAPIRequest( + deleteOneOperationFactory({ + objectMetadataSingularName: 'person', + gqlFields: 'id', + recordId: testPersonId, + }), + ); + await makeGraphqlAPIRequest( + deleteOneOperationFactory({ + objectMetadataSingularName: 'person', + gqlFields: 'id', + recordId: testPerson2Id, + }), + ); + await makeGraphqlAPIRequest( + deleteOneOperationFactory({ + objectMetadataSingularName: 'person', + gqlFields: 'id', + recordId: testPerson3Id, + }), + ); + }); + it('groups by city', async () => { + const cityA = 'City A'; + const cityB = 'City B'; + + await makeGraphqlAPIRequest( + createOneOperationFactory({ + objectMetadataSingularName: 'person', + gqlFields: PERSON_GQL_FIELDS, + data: { id: testPersonId, city: cityA }, + }), + ); + await makeGraphqlAPIRequest( + createOneOperationFactory({ + objectMetadataSingularName: 'person', + gqlFields: PERSON_GQL_FIELDS, + data: { id: testPerson2Id, city: cityB }, + }), + ); + await makeGraphqlAPIRequest( + createOneOperationFactory({ + objectMetadataSingularName: 'person', + gqlFields: PERSON_GQL_FIELDS, + data: { id: testPerson3Id, city: cityB }, + }), + ); + + const response = await makeGraphqlAPIRequest( + groupByOperationFactory({ + objectMetadataSingularName: 'person', + objectMetadataPluralName: 'people', + groupBy: [{ city: true }], + }), + ); + + const groups = response.body.data.peopleGroupBy; + + expect(groups).toBeDefined(); + expect(groups).toEqual( + expect.arrayContaining([ + expect.objectContaining({ groupByDimensionValues: [cityA] }), + expect.objectContaining({ groupByDimensionValues: [cityB] }), + ]), + ); + + const groupWithCityA = groups.find( + (group: any) => group.groupByDimensionValues[0] === cityA, + ); + + expect(groupWithCityA.groupByDimensionValues).toEqual([cityA]); + expect(groupWithCityA.totalCount).toEqual(1); + + const groupWithCityB = groups.find( + (group: any) => group.groupByDimensionValues[0] === cityB, + ); + + expect(groupWithCityB.groupByDimensionValues).toEqual([cityB]); + expect(groupWithCityB.totalCount).toEqual(2); + }); + }); + + describe('with viewId defined', () => { + const testPersonId = randomUUID(); + const testPerson2Id = randomUUID(); + const testPerson3Id = randomUUID(); + + afterEach(async () => { + // cleanup created people + await makeGraphqlAPIRequest( + deleteOneOperationFactory({ + objectMetadataSingularName: 'person', + gqlFields: 'id', + recordId: testPersonId, + }), + ); + await makeGraphqlAPIRequest( + deleteOneOperationFactory({ + objectMetadataSingularName: 'person', + gqlFields: 'id', + recordId: testPerson2Id, + }), + ); + await makeGraphqlAPIRequest( + deleteOneOperationFactory({ + objectMetadataSingularName: 'person', + gqlFields: 'id', + recordId: testPerson3Id, + }), + ); + }); + it('groups by city', async () => { + const { objects } = await findManyObjectMetadata({ + input: { + filter: {}, + paging: { + first: 100, + }, + }, + gqlFields: 'id nameSingular fieldsList { id name }', + expectToFail: false, + }); + + const personObject = objects.find((o) => o.nameSingular === 'person'); + const personObjectMetadataId = personObject?.id; + + const cityFieldMetadata = personObject?.fieldsList?.find( + (f: FieldMetadataDTO) => f.name === 'city', + ); + const cityFieldMetadataId = cityFieldMetadata?.id; + + const cityToKeep = 'City To Keep'; + const cityToExclude = 'City To Exclude'; + + await makeGraphqlAPIRequest( + createOneOperationFactory({ + objectMetadataSingularName: 'person', + gqlFields: PERSON_GQL_FIELDS, + data: { id: testPersonId, city: cityToKeep }, + }), + ); + await makeGraphqlAPIRequest( + createOneOperationFactory({ + objectMetadataSingularName: 'person', + gqlFields: PERSON_GQL_FIELDS, + data: { id: testPerson2Id, city: cityToExclude }, + }), + ); + + // create a view with a filter: city eq cityToKeep + const createViewResponse = await makeGraphqlAPIRequest( + createViewOperationFactory({ + data: { + name: 'People View City Keep', + objectMetadataId: personObjectMetadataId, + icon: 'Icon123', + }, + }), + ); + + const viewId = createViewResponse.body.data.createCoreView.id as string; + + // create a filter group and a filter for the view + const viewFilterGroupResponse = await makeGraphqlAPIRequest( + createViewFilterGroupOperationFactory({ + data: { + viewId, + logicalOperator: ViewFilterGroupLogicalOperator.AND, + positionInViewFilterGroup: 0, + }, + }), + ); + + const viewFilterGroupId = viewFilterGroupResponse.body.data + .createCoreViewFilterGroup.id as string; + + await makeGraphqlAPIRequest( + createViewFilterOperationFactory({ + data: { + viewId, + viewFilterGroupId, + fieldMetadataId: cityFieldMetadataId, + operand: ViewFilterOperand.CONTAINS, + value: cityToKeep, + positionInViewFilterGroup: 0, + }, + }), + ); + + const response = await makeGraphqlAPIRequest( + groupByOperationFactory({ + objectMetadataSingularName: 'person', + objectMetadataPluralName: 'people', + groupBy: [{ city: true }], + viewId, + }), + ); + + const groups = response.body.data.peopleGroupBy; + + expect(groups).toBeDefined(); + expect(groups).toEqual( + expect.arrayContaining([ + expect.objectContaining({ groupByDimensionValues: [cityToKeep] }), + ]), + ); + // Ensure excluded city is not present + expect(groups).toEqual( + expect.not.arrayContaining([ + expect.objectContaining({ groupByDimensionValues: [cityToExclude] }), + ]), + ); + }); + }); +}); diff --git a/packages/twenty-server/test/integration/graphql/utils/group-by-operation-factory.util.ts b/packages/twenty-server/test/integration/graphql/utils/group-by-operation-factory.util.ts new file mode 100644 index 0000000000..47ca97cb90 --- /dev/null +++ b/packages/twenty-server/test/integration/graphql/utils/group-by-operation-factory.util.ts @@ -0,0 +1,35 @@ +import gql from 'graphql-tag'; +import { capitalize } from 'twenty-shared/utils'; + +type GroupByOperationFactoryParams = { + objectMetadataSingularName: string; + objectMetadataPluralName: string; + groupBy: object[]; + filter?: object; + orderBy?: object[]; + viewId?: string; +}; + +export const groupByOperationFactory = ({ + objectMetadataSingularName, + objectMetadataPluralName, + groupBy, + filter = {}, + orderBy = [], + viewId, +}: GroupByOperationFactoryParams) => ({ + query: gql` + query ${capitalize(objectMetadataPluralName)}GroupBy($groupBy: [${capitalize(objectMetadataSingularName)}GroupByInput!]!, $filter: ${capitalize(objectMetadataSingularName)}FilterInput, $orderBy: [${capitalize(objectMetadataSingularName)}OrderByWithGroupByInput!], $viewId: UUID) { + ${objectMetadataPluralName}GroupBy(groupBy: $groupBy, filter: $filter, orderBy: $orderBy, viewId: $viewId) { + groupByDimensionValues + totalCount + } + } + `, + variables: { + groupBy, + filter, + orderBy, + ...(viewId && { viewId }), + }, +}); diff --git a/packages/twenty-server/test/integration/metadata/suites/object-metadata/utils/find-many-object-metadata.util.ts b/packages/twenty-server/test/integration/metadata/suites/object-metadata/utils/find-many-object-metadata.util.ts index 06bd7b98ba..09fb0f215a 100644 --- a/packages/twenty-server/test/integration/metadata/suites/object-metadata/utils/find-many-object-metadata.util.ts +++ b/packages/twenty-server/test/integration/metadata/suites/object-metadata/utils/find-many-object-metadata.util.ts @@ -8,6 +8,7 @@ import { warnIfErrorButNotExpectedToFail } from 'test/integration/metadata/utils import { warnIfNoErrorButExpectedToFail } from 'test/integration/metadata/utils/warn-if-no-error-but-expected-to-fail.util'; import { type BaseGraphQLError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; +import { type FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto'; import { type ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto'; export const findManyObjectMetadata = async ({ @@ -16,7 +17,7 @@ export const findManyObjectMetadata = async ({ expectToFail, }: PerformMetadataQueryParams): Promise<{ errors: BaseGraphQLError[]; - objects: ObjectMetadataDTO[]; + objects: (ObjectMetadataDTO & { fieldsList?: FieldMetadataDTO[] })[]; }> => { const graphqlOperation = findManyObjectMetadataQueryFactory({ input, diff --git a/packages/twenty-shared/src/constants/CompositeFieldTypeSubFieldsNames.ts b/packages/twenty-shared/src/constants/CompositeFieldTypeSubFieldsNames.ts new file mode 100644 index 0000000000..07919c6297 --- /dev/null +++ b/packages/twenty-shared/src/constants/CompositeFieldTypeSubFieldsNames.ts @@ -0,0 +1,49 @@ +import { FieldMetadataType } from '@/types'; + +export const COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES = { + [FieldMetadataType.CURRENCY]: { + 'amountMicros': 'amountMicros', + 'currencyCode': 'currencyCode', + }, + [FieldMetadataType.EMAILS]: { + 'primaryEmail': 'primaryEmail', + 'additionalEmails': 'additionalEmails', + }, + [FieldMetadataType.LINKS]: { + 'primaryLinkUrl': 'primaryLinkUrl', + 'primaryLinkLabel': 'primaryLinkLabel', + 'secondaryLinks': 'secondaryLinks', + }, + [FieldMetadataType.PHONES]: { + 'primaryPhoneCallingCode': 'primaryPhoneCallingCode', + 'primaryPhoneCountryCode': 'primaryPhoneCountryCode', + 'primaryPhoneNumber': 'primaryPhoneNumber', + 'additionalPhones': 'additionalPhones', + }, + [FieldMetadataType.FULL_NAME]: { + 'firstName': 'firstName', + 'lastName': 'lastName', + }, + [FieldMetadataType.ADDRESS]: { + 'addressStreet1': 'addressStreet1', + 'addressStreet2': 'addressStreet2', + 'addressCity': 'addressCity', + 'addressState': 'addressState', + 'addressCountry': 'addressCountry', + 'addressPostcode': 'addressPostcode', + 'addressLat': 'addressLat', + 'addressLng': 'addressLng', + }, + [FieldMetadataType.ACTOR]: { + 'source': 'source', + 'name': 'name', + 'workspaceMemberId': 'workspaceMemberId', + 'context': 'context', + }, + [FieldMetadataType.RICH_TEXT_V2]: { + 'blocknote': 'blocknote', + 'markdown': 'markdown', + }, +} as const; + + diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/constants/RatingValues.ts b/packages/twenty-shared/src/constants/RatingValues.ts similarity index 100% rename from packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/constants/RatingValues.ts rename to packages/twenty-shared/src/constants/RatingValues.ts diff --git a/packages/twenty-shared/src/constants/index.ts b/packages/twenty-shared/src/constants/index.ts index 1afe9335c8..6fd8c5162f 100644 --- a/packages/twenty-shared/src/constants/index.ts +++ b/packages/twenty-shared/src/constants/index.ts @@ -7,6 +7,7 @@ * |___/ */ +export { COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES } from './CompositeFieldTypeSubFieldsNames'; export { FIELD_FOR_TOTAL_COUNT_AGGREGATE_OPERATION } from './FieldForTotalCountAggregateOperation'; export { MAX_OPTIONS_TO_DISPLAY } from './FieldMetadataMaxOptionsToDisplay'; export { FIELD_RESTRICTED_ADDITIONAL_PERMISSIONS_REQUIRED } from './FieldRestrictedAdditionalPermissionsRequired'; @@ -16,6 +17,7 @@ export { PermissionsOnAllObjectRecords } from './PermissionsOnAllObjectRecords'; export { QUERY_DEFAULT_LIMIT_RECORDS } from './QueryDefaultLimitRecords'; export { QUERY_MAX_RECORDS } from './QueryMaxRecords'; export { QUOTED_STRING_REGEX } from './QuotedStringRegex'; +export { RATING_VALUES } from './RatingValues'; export { RELATION_NESTED_QUERY_KEYWORDS } from './RelationNestedQueriesKeyword'; export { STANDARD_OBJECT_RECORDS_UNDER_OBJECT_RECORDS_PERMISSIONS } from './StandardObjectRecordsUnderObjectRecordsPermissions'; export { TWENTY_COMPANIES_BASE_URL } from './TwentyCompaniesBaseUrl'; diff --git a/packages/twenty-shared/src/types/CompositeFieldSubFieldNameType.ts b/packages/twenty-shared/src/types/CompositeFieldSubFieldNameType.ts new file mode 100644 index 0000000000..5c14bb4800 --- /dev/null +++ b/packages/twenty-shared/src/types/CompositeFieldSubFieldNameType.ts @@ -0,0 +1,6 @@ +import { COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES } from '@/constants/CompositeFieldTypeSubFieldsNames'; + +const _allSubFieldValues = Object.values(COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES) + .flatMap(obj => Object.values(obj)); + +export type CompositeFieldSubFieldName = typeof _allSubFieldValues[number]; \ No newline at end of file diff --git a/packages/twenty-shared/src/types/FieldRatingValue.ts b/packages/twenty-shared/src/types/FieldRatingValue.ts new file mode 100644 index 0000000000..504bac09e6 --- /dev/null +++ b/packages/twenty-shared/src/types/FieldRatingValue.ts @@ -0,0 +1,3 @@ +import { type RATING_VALUES } from "@/constants/RatingValues"; + +export type FieldRatingValue = (typeof RATING_VALUES)[number] | null; \ No newline at end of file diff --git a/packages/twenty-front/src/modules/object-record/record-filter/types/FilterableFieldType.ts b/packages/twenty-shared/src/types/FilterableFieldType.ts similarity index 79% rename from packages/twenty-front/src/modules/object-record/record-filter/types/FilterableFieldType.ts rename to packages/twenty-shared/src/types/FilterableFieldType.ts index 9bef02876d..26e5740e01 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/types/FilterableFieldType.ts +++ b/packages/twenty-shared/src/types/FilterableFieldType.ts @@ -1,5 +1,6 @@ -import { type FieldType } from '@/settings/data-model/types/FieldType'; -import { type PickLiteral } from '~/types/PickLiteral'; +import { type FieldMetadataType } from '@/types/FieldMetadataType'; + +type PickLiteral = U; export const FILTERABLE_FIELD_TYPES = [ 'TEXT', @@ -26,7 +27,7 @@ export const FILTERABLE_FIELD_TYPES = [ type FilterableFieldTypeBaseLiteral = (typeof FILTERABLE_FIELD_TYPES)[number]; export type FilterableFieldType = PickLiteral< - FieldType, + `${FieldMetadataType}`, FilterableFieldTypeBaseLiteral >; diff --git a/packages/twenty-shared/src/types/PartialFieldMetadataItem.ts b/packages/twenty-shared/src/types/PartialFieldMetadataItem.ts new file mode 100644 index 0000000000..f4b1a77465 --- /dev/null +++ b/packages/twenty-shared/src/types/PartialFieldMetadataItem.ts @@ -0,0 +1,8 @@ +import { type FieldMetadataType } from "@/types/FieldMetadataType"; + +export type PartialFieldMetadataItem = { + id: string; + name: string; + type: FieldMetadataType; + label: string; + } \ No newline at end of file diff --git a/packages/twenty-front/src/modules/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator.ts b/packages/twenty-shared/src/types/RecordFilterGroupLogicalOperator.ts similarity index 100% rename from packages/twenty-front/src/modules/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator.ts rename to packages/twenty-shared/src/types/RecordFilterGroupLogicalOperator.ts diff --git a/packages/twenty-front/src/modules/object-record/record-filter/types/RecordFilterValueDependencies.ts b/packages/twenty-shared/src/types/RecordFilterValueDependencies.ts similarity index 100% rename from packages/twenty-front/src/modules/object-record/record-filter/types/RecordFilterValueDependencies.ts rename to packages/twenty-shared/src/types/RecordFilterValueDependencies.ts diff --git a/packages/twenty-front/src/modules/object-record/graphql/types/RecordGqlOperationFilter.ts b/packages/twenty-shared/src/types/RecordGqlOperationFilter.ts similarity index 100% rename from packages/twenty-front/src/modules/object-record/graphql/types/RecordGqlOperationFilter.ts rename to packages/twenty-shared/src/types/RecordGqlOperationFilter.ts diff --git a/packages/twenty-shared/src/types/index.ts b/packages/twenty-shared/src/types/index.ts index 27303feaee..5621145246 100644 --- a/packages/twenty-shared/src/types/index.ts +++ b/packages/twenty-shared/src/types/index.ts @@ -11,11 +11,18 @@ export type { AllowedAddressSubField } from './AddressFieldsType'; export { ALLOWED_ADDRESS_SUBFIELDS } from './AddressFieldsType'; export { AppBasePath } from './AppBasePath'; export { AppPath } from './AppPath'; +export type { CompositeFieldSubFieldName } from './CompositeFieldSubFieldNameType'; export type { ConfigVariableValue } from './ConfigVariableValue'; export { ConnectedAccountProvider } from './ConnectedAccountProvider'; export type { EnumFieldMetadataType } from './EnumFieldMetadataType'; export type { ExcludeFunctions } from './ExcludeFunctions'; export { FieldMetadataType } from './FieldMetadataType'; +export type { FieldRatingValue } from './FieldRatingValue'; +export type { + FilterableFieldType, + FilterableAndTSVectorFieldType, +} from './FilterableFieldType'; +export { FILTERABLE_FIELD_TYPES } from './FilterableFieldType'; export type { FromTo } from './FromToType'; export type { IsExactly } from './IsExactly'; export type { NonNullableRequired } from './NonNullableRequired'; @@ -27,6 +34,41 @@ export type { ObjectsPermissions } from './ObjectsPermissions'; export type { ObjectsPermissionsByRoleId } from './ObjectsPermissionsByRoleId'; export type { ObjectsPermissionsByRoleIdDeprecated } from './ObjectsPermissionsByRoleIdDeprecated'; export type { ObjectsPermissionsDeprecated } from './ObjectsPermissionsDeprecated'; +export type { PartialFieldMetadataItem } from './PartialFieldMetadataItem'; +export { RecordFilterGroupLogicalOperator } from './RecordFilterGroupLogicalOperator'; +export type { RecordFilterValueDependencies } from './RecordFilterValueDependencies'; +export type { + UUIDFilterValue, + IsFilter, + UUIDFilter, + RelationFilter, + BooleanFilter, + StringFilter, + RatingFilter, + FloatFilter, + DateFilter, + CurrencyFilter, + URLFilter, + FullNameFilter, + AddressFilter, + LinksFilter, + ActorFilter, + EmailsFilter, + PhonesFilter, + SelectFilter, + MultiSelectFilter, + ArrayFilter, + RawJsonFilter, + RichTextV2LeafFilter, + RichTextV2Filter, + TSVectorFilter, + LeafFilter, + AndObjectRecordFilter, + OrObjectRecordFilter, + NotObjectRecordFilter, + LeafObjectRecordFilter, + RecordGqlOperationFilter, +} from './RecordGqlOperationFilter'; export type { RelationAndMorphRelationFieldMetadataType } from './RelationAndMorphRelationFieldMetadataType'; export type { RelationCreationPayload } from './RelationCreationPayload'; export { RelationType } from './RelationType'; diff --git a/packages/twenty-front/src/modules/error-handler/CustomError.ts b/packages/twenty-shared/src/utils/errors/CustomError.ts similarity index 100% rename from packages/twenty-front/src/modules/error-handler/CustomError.ts rename to packages/twenty-shared/src/utils/errors/CustomError.ts diff --git a/packages/twenty-shared/src/utils/errors/index.ts b/packages/twenty-shared/src/utils/errors/index.ts new file mode 100644 index 0000000000..4aef179e5a --- /dev/null +++ b/packages/twenty-shared/src/utils/errors/index.ts @@ -0,0 +1 @@ +export { CustomError } from './CustomError'; diff --git a/packages/twenty-shared/src/utils/filter/checkIfShouldComputeEmptinessFilter.ts b/packages/twenty-shared/src/utils/filter/checkIfShouldComputeEmptinessFilter.ts new file mode 100644 index 0000000000..c20a20ec58 --- /dev/null +++ b/packages/twenty-shared/src/utils/filter/checkIfShouldComputeEmptinessFilter.ts @@ -0,0 +1,29 @@ +import { type FieldMetadataType, type FilterableAndTSVectorFieldType, type ViewFilterOperand } from '@/types'; +import { isEmptinessOperand } from '@/utils/filter/isEmptinessOperand'; +import { getFilterTypeFromFieldType } from '@/utils/filter/utils/getFilterTypeFromFieldType'; + +export const checkIfShouldComputeEmptinessFilter = ({ + recordFilterOperand, + correspondingFieldMetadataItem, +}: { + recordFilterOperand: ViewFilterOperand; + correspondingFieldMetadataItem: {type: FieldMetadataType}; +}) => { + const isAnEmptinessOperand = isEmptinessOperand(recordFilterOperand); + + if (!isAnEmptinessOperand) { + return false; + } + + const filterTypesThatHaveNoEmptinessOperand: FilterableAndTSVectorFieldType[] = + ['BOOLEAN', 'TS_VECTOR']; + + const filterType = getFilterTypeFromFieldType( + correspondingFieldMetadataItem.type, + ); + + const filterHasEmptinessOperands = + !filterTypesThatHaveNoEmptinessOperand.includes(filterType); + + return filterHasEmptinessOperands === true; +}; diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/checkIfShouldSkipFiltering.ts b/packages/twenty-shared/src/utils/filter/checkIfShouldSkipFiltering.ts similarity index 60% rename from packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/checkIfShouldSkipFiltering.ts rename to packages/twenty-shared/src/utils/filter/checkIfShouldSkipFiltering.ts index 47676852ad..b4665beecd 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/checkIfShouldSkipFiltering.ts +++ b/packages/twenty-shared/src/utils/filter/checkIfShouldSkipFiltering.ts @@ -1,13 +1,14 @@ -import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; -import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand'; -import { isEmptinessOperand } from '@/object-record/record-filter/utils/isEmptinessOperand'; -import { isDefined } from 'twenty-shared/utils'; +import { ViewFilterOperand as RecordFilterOperand } from '@/types'; +import { isDefined } from '@/utils'; +import { isEmptinessOperand, type RecordFilter } from '@/utils/filter'; + +type CheckIfShouldSkipFilteringParams = { + recordFilter: Pick; +}; export const checkIfShouldSkipFiltering = ({ recordFilter, -}: { - recordFilter: RecordFilter; -}) => { +}: CheckIfShouldSkipFilteringParams) => { const isAnEmptinessOperand = isEmptinessOperand(recordFilter.operand); const isDateOperandWithoutValue = [ diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForEmails.ts b/packages/twenty-shared/src/utils/filter/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForEmails.ts similarity index 88% rename from packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForEmails.ts rename to packages/twenty-shared/src/utils/filter/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForEmails.ts index 1e9cbe9551..6ffcf9f203 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForEmails.ts +++ b/packages/twenty-shared/src/utils/filter/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForEmails.ts @@ -1,13 +1,13 @@ -import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { + type CompositeFieldSubFieldName, type EmailsFilter, + type PartialFieldMetadataItem, + ViewFilterOperand as RecordFilterOperand, type RecordGqlOperationFilter, -} from '@/object-record/graphql/types/RecordGqlOperationFilter'; +} from '@/types'; +import { CustomError } from '@/utils/errors'; -import { CustomError } from '@/error-handler/CustomError'; -import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; -import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand'; -import { type CompositeFieldSubFieldName } from '@/settings/data-model/types/CompositeFieldSubFieldName'; +import { type RecordFilter } from '@/utils/filter/turnRecordFilterGroupIntoGqlOperationFilter'; import { isNonEmptyString } from '@sniptt/guards'; export const computeGqlOperationFilterForEmails = ({ @@ -16,7 +16,7 @@ export const computeGqlOperationFilterForEmails = ({ subFieldName, }: { recordFilter: RecordFilter; - correspondingFieldMetadataItem: Pick; + correspondingFieldMetadataItem: Pick; subFieldName: CompositeFieldSubFieldName | null | undefined; }): RecordGqlOperationFilter => { const isSubFieldFilter = isNonEmptyString(subFieldName); diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForLinks.ts b/packages/twenty-shared/src/utils/filter/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForLinks.ts similarity index 87% rename from packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForLinks.ts rename to packages/twenty-shared/src/utils/filter/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForLinks.ts index d9ee9e0e42..5fe3aaa614 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForLinks.ts +++ b/packages/twenty-shared/src/utils/filter/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForLinks.ts @@ -1,9 +1,6 @@ -import { CustomError } from '@/error-handler/CustomError'; -import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; -import { type LinksFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; -import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; -import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand'; -import { type CompositeFieldSubFieldName } from '@/settings/data-model/types/CompositeFieldSubFieldName'; +import { ViewFilterOperand as RecordFilterOperand, type CompositeFieldSubFieldName, type LinksFilter, type PartialFieldMetadataItem } from '@/types'; +import { CustomError } from '@/utils/errors'; +import { type RecordFilter } from '@/utils/filter/turnRecordFilterGroupIntoGqlOperationFilter'; import { isNonEmptyString } from '@sniptt/guards'; export const computeGqlOperationFilterForLinks = ({ @@ -12,7 +9,7 @@ export const computeGqlOperationFilterForLinks = ({ subFieldName, }: { recordFilter: RecordFilter; - correspondingFieldMetadataItem: Pick; + correspondingFieldMetadataItem: Pick subFieldName: CompositeFieldSubFieldName | null | undefined; }) => { const isSubFieldFilter = isNonEmptyString(subFieldName); @@ -41,8 +38,9 @@ export const computeGqlOperationFilterForLinks = ({ }, }; default: - throw new Error( + throw new CustomError( `Unknown operand ${recordFilter.operand} for ${correspondingFieldMetadataItem.type} filter`, + 'UNKNOWN_OPERAND_FOR_FILTER', ); } } @@ -84,9 +82,9 @@ export const computeGqlOperationFilterForLinks = ({ } } default: { - throw new CustomError( + throw new Error( // TODO `Unknown subfield name ${subFieldName}`, - 'UNKNOWN_SUBFIELD_NAME', + // 'UNKNOWN_SUBFIELD_NAME', ); } } diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/compute-empty-record-gql-operation-filter/for-composite-field/computeEmptyGqlOperationFilterForEmails.ts b/packages/twenty-shared/src/utils/filter/computeEmptyGqlOperationFilterForEmails.ts similarity index 84% rename from packages/twenty-front/src/modules/object-record/record-filter/utils/compute-empty-record-gql-operation-filter/for-composite-field/computeEmptyGqlOperationFilterForEmails.ts rename to packages/twenty-shared/src/utils/filter/computeEmptyGqlOperationFilterForEmails.ts index 4051a4914d..c676370bda 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/compute-empty-record-gql-operation-filter/for-composite-field/computeEmptyGqlOperationFilterForEmails.ts +++ b/packages/twenty-shared/src/utils/filter/computeEmptyGqlOperationFilterForEmails.ts @@ -1,11 +1,11 @@ -import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { type EmailsFilter, + type PartialFieldMetadataItem, type RecordGqlOperationFilter, -} from '@/object-record/graphql/types/RecordGqlOperationFilter'; +} from '@/types'; +import { CustomError } from '@/utils/errors'; -import { CustomError } from '@/error-handler/CustomError'; -import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; +import { type RecordFilter } from '@/utils/filter/turnRecordFilterGroupIntoGqlOperationFilter'; import { isNonEmptyString } from '@sniptt/guards'; export const computeEmptyGqlOperationFilterForEmails = ({ @@ -13,7 +13,7 @@ export const computeEmptyGqlOperationFilterForEmails = ({ correspondingFieldMetadataItem, }: { recordFilter: RecordFilter; - correspondingFieldMetadataItem: Pick; + correspondingFieldMetadataItem: Pick; }): RecordGqlOperationFilter => { const subFieldName = recordFilter.subFieldName; const isSubFieldFilter = isNonEmptyString(subFieldName); @@ -53,7 +53,7 @@ export const computeEmptyGqlOperationFilterForEmails = ({ }; } default: { - throw new CustomError( + throw new CustomError( `Unknown subfield name ${subFieldName}`, 'UNKNOWN_SUBFIELD_NAME', ); diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/compute-empty-record-gql-operation-filter/for-composite-field/computeEmptyGqlOperationFilterForLinks.ts b/packages/twenty-shared/src/utils/filter/computeEmptyGqlOperationFilterForLinks.ts similarity index 88% rename from packages/twenty-front/src/modules/object-record/record-filter/utils/compute-empty-record-gql-operation-filter/for-composite-field/computeEmptyGqlOperationFilterForLinks.ts rename to packages/twenty-shared/src/utils/filter/computeEmptyGqlOperationFilterForLinks.ts index d0f712b4cd..ef78023fcf 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/compute-empty-record-gql-operation-filter/for-composite-field/computeEmptyGqlOperationFilterForLinks.ts +++ b/packages/twenty-shared/src/utils/filter/computeEmptyGqlOperationFilterForLinks.ts @@ -1,11 +1,11 @@ -import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { type LinksFilter, + type PartialFieldMetadataItem, type RecordGqlOperationFilter, -} from '@/object-record/graphql/types/RecordGqlOperationFilter'; +} from '@/types'; +import { CustomError } from '@/utils/errors'; -import { CustomError } from '@/error-handler/CustomError'; -import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; +import { type RecordFilter } from '@/utils/filter/turnRecordFilterGroupIntoGqlOperationFilter'; import { isNonEmptyString } from '@sniptt/guards'; export const computeEmptyGqlOperationFilterForLinks = ({ @@ -13,7 +13,7 @@ export const computeEmptyGqlOperationFilterForLinks = ({ correspondingFieldMetadataItem, }: { recordFilter: RecordFilter; - correspondingFieldMetadataItem: Pick; + correspondingFieldMetadataItem: Pick; }): RecordGqlOperationFilter => { const subFieldName = recordFilter.subFieldName; const isSubFieldFilter = isNonEmptyString(subFieldName); @@ -69,7 +69,7 @@ export const computeEmptyGqlOperationFilterForLinks = ({ }; } default: { - throw new CustomError( + throw new CustomError( `Unknown subfield name ${subFieldName}`, 'UNKNOWN_SUBFIELD_NAME', ); diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/computeRecordGqlOperationFilter.ts b/packages/twenty-shared/src/utils/filter/computeRecordGqlOperationFilter.ts similarity index 53% rename from packages/twenty-front/src/modules/object-record/record-filter/utils/computeRecordGqlOperationFilter.ts rename to packages/twenty-shared/src/utils/filter/computeRecordGqlOperationFilter.ts index ab920cc770..6fad5201c8 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/computeRecordGqlOperationFilter.ts +++ b/packages/twenty-shared/src/utils/filter/computeRecordGqlOperationFilter.ts @@ -1,35 +1,38 @@ -import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; -import { type Field } from '~/generated/graphql'; -import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; -import { type RecordFilterValueDependencies } from '@/object-record/record-filter/types/RecordFilterValueDependencies'; - -import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; -import { turnRecordFilterGroupsIntoGqlOperationFilter } from '@/object-record/record-filter/utils/compute-record-gql-operation-filter/turnRecordFilterGroupIntoGqlOperationFilter'; -import { turnRecordFilterIntoRecordGqlOperationFilter } from '@/object-record/record-filter/utils/compute-record-gql-operation-filter/turnRecordFilterIntoGqlOperationFilter'; -import { isDefined } from 'twenty-shared/utils'; +import { + type PartialFieldMetadataItem, + type RecordFilterValueDependencies, + type RecordGqlOperationFilter, +} from '@/types'; +import { + isDefined, + turnRecordFilterGroupsIntoGqlOperationFilter, + turnRecordFilterIntoRecordGqlOperationFilter, + type RecordFilter, + type RecordFilterGroup, +} from '@/utils'; export const computeRecordGqlOperationFilter = ({ fields, - filterValueDependencies, recordFilters, recordFilterGroups, + filterValueDependencies, }: { - filterValueDependencies: RecordFilterValueDependencies; recordFilters: RecordFilter[]; - fields: Pick[]; + fields: PartialFieldMetadataItem[]; recordFilterGroups: RecordFilterGroup[]; + filterValueDependencies: RecordFilterValueDependencies; }): RecordGqlOperationFilter => { const regularRecordGqlOperationFilter: RecordGqlOperationFilter[] = recordFilters .filter((filter) => !isDefined(filter.recordFilterGroupId)) - .map((regularFilter) => - turnRecordFilterIntoRecordGqlOperationFilter({ - filterValueDependencies, + .map((regularFilter) => { + return turnRecordFilterIntoRecordGqlOperationFilter({ recordFilter: regularFilter, fieldMetadataItems: fields, - }), - ) + filterValueDependencies, + }); + }) .filter(isDefined); const outermostFilterGroupId = recordFilterGroups.find( @@ -37,12 +40,13 @@ export const computeRecordGqlOperationFilter = ({ )?.id; const advancedRecordGqlOperationFilter = - turnRecordFilterGroupsIntoGqlOperationFilter( + turnRecordFilterGroupsIntoGqlOperationFilter({ filterValueDependencies, - recordFilters, + filters: recordFilters, fields, recordFilterGroups, - outermostFilterGroupId, + currentRecordFilterGroupId: outermostFilterGroupId, + } ); const recordGqlOperationFilters = [ diff --git a/packages/twenty-shared/src/utils/filter/index.ts b/packages/twenty-shared/src/utils/filter/index.ts new file mode 100644 index 0000000000..d8b3917394 --- /dev/null +++ b/packages/twenty-shared/src/utils/filter/index.ts @@ -0,0 +1,22 @@ +export * from './checkIfShouldComputeEmptinessFilter'; +export * from './checkIfShouldSkipFiltering'; +export * from './compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForEmails'; +export * from './compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForLinks'; +export * from './computeEmptyGqlOperationFilterForEmails'; +export * from './computeEmptyGqlOperationFilterForLinks'; +export * from './computeRecordGqlOperationFilter'; +export * from './isEmptinessOperand'; +export * from './turnRecordFilterGroupIntoGqlOperationFilter'; +export * from './turnRecordFilterIntoGqlOperationFilter'; +export * from './utils/combineFilters'; +export * from './utils/fieldRatingConvertors'; +export * from './utils/generateILikeFiltersForCompositeFields'; +export * from './utils/getEmptyRecordGqlOperationFilter'; +export * from './utils/getFilterTypeFromFieldType'; +export * from './utils/isExpectedSubFieldName'; +export * from './utils/resolveDateViewFilterValue'; +export * from './utils/validation-schemas/arrayOfStringsOrVariablesSchema'; +export * from './utils/validation-schemas/arrayOfUuidsOrVariablesSchema'; +export * from './utils/validation-schemas/jsonRelationFilterValueSchema'; + + diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isEmptinessOperand.ts b/packages/twenty-shared/src/utils/filter/isEmptinessOperand.ts similarity index 65% rename from packages/twenty-front/src/modules/object-record/record-filter/utils/isEmptinessOperand.ts rename to packages/twenty-shared/src/utils/filter/isEmptinessOperand.ts index db1b3b03e1..94528ab8ba 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isEmptinessOperand.ts +++ b/packages/twenty-shared/src/utils/filter/isEmptinessOperand.ts @@ -1,4 +1,4 @@ -import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand'; +import { ViewFilterOperand as RecordFilterOperand } from '@/types'; export const isEmptinessOperand = (operand: RecordFilterOperand): boolean => { return [RecordFilterOperand.IsEmpty, RecordFilterOperand.IsNotEmpty].includes( diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/turnRecordFilterGroupIntoGqlOperationFilter.ts b/packages/twenty-shared/src/utils/filter/turnRecordFilterGroupIntoGqlOperationFilter.ts similarity index 60% rename from packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/turnRecordFilterGroupIntoGqlOperationFilter.ts rename to packages/twenty-shared/src/utils/filter/turnRecordFilterGroupIntoGqlOperationFilter.ts index bc09020e27..7e4f4e20b0 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/turnRecordFilterGroupIntoGqlOperationFilter.ts +++ b/packages/twenty-shared/src/utils/filter/turnRecordFilterGroupIntoGqlOperationFilter.ts @@ -1,21 +1,37 @@ -import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; -import { type Field } from '~/generated/graphql'; +import { type CompositeFieldSubFieldName, type FilterableAndTSVectorFieldType, type PartialFieldMetadataItem, RecordFilterGroupLogicalOperator, type RecordFilterValueDependencies, type RecordGqlOperationFilter, type ViewFilterOperand } from '@/types'; -import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; -import { type RecordFilterValueDependencies } from '@/object-record/record-filter/types/RecordFilterValueDependencies'; +import { isDefined } from '@/utils'; +import { turnRecordFilterIntoRecordGqlOperationFilter } from '@/utils/filter/turnRecordFilterIntoGqlOperationFilter'; -import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; -import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; -import { turnRecordFilterIntoRecordGqlOperationFilter } from '@/object-record/record-filter/utils/compute-record-gql-operation-filter/turnRecordFilterIntoGqlOperationFilter'; -import { isDefined } from 'twenty-shared/utils'; +export type RecordFilter = { + id: string; + fieldMetadataId: string; + value: string; + type: FilterableAndTSVectorFieldType; + recordFilterGroupId?: string | null; + operand: ViewFilterOperand; + subFieldName?: CompositeFieldSubFieldName | null | undefined; +}; -export const turnRecordFilterGroupsIntoGqlOperationFilter = ( +export type RecordFilterGroup = { + id: string; + parentRecordFilterGroupId?: string | null; + logicalOperator: RecordFilterGroupLogicalOperator; +} + +export const turnRecordFilterGroupsIntoGqlOperationFilter = ({ + filterValueDependencies, + filters, + fields, + recordFilterGroups, + currentRecordFilterGroupId, +}: { filterValueDependencies: RecordFilterValueDependencies, filters: RecordFilter[], - fields: Pick[], + fields: PartialFieldMetadataItem[], recordFilterGroups: RecordFilterGroup[], currentRecordFilterGroupId?: string, -): RecordGqlOperationFilter | undefined => { +}): RecordGqlOperationFilter | undefined => { const currentRecordFilterGroup = recordFilterGroups.find( (recordFilterGroup) => recordFilterGroup.id === currentRecordFilterGroupId, ); @@ -29,7 +45,7 @@ export const turnRecordFilterGroupsIntoGqlOperationFilter = ( ); const groupRecordGqlOperationFilters = recordFiltersInGroup - .map((recordFilter) => + .map((recordFilter) => turnRecordFilterIntoRecordGqlOperationFilter({ filterValueDependencies, recordFilter: recordFilter, @@ -45,13 +61,13 @@ export const turnRecordFilterGroupsIntoGqlOperationFilter = ( currentRecordFilterGroupId, ) .map((subRecordFilterGroup) => - turnRecordFilterGroupsIntoGqlOperationFilter( + turnRecordFilterGroupsIntoGqlOperationFilter({ filterValueDependencies, filters, fields, recordFilterGroups, - subRecordFilterGroup.id, - ), + currentRecordFilterGroupId: subRecordFilterGroup.id, + }), ) .filter(isDefined); diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/turnRecordFilterIntoGqlOperationFilter.ts b/packages/twenty-shared/src/utils/filter/turnRecordFilterIntoGqlOperationFilter.ts similarity index 92% rename from packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/turnRecordFilterIntoGqlOperationFilter.ts rename to packages/twenty-shared/src/utils/filter/turnRecordFilterIntoGqlOperationFilter.ts index 009df00c8e..c9ca89aef2 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/compute-record-gql-operation-filter/turnRecordFilterIntoGqlOperationFilter.ts +++ b/packages/twenty-shared/src/utils/filter/turnRecordFilterIntoGqlOperationFilter.ts @@ -1,6 +1,8 @@ import { isNonEmptyString } from '@sniptt/guards'; import { + FieldMetadataType, + ViewFilterOperand as RecordFilterOperand, type ActorFilter, type AddressFilter, type ArrayFilter, @@ -12,52 +14,54 @@ import { type PhonesFilter, type RatingFilter, type RawJsonFilter, + type RecordFilterValueDependencies, type RecordGqlOperationFilter, type RelationFilter, type SelectFilter, type StringFilter, type TSVectorFilter, type UUIDFilter, -} from '@/object-record/graphql/types/RecordGqlOperationFilter'; -import { type Field } from '~/generated/graphql'; -import { generateILikeFiltersForCompositeFields } from '~/utils/array/generateILikeFiltersForCompositeFields'; +} from '@/types'; -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { + computeGqlOperationFilterForEmails, + computeGqlOperationFilterForLinks, convertGreaterThanOrEqualRatingToArrayOfRatingValues, convertLessThanOrEqualRatingToArrayOfRatingValues, convertRatingToRatingValue, -} from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownRatingInput'; -import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; -import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand'; -import { type RecordFilterValueDependencies } from '@/object-record/record-filter/types/RecordFilterValueDependencies'; -import { getEmptyRecordGqlOperationFilter } from '@/object-record/record-filter/utils/getEmptyRecordGqlOperationFilter'; + generateILikeFiltersForCompositeFields, getEmptyRecordGqlOperationFilter, + isExpectedSubFieldName, +} from '@/utils/filter'; -import { resolveDateViewFilterValue } from '@/views/view-filter-value/utils/resolveDateViewFilterValue'; -import { jsonRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema'; +import { resolveDateViewFilterValue } from '@/utils/filter/utils/resolveDateViewFilterValue'; import { endOfDay, roundToNearestMinutes, startOfDay } from 'date-fns'; import { z } from 'zod'; -import { isExpectedSubFieldName } from '@/object-record/object-filter-dropdown/utils/isExpectedSubFieldName'; -import { checkIfShouldComputeEmptinessFilter } from '@/object-record/record-filter/utils/compute-record-gql-operation-filter/checkIfShouldComputeEmptinessFilter'; -import { checkIfShouldSkipFiltering } from '@/object-record/record-filter/utils/compute-record-gql-operation-filter/checkIfShouldSkipFiltering'; -import { computeGqlOperationFilterForEmails } from '@/object-record/record-filter/utils/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForEmails'; -import { computeGqlOperationFilterForLinks } from '@/object-record/record-filter/utils/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForLinks'; -import { arrayOfStringsOrVariablesSchema } from '@/views/view-filter-value/validation-schemas/arrayOfStringsOrVariablesSchema'; -import { arrayOfUuidOrVariableSchema } from '@/views/view-filter-value/validation-schemas/arrayOfUuidsOrVariablesSchema'; -import { FieldMetadataType } from 'twenty-shared/types'; -import { isDefined } from 'twenty-shared/utils'; +import { checkIfShouldComputeEmptinessFilter, checkIfShouldSkipFiltering, CustomError, getFilterTypeFromFieldType, isDefined, type RecordFilter } from '@/utils'; +import { arrayOfStringsOrVariablesSchema } from '@/utils/filter/utils/validation-schemas/arrayOfStringsOrVariablesSchema'; +import { arrayOfUuidOrVariableSchema } from '@/utils/filter/utils/validation-schemas/arrayOfUuidsOrVariablesSchema'; +import { jsonRelationFilterValueSchema } from '@/utils/filter/utils/validation-schemas/jsonRelationFilterValueSchema'; + +type FieldShared = { + id: string; + name: string; + type: FieldMetadataType; + label: string; +} type TurnRecordFilterIntoRecordGqlOperationFilterParams = { - filterValueDependencies: RecordFilterValueDependencies; + filterValueDependencies?: RecordFilterValueDependencies; recordFilter: RecordFilter; - fieldMetadataItems: Pick[]; + fieldMetadataItems: FieldShared[]; + recordIdsForUuid?: string[]; }; + export const turnRecordFilterIntoRecordGqlOperationFilter = ({ - filterValueDependencies, recordFilter, fieldMetadataItems, + recordIdsForUuid, + filterValueDependencies, }: TurnRecordFilterIntoRecordGqlOperationFilterParams): | RecordGqlOperationFilter | undefined => { @@ -76,7 +80,7 @@ export const turnRecordFilterIntoRecordGqlOperationFilter = ({ } const shouldComputeEmptinessFilter = checkIfShouldComputeEmptinessFilter({ - recordFilter, + recordFilterOperand: recordFilter.operand, correspondingFieldMetadataItem, }); @@ -116,8 +120,9 @@ export const turnRecordFilterIntoRecordGqlOperationFilter = ({ }, }; default: - throw new Error( + throw new CustomError( `Unknown operand ${recordFilter.operand} for ${filterType} filter`, + 'UNKNOWN_OPERAND_FOR_FILTER', ); } case 'TS_VECTOR': @@ -328,11 +333,11 @@ export const turnRecordFilterIntoRecordGqlOperationFilter = ({ const recordIds = isCurrentWorkspaceMemberSelected ? [ ...selectedRecordIds, - filterValueDependencies.currentWorkspaceMemberId, + filterValueDependencies?.currentWorkspaceMemberId, ] : selectedRecordIds; - if (recordIds.length === 0) return; + if (!isDefined (recordIds) || recordIds.length === 0) return; switch (recordFilter.operand) { case RecordFilterOperand.Is: @@ -342,7 +347,7 @@ export const turnRecordFilterIntoRecordGqlOperationFilter = ({ } as RelationFilter, }; case RecordFilterOperand.IsNot: { - if (recordIds.length === 0) return; + if (!isDefined (recordIds) || recordIds.length === 0) return; return { or: [ { @@ -942,10 +947,15 @@ export const turnRecordFilterIntoRecordGqlOperationFilter = ({ }, }; } - default: - throw new Error( - `Unknown operand ${recordFilter.operand} for ${recordFilter.label} filter`, + default: { + const fieldForRecordFilter = fieldMetadataItems.find( + (field) => field.id === recordFilter.fieldMetadataId, ); + + throw new Error( + `Unknown operand ${recordFilter.operand} for ${fieldForRecordFilter?.label ?? ''} filter`, + ); + } } } @@ -976,10 +986,15 @@ export const turnRecordFilterIntoRecordGqlOperationFilter = ({ }, ], }; - default: - throw new Error( - `Unknown operand ${recordFilter.operand} for ${recordFilter.label} filter`, + default: { + const fieldForRecordFilter = fieldMetadataItems.find( + (field) => field.id === recordFilter.fieldMetadataId, ); + + throw new Error( + `Unknown operand ${recordFilter.operand} for ${fieldForRecordFilter?.label ?? ''} filter`, + ); + } } } case 'EMAILS': { @@ -1184,9 +1199,9 @@ export const turnRecordFilterIntoRecordGqlOperationFilter = ({ }; } case 'UUID': { - const recordIds = arrayOfUuidOrVariableSchema.parse(recordFilter.value); + const recordIds = recordIdsForUuid; - if (recordIds.length === 0) return; + if (!isDefined (recordIds) || recordIds.length === 0) return; switch (recordFilter.operand) { case RecordFilterOperand.Is: diff --git a/packages/twenty-front/src/modules/views/view-filter-value/validation-schemas/__tests__/arrayOfStringsOrVariablesSchema.test.ts b/packages/twenty-shared/src/utils/filter/utils/__tests__/arrayOfStringsOrVariablesSchema.test.ts similarity index 95% rename from packages/twenty-front/src/modules/views/view-filter-value/validation-schemas/__tests__/arrayOfStringsOrVariablesSchema.test.ts rename to packages/twenty-shared/src/utils/filter/utils/__tests__/arrayOfStringsOrVariablesSchema.test.ts index c37a2e9093..a7af5ac248 100644 --- a/packages/twenty-front/src/modules/views/view-filter-value/validation-schemas/__tests__/arrayOfStringsOrVariablesSchema.test.ts +++ b/packages/twenty-shared/src/utils/filter/utils/__tests__/arrayOfStringsOrVariablesSchema.test.ts @@ -1,4 +1,4 @@ -import { arrayOfStringsOrVariablesSchema } from '../arrayOfStringsOrVariablesSchema'; +import { arrayOfStringsOrVariablesSchema } from "@/utils/filter/utils/validation-schemas/arrayOfStringsOrVariablesSchema"; describe('arrayOfStringsOrVariablesSchema', () => { describe('Empty value handling', () => { diff --git a/packages/twenty-front/src/modules/views/view-filter-value/validation-schemas/__tests__/arrayOfUuidOrVariableSchema.test.ts b/packages/twenty-shared/src/utils/filter/utils/__tests__/arrayOfUuidOrVariableSchema.test.ts similarity index 98% rename from packages/twenty-front/src/modules/views/view-filter-value/validation-schemas/__tests__/arrayOfUuidOrVariableSchema.test.ts rename to packages/twenty-shared/src/utils/filter/utils/__tests__/arrayOfUuidOrVariableSchema.test.ts index f635b5edf5..04668ee53e 100644 --- a/packages/twenty-front/src/modules/views/view-filter-value/validation-schemas/__tests__/arrayOfUuidOrVariableSchema.test.ts +++ b/packages/twenty-shared/src/utils/filter/utils/__tests__/arrayOfUuidOrVariableSchema.test.ts @@ -1,4 +1,4 @@ -import { arrayOfUuidOrVariableSchema } from '../arrayOfUuidsOrVariablesSchema'; +import { arrayOfUuidOrVariableSchema } from '../validation-schemas/arrayOfUuidsOrVariablesSchema'; describe('arrayOfUuidOrVariableSchema', () => { describe('UUID validation', () => { diff --git a/packages/twenty-front/src/utils/array/__tests__/generateILikeFiltersForCompositeFields.test.ts b/packages/twenty-shared/src/utils/filter/utils/__tests__/generateILikeFiltersForCompositeFields.test.ts similarity index 90% rename from packages/twenty-front/src/utils/array/__tests__/generateILikeFiltersForCompositeFields.test.ts rename to packages/twenty-shared/src/utils/filter/utils/__tests__/generateILikeFiltersForCompositeFields.test.ts index d4b37f60dc..e4ae7a3441 100644 --- a/packages/twenty-front/src/utils/array/__tests__/generateILikeFiltersForCompositeFields.test.ts +++ b/packages/twenty-shared/src/utils/filter/utils/__tests__/generateILikeFiltersForCompositeFields.test.ts @@ -1,4 +1,4 @@ -import { generateILikeFiltersForCompositeFields } from '~/utils/array/generateILikeFiltersForCompositeFields'; +import { generateILikeFiltersForCompositeFields } from "@/utils/filter/utils/generateILikeFiltersForCompositeFields"; describe('generateILikeFiltersForCompositeFields', () => { it('should format composite filters for simple filter string', () => { diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/combineFilters.ts b/packages/twenty-shared/src/utils/filter/utils/combineFilters.ts similarity index 78% rename from packages/twenty-front/src/modules/object-record/record-filter/utils/combineFilters.ts rename to packages/twenty-shared/src/utils/filter/utils/combineFilters.ts index 569927fc93..1301365fa7 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/combineFilters.ts +++ b/packages/twenty-shared/src/utils/filter/utils/combineFilters.ts @@ -1,4 +1,4 @@ -import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; +import { type RecordGqlOperationFilter } from '@/types'; export const combineFilters = ( filters: RecordGqlOperationFilter[], diff --git a/packages/twenty-shared/src/utils/filter/utils/convertViewFilterValueToString.ts b/packages/twenty-shared/src/utils/filter/utils/convertViewFilterValueToString.ts new file mode 100644 index 0000000000..7719942f3f --- /dev/null +++ b/packages/twenty-shared/src/utils/filter/utils/convertViewFilterValueToString.ts @@ -0,0 +1,5 @@ +export const convertViewFilterValueToString = (value: any) => { + return typeof value === 'string' + ? value + : JSON.stringify(value ?? ''); +}; \ No newline at end of file diff --git a/packages/twenty-shared/src/utils/filter/utils/fieldRatingConvertors.ts b/packages/twenty-shared/src/utils/filter/utils/fieldRatingConvertors.ts new file mode 100644 index 0000000000..7900f81714 --- /dev/null +++ b/packages/twenty-shared/src/utils/filter/utils/fieldRatingConvertors.ts @@ -0,0 +1,19 @@ +import { RATING_VALUES } from "@/constants"; +import { type FieldRatingValue } from "@/types"; + +export const convertGreaterThanOrEqualRatingToArrayOfRatingValues = ( + greaterThanValue: number, +) => + RATING_VALUES.filter( + (ratingValue) => +ratingValue.split('_')[1] >= greaterThanValue, + ); + +export const convertLessThanOrEqualRatingToArrayOfRatingValues = ( + lessThanValue: number, +) => + RATING_VALUES.filter( + (ratingValue) => +ratingValue.split('_')[1] <= lessThanValue, + ); + +export const convertRatingToRatingValue = (rating: number) => + `RATING_${rating}` as FieldRatingValue; diff --git a/packages/twenty-front/src/utils/array/generateILikeFiltersForCompositeFields.ts b/packages/twenty-shared/src/utils/filter/utils/generateILikeFiltersForCompositeFields.ts similarity index 90% rename from packages/twenty-front/src/utils/array/generateILikeFiltersForCompositeFields.ts rename to packages/twenty-shared/src/utils/filter/utils/generateILikeFiltersForCompositeFields.ts index 606051c5a8..b11e4b806b 100644 --- a/packages/twenty-front/src/utils/array/generateILikeFiltersForCompositeFields.ts +++ b/packages/twenty-shared/src/utils/filter/utils/generateILikeFiltersForCompositeFields.ts @@ -1,4 +1,4 @@ -import { type RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; +import { type RecordGqlOperationFilter } from '@/types'; export const generateILikeFiltersForCompositeFields = ( filterString: string, diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/getEmptyRecordGqlOperationFilter.ts b/packages/twenty-shared/src/utils/filter/utils/getEmptyRecordGqlOperationFilter.ts similarity index 90% rename from packages/twenty-front/src/modules/object-record/record-filter/utils/getEmptyRecordGqlOperationFilter.ts rename to packages/twenty-shared/src/utils/filter/utils/getEmptyRecordGqlOperationFilter.ts index 211a37573a..c7c62d56a5 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/getEmptyRecordGqlOperationFilter.ts +++ b/packages/twenty-shared/src/utils/filter/utils/getEmptyRecordGqlOperationFilter.ts @@ -1,6 +1,5 @@ -import { CustomError } from '@/error-handler/CustomError'; -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { + ViewFilterOperand, type ActorFilter, type AddressFilter, type ArrayFilter, @@ -8,6 +7,7 @@ import { type DateFilter, type FloatFilter, type MultiSelectFilter, + type PartialFieldMetadataItem, type PhonesFilter, type RatingFilter, type RawJsonFilter, @@ -15,18 +15,18 @@ import { type RelationFilter, type SelectFilter, type StringFilter, -} from '@/object-record/graphql/types/RecordGqlOperationFilter'; -import { type 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'; +} from '@/types'; +import { CustomError } from '@/utils/errors'; +import { computeEmptyGqlOperationFilterForEmails } from '@/utils/filter/computeEmptyGqlOperationFilterForEmails'; +import { computeEmptyGqlOperationFilterForLinks } from '@/utils/filter/computeEmptyGqlOperationFilterForLinks'; +import { type RecordFilter } from '@/utils/filter/turnRecordFilterGroupIntoGqlOperationFilter'; +import { generateILikeFiltersForCompositeFields } from '@/utils/filter/utils/generateILikeFiltersForCompositeFields'; +import { getFilterTypeFromFieldType } from '@/utils/filter/utils/getFilterTypeFromFieldType'; import { isNonEmptyString } from '@sniptt/guards'; -import { ViewFilterOperand } from 'twenty-shared/types'; -import { type Field } from '~/generated/graphql'; -import { generateILikeFiltersForCompositeFields } from '~/utils/array/generateILikeFiltersForCompositeFields'; type GetEmptyRecordGqlOperationFilterParams = { operand: ViewFilterOperand; - correspondingField: Pick; + correspondingField: Pick; recordFilter: RecordFilter; }; @@ -385,7 +385,7 @@ export const getEmptyRecordGqlOperationFilter = ({ }); break; default: - throw new CustomError( + throw new CustomError( `Unsupported empty filter type ${filterType}`, 'UNSUPPORTED_EMPTY_FILTER_TYPE', ); @@ -399,7 +399,7 @@ export const getEmptyRecordGqlOperationFilter = ({ not: emptyRecordFilter, }; default: - throw new CustomError( + throw new CustomError( `Unknown operand ${operand} for ${filterType} filter`, 'UNKNOWN_OPERAND_FOR_FILTER', ); diff --git a/packages/twenty-shared/src/utils/filter/utils/getFilterTypeFromFieldType.ts b/packages/twenty-shared/src/utils/filter/utils/getFilterTypeFromFieldType.ts new file mode 100644 index 0000000000..e1d9642c00 --- /dev/null +++ b/packages/twenty-shared/src/utils/filter/utils/getFilterTypeFromFieldType.ts @@ -0,0 +1,49 @@ +import { FieldMetadataType, type FilterableAndTSVectorFieldType } from "@/types"; + + +export const getFilterTypeFromFieldType = ( + fieldType: FieldMetadataType, +): FilterableAndTSVectorFieldType => { + switch (fieldType) { + case FieldMetadataType.DATE_TIME: + return 'DATE_TIME'; + case FieldMetadataType.DATE: + return 'DATE'; + case FieldMetadataType.LINKS: + return 'LINKS'; + case FieldMetadataType.FULL_NAME: + return 'FULL_NAME'; + case FieldMetadataType.NUMBER: + return 'NUMBER'; + case FieldMetadataType.CURRENCY: + return 'CURRENCY'; + case FieldMetadataType.EMAILS: + return 'EMAILS'; + case FieldMetadataType.PHONES: + return 'PHONES'; + case FieldMetadataType.RELATION: + return 'RELATION'; + case FieldMetadataType.SELECT: + return 'SELECT'; + case FieldMetadataType.MULTI_SELECT: + return 'MULTI_SELECT'; + case FieldMetadataType.ADDRESS: + return 'ADDRESS'; + case FieldMetadataType.RATING: + return 'RATING'; + case FieldMetadataType.ACTOR: + return 'ACTOR'; + case FieldMetadataType.ARRAY: + return 'ARRAY'; + case FieldMetadataType.RAW_JSON: + return 'RAW_JSON'; + case FieldMetadataType.BOOLEAN: + return 'BOOLEAN'; + case FieldMetadataType.TS_VECTOR: + return 'TS_VECTOR'; + case FieldMetadataType.UUID: + return 'UUID'; + default: + return 'TEXT'; + } +}; \ No newline at end of file diff --git a/packages/twenty-shared/src/utils/filter/utils/isExpectedSubFieldName.ts b/packages/twenty-shared/src/utils/filter/utils/isExpectedSubFieldName.ts new file mode 100644 index 0000000000..19c741bce4 --- /dev/null +++ b/packages/twenty-shared/src/utils/filter/utils/isExpectedSubFieldName.ts @@ -0,0 +1,24 @@ +import { COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES } from '@/constants/CompositeFieldTypeSubFieldsNames'; +import { type CompositeFieldSubFieldName } from '@/types'; + +type CompositeMap = typeof COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES; + +export const isExpectedSubFieldName = < + FieldMetadataType extends keyof CompositeMap, + PossibleSubFieldName extends CompositeFieldSubFieldName, +>( + fieldMetadataType: FieldMetadataType, + subFieldName: PossibleSubFieldName, + subFieldNameToCheck: string | null | undefined, +): subFieldNameToCheck is PossibleSubFieldName => { + const allowedSubFields = Object.values(COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES[ + fieldMetadataType + ]) as readonly string[]; + + return ( + allowedSubFields.includes(subFieldName as string) && + subFieldName === subFieldNameToCheck + ); +}; + + diff --git a/packages/twenty-front/src/modules/views/view-filter-value/utils/resolveDateViewFilterValue.ts b/packages/twenty-shared/src/utils/filter/utils/resolveDateViewFilterValue.ts similarity index 95% rename from packages/twenty-front/src/modules/views/view-filter-value/utils/resolveDateViewFilterValue.ts rename to packages/twenty-shared/src/utils/filter/utils/resolveDateViewFilterValue.ts index 9633fdb072..f952cbf631 100644 --- a/packages/twenty-front/src/modules/views/view-filter-value/utils/resolveDateViewFilterValue.ts +++ b/packages/twenty-shared/src/utils/filter/utils/resolveDateViewFilterValue.ts @@ -1,4 +1,4 @@ -import { type ViewFilter } from '@/views/types/ViewFilter'; +import { ViewFilterOperand } from '@/types'; import { addDays, addMonths, @@ -18,7 +18,6 @@ import { subWeeks, subYears, } from 'date-fns'; -import { ViewFilterOperand } from 'twenty-shared/types'; import { z } from 'zod'; const variableDateViewFilterValueDirectionSchema = z.enum([ @@ -170,10 +169,7 @@ export type ResolvedDateViewFilterValue = ? ReturnType : Date | null; -type PartialViewFilter = Pick< - ViewFilter, - 'value' -> & { operand: O }; +type PartialViewFilter = {value: string, operand: O} // TODO, was done to avoid ViewFilter export export const resolveDateViewFilterValue = ( viewFilter: PartialViewFilter, diff --git a/packages/twenty-front/src/modules/views/view-filter-value/validation-schemas/arrayOfStringsOrVariablesSchema.ts b/packages/twenty-shared/src/utils/filter/utils/validation-schemas/arrayOfStringsOrVariablesSchema.ts similarity index 88% rename from packages/twenty-front/src/modules/views/view-filter-value/validation-schemas/arrayOfStringsOrVariablesSchema.ts rename to packages/twenty-shared/src/utils/filter/utils/validation-schemas/arrayOfStringsOrVariablesSchema.ts index d17ea019ba..17690b4476 100644 --- a/packages/twenty-front/src/modules/views/view-filter-value/validation-schemas/arrayOfStringsOrVariablesSchema.ts +++ b/packages/twenty-shared/src/utils/filter/utils/validation-schemas/arrayOfStringsOrVariablesSchema.ts @@ -1,4 +1,4 @@ -import { isValidVariable } from 'twenty-shared/utils'; +import { isValidVariable } from '@/utils'; import { z } from 'zod'; export const arrayOfStringsOrVariablesSchema = z diff --git a/packages/twenty-front/src/modules/views/view-filter-value/validation-schemas/arrayOfUuidsOrVariablesSchema.ts b/packages/twenty-shared/src/utils/filter/utils/validation-schemas/arrayOfUuidsOrVariablesSchema.ts similarity index 91% rename from packages/twenty-front/src/modules/views/view-filter-value/validation-schemas/arrayOfUuidsOrVariablesSchema.ts rename to packages/twenty-shared/src/utils/filter/utils/validation-schemas/arrayOfUuidsOrVariablesSchema.ts index 64b573f19c..16c6128d42 100644 --- a/packages/twenty-front/src/modules/views/view-filter-value/validation-schemas/arrayOfUuidsOrVariablesSchema.ts +++ b/packages/twenty-shared/src/utils/filter/utils/validation-schemas/arrayOfUuidsOrVariablesSchema.ts @@ -1,4 +1,4 @@ -import { isValidUuid, isValidVariable } from 'twenty-shared/utils'; +import { isValidUuid, isValidVariable } from '@/utils'; import { z } from 'zod'; export const arrayOfUuidOrVariableSchema = z diff --git a/packages/twenty-front/src/modules/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema.ts b/packages/twenty-shared/src/utils/filter/utils/validation-schemas/jsonRelationFilterValueSchema.ts similarity index 100% rename from packages/twenty-front/src/modules/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema.ts rename to packages/twenty-shared/src/utils/filter/utils/validation-schemas/jsonRelationFilterValueSchema.ts diff --git a/packages/twenty-shared/src/utils/index.ts b/packages/twenty-shared/src/utils/index.ts index d8651c8a72..27f97d77b6 100644 --- a/packages/twenty-shared/src/utils/index.ts +++ b/packages/twenty-shared/src/utils/index.ts @@ -16,8 +16,50 @@ export { sumByProperty } from './array/sumByProperty'; export { assertUnreachable } from './assertUnreachable'; export { computeDiffBetweenObjects } from './compute-diff-between-objects'; export { deepMerge } from './deepMerge'; +export { CustomError } from './errors/CustomError'; export { extractAndSanitizeObjectStringFields } from './extractAndSanitizeObjectStringFields'; export { isFieldMetadataDateKind } from './fieldMetadata/isFieldMetadataDateKind'; +export { checkIfShouldComputeEmptinessFilter } from './filter/checkIfShouldComputeEmptinessFilter'; +export { checkIfShouldSkipFiltering } from './filter/checkIfShouldSkipFiltering'; +export { computeGqlOperationFilterForEmails } from './filter/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForEmails'; +export { computeGqlOperationFilterForLinks } from './filter/compute-record-gql-operation-filter/for-composite-field/computeGqlOperationFilterForLinks'; +export { computeEmptyGqlOperationFilterForEmails } from './filter/computeEmptyGqlOperationFilterForEmails'; +export { computeEmptyGqlOperationFilterForLinks } from './filter/computeEmptyGqlOperationFilterForLinks'; +export { computeRecordGqlOperationFilter } from './filter/computeRecordGqlOperationFilter'; +export { isEmptinessOperand } from './filter/isEmptinessOperand'; +export type { + RecordFilter, + RecordFilterGroup, +} from './filter/turnRecordFilterGroupIntoGqlOperationFilter'; +export { turnRecordFilterGroupsIntoGqlOperationFilter } from './filter/turnRecordFilterGroupIntoGqlOperationFilter'; +export { turnRecordFilterIntoRecordGqlOperationFilter } from './filter/turnRecordFilterIntoGqlOperationFilter'; +export { combineFilters } from './filter/utils/combineFilters'; +export { convertViewFilterValueToString } from './filter/utils/convertViewFilterValueToString'; +export { + convertGreaterThanOrEqualRatingToArrayOfRatingValues, + convertLessThanOrEqualRatingToArrayOfRatingValues, + convertRatingToRatingValue, +} from './filter/utils/fieldRatingConvertors'; +export { generateILikeFiltersForCompositeFields } from './filter/utils/generateILikeFiltersForCompositeFields'; +export { getEmptyRecordGqlOperationFilter } from './filter/utils/getEmptyRecordGqlOperationFilter'; +export { getFilterTypeFromFieldType } from './filter/utils/getFilterTypeFromFieldType'; +export { isExpectedSubFieldName } from './filter/utils/isExpectedSubFieldName'; +export type { + VariableDateViewFilterValueDirection, + VariableDateViewFilterValueUnit, + ResolvedDateViewFilterValue, +} from './filter/utils/resolveDateViewFilterValue'; +export { + variableDateViewFilterValueUnitSchema, + variableDateViewFilterValuePartsSchema, + resolveDateViewFilterValue, +} from './filter/utils/resolveDateViewFilterValue'; +export { arrayOfStringsOrVariablesSchema } from './filter/utils/validation-schemas/arrayOfStringsOrVariablesSchema'; +export { arrayOfUuidOrVariableSchema } from './filter/utils/validation-schemas/arrayOfUuidsOrVariablesSchema'; +export { + relationFilterValueSchemaObject, + jsonRelationFilterValueSchema, +} from './filter/utils/validation-schemas/jsonRelationFilterValueSchema'; export { fromArrayToUniqueKeyRecord } from './from-array-to-unique-key-record.util'; export { fromArrayToValuesByKeyRecord } from './fromArrayToValuesByKeyRecord.util'; export { getURLSafely } from './getURLSafely';