(frontend) add config provider

Add a ConfigProvider to the frontend to provide
configuration to the app.
The configuration is loaded from the config
endpoint, we will use react-query cache capabilities
to store the configuration.
This commit is contained in:
Anthony LC
2024-11-15 09:33:08 +01:00
committed by Anthony LC
parent 0e55bf5c43
commit 5b1745f991
7 changed files with 80 additions and 1 deletions

View File

@@ -15,6 +15,8 @@ and this project adheres to
- 🌐(frontend) Add German translation #255
- ✨(frontend) Add a broadcast store #387
- ✨(backend) whitelist pod's IP address #443
- ✨(backend) config endpoint #425
- ✨(frontend) config endpoint #424
## Changed

View File

@@ -0,0 +1,29 @@
import { expect, test } from '@playwright/test';
test.describe('Config', () => {
test('it checks the config api is called', async ({ page }) => {
const responsePromise = page.waitForResponse(
(response) =>
response.url().includes('/config/') && response.status() === 200,
);
await page.goto('/');
const response = await responsePromise;
expect(response.ok()).toBeTruthy();
expect(await response.json()).toStrictEqual({
COLLABORATION_SERVER_URL: 'ws://localhost:4444',
ENVIRONMENT: 'development',
FRONTEND_THEME: 'dsfr',
MEDIA_BASE_URL: 'http://localhost:8083',
LANGUAGES: [
['en-us', 'English'],
['fr-fr', 'French'],
['de-de', 'German'],
],
LANGUAGE_CODE: 'en-us',
SENTRY_DSN: null,
});
});
});

View File

@@ -7,6 +7,7 @@ import '@/i18n/initI18n';
import { useResponsiveStore } from '@/stores/';
import { Auth } from './auth/';
import { ConfigProvider } from './config/';
/**
* QueryClient:
@@ -39,7 +40,9 @@ export function AppProvider({ children }: { children: React.ReactNode }) {
return (
<QueryClientProvider client={queryClient}>
<CunninghamProvider theme={theme}>
<Auth>{children}</Auth>
<ConfigProvider>
<Auth>{children}</Auth>
</ConfigProvider>
</CunninghamProvider>
</QueryClientProvider>
);

View File

@@ -0,0 +1,9 @@
import { PropsWithChildren } from 'react';
import { useConfig } from './api/useConfig';
export const ConfigProvider = ({ children }: PropsWithChildren) => {
useConfig();
return children;
};

View File

@@ -0,0 +1 @@
export * from './useConfig';

View File

@@ -0,0 +1,33 @@
import { useQuery } from '@tanstack/react-query';
import { APIError, errorCauses, fetchAPI } from '@/api';
interface ConfigResponse {
SENTRY_DSN: string;
COLLABORATION_SERVER_URL: string;
ENVIRONMENT: string;
FRONTEND_THEME: string;
LANGUAGES: [string, string][];
LANGUAGE_CODE: string;
MEDIA_BASE_URL: string;
}
export const getConfig = async (): Promise<ConfigResponse> => {
const response = await fetchAPI(`config/`);
if (!response.ok) {
throw new APIError('Failed to get the doc', await errorCauses(response));
}
return response.json() as Promise<ConfigResponse>;
};
export const KEY_CONFIG = 'config';
export function useConfig() {
return useQuery<ConfigResponse, APIError, ConfigResponse>({
queryKey: [KEY_CONFIG],
queryFn: () => getConfig(),
staleTime: Infinity,
});
}

View File

@@ -0,0 +1,2 @@
export * from './api/useConfig';
export * from './ConfigProvider';