Feat: Advanced filter (#7700)
Design:  Not ready to be merged yet! --------- Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
@ -0,0 +1,214 @@
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { triggerCreateRecordsOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerCreateRecordsOptimisticEffect';
|
||||
import { triggerDestroyRecordsOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerDestroyRecordsOptimisticEffect';
|
||||
import { triggerUpdateRecordOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerUpdateRecordOptimisticEffect';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordFromCache';
|
||||
import { useCreateOneRecordMutation } from '@/object-record/hooks/useCreateOneRecordMutation';
|
||||
import { useDestroyOneRecordMutation } from '@/object-record/hooks/useDestroyOneRecordMutation';
|
||||
import { useUpdateOneRecordMutation } from '@/object-record/hooks/useUpdateOneRecordMutation';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { GraphQLView } from '@/views/types/GraphQLView';
|
||||
import { ViewFilterGroup } from '@/views/types/ViewFilterGroup';
|
||||
import { isDefined } from 'twenty-ui';
|
||||
|
||||
export const usePersistViewFilterGroupRecords = () => {
|
||||
const { objectMetadataItem } = useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.ViewFilterGroup,
|
||||
});
|
||||
|
||||
const getRecordFromCache = useGetRecordFromCache({
|
||||
objectNameSingular: CoreObjectNameSingular.ViewFilterGroup,
|
||||
});
|
||||
|
||||
const { destroyOneRecordMutation } = useDestroyOneRecordMutation({
|
||||
objectNameSingular: CoreObjectNameSingular.ViewFilterGroup,
|
||||
});
|
||||
|
||||
const { createOneRecordMutation } = useCreateOneRecordMutation({
|
||||
objectNameSingular: CoreObjectNameSingular.ViewFilterGroup,
|
||||
});
|
||||
|
||||
const { updateOneRecordMutation } = useUpdateOneRecordMutation({
|
||||
objectNameSingular: CoreObjectNameSingular.ViewFilterGroup,
|
||||
});
|
||||
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
|
||||
const apolloClient = useApolloClient();
|
||||
|
||||
const createViewFilterGroupRecord = useCallback(
|
||||
async (viewFilterGroup: ViewFilterGroup, view: GraphQLView) => {
|
||||
const result = await apolloClient.mutate<{
|
||||
createViewFilterGroup: ViewFilterGroup;
|
||||
}>({
|
||||
mutation: createOneRecordMutation,
|
||||
variables: {
|
||||
input: {
|
||||
id: viewFilterGroup.id,
|
||||
viewId: view.id,
|
||||
parentViewFilterGroupId: viewFilterGroup.parentViewFilterGroupId,
|
||||
logicalOperator: viewFilterGroup.logicalOperator,
|
||||
positionInViewFilterGroup:
|
||||
viewFilterGroup.positionInViewFilterGroup,
|
||||
},
|
||||
},
|
||||
update: (cache, { data }) => {
|
||||
const record = data?.createViewFilterGroup;
|
||||
if (!record) return;
|
||||
|
||||
triggerCreateRecordsOptimisticEffect({
|
||||
cache,
|
||||
objectMetadataItem,
|
||||
recordsToCreate: [record],
|
||||
objectMetadataItems,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
if (!result.data) {
|
||||
throw new Error('Failed to create view filter group');
|
||||
}
|
||||
|
||||
return { newRecordId: result.data.createViewFilterGroup.id };
|
||||
},
|
||||
[
|
||||
apolloClient,
|
||||
createOneRecordMutation,
|
||||
objectMetadataItem,
|
||||
objectMetadataItems,
|
||||
],
|
||||
);
|
||||
|
||||
const createViewFilterGroupRecords = useCallback(
|
||||
async (viewFilterGroupsToCreate: ViewFilterGroup[], view: GraphQLView) => {
|
||||
if (!viewFilterGroupsToCreate.length) return [];
|
||||
|
||||
const oldToNewId = new Map<string, string>();
|
||||
|
||||
for (const viewFilterGroupToCreate of viewFilterGroupsToCreate) {
|
||||
const newParentViewFilterGroupId = isDefined(
|
||||
viewFilterGroupToCreate.parentViewFilterGroupId,
|
||||
)
|
||||
? (oldToNewId.get(viewFilterGroupToCreate.parentViewFilterGroupId) ??
|
||||
viewFilterGroupToCreate.parentViewFilterGroupId)
|
||||
: undefined;
|
||||
|
||||
const { newRecordId } = await createViewFilterGroupRecord(
|
||||
{
|
||||
...viewFilterGroupToCreate,
|
||||
parentViewFilterGroupId: newParentViewFilterGroupId,
|
||||
},
|
||||
view,
|
||||
);
|
||||
|
||||
oldToNewId.set(viewFilterGroupToCreate.id, newRecordId);
|
||||
}
|
||||
|
||||
const newRecordIds = viewFilterGroupsToCreate.map((viewFilterGroup) => {
|
||||
const newId = oldToNewId.get(viewFilterGroup.id);
|
||||
if (!newId) {
|
||||
throw new Error('Failed to create view filter group');
|
||||
}
|
||||
return newId;
|
||||
});
|
||||
|
||||
return newRecordIds;
|
||||
},
|
||||
[createViewFilterGroupRecord],
|
||||
);
|
||||
|
||||
const updateViewFilterGroupRecords = useCallback(
|
||||
(viewFilterGroupsToUpdate: ViewFilterGroup[]) => {
|
||||
if (!viewFilterGroupsToUpdate.length) return;
|
||||
return Promise.all(
|
||||
viewFilterGroupsToUpdate.map((viewFilterGroup) =>
|
||||
apolloClient.mutate<{ updateViewFilterGroup: ViewFilterGroup }>({
|
||||
mutation: updateOneRecordMutation,
|
||||
variables: {
|
||||
idToUpdate: viewFilterGroup.id,
|
||||
input: {
|
||||
parentViewFilterGroupId:
|
||||
viewFilterGroup.parentViewFilterGroupId,
|
||||
logicalOperator: viewFilterGroup.logicalOperator,
|
||||
positionInViewFilterGroup:
|
||||
viewFilterGroup.positionInViewFilterGroup,
|
||||
},
|
||||
},
|
||||
update: (cache, { data }) => {
|
||||
const record = data?.updateViewFilterGroup;
|
||||
if (!record) return;
|
||||
const cachedRecord = getRecordFromCache<ObjectRecord>(record.id);
|
||||
|
||||
if (!cachedRecord) return;
|
||||
|
||||
triggerUpdateRecordOptimisticEffect({
|
||||
cache,
|
||||
objectMetadataItem,
|
||||
currentRecord: cachedRecord,
|
||||
updatedRecord: record,
|
||||
objectMetadataItems,
|
||||
});
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
},
|
||||
[
|
||||
apolloClient,
|
||||
getRecordFromCache,
|
||||
objectMetadataItem,
|
||||
objectMetadataItems,
|
||||
updateOneRecordMutation,
|
||||
],
|
||||
);
|
||||
|
||||
const deleteViewFilterGroupRecords = useCallback(
|
||||
(viewFilterGroupIdsToDelete: string[]) => {
|
||||
if (!viewFilterGroupIdsToDelete.length) return;
|
||||
return Promise.all(
|
||||
viewFilterGroupIdsToDelete.map((viewFilterGroupId) =>
|
||||
apolloClient.mutate<{ destroyViewFilterGroup: ViewFilterGroup }>({
|
||||
mutation: destroyOneRecordMutation,
|
||||
variables: {
|
||||
idToDestroy: viewFilterGroupId,
|
||||
},
|
||||
update: (cache, { data }) => {
|
||||
const record = data?.destroyViewFilterGroup;
|
||||
|
||||
if (!record) return;
|
||||
|
||||
const cachedRecord = getRecordFromCache(record.id, cache);
|
||||
|
||||
if (!cachedRecord) return;
|
||||
|
||||
triggerDestroyRecordsOptimisticEffect({
|
||||
cache,
|
||||
objectMetadataItem,
|
||||
recordsToDestroy: [cachedRecord],
|
||||
objectMetadataItems,
|
||||
});
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
},
|
||||
[
|
||||
apolloClient,
|
||||
destroyOneRecordMutation,
|
||||
getRecordFromCache,
|
||||
objectMetadataItem,
|
||||
objectMetadataItems,
|
||||
],
|
||||
);
|
||||
|
||||
return {
|
||||
createViewFilterGroupRecords,
|
||||
updateViewFilterGroupRecords,
|
||||
deleteViewFilterGroupRecords,
|
||||
};
|
||||
};
|
||||
@ -50,11 +50,13 @@ export const usePersistViewFilterRecords = () => {
|
||||
mutation: createOneRecordMutation,
|
||||
variables: {
|
||||
input: {
|
||||
id: viewFilter.id,
|
||||
fieldMetadataId: viewFilter.fieldMetadataId,
|
||||
viewId: view.id,
|
||||
value: viewFilter.value,
|
||||
displayValue: viewFilter.displayValue,
|
||||
operand: viewFilter.operand,
|
||||
viewFilterGroupId: viewFilter.viewFilterGroupId,
|
||||
},
|
||||
},
|
||||
update: (cache, { data }) => {
|
||||
|
||||
Reference in New Issue
Block a user