fix(client-config): set isLoaded to false on API status update (#12371)

Attempt at #12289 (edit Félix: removed fix keyword since I don't think
it fixes it)

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
This commit is contained in:
Antoine Moreaux
2025-05-30 14:44:31 +02:00
committed by GitHub
parent 35a4b07bc2
commit b7473371b3
25 changed files with 224 additions and 170 deletions

View File

@ -9,7 +9,6 @@ import { clientConfigApiStatusState } from '@/client-config/states/clientConfigA
import { isAnalyticsEnabledState } from '@/client-config/states/isAnalyticsEnabledState';
import { isAttachmentPreviewEnabledState } from '@/client-config/states/isAttachmentPreviewEnabledState';
import { isConfigVariablesInDbEnabledState } from '@/client-config/states/isConfigVariablesInDbEnabledState';
import { isDebugModeState } from '@/client-config/states/isDebugModeState';
import { isDeveloperDefaultSignInPrefilledState } from '@/client-config/states/isDeveloperDefaultSignInPrefilledState';
import { isEmailVerificationRequiredState } from '@/client-config/states/isEmailVerificationRequiredState';
import { isGoogleCalendarEnabledState } from '@/client-config/states/isGoogleCalendarEnabledState';
@ -26,7 +25,6 @@ import { useRecoilState, useSetRecoilState } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
export const ClientConfigProviderEffect = () => {
const setIsDebugMode = useSetRecoilState(isDebugModeState);
const setIsAnalyticsEnabled = useSetRecoilState(isAnalyticsEnabledState);
const setDomainConfiguration = useSetRecoilState(domainConfigurationState);
const setAuthProviders = useSetRecoilState(authProvidersState);
@ -90,10 +88,17 @@ export const ClientConfigProviderEffect = () => {
const { data, loading, error, fetchClientConfig } = useClientConfig();
useEffect(() => {
if (!clientConfigApiStatus.isLoaded) {
if (
!clientConfigApiStatus.isLoadedOnce &&
!clientConfigApiStatus.isLoading
) {
fetchClientConfig();
}
}, [clientConfigApiStatus.isLoaded, fetchClientConfig]);
}, [
clientConfigApiStatus.isLoadedOnce,
clientConfigApiStatus.isLoading,
fetchClientConfig,
]);
useEffect(() => {
if (loading) return;
@ -124,7 +129,6 @@ export const ClientConfigProviderEffect = () => {
magicLink: false,
sso: data?.clientConfig.authProviders.sso,
});
setIsDebugMode(data?.clientConfig.debugMode);
setIsAnalyticsEnabled(data?.clientConfig.analyticsEnabled);
setIsDeveloperDefaultSignInPrefilled(data?.clientConfig.signInPrefilled);
setIsMultiWorkspaceEnabled(data?.clientConfig.isMultiWorkspaceEnabled);
@ -167,24 +171,23 @@ export const ClientConfigProviderEffect = () => {
);
setClientConfigApiStatus((currentStatus) => ({
...currentStatus,
isLoaded: true,
isSaved: true,
}));
}, [
data,
setIsDebugMode,
loading,
error,
setIsDeveloperDefaultSignInPrefilled,
setIsMultiWorkspaceEnabled,
setIsEmailVerificationRequired,
setSupportChat,
setBilling,
setSentryConfig,
loading,
setClientConfigApiStatus,
setCaptcha,
setChromeExtensionId,
setApiConfig,
setIsAnalyticsEnabled,
error,
setDomainConfiguration,
setAuthProviders,
setCanManageFeatureFlags,

View File

@ -1,4 +1,4 @@
import { useRecoilCallback, useRecoilValue } from 'recoil';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { ClientConfig } from '~/generated/graphql';
import { clientConfigApiStatusState } from '../states/clientConfigApiStatusState';
import { getClientConfig } from '../utils/getClientConfig';
@ -13,41 +13,38 @@ type UseClientConfigResult = {
export const useClientConfig = (): UseClientConfigResult => {
const clientConfigApiStatus = useRecoilValue(clientConfigApiStatusState);
const fetchClientConfig = useRecoilCallback(
({ set }) =>
async () => {
set(clientConfigApiStatusState, (prev) => ({
...prev,
isLoading: true,
isErrored: false,
error: undefined,
}));
try {
const clientConfig = await getClientConfig();
set(clientConfigApiStatusState, (prev) => ({
...prev,
isLoading: false,
isLoaded: true,
data: { clientConfig },
}));
} catch (err) {
const error =
err instanceof Error
? err
: new Error('Failed to fetch client config');
set(clientConfigApiStatusState, (prev) => ({
...prev,
isLoading: false,
isErrored: true,
error,
}));
}
},
[],
const setClientConfigApiStatus = useSetRecoilState(
clientConfigApiStatusState,
);
const fetchClientConfig = async () => {
setClientConfigApiStatus((prev) => ({
...prev,
isLoading: true,
}));
try {
const clientConfig = await getClientConfig();
setClientConfigApiStatus((prev) => ({
...prev,
isLoading: false,
isLoadedOnce: true,
isErrored: false,
error: undefined,
data: { clientConfig },
}));
} catch (err) {
const error =
err instanceof Error ? err : new Error('Failed to fetch client config');
setClientConfigApiStatus((prev) => ({
...prev,
isLoading: false,
isErrored: true,
error,
}));
}
};
return {
data: clientConfigApiStatus.data,
loading: clientConfigApiStatus.isLoading || false,

View File

@ -2,9 +2,10 @@ import { createState } from 'twenty-ui/utilities';
import { ClientConfig } from '~/generated/graphql';
type ClientConfigApiStatus = {
isLoaded: boolean;
isLoadedOnce: boolean;
isLoading: boolean;
isErrored: boolean;
isSaved: boolean;
error?: Error;
data?: { clientConfig: ClientConfig };
};
@ -12,9 +13,10 @@ type ClientConfigApiStatus = {
export const clientConfigApiStatusState = createState<ClientConfigApiStatus>({
key: 'clientConfigApiStatus',
defaultValue: {
isLoaded: false,
isLoadedOnce: false,
isLoading: false,
isErrored: false,
isSaved: false,
error: undefined,
data: undefined,
},

View File

@ -1,5 +0,0 @@
import { createState } from 'twenty-ui/utilities';
export const isDebugModeState = createState<boolean>({
key: 'isDebugModeState',
defaultValue: false,
});