import { useRecoilCallback } from 'recoil'; import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState'; import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState'; import { usePersistViewGroupRecords } from '@/views/hooks/internal/usePersistViewGroup'; import { useGetViewFromPrefetchState } from '@/views/hooks/useGetViewFromPrefetchState'; import { type ViewGroup } from '@/views/types/ViewGroup'; import { isDefined } from 'twenty-shared/utils'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; export const useSaveCurrentViewGroups = () => { const { createViewGroups, updateViewGroups } = usePersistViewGroupRecords(); const { getViewFromPrefetchState } = useGetViewFromPrefetchState(); const currentViewIdCallbackState = useRecoilComponentCallbackState( contextStoreCurrentViewIdComponentState, ); const saveViewGroup = useRecoilCallback( ({ snapshot }) => async (viewGroupToSave: ViewGroup) => { const currentViewId = snapshot .getLoadable(currentViewIdCallbackState) .getValue(); if (!currentViewId) { return; } const view = getViewFromPrefetchState(currentViewId); if (isUndefinedOrNull(view)) { return; } const currentViewGroups = view.viewGroups; const existingField = currentViewGroups.find( (currentViewGroup) => currentViewGroup.fieldValue === viewGroupToSave.fieldValue, ); if (isUndefinedOrNull(existingField)) { return; } if ( isDeeplyEqual( { position: existingField.position, isVisible: existingField.isVisible, }, { position: viewGroupToSave.position, isVisible: viewGroupToSave.isVisible, }, ) ) { return; } await updateViewGroups([ { input: { id: existingField.id, update: { isVisible: viewGroupToSave.isVisible, position: viewGroupToSave.position, fieldMetadataId: viewGroupToSave.fieldMetadataId, fieldValue: viewGroupToSave.fieldValue, }, }, }, ]); }, [currentViewIdCallbackState, getViewFromPrefetchState, updateViewGroups], ); const saveViewGroups = useRecoilCallback( ({ snapshot }) => async (viewGroupsToSave: ViewGroup[]) => { const currentViewId = snapshot .getLoadable(currentViewIdCallbackState) .getValue(); if (!currentViewId) { return; } const view = getViewFromPrefetchState(currentViewId); if (isUndefinedOrNull(view)) { return; } const currentViewGroups = view.viewGroups; const viewGroupsToUpdate = viewGroupsToSave .map((viewGroupToSave) => { const existingField = currentViewGroups.find( (currentViewGroup) => currentViewGroup.fieldValue === viewGroupToSave.fieldValue, ); if (isUndefinedOrNull(existingField)) { return undefined; } if ( isDeeplyEqual( { position: existingField.position, isVisible: existingField.isVisible, }, { position: viewGroupToSave.position, isVisible: viewGroupToSave.isVisible, }, ) ) { return undefined; } return { input: { id: existingField.id, update: { isVisible: viewGroupToSave.isVisible, position: viewGroupToSave.position, fieldMetadataId: viewGroupToSave.fieldMetadataId, fieldValue: viewGroupToSave.fieldValue, }, }, }; }) .filter(isDefined); const viewGroupsToCreate = viewGroupsToSave.filter( (viewFieldToSave) => !currentViewGroups.some( (currentViewGroup) => currentViewGroup.fieldValue === viewFieldToSave.fieldValue, ), ); await Promise.all([ createViewGroups( viewGroupsToCreate.map(({ __typename, ...viewGroup }) => ({ input: { ...viewGroup, viewId: view.id, }, })), ), updateViewGroups(viewGroupsToUpdate), ]); }, [ createViewGroups, currentViewIdCallbackState, getViewFromPrefetchState, updateViewGroups, ], ); return { saveViewGroup, saveViewGroups, }; };