import { InMemoryCache, NormalizedCacheObject } from '@apollo/client'; import { useMemo, useRef } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { useRecoilState, useSetRecoilState } from 'recoil'; import { currentUserState } from '@/auth/states/currentUserState'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; import { previousUrlState } from '@/auth/states/previousUrlState'; import { tokenPairState } from '@/auth/states/tokenPairState'; import { REACT_APP_SERVER_BASE_URL } from '~/config'; import { useUpdateEffect } from '~/hooks/useUpdateEffect'; import { isMatchingLocation } from '~/utils/isMatchingLocation'; import { currentUserWorkspaceState } from '@/auth/states/currentUserWorkspaceState'; import { AppPath } from '@/types/AppPath'; import { isDefined } from 'twenty-shared/utils'; import { ApolloFactory, Options } from '../services/apollo.factory'; export const useApolloFactory = (options: Partial> = {}) => { // eslint-disable-next-line @nx/workspace-no-state-useref const apolloRef = useRef | null>(null); const navigate = useNavigate(); const setTokenPair = useSetRecoilState(tokenPairState); const [currentWorkspace, setCurrentWorkspace] = useRecoilState( currentWorkspaceState, ); const [currentWorkspaceMember, setCurrentWorkspaceMember] = useRecoilState( currentWorkspaceMemberState, ); const setCurrentUser = useSetRecoilState(currentUserState); const setCurrentUserWorkspace = useSetRecoilState(currentUserWorkspaceState); const setPreviousUrl = useSetRecoilState(previousUrlState); const location = useLocation(); const apolloClient = useMemo(() => { apolloRef.current = new ApolloFactory({ uri: `${REACT_APP_SERVER_BASE_URL}/graphql`, cache: new InMemoryCache({ typePolicies: { RemoteTable: { keyFields: ['name'], }, }, }), defaultOptions: { watchQuery: { fetchPolicy: 'cache-and-network', }, }, connectToDevTools: process.env.IS_DEBUG_MODE === 'true', currentWorkspaceMember: currentWorkspaceMember, currentWorkspace: currentWorkspace, onTokenPairChange: (tokenPair) => { setTokenPair(tokenPair); }, onUnauthenticatedError: () => { setTokenPair(null); setCurrentUser(null); setCurrentWorkspaceMember(null); setCurrentWorkspace(null); setCurrentUserWorkspace(null); if ( !isMatchingLocation(location, AppPath.Verify) && !isMatchingLocation(location, AppPath.SignInUp) && !isMatchingLocation(location, AppPath.Invite) && !isMatchingLocation(location, AppPath.ResetPassword) ) { setPreviousUrl(`${location.pathname}${location.search}`); navigate(AppPath.SignInUp); } }, extraLinks: [], isDebugMode: process.env.IS_DEBUG_MODE === 'true', // Override options ...options, }); return apolloRef.current.getClient(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [ setTokenPair, setCurrentUser, setCurrentWorkspaceMember, setCurrentWorkspace, setPreviousUrl, ]); useUpdateEffect(() => { if (isDefined(apolloRef.current)) { apolloRef.current.updateWorkspaceMember(currentWorkspaceMember); } }, [currentWorkspaceMember]); useUpdateEffect(() => { if (isDefined(apolloRef.current)) { apolloRef.current.updateCurrentWorkspace(currentWorkspace); } }, [currentWorkspace]); return apolloClient; };