Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Webapp): implement create user button and user page #1030

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/webapp/src/browser/bootstrap/bootstrap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ export async function bootstrap(document: NonElementParentNode): Promise<void> {

if (rootElement) {
const root = createRoot(rootElement);
root.render(<App configuration={configuration} />);
root.render(<App />);
}
}
16 changes: 14 additions & 2 deletions packages/webapp/src/browser/core/i18n/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ export const translations = {
en: {
core: {
helloWorld: 'Hello World!',
notFoundTitle: 'Page not found',
notFoundMessage: 'The page you are looking for does not exist.',
},
nav: {
changeLanguageTo: 'Change language to {{nextLanguage}} ({{lng}})',
Expand All @@ -19,14 +21,20 @@ export const translations = {
deleteUser: 'Delete {{user}}',
deleteUserMessage: 'Are you sure you want to delete this user?',
deleteUserSuccess: 'User {{user}} has been deleted!',
create: 'Create user...',
},
user: {
viewTitle: 'User information',
readTitle: 'User information',
editTitle: 'Edit user',
createTitle: 'Create user',
requiredFields: 'Required fields are marked with an asterisk',
},
},
fr: {
core: {
helloWorld: 'Bonjour le monde!',
notFoundTitle: 'Page non trouvée',
notFoundMessage: 'La page que vous cherchez n\'existe pas.',
},
nav: {
changeLanguageTo: 'Changer la langue pour {{nextLanguage}} ({{lng}})',
Expand All @@ -44,9 +52,13 @@ export const translations = {
deleteUser: 'Supprimer {{user}}',
deleteUserMessage: 'Êtes-vous sûr de vouloir supprimer cet utilisateur?',
deleteUserSuccess: 'L\'utilisateur {{user}} a été supprimé!',
create: 'Créer un utilisateur...',
},
user: {
viewTitle: 'Information sur l\'utilisateur',
readTitle: 'Information sur l\'utilisateur',
editTitle: 'Modifier l\'utilisateur',
createTitle: 'Créer un utilisateur',
requiredFields: 'Les champs obligatoires sont marqués d\'un astérisque',
},
},
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { RouteObject } from 'react-router';
import { RouteCollection, RouteDefinition } from '../../core';
import { HomePage } from '../home';
import { UserPage, UsersPage } from '../users';
import { HomePage } from '../../modules/home';
import { UserPage, UsersPage } from '../../modules/users';
import { RouteCollection, RouteDefinition } from './route.types';

export const ROUTES: RouteCollection = {
home: {
Expand All @@ -15,7 +15,7 @@ export const ROUTES: RouteCollection = {
end: true,
},
user: {
path: '/user/:id?',
path: '/users/:mode?/:id?',
component: UserPage,
end: true,
},
Expand Down
59 changes: 10 additions & 49 deletions packages/webapp/src/browser/modules/app/App.component.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,12 @@
import { DesignSystem } from '@equisoft/design-elements-react';
import { FunctionComponent } from 'react';
import { useTranslation } from 'react-i18next';
import { RouterProvider } from 'react-router-dom';
import { Configuration, ConfigurationProvider, createRouter, initializeConfiguration } from '../../core';
import { Provider as UsersProvider } from '../users/components/Provider.component';
import { AppLayout, AppLoader, UnexpectedErrorBoundary } from './layout';
import { ROUTER_ROUTES } from './routes';

export interface AppProps {
configuration: Configuration;
}

const appConfig = initializeConfiguration();
const router = createRouter([
{
path: '/',
element: <AppLayout />,
children: ROUTER_ROUTES,
},
], {
basename: appConfig.publicPath,
});

export const DataProviders: FunctionComponent = (
{ children },
) => (
<UsersProvider>
{children}
</UsersProvider>
import { AppLoader } from './layout';
import { AppProviders } from './Providers.component';
import { AppRouter } from './Router.component';

export const App: FunctionComponent = () => (
<AppProviders>
<AppLoader>
<AppRouter />
</AppLoader>
</AppProviders>
);

export const App: FunctionComponent<AppProps> = ({
configuration,
}) => {
const { i18n } = useTranslation();

return (
<ConfigurationProvider configuration={configuration}>
<UnexpectedErrorBoundary>
<DesignSystem language={i18n.language}>
<DataProviders>
<AppLoader>
<RouterProvider router={router} />
</AppLoader>
</DataProviders>
</DesignSystem>
</UnexpectedErrorBoundary>
</ConfigurationProvider>
);
};
25 changes: 25 additions & 0 deletions packages/webapp/src/browser/modules/app/Providers.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { DesignSystem } from '@equisoft/design-elements-react';
import { FunctionComponent } from 'react';
import { useTranslation } from 'react-i18next';
import { ConfigurationProvider, initializeConfiguration } from '../../core';
import { Provider as UsersProvider } from '../users/components/Provider.component';
import { UnexpectedErrorBoundary } from './layout';

export const AppProviders: FunctionComponent = (
{ children },
) => {
const appConfig = initializeConfiguration();
const { i18n } = useTranslation();

return (
<ConfigurationProvider configuration={appConfig}>
<UnexpectedErrorBoundary>
<UsersProvider>
<DesignSystem language={i18n.language}>
{children}
</DesignSystem>
</UsersProvider>
</UnexpectedErrorBoundary>
</ConfigurationProvider>
);
};
23 changes: 23 additions & 0 deletions packages/webapp/src/browser/modules/app/Router.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FunctionComponent } from 'react';
import { RouterProvider } from 'react-router-dom';
import { createRouter, useConfiguration } from '../../core';
import { ROUTER_ROUTES } from '../../core/navigation/routes';
import { AppLayout } from './layout';

export const AppRouter: FunctionComponent = () => {
const { configuration } = useConfiguration();

const router = createRouter([
{
path: '/',
element: <AppLayout />,
children: ROUTER_ROUTES,
},
], {
basename: configuration.publicPath,
});

return (
<RouterProvider router={router} />
);
};
2 changes: 1 addition & 1 deletion packages/webapp/src/browser/modules/app/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { App, AppProps } from './App.component';
export { App } from './App.component';
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Outlet } from 'react-router';
import styled from 'styled-components';
import { Header } from './Header.component';
import { Menu } from './Menu.component';
import { UnexpectedErrorBoundary } from './UnexpectedErrorBoundary.component';
import { UnexpectedErrorBoundary } from './ErrorBoundary.component';

const Screen = styled.div`
display: grid;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Link } from '@equisoft/design-elements-react';
import { FC, FunctionComponent, PropsWithChildren } from 'react';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';
import { ErrorBoundary } from '../../../core';
import { ROUTES } from '../../../core/navigation/routes';
import { ScreenCentered } from './styled-elements';

const NotFoundContainer = styled.div`
align-items: center;
display: flex;
flex-direction: column;
font-weight: 600; /* font-semibold */
margin-top: 13rem; /* mt-52 */
`;

export const NotFoundRoute: FC = () => {
const { t } = useTranslation('core');
return (
<NotFoundContainer>
<h1>{t('notFoundTitle')}</h1>
<p>{t('notFoundMessage')}</p>
<Link href={ROUTES.home.path}>
{t('backToHome')}
</Link>
</NotFoundContainer>
);
};

export const UnexpectedError: FunctionComponent = () => {
const { t } = useTranslation();

return (<ScreenCentered>{t('unexpectedError')}</ScreenCentered>);
};

export const UnexpectedErrorBoundary: FunctionComponent<PropsWithChildren<{}>> = ({ children }) => (
<ErrorBoundary fallback={<UnexpectedError />}>
{children}
</ErrorBoundary>
);
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { GlobalNavigation } from '@equisoft/design-elements-react';
import { FunctionComponent } from 'react';
import { useTranslation } from 'react-i18next';
import { ROUTES } from '../routes';
import { ROUTES } from '../../../core/navigation/routes';

export const Menu: FunctionComponent = () => {
const { t } = useTranslation();
Expand Down

This file was deleted.

2 changes: 1 addition & 1 deletion packages/webapp/src/browser/modules/app/layout/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { AppLayout } from './AppLayout.component';
export { AppLoader } from './AppLoader.component';
export { UnexpectedErrorBoundary } from './UnexpectedErrorBoundary.component';
export { UnexpectedErrorBoundary, UnexpectedError, NotFoundRoute } from './ErrorBoundary.component';
48 changes: 47 additions & 1 deletion packages/webapp/src/browser/modules/users/User.component.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,57 @@
import { Heading } from '@equisoft/design-elements-react';
import { FunctionComponent } from 'react';
import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router';
import styled from 'styled-components';
import { Form as UserForm } from './components/form/Form.component';
import { UserMode } from './types';

const PageWrapper = styled.div`
display: flex;
flex-direction: column;
gap: 16px;
`;

const StyledWarning = styled.span`
color: ${({ theme }) => theme.alias['color-content']};
display: flex;
flex-direction: row;
font-size: 12px;
font-style: normal;
font-weight: 400;
gap: 4px;
letter-spacing: 0.2px;
line-height: 20px;
`;

const StyledAsterisk = styled.span`
color: ${({ theme }) => theme.alias['color-feedback-border-alert']};
font-size: 12px;
font-style: normal;
font-weight: 400;
letter-spacing: 0.2px;
line-height: 20px;
`;

export const UserPage: FunctionComponent = () => {
const { t } = useTranslation('user');
const { mode, id } = useParams();
const userMode = mode as UserMode || UserMode.CREATE;
const titleMap = {
[UserMode.CREATE]: t('createTitle'),
[UserMode.EDIT]: t('editTitle'),
[UserMode.READ]: t('readTitle'),
};
const title = titleMap[userMode];

return (
<Heading bold noMargin type='xlarge' tag="h1">{t('viewTitle')}</Heading>
<PageWrapper>
<Heading bold noMargin type='xlarge' tag="h1">{title}</Heading>
<StyledWarning>
{t('requiredFields')}
<StyledAsterisk>*</StyledAsterisk>
</StyledWarning>
<UserForm id={id} />
</PageWrapper>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { FunctionComponent } from 'react';

interface UserFormProps {
id?: string;
}

export const Form: FunctionComponent<UserFormProps> = (
{ id },
) => {
// eslint-disable-next-line no-console
console.log(id);
return (
<form />
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
Delete as DeleteCell,
} from './cells';
import { Footer as TableFooter } from './Footer.component';
import { ToolBar } from './toolbar/Toolbar.component';

const TableContainer = styled.div`
align-items: flex-start;
Expand All @@ -25,7 +26,7 @@ const TableContainer = styled.div`
flex-shrink: 0;
gap: 8px;
padding: 16px 32px;

td:nth-child(4) {
padding-left: 0;
padding-right: 0;
Expand Down Expand Up @@ -58,7 +59,7 @@ export const Table: FunctionComponent = () => {
focusable: true,
// eslint-disable-next-line react/no-unstable-nested-components
cell: (props) => (
<NameCell id={props.cell.getValue() as User['id']} />
<NameCell id={props.row.original.id} name={props.row.original.name} />
),
},
{
Expand All @@ -84,13 +85,14 @@ export const Table: FunctionComponent = () => {
sortable: false,
// eslint-disable-next-line react/no-unstable-nested-components
cell: (props) => (
<DeleteCell id={props.cell.getValue() as User['id']} />
<DeleteCell id={props.row.original.id} />
),
},
], [t]);

return (
<TableContainer>
<ToolBar />
<DataTable
rowSize="small"
columns={columns}
Expand Down
Loading