Display a generic fallback component when initial config load fails (#8588)

Fixes: #8487 #5027 

1. Summary
The purpose of these changes is to elevate the dev/user experience when
the initial config load call fails for whatever reason by displaying a
fallback component.

2. Solution
I ended up making more changes than I initially planned. I had to update
the order of the contexts a bit because `GenericErrorFallback` is
dependent on `AppThemeProvider` for styling and `AppThemeProvider` is
dependent on `ObjectMetadataItemsProvider` for
[`useObjectMetadataItem`](ae2f193d68/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItem.ts (L22))
hook (`AppThemeProvider` -> `useColorScheme` -> `useUpdateOneRecord` ->
`useObjectMetadataItem`). I had to create a wrapper component for
`AppThemeProvider` and stylize it in a way that it looks responsive on
both mobile and desktop devices. Finally, I had to introduce the
`isErrored` flag to differentiate the loading and error states.

    There are some improvements we can make later - 
    - Display a loading state for the initial config load
    - Implement a refetch logic for the initial config loading failure
    
3. Recording



https://github.com/user-attachments/assets/c2f43573-8006-4118-8e18-8576099d78fd



https://github.com/user-attachments/assets/9c5853d3-539b-4880-aa38-c416c3e13594

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
This commit is contained in:
Khuddite
2024-11-22 16:45:23 +08:00
committed by GitHub
parent 04c359a5dc
commit 62df0f0445
12 changed files with 228 additions and 121 deletions

View File

@ -13,7 +13,8 @@ import { PrefetchDataProvider } from '@/prefetch/components/PrefetchDataProvider
import { DialogManager } from '@/ui/feedback/dialog-manager/components/DialogManager';
import { DialogManagerScope } from '@/ui/feedback/dialog-manager/scopes/DialogManagerScope';
import { SnackBarProvider } from '@/ui/feedback/snack-bar-manager/components/SnackBarProvider';
import { AppThemeProvider } from '@/ui/theme/components/AppThemeProvider';
import { UserThemeProviderEffect } from '@/ui/theme/components/AppThemeProvider';
import { BaseThemeProvider } from '@/ui/theme/components/BaseThemeProvider';
import { PageTitle } from '@/ui/utilities/page-title/components/PageTitle';
import { UserProvider } from '@/users/components/UserProvider';
import { UserProviderEffect } from '@/users/components/UserProviderEffect';
@ -27,17 +28,18 @@ export const AppRouterProviders = () => {
return (
<ApolloProvider>
<ClientConfigProviderEffect />
<ClientConfigProvider>
<ChromeExtensionSidecarEffect />
<ChromeExtensionSidecarProvider>
<UserProviderEffect />
<UserProvider>
<AuthProvider>
<ApolloMetadataClientProvider>
<ObjectMetadataItemsProvider>
<PrefetchDataProvider>
<AppThemeProvider>
<BaseThemeProvider>
<ClientConfigProviderEffect />
<ClientConfigProvider>
<ChromeExtensionSidecarEffect />
<ChromeExtensionSidecarProvider>
<UserProviderEffect />
<UserProvider>
<AuthProvider>
<ApolloMetadataClientProvider>
<ObjectMetadataItemsProvider>
<PrefetchDataProvider>
<UserThemeProviderEffect />
<SnackBarProvider>
<DialogManagerScope dialogManagerScopeId="dialog-manager">
<DialogManager>
@ -50,15 +52,15 @@ export const AppRouterProviders = () => {
</DialogManager>
</DialogManagerScope>
</SnackBarProvider>
</AppThemeProvider>
</PrefetchDataProvider>
<PageChangeEffect />
</ObjectMetadataItemsProvider>
</ApolloMetadataClientProvider>
</AuthProvider>
</UserProvider>
</ChromeExtensionSidecarProvider>
</ClientConfigProvider>
</PrefetchDataProvider>
<PageChangeEffect />
</ObjectMetadataItemsProvider>
</ApolloMetadataClientProvider>
</AuthProvider>
</UserProvider>
</ChromeExtensionSidecarProvider>
</ClientConfigProvider>
</BaseThemeProvider>
</ApolloProvider>
);
};