Merge pull request #86 from bigcapitalhq/BIG-421-account-form-issues

fix: BIG-421 account form issues
This commit is contained in:
Ahmed Bouhuolia
2023-02-15 21:55:03 +02:00
committed by GitHub
4 changed files with 82 additions and 50 deletions

View File

@@ -5,6 +5,7 @@ import TenancyService from '@/services/Tenancy/TenancyService';
import DynamicListingService from '@/services/DynamicListing/DynamicListService'; import DynamicListingService from '@/services/DynamicListing/DynamicListService';
import { AccountTransformer } from './AccountTransform'; import { AccountTransformer } from './AccountTransform';
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable'; import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
import { flatToNestedArray } from '@/utils';
@Service() @Service()
export class GetAccounts { export class GetAccounts {
@@ -53,11 +54,17 @@ export class GetAccounts {
builder.modify('inactiveMode', filter.inactiveMode); builder.modify('inactiveMode', filter.inactiveMode);
}); });
// Retrievs the formatted accounts collection. // Retrievs the formatted accounts collection.
const transformedAccounts = await this.transformer.transform( const preTransformedAccounts = await this.transformer.transform(
tenantId, tenantId,
accounts, accounts,
new AccountTransformer() new AccountTransformer()
); );
// Transform accounts to nested array.
const transformedAccounts = flatToNestedArray(preTransformedAccounts, {
id: 'id',
parentId: 'parentAccountId',
});
return { return {
accounts: transformedAccounts, accounts: transformedAccounts,
filterMeta: dynamicList.getResponseMeta(), filterMeta: dynamicList.getResponseMeta(),

View File

@@ -3,7 +3,6 @@ import React, { useCallback } from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { Intent } from '@blueprintjs/core'; import { Intent } from '@blueprintjs/core';
import { Formik } from 'formik'; import { Formik } from 'formik';
import { omit } from 'lodash';
import { AppToaster } from '@/components'; import { AppToaster } from '@/components';
import AccountDialogFormContent from './AccountDialogFormContent'; import AccountDialogFormContent from './AccountDialogFormContent';
@@ -14,7 +13,11 @@ import {
CreateAccountFormSchema, CreateAccountFormSchema,
} from './AccountForm.schema'; } from './AccountForm.schema';
import { compose, transformToForm } from '@/utils'; import { compose, transformToForm } from '@/utils';
import { transformApiErrors, transformAccountToForm } from './utils'; import {
transformApiErrors,
transformAccountToForm,
transformFormToReq,
} from './utils';
import '@/style/pages/Accounts/AccountFormDialog.scss'; import '@/style/pages/Accounts/AccountFormDialog.scss';
import { useAccountDialogContext } from './AccountDialogProvider'; import { useAccountDialogContext } from './AccountDialogProvider';
@@ -26,7 +29,7 @@ const defaultInitialValues = {
name: '', name: '',
code: '', code: '',
description: '', description: '',
currency_code:'', currency_code: '',
subaccount: false, subaccount: false,
}; };
@@ -43,7 +46,6 @@ function AccountFormDialogContent({
createAccountMutate, createAccountMutate,
account, account,
accountId,
payload, payload,
isNewMode, isNewMode,
dialogName, dialogName,
@@ -56,7 +58,7 @@ function AccountFormDialogContent({
// Callbacks handles form submit. // Callbacks handles form submit.
const handleFormSubmit = (values, { setSubmitting, setErrors }) => { const handleFormSubmit = (values, { setSubmitting, setErrors }) => {
const form = omit(values, ['subaccount']); const form = transformFormToReq(values);
const toastAccountName = values.code const toastAccountName = values.code
? `${values.code} - ${values.name}` ? `${values.code} - ${values.name}`
: values.name; : values.name;
@@ -90,8 +92,8 @@ function AccountFormDialogContent({
setErrors({ ...errorsTransformed }); setErrors({ ...errorsTransformed });
setSubmitting(false); setSubmitting(false);
}; };
if (accountId) { if (payload.accountId) {
editAccountMutate([accountId, form]) editAccountMutate([payload.accountId, form])
.then(handleSuccess) .then(handleSuccess)
.catch(handleError); .catch(handleError);
} else { } else {
@@ -113,7 +115,6 @@ function AccountFormDialogContent({
defaultInitialValues, defaultInitialValues,
), ),
}; };
// Handles dialog close. // Handles dialog close.
const handleClose = useCallback(() => { const handleClose = useCallback(() => {
closeDialog(dialogName); closeDialog(dialogName);

View File

@@ -26,6 +26,7 @@ import { inputIntent, compose } from '@/utils';
import { useAutofocus } from '@/hooks'; import { useAutofocus } from '@/hooks';
import { FOREIGN_CURRENCY_ACCOUNTS } from '@/constants/accountTypes'; import { FOREIGN_CURRENCY_ACCOUNTS } from '@/constants/accountTypes';
import { useAccountDialogContext } from './AccountDialogProvider'; import { useAccountDialogContext } from './AccountDialogProvider';
import { parentAccountShouldUpdate } from './utils';
/** /**
* Account form dialogs fields. * Account form dialogs fields.
@@ -115,12 +116,7 @@ function AccountFormDialogFields({
> >
<Checkbox <Checkbox
inline={true} inline={true}
label={ label={<T id={'sub_account'} />}
<>
<T id={'sub_account'} />
<Hint />
</>
}
name={'subaccount'} name={'subaccount'}
{...field} {...field}
/> />
@@ -128,37 +124,36 @@ function AccountFormDialogFields({
)} )}
</Field> </Field>
<If condition={values.subaccount}> <FastField
<FastField name={'parent_account_id'}> name={'parent_account_id'}
{({ shouldUpdate={parentAccountShouldUpdate}
form: { values, setFieldValue }, >
field: { value }, {({
meta: { error, touched }, form: { values, setFieldValue },
}) => ( field: { value },
<FormGroup meta: { error, touched },
label={<T id={'parent_account'} />} }) => (
className={classNames( <FormGroup
'form-group--parent-account', label={<T id={'parent_account'} />}
Classes.FILL, className={classNames('form-group--parent-account', Classes.FILL)}
)} inline={true}
inline={true} intent={inputIntent({ error, touched })}
intent={inputIntent({ error, touched })} helperText={<ErrorMessage name="parent_account_id" />}
helperText={<ErrorMessage name="parent_account_id" />} >
> <AccountsSelectList
<AccountsSelectList accounts={accounts}
accounts={accounts} onAccountSelected={(account) => {
onAccountSelected={(account) => { setFieldValue('parent_account_id', account.id);
setFieldValue('parent_account_id', account.id); }}
}} defaultSelectText={<T id={'select_parent_account'} />}
defaultSelectText={<T id={'select_parent_account'} />} selectedAccountId={value}
selectedAccountId={value} popoverFill={true}
popoverFill={true} filterByTypes={values.account_type}
filterByTypes={values.account_type} disabled={!values.subaccount}
/> />
</FormGroup> </FormGroup>
)} )}
</FastField> </FastField>
</If>
<If condition={FOREIGN_CURRENCY_ACCOUNTS.includes(values.account_type)}> <If condition={FOREIGN_CURRENCY_ACCOUNTS.includes(values.account_type)}>
{/*------------ Currency -----------*/} {/*------------ Currency -----------*/}

View File

@@ -2,6 +2,7 @@
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import * as R from 'ramda'; import * as R from 'ramda';
import { isUndefined } from 'lodash'; import { isUndefined } from 'lodash';
import { defaultFastFieldShouldUpdate } from '@/utils';
export const AccountDialogAction = { export const AccountDialogAction = {
Edit: 'edit', Edit: 'edit',
@@ -33,7 +34,7 @@ export const transformApiErrors = (errors) => {
/** /**
* Payload transformer in account edit mode. * Payload transformer in account edit mode.
*/ */
function tranformNewChildAccountPayload(payload) { function tranformNewChildAccountPayload(account, payload) {
return { return {
parent_account_id: payload.parentAccountId || '', parent_account_id: payload.parentAccountId || '',
account_type: payload.accountType || '', account_type: payload.accountType || '',
@@ -44,7 +45,7 @@ function tranformNewChildAccountPayload(payload) {
/** /**
* Payload transformer in new account with defined type. * Payload transformer in new account with defined type.
*/ */
function transformNewDefinedTypePayload(payload) { function transformNewDefinedTypePayload(account, payload) {
return { return {
account_type: payload.accountType || '', account_type: payload.accountType || '',
}; };
@@ -63,7 +64,9 @@ const mergeWithAccount = R.curry((transformed, account) => {
/** /**
* Default account payload transformer. * Default account payload transformer.
*/ */
const defaultPayloadTransform = () => ({}); const defaultPayloadTransform = (account, payload) => ({
subaccount: !!account.parent_account_id,
});
/** /**
* Defined payload transformers. * Defined payload transformers.
@@ -89,7 +92,7 @@ export const transformAccountToForm = (account, payload) => {
return [ return [
condition[0] === payload.action ? R.T : R.F, condition[0] === payload.action ? R.T : R.F,
mergeWithAccount(transformer(payload)), mergeWithAccount(transformer(account, payload)),
]; ];
}); });
return R.cond(results)(account); return R.cond(results)(account);
@@ -106,3 +109,29 @@ export const getDisabledFormFields = (account, payload) => {
payload.action === AccountDialogAction.NewDefinedType, payload.action === AccountDialogAction.NewDefinedType,
}; };
}; };
/**
* Detarmines whether should update the parent account field.
* @param newProps
* @param oldProps
* @returns {boolean}
*/
export const parentAccountShouldUpdate = (newProps, oldProps) => {
return (
newProps.formik.values.subaccount !== oldProps.formik.values.subaccount ||
defaultFastFieldShouldUpdate(newProps, oldProps)
);
};
/**
* Transformes the form values to the request.
*/
export const transformFormToReq = (form) => {
return R.compose(
R.omit(['subaccount']),
R.when(
R.propSatisfies(R.equals(R.__, false), 'subaccount'),
R.assoc(['parent_account_id'], ''),
),
)(form);
};