fix(Setup): fix organization setup.

This commit is contained in:
a.bouhuolia
2021-03-20 18:59:40 +02:00
parent e801d5d618
commit 671af0daae
46 changed files with 517 additions and 445 deletions

View File

@@ -1,53 +1,49 @@
import React, { useEffect } from 'react';
import { useQuery } from 'react-query';
import { withWizard } from 'react-albus'
import { ProgressBar, Intent } from '@blueprintjs/core';
import { useBuildTenant } from 'hooks/query';
import 'style/pages/Setup/Initializing.scss';
import withOrganizationActions from 'containers/Organization/withOrganizationActions';
import { compose } from 'utils';
/**
* Setup initializing step form.
*/
function SetupInitializingForm({
// #withOrganizationActions
requestOrganizationBuild,
wizard: { next },
}) {
const { isSuccess } = useQuery(
['build-tenant'], () => requestOrganizationBuild(),
);
export default function SetupInitializingForm() {
const {
mutateAsync: buildTenantMutate,
isLoading,
isError,
} = useBuildTenant();
useEffect(() => {
if (isSuccess) {
next();
}
}, [isSuccess, next]);
buildTenantMutate();
}, [buildTenantMutate]);
return (
<div class="setup-initializing-form">
<ProgressBar intent={Intent.PRIMARY} value={null} />
{isLoading && <ProgressBar intent={Intent.PRIMARY} value={null} />}
<div className={'setup-initializing-form__title'}>
<h1>
{/* You organization is initializin... */}
It's time to make your accounting really simple!
</h1>
<p className={'paragraph'}>
while we set up your account, please remember to verify your account by
clicking on the link we sent to yout registered email address
</p>
{isLoading ? (
<>
<h1>It's time to make your accounting really simple!</h1>
<p className={'paragraph'}>
while we set up your account, please remember to verify your
account by clicking on the link we sent to yout registered email
address
</p>
</>
) : isError ? (
<>
<h1>Something went wrong!</h1>
<p class="paragraph">Please refresh the page</p>
</>
) : (
<>
<h1>Waiting to redirect</h1>
<p class="paragraph">Refresh the page if redirect not worked.</p>
</>
)}
</div>
</div>
);
}
export default compose(
withOrganizationActions,
withWizard,
)(SetupInitializingForm);

View File

@@ -14,7 +14,7 @@ import classNames from 'classnames';
import { TimezonePicker } from '@blueprintjs/timezone';
import { FormattedMessage as T } from 'react-intl';
import { Col, Row, ListSelect } from 'components';
import { FieldRequiredHint, Col, Row, ListSelect } from 'components';
import {
momentFormatter,
tansformDateValue,
@@ -38,9 +38,10 @@ export default function SetupOrganizationForm({ isSubmitting, values }) {
</h3>
{/* ---------- Organization name ---------- */}
<FastField name={'name'}>
<FastField name={'organization_name'}>
{({ form, field, meta: { error, touched } }) => (
<FormGroup
labelInfo={<FieldRequiredHint />}
label={<T id={'legal_organization_name'} />}
className={'form-group--name'}
intent={inputIntent({ error, touched })}
@@ -55,6 +56,7 @@ export default function SetupOrganizationForm({ isSubmitting, values }) {
<FastField name={'financialDateStart'}>
{({ form: { setFieldValue }, field: { value }, meta: { error, touched } }) => (
<FormGroup
labelInfo={<FieldRequiredHint />}
label={<T id={'financial_starting_date'} />}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="financialDateStart" />}
@@ -82,6 +84,7 @@ export default function SetupOrganizationForm({ isSubmitting, values }) {
meta: { error, touched },
}) => (
<FormGroup
labelInfo={<FieldRequiredHint />}
label={<T id={'base_currency'} />}
className={classNames(
'form-group--base-currency',
@@ -137,6 +140,7 @@ export default function SetupOrganizationForm({ isSubmitting, values }) {
selectedItemProp={'value'}
defaultText={<T id={'select_language'} />}
popoverProps={{ minimal: true }}
filterable={false}
/>
</FormGroup>
)}
@@ -147,6 +151,7 @@ export default function SetupOrganizationForm({ isSubmitting, values }) {
<FastField name={'fiscalYear'}>
{({ form: { setFieldValue }, field: { value }, meta: { error, touched } }) => (
<FormGroup
labelInfo={<FieldRequiredHint />}
label={<T id={'fiscal_year'} />}
className={classNames(
'form-group--fiscal_year',
@@ -167,6 +172,7 @@ export default function SetupOrganizationForm({ isSubmitting, values }) {
onItemSelect={(item) => {
setFieldValue('fiscalYear', item.value)
}}
filterable={false}
/>
</FormGroup>
)}
@@ -180,6 +186,7 @@ export default function SetupOrganizationForm({ isSubmitting, values }) {
meta: { error, touched },
}) => (
<FormGroup
labelInfo={<FieldRequiredHint />}
label={<T id={'time_zone'} />}
className={classNames(
'form-group--time-zone',

View File

@@ -3,49 +3,33 @@ import * as Yup from 'yup';
import { Formik } from 'formik';
import moment from 'moment';
import { FormattedMessage as T, useIntl } from 'react-intl';
import { snakeCase } from 'lodash';
import { withWizard } from 'react-albus';
import { useQuery } from 'react-query';
import 'style/pages/Setup/Organization.scss';
import SetupOrganizationForm from './SetupOrganizationForm';
import { useOrganizationSetup } from 'hooks/query';
import withSettingsActions from 'containers/Settings/withSettingsActions';
import withSettings from 'containers/Settings/withSettings';
import withOrganizationActions from 'containers/Organization/withOrganizationActions';
import {
compose,
transformToForm,
optionsMapToArray,
transfromToSnakeCase,
} from 'utils';
/**
* Setup organization form.
*/
function SetupOrganizationPage({
// #withSettingsActions
requestSubmitOptions,
requestFetchOptions,
// #withOrganizationActions
requestOrganizationSeed,
// #withSettings
organizationSettings,
wizard,
setOrganizationSetupCompleted,
}) {
const { formatMessage } = useIntl();
const fetchSettings = useQuery(['settings'], () => requestFetchOptions({}));
const { mutateAsync: organizationSetupMutate } = useOrganizationSetup();
// Validation schema.
const validationSchema = Yup.object().shape({
name: Yup.string()
organization_name: Yup.string()
.required()
.label(formatMessage({ id: 'organization_name_' })),
financialDateStart: Yup.date()
@@ -67,35 +51,21 @@ function SetupOrganizationPage({
// Initial values.
const defaultValues = {
name: '',
organization_name: '',
financialDateStart: moment(new Date()).format('YYYY-MM-DD'),
baseCurrency: '',
language: '',
language: 'en',
fiscalYear: '',
timeZone: '',
...organizationSettings,
};
const initialValues = {
...defaultValues,
/**
* We only care about the fields in the form. Previously unfilled optional
* values such as `notes` come back from the API as null, so remove those
* as well.
*/
...transformToForm(organizationSettings, defaultValues),
};
// Handle the form submit.
const handleSubmit = (values, { setSubmitting, setErrors }) => {
const options = optionsMapToArray(values).map((option) => {
return { ...option, key: snakeCase(option.key), group: 'organization' };
});
requestSubmitOptions({ options })
.then(() => {
return requestOrganizationSeed();
})
organizationSetupMutate({ ...transfromToSnakeCase(values) })
.then(() => {
return setOrganizationSetupCompleted(true);
})
@@ -132,8 +102,4 @@ function SetupOrganizationPage({
export default compose(
withSettingsActions,
withOrganizationActions,
withWizard,
withSettings(({ organizationSettings }) => ({
organizationSettings,
})),
)(SetupOrganizationPage);

View File

@@ -1,13 +1,9 @@
import React from 'react';
import { Wizard } from 'react-albus';
import { useHistory } from 'react-router-dom';
import withSubscriptions from 'containers/Subscriptions/withSubscriptions';
import SetupDialogs from './SetupDialogs';
import SetupWizardContent from './SetupWizardContent';
import withSubscriptions from 'containers/Subscriptions/withSubscriptions';
import withOrganization from 'containers/Organization/withOrganization';
import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
import withSetupWizard from '../../store/organizations/withSetupWizard';
@@ -24,37 +20,17 @@ function SetupRightSection({
isOrganizationSetupCompleted,
// #withSetupWizard
isCongratsStep,
isSubscriptionStep,
isInitializingStep,
isOrganizationStep,
setupStepId,
setupStepIndex,
// #withSubscriptions
isSubscriptionActive,
}) {
const history = useHistory();
const handleSkip = ({ step, push }) => {
const scenarios = [
{ condition: isCongratsStep, redirectTo: 'congrats' },
{ condition: isSubscriptionStep, redirectTo: 'subscription' },
{ condition: isInitializingStep, redirectTo: 'initializing' },
{ condition: isOrganizationStep, redirectTo: 'organization' },
];
const scenario = scenarios.find((scenario) => scenario.condition);
if (scenario) {
push(scenario.redirectTo);
}
};
return (
<section className={'setup-page__right-section'}>
<Wizard
onNext={handleSkip}
basename={'/setup'}
history={history}
render={SetupWizardContent}
<SetupWizardContent
setupStepId={setupStepId}
setupStepIndex={setupStepIndex}
/>
<SetupDialogs />
</section>
@@ -84,17 +60,8 @@ export default compose(
}),
'main',
),
withSetupWizard(
({
isCongratsStep,
isSubscriptionStep,
isInitializingStep,
isOrganizationStep,
}) => ({
isCongratsStep,
isSubscriptionStep,
isInitializingStep,
isOrganizationStep,
}),
),
withSetupWizard(({ setupStepId, setupStepIndex }) => ({
setupStepId,
setupStepIndex,
})),
)(SetupRightSection);

View File

@@ -0,0 +1,8 @@
import React from 'react';
export default function SetupSteps({ step, children }) {
const activeStep = React.Children.toArray(children).filter(
(child) => child.props.id === step.id,
);
return activeStep;
}

View File

@@ -1,21 +1,15 @@
import React from 'react';
import { Formik } from 'formik';
import { withWizard } from 'react-albus';
import 'style/pages/Setup/Subscription.scss';
import SetupSubscriptionForm from './SetupSubscriptionForm';
import { SubscriptionFormSchema } from './SubscriptionForm.schema';
import { compose } from 'utils';
/**
* Subscription step of wizard setup.
*/
function SetupSubscription({
// #withWizard
wizard,
}) {
export default function SetupSubscription() {
// Initial values.
const initialValues = {
plan_slug: 'free',
@@ -23,6 +17,7 @@ function SetupSubscription({
license_code: '',
};
// Handle form submit.
const handleSubmit = () => {};
return (
@@ -35,8 +30,4 @@ function SetupSubscription({
/>
</div>
);
}
export default compose(
withWizard,
)(SetupSubscription);
}

View File

@@ -1,7 +1,6 @@
import React from 'react';
import { Steps, Step } from 'react-albus';
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import SetupSteps from './SetupSteps';
import WizardSetupSteps from './WizardSetupSteps';
import SetupSubscription from './SetupSubscription';
@@ -12,37 +11,19 @@ import SetupCongratsPage from './SetupCongratsPage';
/**
* Setup wizard content.
*/
export default function SetupWizardContent({
step,
steps
}) {
export default function SetupWizardContent({ setupStepIndex, setupStepId }) {
return (
<div class="setup-page__content">
<WizardSetupSteps currentStep={steps.indexOf(step) + 1} />
<WizardSetupSteps currentStep={setupStepIndex} />
<TransitionGroup>
<CSSTransition key={step.id} timeout={{ enter: 500, exit: 500 }}>
<div class="setup-page-form">
<Steps key={step.id} step={step}>
<Step id="subscription">
<SetupSubscription />
</Step>
<Step id={'initializing'}>
<SetupInitializingForm />
</Step>
<Step id="organization">
<SetupOrganizationPage />
</Step>
<Step id="congrats">
<SetupCongratsPage />
</Step>
</Steps>
</div>
</CSSTransition>
</TransitionGroup>
<div class="setup-page-form">
<SetupSteps step={{ id: setupStepId }}>
<SetupSubscription id="subscription" />
<SetupInitializingForm id={'initializing'} />
<SetupOrganizationPage id="organization" />
<SetupCongratsPage id="congrats" />
</SetupSteps>
</div>
</div>
);
}

View File

@@ -1,22 +1,19 @@
import React from 'react';
import classNames from 'classnames';
import { FormattedMessage as T } from 'react-intl';
import { registerWizardSteps } from 'common/registerWizard'
import { registerWizardSteps } from 'common/registerWizard';
function WizardSetupStep({
label,
isActive = false
}) {
function WizardSetupStep({ label, isActive = false }) {
return (
<li className={classNames({ 'is-active': isActive })}>
<p className={'wizard-info'}><T id={label} /></p>
<p className={'wizard-info'}>
<T id={label} />
</p>
</li>
);
}
function WizardSetupSteps({
currentStep = 1,
}) {
export default function WizardSetupSteps({ currentStep = 1 }) {
return (
<div className={'setup-page-steps-container'}>
<div className={'setup-page-steps'}>
@@ -24,7 +21,7 @@ function WizardSetupSteps({
{registerWizardSteps.map((step, index) => (
<WizardSetupStep
label={step.label}
isActive={(index + 1) == currentStep}
isActive={index + 1 === currentStep}
/>
))}
</ul>
@@ -32,5 +29,3 @@ function WizardSetupSteps({
</div>
);
}
export default WizardSetupSteps;