mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 13:50:31 +00:00
refactoring: account form.
refactoring: expense form. refactoring: manual journal form. refactoring: invoice form.
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import { AccountDialogProvider } from './AccountDialogProvider';
|
||||
import AccountDialogForm from './AccountDialogForm';
|
||||
|
||||
/**
|
||||
* Account dialog content.
|
||||
*/
|
||||
export default function AccountDialogContent({
|
||||
dialogName,
|
||||
accountId,
|
||||
action,
|
||||
parentAccountId,
|
||||
accountType,
|
||||
}) {
|
||||
|
||||
return (
|
||||
<AccountDialogProvider
|
||||
dialogName={dialogName}
|
||||
accountId={accountId}
|
||||
action={action}
|
||||
parentAccountId={parentAccountId}
|
||||
accountType={accountType}
|
||||
>
|
||||
<AccountDialogForm />
|
||||
</AccountDialogProvider>
|
||||
);
|
||||
}
|
||||
@@ -3,27 +3,20 @@ import { Intent } from '@blueprintjs/core';
|
||||
import { Formik } from 'formik';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { omit } from 'lodash';
|
||||
import { AppToaster, DialogContent } from 'components';
|
||||
import { AppToaster } from 'components';
|
||||
|
||||
import AccountFormDialogFields from './AccountFormDialogFields';
|
||||
import AccountDialogFormContent from './AccountDialogFormContent';
|
||||
|
||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
import {
|
||||
EditAccountFormSchema,
|
||||
CreateAccountFormSchema,
|
||||
} from './AccountForm.schema';
|
||||
import {
|
||||
useAccounts,
|
||||
useAccountsTypes,
|
||||
useCreateAccount,
|
||||
useAccount,
|
||||
useEditAccount
|
||||
} from 'hooks/query';
|
||||
import { compose, transformToForm } from 'utils';
|
||||
import { transformApiErrors, transformAccountToForm } from './utils';
|
||||
|
||||
import 'style/pages/Accounts/AccountFormDialog.scss';
|
||||
|
||||
import { useAccountDialogContext } from './AccountDialogProvider';
|
||||
|
||||
// Default initial form values.
|
||||
const defaultInitialValues = {
|
||||
@@ -41,43 +34,28 @@ const defaultInitialValues = {
|
||||
function AccountFormDialogContent({
|
||||
// #withDialogActions
|
||||
closeDialog,
|
||||
|
||||
// #ownProp
|
||||
dialogName,
|
||||
accountId,
|
||||
action,
|
||||
parentAccountId,
|
||||
accountType,
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
const isNewMode = !accountId;
|
||||
|
||||
// Account form context.
|
||||
const {
|
||||
editAccountMutate,
|
||||
createAccountMutate,
|
||||
account,
|
||||
|
||||
accountId,
|
||||
action,
|
||||
parentAccountId,
|
||||
accountType,
|
||||
isNewMode,
|
||||
dialogName
|
||||
} = useAccountDialogContext();
|
||||
|
||||
// Form validation schema in create and edit mode.
|
||||
const validationSchema = isNewMode
|
||||
? CreateAccountFormSchema
|
||||
: EditAccountFormSchema;
|
||||
|
||||
const { mutateAsync: createAccountMutate } = useCreateAccount();
|
||||
const { mutateAsync: editAccountMutate } = useEditAccount();
|
||||
|
||||
// Fetches accounts list.
|
||||
const {
|
||||
data: accounts,
|
||||
isLoading: isAccountsLoading,
|
||||
} = useAccounts();
|
||||
|
||||
// Fetches accounts types.
|
||||
const {
|
||||
data: accountsTypes,
|
||||
isLoading: isAccountsTypesLoading
|
||||
} = useAccountsTypes();
|
||||
|
||||
// Fetches the specific account details.
|
||||
const {
|
||||
data: account,
|
||||
isLoading: isAccountLoading,
|
||||
} = useAccount(accountId, { enabled: !!accountId });
|
||||
|
||||
// Callbacks handles form submit.
|
||||
const handleFormSubmit = (values, { setSubmitting, setErrors }) => {
|
||||
const form = omit(values, ['subaccount']);
|
||||
@@ -106,18 +84,22 @@ function AccountFormDialogContent({
|
||||
};
|
||||
// Handle request error.
|
||||
const handleError = (error) => {
|
||||
const { response: { data: { errors } } } = error;
|
||||
const {
|
||||
response: {
|
||||
data: { errors },
|
||||
},
|
||||
} = error;
|
||||
|
||||
const errorsTransformed = transformApiErrors(errors);
|
||||
setErrors({ ...errorsTransformed });
|
||||
setSubmitting(false);
|
||||
};
|
||||
if (accountId) {
|
||||
editAccountMutate(accountId, form)
|
||||
editAccountMutate([accountId, form]).then(handleSuccess).catch(handleError);
|
||||
} else {
|
||||
createAccountMutate({ ...form })
|
||||
.then(handleSuccess)
|
||||
.catch(handleError);
|
||||
} else {
|
||||
createAccountMutate({ ...form }).then(handleSuccess).catch(handleError);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -144,30 +126,19 @@ function AccountFormDialogContent({
|
||||
closeDialog(dialogName);
|
||||
}, [closeDialog, dialogName]);
|
||||
|
||||
const isFetching =
|
||||
isAccountsLoading ||
|
||||
isAccountsTypesLoading ||
|
||||
isAccountLoading;
|
||||
|
||||
return (
|
||||
<DialogContent isLoading={isFetching}>
|
||||
<Formik
|
||||
validationSchema={validationSchema}
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleFormSubmit}
|
||||
>
|
||||
<AccountFormDialogFields
|
||||
accounts={accounts}
|
||||
accountsTypes={accountsTypes}
|
||||
dialogName={dialogName}
|
||||
action={action}
|
||||
onClose={handleClose}
|
||||
/>
|
||||
</Formik>
|
||||
</DialogContent>
|
||||
<Formik
|
||||
validationSchema={validationSchema}
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleFormSubmit}
|
||||
>
|
||||
<AccountDialogFormContent
|
||||
dialogName={dialogName}
|
||||
action={action}
|
||||
onClose={handleClose}
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
)(AccountFormDialogContent);
|
||||
export default compose(withDialogActions)(AccountFormDialogContent);
|
||||
@@ -23,6 +23,7 @@ import withAccounts from 'containers/Accounts/withAccounts';
|
||||
import { inputIntent } from 'utils';
|
||||
import { compose } from 'redux';
|
||||
import { useAutofocus } from 'hooks';
|
||||
import { useAccountDialogContext } from './AccountDialogProvider';
|
||||
|
||||
/**
|
||||
* Account form dialogs fields.
|
||||
@@ -31,12 +32,13 @@ function AccountFormDialogFields({
|
||||
// #ownProps
|
||||
onClose,
|
||||
action,
|
||||
accounts,
|
||||
accountsTypes,
|
||||
}) {
|
||||
const { values, isSubmitting } = useFormikContext();
|
||||
const accountNameFieldRef = useAutofocus();
|
||||
|
||||
// Account form context.
|
||||
const { accounts, accountsTypes } = useAccountDialogContext();
|
||||
|
||||
return (
|
||||
<Form>
|
||||
<div className={Classes.DIALOG_BODY}>
|
||||
@@ -0,0 +1,75 @@
|
||||
import React, { createContext, useContext } from 'react';
|
||||
import { DialogContent } from 'components';
|
||||
import {
|
||||
useCreateAccount,
|
||||
useAccountsTypes,
|
||||
useAccount,
|
||||
useAccounts,
|
||||
useEditAccount,
|
||||
} from 'hooks/query';
|
||||
|
||||
const AccountDialogContext = createContext();
|
||||
|
||||
/**
|
||||
* Account form provider.
|
||||
*/
|
||||
function AccountDialogProvider({
|
||||
accountId,
|
||||
parentAccountId,
|
||||
action,
|
||||
accountType,
|
||||
|
||||
dialogName,
|
||||
...props
|
||||
}) {
|
||||
// Create and edit account mutations.
|
||||
const { mutateAsync: createAccountMutate } = useCreateAccount();
|
||||
const { mutateAsync: editAccountMutate } = useEditAccount();
|
||||
|
||||
// Fetches accounts list.
|
||||
const { data: accounts, isLoading: isAccountsLoading } = useAccounts();
|
||||
|
||||
// Fetches accounts types.
|
||||
const {
|
||||
data: accountsTypes,
|
||||
isLoading: isAccountsTypesLoading,
|
||||
} = useAccountsTypes();
|
||||
|
||||
// Fetches the specific account details.
|
||||
const { data: account, isLoading: isAccountLoading } = useAccount(accountId, {
|
||||
enabled: !!accountId,
|
||||
});
|
||||
|
||||
const isNewMode = !accountId;
|
||||
|
||||
// Provider payload.
|
||||
const provider = {
|
||||
dialogName,
|
||||
accountId,
|
||||
parentAccountId,
|
||||
action,
|
||||
accountType,
|
||||
|
||||
createAccountMutate,
|
||||
editAccountMutate,
|
||||
accounts,
|
||||
accountsTypes,
|
||||
account,
|
||||
|
||||
isAccountsLoading,
|
||||
isNewMode
|
||||
};
|
||||
|
||||
const isLoading =
|
||||
isAccountsLoading || isAccountsTypesLoading || isAccountLoading;
|
||||
|
||||
return (
|
||||
<DialogContent isLoading={isLoading}>
|
||||
<AccountDialogContext.Provider value={provider} {...props} />
|
||||
</DialogContent>
|
||||
);
|
||||
}
|
||||
|
||||
const useAccountDialogContext = () => useContext(AccountDialogContext);
|
||||
|
||||
export { AccountDialogProvider, useAccountDialogContext };
|
||||
@@ -4,7 +4,7 @@ import { Dialog, DialogSuspense } from 'components';
|
||||
import withDialogRedux from 'components/DialogReduxConnect';
|
||||
import { compose } from 'utils';
|
||||
|
||||
const AccountFormDialogContent = lazy(() => import('./AccountFormDialogContent'));
|
||||
const AccountDialogContent = lazy(() => import('./AccountDialogContent'));
|
||||
|
||||
/**
|
||||
* Account form dialog.
|
||||
@@ -28,7 +28,7 @@ function AccountFormDialog({
|
||||
isOpen={isOpen}
|
||||
>
|
||||
<DialogSuspense>
|
||||
<AccountFormDialogContent
|
||||
<AccountDialogContent
|
||||
dialogName={dialogName}
|
||||
accountId={payload.id}
|
||||
action={payload.action}
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { DialogContent } from 'components';
|
||||
import { useQuery, queryCache } from 'react-query';
|
||||
import { useSaveSettings } from 'hooks/query';
|
||||
|
||||
import { InvoiceNumberDialogProvider } from './InvoiceNumberDialogProvider';
|
||||
import ReferenceNumberForm from 'containers/JournalNumber/ReferenceNumberForm';
|
||||
|
||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
@@ -19,52 +19,41 @@ function InvoiceNumberDialogContent({
|
||||
// #withSettings
|
||||
nextNumber,
|
||||
numberPrefix,
|
||||
|
||||
// #withSettingsActions
|
||||
requestFetchOptions,
|
||||
requestSubmitOptions,
|
||||
|
||||
|
||||
// #withDialogActions
|
||||
closeDialog,
|
||||
|
||||
// #withInvoicesActions
|
||||
// setInvoiceNumberChanged,
|
||||
}) {
|
||||
const fetchSettings = useQuery(['settings'], () => requestFetchOptions({}));
|
||||
const { mutateAsync: saveSettings } = useSaveSettings();
|
||||
|
||||
const handleSubmitForm = (values, { setSubmitting }) => {
|
||||
const options = optionsMapToArray(values).map((option) => {
|
||||
return { key: option.key, ...option, group: 'sales_invoices' };
|
||||
});
|
||||
|
||||
requestSubmitOptions({ options })
|
||||
saveSettings({ options })
|
||||
.then(() => {
|
||||
setSubmitting(false);
|
||||
closeDialog('invoice-number-form');
|
||||
|
||||
setTimeout(() => {
|
||||
queryCache.invalidateQueries('settings');
|
||||
// setInvoiceNumberChanged(true);
|
||||
}, 250);
|
||||
})
|
||||
.catch(() => {
|
||||
setSubmitting(false);
|
||||
});
|
||||
};
|
||||
|
||||
// Handle the dialog close.
|
||||
const handleClose = useCallback(() => {
|
||||
closeDialog('invoice-number-form');
|
||||
}, [closeDialog]);
|
||||
|
||||
return (
|
||||
<DialogContent isLoading={fetchSettings.isFetching}>
|
||||
<InvoiceNumberDialogProvider>
|
||||
<ReferenceNumberForm
|
||||
initialNumber={nextNumber}
|
||||
initialPrefix={numberPrefix}
|
||||
onSubmit={handleSubmitForm}
|
||||
onClose={handleClose}
|
||||
/>
|
||||
</DialogContent>
|
||||
</InvoiceNumberDialogProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import React, { createContext, useContext } from 'react';
|
||||
import { DialogContent } from 'components';
|
||||
import { useSettings } from 'hooks/query';
|
||||
|
||||
const InvoiceNumberDialogContext = createContext();
|
||||
|
||||
/**
|
||||
* Invoice number dialog provider.
|
||||
*/
|
||||
function InvoiceNumberDialogProvider({ query, ...props }) {
|
||||
const { isLoading } = useSettings();
|
||||
|
||||
// Provider payload.
|
||||
const provider = {
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<DialogContent isLoading={isLoading}>
|
||||
<InvoiceNumberDialogContext.Provider value={provider} {...props} />
|
||||
</DialogContent>
|
||||
);
|
||||
}
|
||||
|
||||
const useInvoiceNumberDialogContext = () =>
|
||||
useContext(InvoiceNumberDialogContext);
|
||||
|
||||
export { InvoiceNumberDialogProvider, useInvoiceNumberDialogContext };
|
||||
@@ -43,10 +43,6 @@ function JournalNumberDialogContent({
|
||||
setSubmitting(false);
|
||||
closeDialog('journal-number-form');
|
||||
|
||||
setTimeout(() => {
|
||||
queryCache.invalidateQueries('settings');
|
||||
// setJournalNumberChanged(true);
|
||||
}, 250);
|
||||
}).catch(() => {
|
||||
setSubmitting(false);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user