feat: organization setup.

This commit is contained in:
a.bouhuolia
2021-09-04 10:04:07 +02:00
parent f2c51c6023
commit 8141674da8
18 changed files with 188 additions and 252 deletions

View File

@@ -2,37 +2,30 @@ import { connect } from 'react-redux';
import {
getOrganizationByIdFactory,
isOrganizationReadyFactory,
isOrganizationSeededFactory,
isOrganizationBuiltFactory,
isOrganizationSeedingFactory,
isOrganizationInitializingFactory,
isOrganizationSubscribedFactory,
isOrganizationCongratsFactory,
isOrganizationBuildRunningFactory
} from 'store/organizations/organizations.selectors';
export default (mapState) => {
const getOrganizationById = getOrganizationByIdFactory();
const isOrganizationReady = isOrganizationReadyFactory();
const isOrganizationSeeded = isOrganizationSeededFactory();
const isOrganizationBuilt = isOrganizationBuiltFactory();
const isOrganizationInitializing = isOrganizationInitializingFactory();
const isOrganizationSeeding = isOrganizationSeedingFactory();
const isOrganizationSubscribed = isOrganizationSubscribedFactory();
const isOrganizationCongrats = isOrganizationCongratsFactory();
const isOrganizationBuildRunning = isOrganizationBuildRunningFactory();
const mapStateToProps = (state, props) => {
const mapped = {
organization: getOrganizationById(state, props),
isOrganizationReady: isOrganizationReady(state, props),
isOrganizationSeeded: isOrganizationSeeded(state, props),
isOrganizationInitialized: isOrganizationBuilt(state, props),
isOrganizationSeeding: isOrganizationInitializing(state, props),
isOrganizationInitializing: isOrganizationSeeding(state, props),
isOrganizationSubscribed: isOrganizationSubscribed(state, props),
isOrganizationSetupCompleted: isOrganizationCongrats(state, props),
isOrganizationBuildRunning: isOrganizationBuildRunning(state, props)
};
return (mapState) ? mapState(mapped, state, props) : mapped;
};

View File

@@ -1,62 +1,108 @@
import React, { useEffect } from 'react';
import React from 'react';
import { ProgressBar, Intent } from '@blueprintjs/core';
import { useBuildTenant } from 'hooks/query';
import * as R from 'ramda';
import { useJob, useCurrentOrganization } from 'hooks/query';
import { FormattedMessage as T } from 'components';
import withOrganizationActions from 'containers/Organization/withOrganizationActions';
import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
import withOrganization from '../Organization/withOrganization';
import 'style/pages/Setup/Initializing.scss';
/**
* Setup initializing step form.
*/
export default function SetupInitializingForm() {
function SetupInitializingForm({
setOrganizationSetupCompleted,
organization,
}) {
const { refetch, isSuccess } = useCurrentOrganization({ enabled: false });
const [isJobDone, setIsJobDone] = React.useState(false);
const {
mutateAsync: buildTenantMutate,
isLoading,
isError,
} = useBuildTenant();
data: { running, queued, failed, completed },
} = useJob(organization?.build_job_id, {
refetchInterval: 2000,
enabled: !!organization?.build_job_id,
});
React.useEffect(() => {
buildTenantMutate();
}, [buildTenantMutate]);
if (completed) {
refetch();
setIsJobDone(true);
}
}, [refetch, completed, setOrganizationSetupCompleted]);
React.useEffect(() => {
if (isSuccess && isJobDone) {
setOrganizationSetupCompleted(true);
setIsJobDone(false);
}
}, [setOrganizationSetupCompleted, isJobDone, isSuccess]);
return (
<div class="setup-initializing-form">
{isLoading && <ProgressBar intent={Intent.PRIMARY} value={null} />}
<ProgressBar intent={Intent.PRIMARY} value={null} />
<div className={'setup-initializing-form__title'}>
{isLoading ? (
<>
<h1>
<T id={'setup.initializing.title'} />
</h1>
<p className={'paragraph'}>
<T id={'setup.initializing.description'} />
</p>
</>
) : isError ? (
<>
<h1>
<T id={'setup.initializing.something_went_wrong'} />
</h1>
<p class="paragraph">
<T id={'setup.initializing.please_refresh_the_page'} />
</p>
</>
) : (
<>
<h1>
<T id={'setup.initializing.waiting_to_redirect'} />
</h1>
<p class="paragraph">
<T
id={
'setup.initializing.refresh_the_page_if_redirect_not_worked'
}
/>
</p>
</>
)}
{failed ? (
<SetupInitializingFailed />
) : running || queued ? (
<SetupInitializingRunning />
) : completed ? (
<SetupInitializingCompleted />
) : null}
</div>
</div>
);
}
export default R.compose(
withOrganizationActions,
withCurrentOrganization(({ organizationTenantId }) => ({
organizationId: organizationTenantId,
})),
withOrganization(({ organization }) => ({ organization })),
)(SetupInitializingForm);
function SetupInitializingFailed() {
return (
<div class="failed">
<h1>
<T id={'setup.initializing.something_went_wrong'} />
</h1>
<p class="paragraph">
<T id={'setup.initializing.please_refresh_the_page'} />
</p>
</div>
);
}
function SetupInitializingRunning() {
return (
<div class="running">
<h1>
<T id={'setup.initializing.title'} />
</h1>
<p className={'paragraph'}>
<T id={'setup.initializing.description'} />
</p>
</div>
);
}
function SetupInitializingCompleted() {
return (
<div class="completed">
<h1>
<T id={'setup.initializing.waiting_to_redirect'} />
</h1>
<p class="paragraph">
<T id={'setup.initializing.refresh_the_page_if_redirect_not_worked'} />
</p>
</div>
);
}

View File

@@ -11,5 +11,5 @@ export const getSetupOrganizationValidation = () =>
baseCurrency: Yup.string().required().label(intl.get('base_currency_')),
language: Yup.string().required().label(intl.get('language')),
fiscalYear: Yup.string().required().label(intl.get('fiscal_year_')),
timeZone: Yup.string().required().label(intl.get('time_zone_')),
timezone: Yup.string().required().label(intl.get('time_zone_')),
});

View File

@@ -195,7 +195,7 @@ export default function SetupOrganizationForm({ isSubmitting, values }) {
</FastField>
{/* ---------- Time zone ---------- */}
<FastField name={'timeZone'}>
<FastField name={'timezone'}>
{({
form: { setFieldValue },
field: { value },
@@ -209,12 +209,12 @@ export default function SetupOrganizationForm({ isSubmitting, values }) {
Classes.FILL,
)}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name={'timeZone'} />}
helperText={<ErrorMessage name={'timezone'} />}
>
<TimezonePicker
value={value}
onChange={(item) => {
setFieldValue('timeZone', item);
setFieldValue('timezone', item);
}}
valueDisplayFormat="composite"
showLocalTimezone={true}

View File

@@ -3,7 +3,6 @@ import { Formik } from 'formik';
import moment from 'moment';
import { FormattedMessage as T } from 'components';
import 'style/pages/Setup/Organization.scss';
import SetupOrganizationForm from './SetupOrganizationForm';
@@ -15,7 +14,6 @@ import withOrganizationActions from 'containers/Organization/withOrganizationAct
import { compose, transfromToSnakeCase } from 'utils';
import { getSetupOrganizationValidation } from './SetupOrganization.schema';
// Initial values.
const defaultValues = {
organization_name: '',
@@ -23,7 +21,7 @@ const defaultValues = {
baseCurrency: '',
language: 'en',
fiscalYear: '',
timeZone: '',
timezone: '',
};
/**
@@ -43,9 +41,6 @@ function SetupOrganizationPage({ wizard, setOrganizationSetupCompleted }) {
// Handle the form submit.
const handleSubmit = (values, { setSubmitting, setErrors }) => {
organizationSetupMutate({ ...transfromToSnakeCase(values) })
.then(() => {
return setOrganizationSetupCompleted(true);
})
.then((response) => {
setSubmitting(false);
wizard.next();

View File

@@ -47,11 +47,13 @@ export default compose(
isOrganizationInitialized,
isOrganizationSeeded,
isOrganizationSetupCompleted,
isOrganizationBuildRunning,
}) => ({
organization,
isOrganizationInitialized,
isOrganizationSeeded,
isOrganizationSetupCompleted,
isOrganizationBuildRunning,
}),
),
withSubscriptions(

View File

@@ -19,8 +19,8 @@ export default function SetupWizardContent({ setupStepIndex, setupStepId }) {
<div class="setup-page-form">
<SetupSteps step={{ id: setupStepId }}>
<SetupSubscription id="subscription" />
<SetupInitializingForm id={'initializing'} />
<SetupOrganizationPage id="organization" />
<SetupInitializingForm id={'initializing'} />
<SetupCongratsPage id="congrats" />
</SetupSteps>
</div>