Files
twenty/packages/twenty-front/src/modules/activities/hooks/useCreateActivityInCache.ts
Charles Bochet 6a14b1c6d6 Fix tasks (#5199)
## Query depth deprecation

I'm deprecating depth parameter in our graphql query / cache tooling.
They were obsolete since we introduce the possibility to provide
RecordGqlFields

## Refactor combinedFindManyRecordHook

The hook can now take an array of operationSignatures

## Fix tasks issues

Fix optimistic rendering issue. Note that we still haven't handle
optimisticEffect on creation properly
2024-04-29 23:33:23 +02:00

189 lines
6.7 KiB
TypeScript

import { Reference, useApolloClient } from '@apollo/client';
import { useRecoilCallback, useRecoilValue } from 'recoil';
import { v4 } from 'uuid';
import { Activity, ActivityType } from '@/activities/types/Activity';
import { ActivityTarget } from '@/activities/types/ActivityTarget';
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
import { makeActivityTargetsToCreateFromTargetableObjects } from '@/activities/utils/getActivityTargetsToCreateFromTargetableObjects';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useCreateManyRecordsInCache } from '@/object-record/cache/hooks/useCreateManyRecordsInCache';
import { useCreateOneRecordInCache } from '@/object-record/cache/hooks/useCreateOneRecordInCache';
import { getRecordConnectionFromRecords } from '@/object-record/cache/utils/getRecordConnectionFromRecords';
import { modifyRecordFromCache } from '@/object-record/cache/utils/modifyRecordFromCache';
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
import { isDefined } from '~/utils/isDefined';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
export const useCreateActivityInCache = () => {
const { createManyRecordsInCache: createManyActivityTargetsInCache } =
useCreateManyRecordsInCache<ActivityTarget>({
objectNameSingular: CoreObjectNameSingular.ActivityTarget,
});
const cache = useApolloClient().cache;
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
const { record: currentWorkspaceMemberRecord } = useFindOneRecord({
objectNameSingular: CoreObjectNameSingular.WorkspaceMember,
objectRecordId: currentWorkspaceMember?.id,
});
const { objectMetadataItem: objectMetadataItemActivity } =
useObjectMetadataItem({
objectNameSingular: CoreObjectNameSingular.Activity,
});
const { objectMetadataItem: objectMetadataItemActivityTarget } =
useObjectMetadataItem({
objectNameSingular: CoreObjectNameSingular.ActivityTarget,
});
const createOneActivityInCache = useCreateOneRecordInCache<Activity>({
objectMetadataItem: objectMetadataItemActivity,
});
const createActivityInCache = useRecoilCallback(
({ snapshot, set }) =>
({
type,
targetObject,
customAssignee,
}: {
type: ActivityType;
targetObject?: ActivityTargetableObject;
customAssignee?: WorkspaceMember;
}) => {
const activityId = v4();
const createdActivityInCache = createOneActivityInCache({
id: activityId,
__typename: 'Activity',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
author: currentWorkspaceMemberRecord,
authorId: currentWorkspaceMemberRecord?.id,
assignee: customAssignee ?? currentWorkspaceMemberRecord,
assigneeId: customAssignee?.id ?? currentWorkspaceMemberRecord?.id,
type,
});
if (isUndefinedOrNull(createdActivityInCache)) {
throw new Error('Failed to create activity in cache');
}
if (isUndefinedOrNull(targetObject)) {
set(recordStoreFamilyState(activityId), {
...createdActivityInCache,
activityTargets: [],
comments: [],
});
return {
createdActivityInCache: {
...createdActivityInCache,
activityTargets: [],
},
};
}
const targetObjectRecord = snapshot
.getLoadable(recordStoreFamilyState(targetObject.id))
.getValue();
if (isUndefinedOrNull(targetObjectRecord)) {
throw new Error('Failed to find target object record');
}
const activityTargetsToCreate =
makeActivityTargetsToCreateFromTargetableObjects({
activity: createdActivityInCache,
targetableObjects: [targetObject],
targetObjectRecords: [targetObjectRecord],
});
const createdActivityTargetsInCache = createManyActivityTargetsInCache(
activityTargetsToCreate,
);
const activityTargetsConnection = getRecordConnectionFromRecords({
objectMetadataItems: objectMetadataItems,
objectMetadataItem: objectMetadataItemActivityTarget,
records: createdActivityTargetsInCache,
withPageInfo: false,
computeReferences: true,
isRootLevel: false,
});
modifyRecordFromCache({
recordId: createdActivityInCache.id,
cache,
fieldModifiers: {
activityTargets: () => activityTargetsConnection,
},
objectMetadataItem: objectMetadataItemActivity,
});
const targetObjectMetadataItem = objectMetadataItems.find(
(item) => item.nameSingular === targetObject.targetObjectNameSingular,
);
if (isDefined(targetObjectMetadataItem)) {
modifyRecordFromCache({
cache,
objectMetadataItem: targetObjectMetadataItem,
recordId: targetObject.id,
fieldModifiers: {
activityTargets: (activityTargetsRef, { readField }) => {
const edges = readField<{ node: Reference }[]>(
'edges',
activityTargetsRef,
);
if (!edges) return activityTargetsRef;
return {
...activityTargetsRef,
edges: [...edges, ...activityTargetsConnection.edges],
};
},
},
});
}
set(recordStoreFamilyState(activityId), {
...createdActivityInCache,
activityTargets: createdActivityTargetsInCache,
comments: [],
});
return {
createdActivityInCache: {
...createdActivityInCache,
activityTargets: createdActivityTargetsInCache,
},
};
},
[
createOneActivityInCache,
currentWorkspaceMemberRecord,
createManyActivityTargetsInCache,
objectMetadataItems,
objectMetadataItemActivityTarget,
cache,
objectMetadataItemActivity,
],
);
return {
createActivityInCache,
};
};