fix(filters): unify combinedFilter for queries and bulk delete (#13952)
Issue: https://github.com/twentyhq/twenty/issues/13913 Motivation/Problem: Bulk delete and query paths were composing filters differently, causing mismatches. In some cases this led to invalid or empty GraphQL filters (e.g. {"and":[{}]}), breaking delete operations. Fix: Unify filter composition (combinedFilter) across queries and bulk delete, ensuring consistent handling of base filters + soft-deleted clause. Also adjusted record filter grouping logic to avoid dropping filters when no groups exist. Result: Filtered queries and bulk deletes now behave consistently and reliably without producing broken filters. --------- Co-authored-by: root <root@DESKTOP-E2VOJGE> Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
+8
-2
@@ -1,6 +1,7 @@
|
||||
import { ActionModal } from '@/action-menu/actions/components/ActionModal';
|
||||
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters';
|
||||
@@ -39,19 +40,24 @@ export const DeleteMultipleRecordsAction = () => {
|
||||
contextStoreFiltersComponentState,
|
||||
);
|
||||
|
||||
const contextStoreFilterGroups = useRecoilComponentValue(
|
||||
contextStoreFilterGroupsComponentState,
|
||||
);
|
||||
|
||||
const contextStoreAnyFieldFilterValue = useRecoilComponentValue(
|
||||
contextStoreAnyFieldFilterValueComponentState,
|
||||
);
|
||||
|
||||
const { filterValueDependencies } = useFilterValueDependencies();
|
||||
|
||||
const graphqlFilter = computeContextStoreFilters(
|
||||
const graphqlFilter = computeContextStoreFilters({
|
||||
contextStoreTargetedRecordsRule,
|
||||
contextStoreFilters,
|
||||
contextStoreFilterGroups,
|
||||
objectMetadataItem,
|
||||
filterValueDependencies,
|
||||
contextStoreAnyFieldFilterValue,
|
||||
);
|
||||
});
|
||||
|
||||
const { fetchAllRecords: fetchAllRecordIds } = useLazyFetchAllRecords({
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
|
||||
+8
-2
@@ -1,6 +1,7 @@
|
||||
import { ActionModal } from '@/action-menu/actions/components/ActionModal';
|
||||
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters';
|
||||
@@ -39,6 +40,10 @@ export const DestroyMultipleRecordsAction = () => {
|
||||
contextStoreFiltersComponentState,
|
||||
);
|
||||
|
||||
const contextStoreFilterGroups = useRecoilComponentValue(
|
||||
contextStoreFilterGroupsComponentState,
|
||||
);
|
||||
|
||||
const contextStoreAnyFieldFilterValue = useRecoilComponentValue(
|
||||
contextStoreAnyFieldFilterValueComponentState,
|
||||
);
|
||||
@@ -49,13 +54,14 @@ export const DestroyMultipleRecordsAction = () => {
|
||||
deletedAt: { is: 'NOT_NULL' },
|
||||
};
|
||||
const graphqlFilter = {
|
||||
...computeContextStoreFilters(
|
||||
...computeContextStoreFilters({
|
||||
contextStoreTargetedRecordsRule,
|
||||
contextStoreFilters,
|
||||
contextStoreFilterGroups,
|
||||
objectMetadataItem,
|
||||
filterValueDependencies,
|
||||
contextStoreAnyFieldFilterValue,
|
||||
),
|
||||
}),
|
||||
...deletedAtFilter,
|
||||
};
|
||||
|
||||
|
||||
+8
-2
@@ -1,6 +1,7 @@
|
||||
import { ActionModal } from '@/action-menu/actions/components/ActionModal';
|
||||
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters';
|
||||
@@ -39,6 +40,10 @@ export const RestoreMultipleRecordsAction = () => {
|
||||
contextStoreFiltersComponentState,
|
||||
);
|
||||
|
||||
const contextStoreFilterGroups = useRecoilComponentValue(
|
||||
contextStoreFilterGroupsComponentState,
|
||||
);
|
||||
|
||||
const contextStoreAnyFieldFilterValue = useRecoilComponentValue(
|
||||
contextStoreAnyFieldFilterValueComponentState,
|
||||
);
|
||||
@@ -50,13 +55,14 @@ export const RestoreMultipleRecordsAction = () => {
|
||||
};
|
||||
|
||||
const graphqlFilter = {
|
||||
...computeContextStoreFilters(
|
||||
...computeContextStoreFilters({
|
||||
contextStoreTargetedRecordsRule,
|
||||
contextStoreFilters,
|
||||
contextStoreFilterGroups,
|
||||
objectMetadataItem,
|
||||
filterValueDependencies,
|
||||
contextStoreAnyFieldFilterValue,
|
||||
),
|
||||
}),
|
||||
...deletedAtFilter,
|
||||
};
|
||||
|
||||
|
||||
+8
@@ -17,6 +17,7 @@ import { recordStoreFamilyState } from '@/object-record/record-store/states/reco
|
||||
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
|
||||
import { getPeopleRecordConnectionMock } from '~/testing/mock-data/people';
|
||||
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
|
||||
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
|
||||
|
||||
const mockCopyContextStoreStates = jest.fn();
|
||||
jest.mock(
|
||||
@@ -81,6 +82,12 @@ describe('useSetGlobalCommandMenuContext', () => {
|
||||
}),
|
||||
);
|
||||
|
||||
const filterGroups = useRecoilValue(
|
||||
contextStoreFilterGroupsComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
);
|
||||
|
||||
const anyFieldFilterValue = useRecoilValue(
|
||||
contextStoreAnyFieldFilterValueComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
@@ -104,6 +111,7 @@ describe('useSetGlobalCommandMenuContext', () => {
|
||||
targetedRecordsRule,
|
||||
numberOfSelectedRecords,
|
||||
filters,
|
||||
filterGroups,
|
||||
currentViewType,
|
||||
commandMenuPageInfo,
|
||||
hasUserSelectedCommand,
|
||||
|
||||
+16
@@ -2,6 +2,7 @@ import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/s
|
||||
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
|
||||
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
@@ -77,6 +78,21 @@ export const useCopyContextStoreStates = () => {
|
||||
contextStoreFilters,
|
||||
);
|
||||
|
||||
const contextStoreFilterGroups = snapshot
|
||||
.getLoadable(
|
||||
contextStoreFilterGroupsComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
|
||||
set(
|
||||
contextStoreFilterGroupsComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreFilterGroups,
|
||||
);
|
||||
|
||||
const contextStoreAnyFieldFilterValue = snapshot
|
||||
.getLoadable(
|
||||
contextStoreAnyFieldFilterValueComponentState.atomFamily({
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
|
||||
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
@@ -40,6 +41,13 @@ export const useResetContextStoreStates = () => {
|
||||
[],
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreFilterGroupsComponentState.atomFamily({
|
||||
instanceId,
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreAnyFieldFilterValueComponentState.atomFamily({
|
||||
instanceId,
|
||||
|
||||
@@ -5,6 +5,7 @@ import { commandMenuPageInfoState } from '@/command-menu/states/commandMenuPageI
|
||||
import { hasUserSelectedCommandState } from '@/command-menu/states/hasUserSelectedCommandState';
|
||||
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
|
||||
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
|
||||
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
@@ -46,6 +47,13 @@ export const useSetGlobalCommandMenuContext = () => {
|
||||
[],
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreFilterGroupsComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreAnyFieldFilterValueComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
|
||||
+9
-2
@@ -1,5 +1,6 @@
|
||||
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
|
||||
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
|
||||
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters';
|
||||
@@ -37,6 +38,11 @@ export const useFindManyRecordsSelectedInContextStore = ({
|
||||
instanceId,
|
||||
);
|
||||
|
||||
const contextStoreFilterGroups = useRecoilComponentValue(
|
||||
contextStoreFilterGroupsComponentState,
|
||||
instanceId,
|
||||
);
|
||||
|
||||
const contextStoreAnyFieldFilterValue = useRecoilComponentValue(
|
||||
contextStoreAnyFieldFilterValueComponentState,
|
||||
instanceId,
|
||||
@@ -61,13 +67,14 @@ export const useFindManyRecordsSelectedInContextStore = ({
|
||||
);
|
||||
});
|
||||
|
||||
const queryFilter = computeContextStoreFilters(
|
||||
const queryFilter = computeContextStoreFilters({
|
||||
contextStoreTargetedRecordsRule,
|
||||
contextStoreFilters,
|
||||
contextStoreFilterGroups,
|
||||
objectMetadataItem,
|
||||
filterValueDependencies,
|
||||
contextStoreAnyFieldFilterValue,
|
||||
);
|
||||
});
|
||||
|
||||
const { records, loading, totalCount } = useFindManyRecords({
|
||||
objectNameSingular: objectMetadataItem?.nameSingular ?? '',
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext';
|
||||
import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
|
||||
export const contextStoreFilterGroupsComponentState = createComponentState<
|
||||
RecordFilterGroup[]
|
||||
>({
|
||||
key: 'contextStoreFilterGroupsComponentState',
|
||||
defaultValue: [],
|
||||
componentInstanceContext: ContextStoreComponentInstanceContext,
|
||||
});
|
||||
+13
-11
@@ -20,13 +20,14 @@ describe('computeContextStoreFilters', () => {
|
||||
selectedRecordIds: ['1', '2', '3'],
|
||||
};
|
||||
|
||||
const filters = computeContextStoreFilters(
|
||||
const filters = computeContextStoreFilters({
|
||||
contextStoreTargetedRecordsRule,
|
||||
[],
|
||||
personObjectMetadataItem,
|
||||
mockFilterValueDependencies,
|
||||
'',
|
||||
);
|
||||
contextStoreFilters: [],
|
||||
contextStoreFilterGroups: [],
|
||||
objectMetadataItem: personObjectMetadataItem,
|
||||
filterValueDependencies: mockFilterValueDependencies,
|
||||
contextStoreAnyFieldFilterValue: '',
|
||||
});
|
||||
|
||||
expect(filters).toEqual({
|
||||
and: [
|
||||
@@ -63,13 +64,14 @@ describe('computeContextStoreFilters', () => {
|
||||
},
|
||||
];
|
||||
|
||||
const filters = computeContextStoreFilters(
|
||||
const filters = computeContextStoreFilters({
|
||||
contextStoreTargetedRecordsRule,
|
||||
contextStoreFilters,
|
||||
personObjectMetadataItem,
|
||||
mockFilterValueDependencies,
|
||||
'',
|
||||
);
|
||||
contextStoreFilterGroups: [],
|
||||
objectMetadataItem: personObjectMetadataItem,
|
||||
filterValueDependencies: mockFilterValueDependencies,
|
||||
contextStoreAnyFieldFilterValue: '',
|
||||
});
|
||||
|
||||
expect(filters).toEqual({
|
||||
and: [
|
||||
|
||||
+21
-10
@@ -1,24 +1,35 @@
|
||||
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';
|
||||
|
||||
export const computeContextStoreFilters = (
|
||||
contextStoreTargetedRecordsRule: ContextStoreTargetedRecordsRule,
|
||||
contextStoreFilters: RecordFilter[],
|
||||
objectMetadataItem: ObjectMetadataItem,
|
||||
filterValueDependencies: RecordFilterValueDependencies,
|
||||
anyFieldFilterValue: string,
|
||||
) => {
|
||||
type ComputeContextStoreFiltersProps = {
|
||||
contextStoreTargetedRecordsRule: ContextStoreTargetedRecordsRule;
|
||||
contextStoreFilters: RecordFilter[];
|
||||
contextStoreFilterGroups: RecordFilterGroup[];
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
filterValueDependencies: RecordFilterValueDependencies;
|
||||
contextStoreAnyFieldFilterValue: string;
|
||||
};
|
||||
|
||||
export const computeContextStoreFilters = ({
|
||||
contextStoreTargetedRecordsRule,
|
||||
contextStoreFilters,
|
||||
contextStoreFilterGroups,
|
||||
objectMetadataItem,
|
||||
filterValueDependencies,
|
||||
contextStoreAnyFieldFilterValue,
|
||||
}: ComputeContextStoreFiltersProps) => {
|
||||
let queryFilter: RecordGqlOperationFilter | undefined;
|
||||
|
||||
const { recordGqlOperationFilter: recordGqlFilterForAnyFieldFilter } =
|
||||
turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue: anyFieldFilterValue,
|
||||
filterValue: contextStoreAnyFieldFilterValue,
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
@@ -29,7 +40,7 @@ export const computeContextStoreFilters = (
|
||||
filterValueDependencies,
|
||||
fields: objectMetadataItem?.fields ?? [],
|
||||
recordFilters: contextStoreFilters,
|
||||
recordFilterGroups: [],
|
||||
recordFilterGroups: contextStoreFilterGroups,
|
||||
}),
|
||||
contextStoreTargetedRecordsRule.excludedRecordIds.length > 0
|
||||
? {
|
||||
@@ -56,7 +67,7 @@ export const computeContextStoreFilters = (
|
||||
filterValueDependencies,
|
||||
fields: objectMetadataItem?.fields ?? [],
|
||||
recordFilters: contextStoreFilters,
|
||||
recordFilterGroups: [],
|
||||
recordFilterGroups: contextStoreFilterGroups,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -15,6 +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';
|
||||
|
||||
export type UseFindManyRecordsParams<T> = ObjectMetadataItemIdentifier &
|
||||
RecordGqlOperationVariables & {
|
||||
onError?: (error?: Error) => void;
|
||||
@@ -53,9 +55,19 @@ export const useFindManyRecords = <T extends ObjectRecord = ObjectRecord>({
|
||||
handleError: onError,
|
||||
});
|
||||
|
||||
const softDeleteFilter: RecordGqlOperationFilter = {
|
||||
or: [{ deletedAt: { is: 'NULL' } }, { deletedAt: { is: 'NOT_NULL' } }],
|
||||
};
|
||||
|
||||
const withSoftDeleteFilter = withSoftDeleted
|
||||
? {
|
||||
and: [...(filter ? [filter] : []), softDeleteFilter],
|
||||
}
|
||||
: filter;
|
||||
|
||||
const queryIdentifier = getQueryIdentifier({
|
||||
objectNameSingular,
|
||||
filter,
|
||||
filter: withSoftDeleteFilter,
|
||||
orderBy,
|
||||
limit,
|
||||
});
|
||||
@@ -66,10 +78,6 @@ export const useFindManyRecords = <T extends ObjectRecord = ObjectRecord>({
|
||||
onCompleted,
|
||||
});
|
||||
|
||||
const withSoftDeleterFilter = {
|
||||
or: [{ deletedAt: { is: 'NULL' } }, { deletedAt: { is: 'NOT_NULL' } }],
|
||||
};
|
||||
|
||||
const objectPermissions = useObjectPermissionsForObject(
|
||||
objectMetadataItem.id,
|
||||
);
|
||||
@@ -80,14 +88,7 @@ export const useFindManyRecords = <T extends ObjectRecord = ObjectRecord>({
|
||||
useQuery<RecordGqlOperationFindManyResult>(findManyRecordsQuery, {
|
||||
skip: skip || !objectMetadataItem || !hasReadPermission,
|
||||
variables: {
|
||||
filter: withSoftDeleted
|
||||
? {
|
||||
and: [
|
||||
...(filter ? [filter] : []),
|
||||
...(withSoftDeleted ? [withSoftDeleterFilter] : []),
|
||||
],
|
||||
}
|
||||
: filter,
|
||||
filter: withSoftDeleteFilter,
|
||||
orderBy,
|
||||
lastCursor: cursorFilter?.cursor ?? undefined,
|
||||
limit,
|
||||
@@ -101,7 +102,7 @@ export const useFindManyRecords = <T extends ObjectRecord = ObjectRecord>({
|
||||
const { fetchMoreRecords, records, hasNextPage } =
|
||||
useFetchMoreRecordsWithPagination<T>({
|
||||
objectNameSingular,
|
||||
filter,
|
||||
filter: withSoftDeleteFilter,
|
||||
orderBy,
|
||||
limit,
|
||||
fetchMore,
|
||||
|
||||
+15
-7
@@ -1,4 +1,5 @@
|
||||
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
|
||||
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
@@ -41,24 +42,31 @@ export const RecordIndexContainerContextStoreNumberOfSelectedRecordsEffect =
|
||||
contextStoreFiltersComponentState,
|
||||
);
|
||||
|
||||
const contextStoreFilterGroups = useRecoilComponentValue(
|
||||
contextStoreFilterGroupsComponentState,
|
||||
);
|
||||
|
||||
const contextStoreAnyFieldFilterValue = useRecoilComponentValue(
|
||||
contextStoreAnyFieldFilterValueComponentState,
|
||||
);
|
||||
|
||||
const { filterValueDependencies } = useFilterValueDependencies();
|
||||
|
||||
const computedFilter = computeContextStoreFilters({
|
||||
contextStoreTargetedRecordsRule,
|
||||
contextStoreFilters,
|
||||
contextStoreFilterGroups,
|
||||
objectMetadataItem,
|
||||
filterValueDependencies,
|
||||
contextStoreAnyFieldFilterValue,
|
||||
});
|
||||
|
||||
const { totalCount } = useFindManyRecords({
|
||||
...findManyRecordsParams,
|
||||
recordGqlFields: {
|
||||
id: true,
|
||||
},
|
||||
filter: computeContextStoreFilters(
|
||||
contextStoreTargetedRecordsRule,
|
||||
contextStoreFilters,
|
||||
objectMetadataItem,
|
||||
filterValueDependencies,
|
||||
contextStoreAnyFieldFilterValue,
|
||||
),
|
||||
filter: computedFilter,
|
||||
limit: 1,
|
||||
skip: contextStoreTargetedRecordsRule.mode === 'selection',
|
||||
});
|
||||
|
||||
+18
-1
@@ -1,8 +1,10 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
|
||||
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
|
||||
import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||
@@ -20,6 +22,11 @@ export const RecordIndexFiltersToContextStoreEffect = () => {
|
||||
recordIndexId,
|
||||
);
|
||||
|
||||
const recordIndexFilterGroups = useRecoilComponentValue(
|
||||
currentRecordFilterGroupsComponentState,
|
||||
recordIndexId,
|
||||
);
|
||||
|
||||
const setContextStoreTargetedRecords = useSetRecoilComponentState(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
);
|
||||
@@ -68,13 +75,23 @@ export const RecordIndexFiltersToContextStoreEffect = () => {
|
||||
contextStoreFiltersComponentState,
|
||||
);
|
||||
|
||||
const setContextStoreFilterGroups = useSetRecoilComponentState(
|
||||
contextStoreFilterGroupsComponentState,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setContextStoreFilters(recordIndexFilters);
|
||||
setContextStoreFilterGroups(recordIndexFilterGroups);
|
||||
|
||||
return () => {
|
||||
setContextStoreFilters([]);
|
||||
};
|
||||
}, [recordIndexFilters, setContextStoreFilters]);
|
||||
}, [
|
||||
recordIndexFilterGroups,
|
||||
recordIndexFilters,
|
||||
setContextStoreFilterGroups,
|
||||
setContextStoreFilters,
|
||||
]);
|
||||
|
||||
const setContextStoreAnyFieldFilterValue = useSetRecoilComponentState(
|
||||
contextStoreAnyFieldFilterValueComponentState,
|
||||
|
||||
+8
-2
@@ -3,6 +3,7 @@ import { type ColumnDefinition } from '@/object-record/record-table/types/Column
|
||||
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
|
||||
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
|
||||
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters';
|
||||
@@ -73,6 +74,10 @@ export const useRecordIndexLazyFetchRecords = ({
|
||||
contextStoreFiltersComponentState,
|
||||
);
|
||||
|
||||
const contextStoreFilterGroups = useRecoilComponentValue(
|
||||
contextStoreFilterGroupsComponentState,
|
||||
);
|
||||
|
||||
const contextStoreAnyFieldFilterValue = useRecoilComponentValue(
|
||||
contextStoreAnyFieldFilterValueComponentState,
|
||||
);
|
||||
@@ -83,13 +88,14 @@ export const useRecordIndexLazyFetchRecords = ({
|
||||
objectMetadataItem.nameSingular,
|
||||
);
|
||||
|
||||
const queryFilter = computeContextStoreFilters(
|
||||
const queryFilter = computeContextStoreFilters({
|
||||
contextStoreTargetedRecordsRule,
|
||||
contextStoreFilters,
|
||||
contextStoreFilterGroups,
|
||||
objectMetadataItem,
|
||||
filterValueDependencies,
|
||||
contextStoreAnyFieldFilterValue,
|
||||
);
|
||||
});
|
||||
|
||||
const finalColumns = [
|
||||
...columns,
|
||||
|
||||
@@ -3,6 +3,7 @@ import { type PropsWithChildren, useEffect, useState } from 'react';
|
||||
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
|
||||
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import {
|
||||
@@ -11,6 +12,7 @@ import {
|
||||
} from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { type ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
|
||||
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
|
||||
@@ -18,6 +20,7 @@ export type JestContextStoreSetterMocks = {
|
||||
contextStoreTargetedRecordsRule?: ContextStoreTargetedRecordsRule;
|
||||
contextStoreNumberOfSelectedRecords?: number;
|
||||
contextStoreFilters?: RecordFilter[];
|
||||
contextStoreFilterGroups?: RecordFilterGroup[];
|
||||
contextStoreCurrentObjectMetadataNameSingular?: string;
|
||||
contextStoreCurrentViewId?: string;
|
||||
contextStoreCurrentViewType?: ContextStoreViewType;
|
||||
@@ -34,6 +37,7 @@ export const JestContextStoreSetter = ({
|
||||
contextStoreNumberOfSelectedRecords = 0,
|
||||
contextStoreCurrentObjectMetadataNameSingular = 'company',
|
||||
contextStoreFilters = [],
|
||||
contextStoreFilterGroups = [],
|
||||
contextStoreCurrentViewType,
|
||||
children,
|
||||
}: JestContextStoreSetterProps) => {
|
||||
@@ -53,6 +57,10 @@ export const JestContextStoreSetter = ({
|
||||
contextStoreFiltersComponentState,
|
||||
);
|
||||
|
||||
const setContextStoreFilterGroupsComponentState = useSetRecoilComponentState(
|
||||
contextStoreFilterGroupsComponentState,
|
||||
);
|
||||
|
||||
const setContextStoreCurrentViewId = useSetRecoilComponentState(
|
||||
contextStoreCurrentViewIdComponentState,
|
||||
);
|
||||
@@ -74,6 +82,7 @@ export const JestContextStoreSetter = ({
|
||||
setContextStoreCurrentObjectMetadataItemId(objectMetadataItem.id);
|
||||
setContextStoreNumberOfSelectedRecords(contextStoreNumberOfSelectedRecords);
|
||||
setcontextStoreFiltersComponentState(contextStoreFilters);
|
||||
setContextStoreFilterGroupsComponentState(contextStoreFilterGroups);
|
||||
setContextStoreCurrentViewType(contextStoreCurrentViewType ?? null);
|
||||
setIsLoaded(true);
|
||||
}, [
|
||||
@@ -90,6 +99,8 @@ export const JestContextStoreSetter = ({
|
||||
contextStoreCurrentViewId,
|
||||
setContextStoreCurrentViewType,
|
||||
contextStoreCurrentViewType,
|
||||
setContextStoreFilterGroupsComponentState,
|
||||
contextStoreFilterGroups,
|
||||
]);
|
||||
|
||||
return isLoaded ? <>{children}</> : null;
|
||||
|
||||
Reference in New Issue
Block a user