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

Add new org screen full #528

Merged
Merged
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
29 changes: 29 additions & 0 deletions login-workflow/docs/screens/create-org.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# CreateNewOrgScreen

A screen that displays a text field to collect an organization name. The CreateNewOrgScreen must be used within a `RegistrationContextProvider`.

## Usage

```tsx
import { RegistrationContextProvider, CreateNewOrgScreen } from '@brightlayer-ui/react-auth-workflow';

...

<RegistrationContextProvider {...props}>
<CreateNewOrgScreen />
</RegistrationContextProvider>
```

## API

| Prop Name | Type | Description | Default |
|---|---|---|---|
| icon | `JSX.Element` | Icon to display | `<DomainIcon color={'primary'} sx={{ fontSize: 54 }} />`|
| message | `ReactNode` | The message to be displayed on the screen | |
| orgNameLabel | `string` | Text to display as the label for the organization name text field. | `t('bluiCommon:LABELS.ORG_NAME')` |
| initialValue | `string` | The initial value for the organization name text field. | |
| orgNameValidator | `(orgName: string) => boolean \| string` | A function that validates the organization name text field input. | Checks that orgName input has length greater than 0 |
| orgNameTextFieldProps | `TextFieldProps` | Props to pass to the MUI [TextField](https://mui.com/material-ui/api/text-field/) component. | |
| errorDisplayConfig | `ErrorManagerProps` | See [Error Management](../error-management.md) | |

This screen also extends the `WorkflowCardProps` type for updating the title, instructions, buttons, etc. See [Workflow Card](../components/workflow-card.md) for more details.
13 changes: 13 additions & 0 deletions login-workflow/example/src/navigation/AppRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import {
RegistrationContextProvider,
ResetPasswordScreen,
RegistrationWorkflow,
CreateNewOrgScreen,
CreateAccountScreen,
EulaScreen,
} from '@brightlayer-ui/react-auth-workflow';
import { useApp } from '../contexts/AppContextProvider';
import { useNavigate } from 'react-router';
Expand Down Expand Up @@ -127,6 +130,16 @@ export const AppRouter: React.FC = () => {
>
<Route path={'/self-registration'} element={<RegistrationWorkflow />} />
<Route path={'/register-by-invite'} element={<RegistrationWorkflow isInviteRegistration />} />
<Route
path={'/selfregistration'}
element={
<RegistrationWorkflow>
<EulaScreen />
<CreateNewOrgScreen />
<CreateAccountScreen />
</RegistrationWorkflow>
}
/>
</Route>
</Routes>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ const resources: RegistrationLanguageFile = {
VERIFICATION: '验证码',
CODE_VALIDATOR_ERROR: '请输入有效验证码',
},
NEW_ORG: {
SCREEN_TITLE: '创建一个组织',
MESSAGE_1: '既然您已经指定了您的帐户详细信息,您需要添加您的组织详细信息。',
MESSAGE_2: '请输入您的组织名称以继续帐户创建。',
MESSAGE_3: '如果您的组织已经存在,请向您的管理员获取注册码。',
ORG_NAME_ENTRY_ERROR: '请输入有效的组织名称',
},
},
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ const resources: RegistrationLanguageFile = {
VERIFICATION: 'Verification Code',
CODE_VALIDATOR_ERROR: 'You must provide a valid code',
},
NEW_ORG: {
daileytj marked this conversation as resolved.
Show resolved Hide resolved
SCREEN_TITLE: 'Create an Organization',
MESSAGE_1: `Now that you've specified your account details, you need to add your Organization details.`,
MESSAGE_2: 'Enter your organization name to continue with account creation.',
MESSAGE_3:
'If your Organization already exists, ask your administrator to provide you with a Registration Code.',
ORG_NAME_ENTRY_ERROR: 'Please enter a valid organization name',
},
},
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ const resources: RegistrationLanguageFile = {
VERIFICATION: 'Code de vérification',
CODE_VALIDATOR_ERROR: 'Vous devez fournir un code valide',
},
NEW_ORG: {
SCREEN_TITLE: 'Créer une Organisation',
MESSAGE_1:
'Maintenant que vous avez spécifié les détails de votre compte, vous devez ajouter les détails de votre organisation.',
MESSAGE_2: 'Saisissez le nom de votre organisation pour continuer la création de votre compte.',
MESSAGE_3: `Si votre organisation existe déjà, demandez à votre administrateur de vous fournir un Code d'Enregistrement.`,
ORG_NAME_ENTRY_ERROR: `Veuillez entrer un nom d'organisation valide`,
},
},
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ const resources: RegistrationLanguageFile = {
VERIFICATION: 'Código de verificação',
CODE_VALIDATOR_ERROR: 'Você deve fornecer um código válido',
},
NEW_ORG: {
SCREEN_TITLE: 'Criar uma Organização',
MESSAGE_1:
'Agora que você especificou os detalhes da sua conta, você precisa adicionar os detalhes da sua organização.',
MESSAGE_2: 'Digite o nome da sua organização para continuar com a criação da conta.',
MESSAGE_3:
'Se a sua organização já existe, peça ao seu administrador para fornecer um Código de Registro.',
ORG_NAME_ENTRY_ERROR: 'Por favor, insira um nome de organização válido',
},
},
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ const resources: RegistrationLanguageFile = {
VERIFICATION: 'Código de verificación',
CODE_VALIDATOR_ERROR: 'Debe proporcionar un código válido',
},
NEW_ORG: {
SCREEN_TITLE: 'Crear una Organización',
MESSAGE_1:
'Ahora que ha especificado los detalles de su cuenta, debe agregar los detalles de su organización.',
MESSAGE_2: 'Ingrese el nombre de su organización para continuar con la creación de la cuenta.',
MESSAGE_3:
'Si su organización ya existe, pida a su administrador que le proporcione un Código de Registro.',
ORG_NAME_ENTRY_ERROR: 'Por favor, ingrese un nombre de organización válido',
},
},
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ export type RegistrationTranslations = {
VERIFICATION: string;
CODE_VALIDATOR_ERROR: string;
};
NEW_ORG?: {
SCREEN_TITLE: string;
MESSAGE_1: string;
MESSAGE_2: string;
MESSAGE_3: string;
ORG_NAME_ENTRY_ERROR: string;
};
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const resources: CommonTranslationsFile = {
FORGOT_PASSWORD: '忘记密码?',
NEED_ACCOUNT: '新用户?',
VIEW_ALL_EVENTS: '查看共{{count}}个事件',
ORG_NAME: '组织名称',
},
MESSAGES: {
EMAIL_SENT: '邮件已发送',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const resources: CommonTranslationsFile = {
FORGOT_PASSWORD: 'Forgot your password?',
NEED_ACCOUNT: 'Need an account?',
VIEW_ALL_EVENTS: 'View All {{count}} Events',
ORG_NAME: 'Organization Name',
},
MESSAGES: {
EMAIL_SENT: 'Email Sent',
Expand Down
1 change: 1 addition & 0 deletions login-workflow/src/contexts/SharedDictionaries/french.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const resources: CommonTranslationsFile = {
FORGOT_PASSWORD: 'Mot de passe oublié',
NEED_ACCOUNT: 'Besoin dun compte?',
VIEW_ALL_EVENTS: 'Afficher les {{count}} événements',
ORG_NAME: `Nom de l'Organisation`,
},
MESSAGES: {
EMAIL_SENT: 'Email envoyé',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const resources: CommonTranslationsFile = {
FORGOT_PASSWORD: 'Esqueceu-se da sua palavra-passe?',
NEED_ACCOUNT: 'Precisa de uma conta?',
VIEW_ALL_EVENTS: 'Ver todos os {{count}} Eventos',
ORG_NAME: 'Nome da Organização',
},
MESSAGES: {
EMAIL_SENT: 'E-mail enviado',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const resources: CommonTranslationsFile = {
FORGOT_PASSWORD: '¿Ha olvidado su contraseña?',
NEED_ACCOUNT: '¿Necesitas una cuenta?',
VIEW_ALL_EVENTS: 'Ver todos los {{count}} eventos',
ORG_NAME: 'Nombre de la Organización',
},
MESSAGES: {
EMAIL_SENT: 'Correo electrónico enviado',
Expand Down
1 change: 1 addition & 0 deletions login-workflow/src/contexts/SharedDictionaries/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export type CommonTranslations = {
FORGOT_PASSWORD: string;
NEED_ACCOUNT: string;
VIEW_ALL_EVENTS: string;
ORG_NAME?: string;
};
MESSAGES: {
EMAIL_SENT: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import React from 'react';
import '@testing-library/jest-dom';
import { cleanup, render, screen, fireEvent, RenderResult } from '@testing-library/react';
import { CreateNewOrgScreen } from './CreateNewOrgScreen';
import { CreateNewOrgScreenProps } from './types';
import { RegistrationContextProvider } from '../../contexts';
import { RegistrationWorkflow } from '../../components';
import { registrationContextProviderProps } from '../../testUtils';

afterEach(cleanup);

describe('Create New Org Screen', () => {
let mockOnNext: any;
let mockOnPrevious: any;

afterEach(() => {
jest.clearAllMocks();
});

beforeEach(() => {
mockOnNext = jest.fn();
mockOnPrevious = jest.fn();
});

const renderer = (props?: CreateNewOrgScreenProps): RenderResult =>
render(
<RegistrationContextProvider {...registrationContextProviderProps}>
<RegistrationWorkflow initialScreenIndex={0}>
<CreateNewOrgScreen {...props} />
</RegistrationWorkflow>
</RegistrationContextProvider>
);

it('renders without crashing', () => {
renderer();

expect(screen.getByText('Create an Organization')).toBeInTheDocument();
expect(screen.getByLabelText('Organization Name')).toBeInTheDocument();
});

it('does not set error state when organization name is long enough', () => {
const { getByLabelText } = renderer();
const verifyOrgNameInput = getByLabelText('Organization Name');
fireEvent.change(verifyOrgNameInput, { target: { value: 'Acme inc.' } });
fireEvent.blur(verifyOrgNameInput);

expect(verifyOrgNameInput).not.toHaveAttribute('aria-invalid', 'true');
});

it('calls onNext when the next button is clicked', () => {
const { getByLabelText, getByText } = renderer({
WorkflowCardActionsProps: {
onNext: mockOnNext(),
showNext: true,
nextLabel: 'Next',
},
});

const orgNameInput = getByLabelText('Organization Name');
fireEvent.change(orgNameInput, { target: { value: 'Acme inc.' } });
const nextButton = getByText('Next');
expect(nextButton).toBeInTheDocument();
expect(screen.getByText(/Next/i)).toBeEnabled();
fireEvent.click(nextButton);

expect(mockOnNext).toHaveBeenCalled();
});

it('calls onPrevious when the back button is clicked', () => {
const { getByText } = renderer({
WorkflowCardActionsProps: {
onPrevious: mockOnPrevious(),
showPrevious: true,
previousLabel: 'Back',
},
});

const backButton = getByText('Back');
expect(backButton).toBeInTheDocument();
expect(screen.getByText(/Back/i)).toBeEnabled();
fireEvent.click(backButton);
expect(mockOnPrevious).toHaveBeenCalled();
});

it('pre-populates the organization name input field with initialValue', () => {
const { getByLabelText } = renderer();

const orgNameInput = getByLabelText('Organization Name');
fireEvent.change(orgNameInput, { target: { value: 'Acme inc.' } });
expect(orgNameInput).toHaveValue('Acme inc.');
});
});
Loading
Loading