Migrate to a monorepo structure (#2909)

This commit is contained in:
Charles Bochet
2023-12-10 18:10:54 +01:00
committed by GitHub
parent a70a9281eb
commit 5bdca9de6c
2304 changed files with 37152 additions and 25869 deletions

View File

@ -0,0 +1,160 @@
import { ComponentProps, JSX } from 'react';
import styled from '@emotion/styled';
import { isNumber, isString } from '@sniptt/guards';
import { Decorator } from '@storybook/react';
const StyledColumnTitle = styled.h1`
font-size: ${({ theme }) => theme.font.size.lg};
font-weight: ${({ theme }) => theme.font.weight.semiBold};
margin: ${({ theme }) => theme.spacing(2)};
`;
const StyledRowsTitle = styled.h2`
color: ${({ theme }) => theme.font.color.secondary};
font-size: ${({ theme }) => theme.font.size.md};
font-weight: ${({ theme }) => theme.font.weight.semiBold};
margin: ${({ theme }) => theme.spacing(2)};
width: 100px;
`;
const StyledRowTitle = styled.h3`
color: ${({ theme }) => theme.font.color.tertiary};
font-size: ${({ theme }) => theme.font.size.md};
font-weight: ${({ theme }) => theme.font.weight.semiBold};
margin: ${({ theme }) => theme.spacing(2)};
width: 100px;
`;
const StyledElementTitle = styled.span`
color: ${({ theme }) => theme.font.color.light};
font-size: ${({ theme }) => theme.font.size.xs};
font-weight: ${({ theme }) => theme.font.weight.semiBold};
margin-bottom: ${({ theme }) => theme.spacing(1)};
text-align: center;
text-transform: uppercase;
`;
const StyledContainer = styled.div`
display: flex;
flex-direction: row;
`;
const StyledColumnContainer = styled.div`
display: flex;
flex-direction: column;
padding: ${({ theme }) => theme.spacing(2)};
`;
const StyledRowsContainer = styled.div`
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(2)};
`;
const StyledRowContainer = styled.div`
display: flex;
flex: 1;
flex-direction: row;
gap: ${({ theme }) => theme.spacing(2)};
`;
const StyledElementContainer = styled.div<{ width: number }>`
display: flex;
${({ width }) => width && `min-width: ${width}px;`}
`;
const StyledCellContainer = styled.div`
align-items: center;
display: flex;
flex-direction: column;
padding: ${({ theme }) => theme.spacing(2)};
`;
const emptyDimension = {
name: '',
values: [undefined],
props: () => ({}),
} as CatalogDimension;
const isStringOrNumber = (term: unknown): term is string | number =>
isString(term) || isNumber(term);
export type CatalogDimension<
ComponentType extends React.ElementType = () => JSX.Element,
> = {
name: string;
values: any[];
props: (value: any) => Partial<ComponentProps<ComponentType>>;
labels?: (value: any) => string;
};
export type CatalogOptions = {
elementContainer?: {
width?: number;
};
};
export const CatalogDecorator: Decorator = (Story, context) => {
const {
catalog: { dimensions, options },
} = context.parameters;
const [
dimension1,
dimension2 = emptyDimension,
dimension3 = emptyDimension,
dimension4 = emptyDimension,
] = dimensions as CatalogDimension[];
return (
<StyledContainer>
{dimension4.values.map((value4: any) => (
<StyledColumnContainer key={value4}>
<StyledColumnTitle>
{dimension4.labels?.(value4) ??
(isStringOrNumber(value4) ? value4 : '')}
</StyledColumnTitle>
{dimension3.values.map((value3: any) => (
<StyledRowsContainer key={value3}>
<StyledRowsTitle>
{dimension3.labels?.(value3) ??
(isStringOrNumber(value3) ? value3 : '')}
</StyledRowsTitle>
{dimension2.values.map((value2: any) => (
<StyledRowContainer key={value2}>
<StyledRowTitle>
{dimension2.labels?.(value2) ??
(isStringOrNumber(value2) ? value2 : '')}
</StyledRowTitle>
{dimension1.values.map((value1: any) => {
return (
<StyledCellContainer key={value1} id={value1}>
<StyledElementTitle>
{dimension1.labels?.(value1) ??
(isStringOrNumber(value1) ? value1 : '')}
</StyledElementTitle>
<StyledElementContainer
width={options?.elementContainer?.width}
>
<Story
args={{
...context.args,
...dimension1.props(value1),
...dimension2.props(value2),
...dimension3.props(value3),
...dimension4.props(value4),
}}
/>
</StyledElementContainer>
</StyledCellContainer>
);
})}
</StyledRowContainer>
))}
</StyledRowsContainer>
))}
</StyledColumnContainer>
))}
</StyledContainer>
);
};

View File

@ -0,0 +1,13 @@
import { Decorator } from '@storybook/react';
import { ComponentStorybookLayout } from '../ComponentStorybookLayout';
export const ComponentDecorator: Decorator = (Story, context) => {
const { container } = context.parameters;
return (
<ComponentStorybookLayout width={container?.width}>
<Story />
</ComponentStorybookLayout>
);
};

View File

@ -0,0 +1,14 @@
import { Decorator } from '@storybook/react';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
export const ComponentWithRecoilScopeDecorator: Decorator = (
Story,
context,
) => (
<RecoilScope
CustomRecoilScopeContext={context.parameters.customRecoilScopeContext}
>
<Story />
</RecoilScope>
);

View File

@ -0,0 +1,12 @@
import { MemoryRouter } from 'react-router-dom';
import { Decorator } from '@storybook/react';
import { ComponentStorybookLayout } from '../ComponentStorybookLayout';
export const ComponentWithRouterDecorator: Decorator = (Story) => (
<ComponentStorybookLayout>
<MemoryRouter>
<Story />
</MemoryRouter>
</ComponentStorybookLayout>
);

View File

@ -0,0 +1,9 @@
import { Decorator } from '@storybook/react';
import { ObjectMetadataItemsProvider } from '@/object-metadata/components/ObjectMetadataItemsProvider';
export const ObjectMetadataItemsDecorator: Decorator = (Story) => (
<ObjectMetadataItemsProvider>
<Story />
</ObjectMetadataItemsProvider>
);

View File

@ -0,0 +1,59 @@
import { HelmetProvider } from 'react-helmet-async';
import { MemoryRouter, Route, Routes } from 'react-router-dom';
import { Decorator } from '@storybook/react';
import { RecoilRoot } from 'recoil';
import { RelationPickerScope } from '@/object-record/relation-picker/scopes/RelationPickerScope';
import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
import { ClientConfigProvider } from '~/modules/client-config/components/ClientConfigProvider';
import { DefaultLayout } from '~/modules/ui/layout/page/DefaultLayout';
import { UserProvider } from '~/modules/users/components/UserProvider';
import { FullHeightStorybookLayout } from '../FullHeightStorybookLayout';
export type PageDecoratorArgs = {
routePath: string;
routeParams: RouteParams;
};
type RouteParams = {
[param: string]: string;
};
const computeLocation = (routePath: string, routeParams: RouteParams) => {
return {
pathname: routePath.replace(
/:(\w+)/g,
(paramName) => routeParams[paramName] ?? '',
),
};
};
export const PageDecorator: Decorator<{
routePath: string;
routeParams: RouteParams;
}> = (Story, { args }) => (
<RecoilRoot>
<UserProvider>
<ClientConfigProvider>
<MemoryRouter
initialEntries={[computeLocation(args.routePath, args.routeParams)]}
>
<FullHeightStorybookLayout>
<HelmetProvider>
<SnackBarProviderScope snackBarManagerScopeId="snack-bar-manager">
<RelationPickerScope relationPickerScopeId="relation-picker">
<DefaultLayout>
<Routes>
<Route path={args.routePath} element={<Story />} />
</Routes>
</DefaultLayout>
</RelationPickerScope>
</SnackBarProviderScope>
</HelmetProvider>
</FullHeightStorybookLayout>
</MemoryRouter>
</ClientConfigProvider>
</UserProvider>
</RecoilRoot>
);

View File

@ -0,0 +1,9 @@
import { Decorator } from '@storybook/react';
import { RelationPickerScope } from '@/object-record/relation-picker/scopes/RelationPickerScope';
export const RelationPickerDecorator: Decorator = (Story) => (
<RelationPickerScope relationPickerScopeId="relation-picker">
<Story />
</RelationPickerScope>
);

View File

@ -0,0 +1,19 @@
import { ApolloProvider } from '@apollo/client';
import { Decorator } from '@storybook/react';
import { RecoilRoot } from 'recoil';
import { ApolloMetadataClientProvider } from '@/object-metadata/components/ApolloMetadataClientProvider';
import { InitializeHotkeyStorybookHookEffect } from '../InitializeHotkeyStorybookHook';
import { mockedClient } from '../mockedClient';
export const RootDecorator: Decorator = (Story) => (
<RecoilRoot>
<ApolloProvider client={mockedClient}>
<ApolloMetadataClientProvider>
<InitializeHotkeyStorybookHookEffect />
<Story />
</ApolloMetadataClientProvider>
</ApolloProvider>
</RecoilRoot>
);

View File

@ -0,0 +1,9 @@
import { Decorator } from '@storybook/react';
import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
export const SnackBarDecorator: Decorator = (Story) => (
<SnackBarProviderScope snackBarManagerScopeId="snack-bar-manager">
<Story />
</SnackBarProviderScope>
);