Files
twenty/packages/twenty-front/src/modules/apollo/hooks/useApolloFactory.ts
Paul Rastoin 7fd89678b7 [CHORE] Avoid isDefined duplicated reference, move it to twenty-shared (#9967)
# Introduction
Avoid having multiple `isDefined` definition across our pacakges
Also avoid importing `isDefined` from `twenty-ui` which exposes a huge
barrel for a such little util function

## In a nutshell
Removed own `isDefined.ts` definition from `twenty-ui` `twenty-front`
and `twenty-server` to move it to `twenty-shared`.
Updated imports for each packages, and added explicit dependencies to
`twenty-shared` if not already in place

Related PR https://github.com/twentyhq/twenty/pull/9941
2025-02-01 12:10:10 +01:00

118 lines
4.1 KiB
TypeScript

import { InMemoryCache, NormalizedCacheObject } from '@apollo/client';
import { useMemo, useRef } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { useRecoilState, useRecoilValue, 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 { workspacesState } from '@/auth/states/workspaces';
import { isDebugModeState } from '@/client-config/states/isDebugModeState';
import { isDefined } from 'twenty-shared';
import { REACT_APP_SERVER_BASE_URL } from '~/config';
import { useIsMatchingLocation } from '~/hooks/useIsMatchingLocation';
import { useUpdateEffect } from '~/hooks/useUpdateEffect';
import { AppPath } from '@/types/AppPath';
import { ApolloFactory, Options } from '../services/apollo.factory';
export const useApolloFactory = (options: Partial<Options<any>> = {}) => {
// eslint-disable-next-line @nx/workspace-no-state-useref
const apolloRef = useRef<ApolloFactory<NormalizedCacheObject> | null>(null);
const [isDebugMode] = useRecoilState(isDebugModeState);
const navigate = useNavigate();
const isMatchingLocation = useIsMatchingLocation();
const [tokenPair, setTokenPair] = useRecoilState(tokenPairState);
const [currentWorkspace, setCurrentWorkspace] = useRecoilState(
currentWorkspaceState,
);
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
const setCurrentUser = useSetRecoilState(currentUserState);
const setCurrentWorkspaceMember = useSetRecoilState(
currentWorkspaceMemberState,
);
const setWorkspaces = useSetRecoilState(workspacesState);
const [, setPreviousUrl] = useRecoilState(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'],
},
},
}),
headers: {
...(currentWorkspace?.metadataVersion && {
'X-Schema-Version': `${currentWorkspace.metadataVersion}`,
}),
},
defaultOptions: {
query: {
fetchPolicy: 'cache-first',
},
},
connectToDevTools: isDebugMode,
// We don't want to re-create the client on token change or it will cause infinite loop
initialTokenPair: tokenPair,
currentWorkspaceMember: currentWorkspaceMember,
onTokenPairChange: (tokenPair) => {
setTokenPair(tokenPair);
},
onUnauthenticatedError: () => {
setTokenPair(null);
setCurrentUser(null);
setCurrentWorkspaceMember(null);
setCurrentWorkspace(null);
setWorkspaces([]);
if (
!isMatchingLocation(AppPath.Verify) &&
!isMatchingLocation(AppPath.SignInUp) &&
!isMatchingLocation(AppPath.Invite) &&
!isMatchingLocation(AppPath.ResetPassword)
) {
setPreviousUrl(`${location.pathname}${location.search}`);
navigate(AppPath.SignInUp);
}
},
extraLinks: [],
isDebugMode,
// Override options
...options,
});
return apolloRef.current.getClient();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
setTokenPair,
setCurrentUser,
setCurrentWorkspaceMember,
setCurrentWorkspace,
setWorkspaces,
isDebugMode,
currentWorkspace?.metadataVersion,
setPreviousUrl,
]);
useUpdateEffect(() => {
if (isDefined(apolloRef.current)) {
apolloRef.current.updateTokenPair(tokenPair);
}
}, [tokenPair]);
useUpdateEffect(() => {
if (isDefined(apolloRef.current)) {
apolloRef.current.updateWorkspaceMember(currentWorkspaceMember);
}
}, [currentWorkspaceMember]);
return apolloClient;
};