♻️(frontend) replace env NEXT_PUBLIC_FEATURE_TEAM

NEXT_PUBLIC_FEATURE_TEAM is a buid-time env
variable, it is not easy to overload it per
environment.
We will use the config endpoint to get the
feature flag at runtime.
To do so, we are using the ConfigStore.
This commit is contained in:
Anthony LC
2024-08-20 10:31:34 +02:00
committed by Anthony LC
parent 75647fe289
commit 32889b9e8c
12 changed files with 111 additions and 19 deletions

View File

@@ -1,2 +1 @@
NEXT_PUBLIC_API_ORIGIN=http://localhost:8071
NEXT_PUBLIC_FEATURE_TEAM=true

View File

@@ -1,2 +1 @@
NEXT_PUBLIC_API_ORIGIN=http://test.jest
NEXT_PUBLIC_FEATURE_TEAM=true

View File

@@ -1,23 +1,41 @@
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/react';
import { render } from '@testing-library/react';
import { useConfigStore } from '@/core';
import { AppWrapper } from '@/tests/utils';
import Page from '../pages';
const mockedPush = jest.fn();
const mockedUseRouter = jest.fn().mockReturnValue({
push: mockedPush,
});
jest.mock('next/navigation', () => ({
...jest.requireActual('next/navigation'),
useRouter: () => ({}),
useRouter: () => mockedUseRouter(),
}));
describe('Page', () => {
it('checks Page rendering', () => {
afterEach(() => jest.clearAllMocks());
it('checks Page rendering with team feature', () => {
useConfigStore.setState({
config: { FEATURES: { TEAMS: true }, LANGUAGES: [] },
});
render(<Page />, { wrapper: AppWrapper });
expect(
screen.getByRole('button', {
name: /Create a new team/i,
}),
).toBeInTheDocument();
expect(mockedPush).toHaveBeenCalledWith('/teams/');
});
it('checks Page rendering without team feature', () => {
useConfigStore.setState({
config: { FEATURES: { TEAMS: false }, LANGUAGES: [] },
});
render(<Page />, { wrapper: AppWrapper });
expect(mockedPush).toHaveBeenCalledWith('/mail-domains/');
});
});

View File

@@ -5,13 +5,17 @@ import { Footer } from '@/features/footer/Footer';
import { HEADER_HEIGHT, Header } from '@/features/header';
import { Menu } from '@/features/menu';
import { useConfigStore } from './config';
export function MainLayout({ children }: PropsWithChildren) {
const { config } = useConfigStore();
return (
<Box>
<Box $height="100vh">
<Header />
<Box $css="flex: 1;" $direction="row">
{process.env.NEXT_PUBLIC_FEATURE_TEAM === 'true' && <Menu />}
{config?.FEATURES.TEAMS && <Menu />}
<Box
as="main"
$height={`calc(100vh - ${HEADER_HEIGHT})`}

View File

@@ -4,6 +4,7 @@ import { render, screen } from '@testing-library/react';
import { AppWrapper } from '@/tests/utils';
import { MainLayout } from '../MainLayout';
import { useConfigStore } from '../config';
jest.mock('next/navigation', () => ({
...jest.requireActual('next/navigation'),
@@ -11,7 +12,11 @@ jest.mock('next/navigation', () => ({
}));
describe('MainLayout', () => {
it('checks menu rendering', () => {
it('checks menu rendering with team feature', () => {
useConfigStore.setState({
config: { FEATURES: { TEAMS: true }, LANGUAGES: [] },
});
render(<MainLayout />, { wrapper: AppWrapper });
expect(
@@ -28,8 +33,6 @@ describe('MainLayout', () => {
});
it('checks menu rendering without team feature', () => {
process.env.NEXT_PUBLIC_FEATURE_TEAM = 'false';
render(<MainLayout />, { wrapper: AppWrapper });
expect(

View File

@@ -3,6 +3,7 @@ import { useTranslation } from 'react-i18next';
import IconOpenClose from '@/assets/icons/icon-open-close.svg';
import { Box, BoxButton, Text } from '@/components';
import { useConfigStore } from '@/core/';
import { useCunninghamTheme } from '@/cunningham';
import { ItemList } from './ItemList';
@@ -11,6 +12,7 @@ import { PanelActions } from './PanelActions';
export const Panel = () => {
const { t } = useTranslation();
const { colorsTokens } = useCunninghamTheme();
const { config } = useConfigStore();
const [isOpen, setIsOpen] = useState(true);
@@ -20,7 +22,7 @@ export const Panel = () => {
$minWidth: '0',
};
const styleNoTeam = process.env.NEXT_PUBLIC_FEATURE_TEAM !== 'true' && {
const styleNoTeam = !config?.FEATURES.TEAMS && {
$display: 'none',
tabIndex: -1,
};

View File

@@ -25,7 +25,7 @@ export const Menu = () => {
<MenuItem
Icon={IconGroup}
label={t('Teams')}
href="/"
href="/teams"
alias={['/teams']}
/>
<MenuItem

View File

@@ -11,7 +11,7 @@ const Page: NextPageWithLayout = () => {
useEffect(() => {
config?.FEATURES.TEAMS
? router.push('/teams/')
: router.push('mail-domains/');
: router.push('/mail-domains/');
}, [config?.FEATURES.TEAMS, router]);
return null;