Files
twenty_crm/packages/twenty-front/src/modules/activities/hooks/useUpsertActivity.ts
Charles Bochet cfb0cce9b8 Refactor Views by cleaning the code, relying on apolloCache and improving performances (#4516)
* Wip refactoring view

* Post merge conflicts

* Fix review

* Add create view capability

* Fix create object missing view

* Fix tests
2024-03-20 14:21:58 +01:00

189 lines
7.3 KiB
TypeScript

import { useLocation } from 'react-router-dom';
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
import { useActivityConnectionUtils } from '@/activities/hooks/useActivityConnectionUtils';
import { useCreateActivityInDB } from '@/activities/hooks/useCreateActivityInDB';
import { useInjectIntoActivitiesQueries } from '@/activities/hooks/useInjectIntoActivitiesQueries';
import { useInjectIntoActivityTargetsQueries } from '@/activities/hooks/useInjectIntoActivityTargetsQueries';
import { currentNotesQueryVariablesState } from '@/activities/notes/states/currentNotesQueryVariablesState';
import { activityIdInDrawerState } from '@/activities/states/activityIdInDrawerState';
import { isActivityInCreateModeState } from '@/activities/states/isActivityInCreateModeState';
import { isUpsertingActivityInDBState } from '@/activities/states/isCreatingActivityInDBState';
import { currentCompletedTaskQueryVariablesState } from '@/activities/tasks/states/currentCompletedTaskQueryVariablesState';
import { currentIncompleteTaskQueryVariablesState } from '@/activities/tasks/states/currentIncompleteTaskQueryVariablesState';
import { useInjectIntoTimelineActivitiesQueries } from '@/activities/timeline/hooks/useInjectIntoTimelineActivitiesQueries';
import { objectShowPageTargetableObjectState } from '@/activities/timeline/states/objectShowPageTargetableObjectIdState';
import { Activity } from '@/activities/types/Activity';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { isDefined } from '~/utils/isDefined';
// TODO: create a generic way to have records only in cache for create mode and delete them afterwards ?
export const useUpsertActivity = () => {
const [isActivityInCreateMode, setIsActivityInCreateMode] = useRecoilState(
isActivityInCreateModeState,
);
const { updateOneRecord: updateOneActivity } = useUpdateOneRecord<Activity>({
objectNameSingular: CoreObjectNameSingular.Activity,
});
const { createActivityInDB } = useCreateActivityInDB();
const [, setIsUpsertingActivityInDB] = useRecoilState(
isUpsertingActivityInDBState,
);
const setActivityIdInDrawer = useSetRecoilState(activityIdInDrawerState);
const objectShowPageTargetableObject = useRecoilValue(
objectShowPageTargetableObjectState,
);
const { injectActivitiesQueries } = useInjectIntoActivitiesQueries();
const { injectActivityTargetsQueries } =
useInjectIntoActivityTargetsQueries();
const { pathname } = useLocation();
const weAreOnObjectShowPage = pathname.startsWith('/object');
const weAreOnTaskPage = pathname.startsWith('/tasks');
const { injectIntoTimelineActivitiesQueries } =
useInjectIntoTimelineActivitiesQueries();
const { makeActivityWithConnection } = useActivityConnectionUtils();
const currentCompletedTaskQueryVariables = useRecoilValue(
currentCompletedTaskQueryVariablesState,
);
const currentIncompleteTaskQueryVariables = useRecoilValue(
currentIncompleteTaskQueryVariablesState,
);
const currentNotesQueryVariables = useRecoilValue(
currentNotesQueryVariablesState,
);
const upsertActivity = async ({
activity,
input,
}: {
activity: Activity;
input: Partial<Activity>;
}) => {
setIsUpsertingActivityInDB(true);
if (isActivityInCreateMode) {
const activityToCreate: Activity = {
...activity,
...input,
};
const { activityWithConnection } =
makeActivityWithConnection(activityToCreate);
if (weAreOnTaskPage) {
if (isDefined(activityWithConnection.completedAt)) {
injectActivitiesQueries({
activitiesFilters: currentCompletedTaskQueryVariables?.filter,
activitiesOrderByVariables:
currentCompletedTaskQueryVariables?.orderBy,
activityTargetsToInject: activityToCreate.activityTargets,
activityToInject: activityWithConnection,
targetableObjects: [],
});
} else {
injectActivitiesQueries({
activitiesFilters: currentIncompleteTaskQueryVariables?.filter,
activitiesOrderByVariables:
currentIncompleteTaskQueryVariables?.orderBy,
activityTargetsToInject: activityToCreate.activityTargets,
activityToInject: activityWithConnection,
targetableObjects: [],
});
}
injectActivityTargetsQueries({
activityTargetsToInject: activityToCreate.activityTargets,
targetableObjects: [],
});
}
// Call optimistic effects
if (weAreOnObjectShowPage && isDefined(objectShowPageTargetableObject)) {
injectIntoTimelineActivitiesQueries({
timelineTargetableObject: objectShowPageTargetableObject,
activityToInject: activityWithConnection,
activityTargetsToInject: activityToCreate.activityTargets,
});
const injectOnlyInIdFilterForTaskQueries =
activityWithConnection.type !== 'Task';
const injectOnlyInIdFilterForNotesQueries =
activityWithConnection.type !== 'Note';
if (isDefined(currentCompletedTaskQueryVariables)) {
injectActivitiesQueries({
activitiesFilters: currentCompletedTaskQueryVariables?.filter,
activitiesOrderByVariables:
currentCompletedTaskQueryVariables?.orderBy,
activityTargetsToInject: activityToCreate.activityTargets,
activityToInject: activityWithConnection,
targetableObjects: [objectShowPageTargetableObject],
injectOnlyInIdFilter: injectOnlyInIdFilterForTaskQueries,
});
}
if (isDefined(currentIncompleteTaskQueryVariables)) {
injectActivitiesQueries({
activitiesFilters:
currentIncompleteTaskQueryVariables?.filter ?? {},
activitiesOrderByVariables:
currentIncompleteTaskQueryVariables?.orderBy ?? {},
activityTargetsToInject: activityToCreate.activityTargets,
activityToInject: activityWithConnection,
targetableObjects: [objectShowPageTargetableObject],
injectOnlyInIdFilter: injectOnlyInIdFilterForTaskQueries,
});
}
if (isDefined(currentNotesQueryVariables)) {
injectActivitiesQueries({
activitiesFilters: currentNotesQueryVariables?.filter,
activitiesOrderByVariables: currentNotesQueryVariables?.orderBy,
activityTargetsToInject: activityToCreate.activityTargets,
activityToInject: activityWithConnection,
targetableObjects: [objectShowPageTargetableObject],
injectOnlyInIdFilter: injectOnlyInIdFilterForNotesQueries,
});
}
injectActivityTargetsQueries({
activityTargetsToInject: activityToCreate.activityTargets,
targetableObjects: [objectShowPageTargetableObject],
});
}
await createActivityInDB(activityToCreate);
setActivityIdInDrawer(activityToCreate.id);
setIsActivityInCreateMode(false);
} else {
await updateOneActivity?.({
idToUpdate: activity.id,
updateOneRecordInput: input,
});
}
setIsUpsertingActivityInDB(false);
};
return {
upsertActivity,
};
};