Files
twenty/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewGroupOptimisticEffect.ts
T
2026-02-24 20:38:30 +01:00

144 lines
4.6 KiB
TypeScript

import { coreViewsState } from '@/views/states/coreViewState';
import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations';
import { useApolloClient } from '@apollo/client';
import { useCallback } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { type CoreViewGroup } from '~/generated-metadata/graphql';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
import { useStore } from 'jotai';
type UpdatedDeletedCoreViewGroup = {
createdViewGroups?: Omit<CoreViewGroup, 'workspaceId'>[];
updatedViewGroups?: Omit<CoreViewGroup, 'workspaceId'>[];
deletedViewGroups?: Pick<CoreViewGroup, 'id' | 'viewId'>[];
};
export const useTriggerViewGroupOptimisticEffect = () => {
const store = useStore();
const apolloClient = useApolloClient();
const cache = apolloClient.cache;
const triggerViewGroupOptimisticEffect = useCallback(
({
createdViewGroups = [],
updatedViewGroups = [],
deletedViewGroups = [],
}: UpdatedDeletedCoreViewGroup) => {
const coreViews = store.get(coreViewsState.atom);
let newCoreViews = [...coreViews];
createdViewGroups.forEach((createdViewGroup) => {
cache.modify<CoreViewWithRelations>({
id: cache.identify({
__typename: 'CoreView',
id: createdViewGroup.viewId,
}),
fields: {
viewGroups: (existingViewGroups, { toReference }) => [
...(existingViewGroups ?? []),
toReference(createdViewGroup),
],
},
});
const toBeModifiedCoreView = newCoreViews.find(
(coreView) => coreView.id === createdViewGroup.viewId,
);
if (isDefined(toBeModifiedCoreView)) {
newCoreViews = [
...newCoreViews.filter(
(coreView) => coreView.id !== createdViewGroup.viewId,
),
{
...toBeModifiedCoreView,
viewGroups: [
...toBeModifiedCoreView.viewGroups,
createdViewGroup,
],
},
];
}
});
updatedViewGroups.forEach((updatedViewGroup) => {
cache.modify<CoreViewWithRelations>({
id: cache.identify({
__typename: 'CoreView',
id: updatedViewGroup.viewId,
}),
fields: {
viewGroups: (existingViewGroups, { readField, toReference }) =>
existingViewGroups.map((viewGroup) => {
const viewGroupId = readField<string>('id', viewGroup);
if (viewGroupId === updatedViewGroup.id) {
return toReference(updatedViewGroup);
}
return viewGroup;
}),
},
});
const toBeModifiedCoreView = newCoreViews.find(
(coreView) => coreView.id === updatedViewGroup.viewId,
);
if (isDefined(toBeModifiedCoreView)) {
newCoreViews = [
...newCoreViews.filter(
(coreView) => coreView.id !== updatedViewGroup.viewId,
),
{
...toBeModifiedCoreView,
viewGroups: [
...toBeModifiedCoreView.viewGroups.filter(
(viewGroup) => viewGroup.id !== updatedViewGroup.id,
),
updatedViewGroup,
],
},
];
}
});
deletedViewGroups.forEach((deletedViewGroup) => {
cache.modify<CoreViewWithRelations>({
id: cache.identify({
__typename: 'CoreView',
id: deletedViewGroup.viewId,
}),
fields: {
viewGroups: (existingViewGroups, { readField }) =>
existingViewGroups.filter(
(viewGroup) =>
readField('id', viewGroup) !== deletedViewGroup.id,
),
},
});
const toBeModifiedCoreView = newCoreViews.find(
(coreView) => coreView.id === deletedViewGroup.viewId,
);
if (isDefined(toBeModifiedCoreView)) {
newCoreViews = [
...newCoreViews.filter(
(coreView) => coreView.id !== deletedViewGroup.viewId,
),
{
...toBeModifiedCoreView,
viewGroups: toBeModifiedCoreView.viewGroups.filter(
(viewGroup) => viewGroup.id !== deletedViewGroup.id,
),
},
];
}
});
if (!isDeeplyEqual(coreViews, newCoreViews)) {
store.set(coreViewsState.atom, newCoreViews);
}
},
[cache, store],
);
return {
triggerViewGroupOptimisticEffect,
};
};