Fix: Item Category Dialog

This commit is contained in:
elforjani3
2020-11-09 20:43:13 +02:00
parent f151e6242e
commit e4f720fe49
5 changed files with 109 additions and 244 deletions

View File

@@ -3,13 +3,13 @@ import React, { lazy } from 'react';
import AccountFormDialog from 'containers/Dialogs/AccountFormDialog';
import UserFormDialog from 'containers/Dialogs/UserFormDialog';
// import ItemCategoryDialog from 'containers/Dialogs/ItemCategoryDialog';
import ItemCategoryDialog from 'containers/Dialogs/ItemCategoryDialog';
import CurrencyFormDialog from 'containers/Dialogs/CurrencyFormDialog';
// import InviteUserDialog from 'containers/Dialogs/InviteUserDialog';
import ExchangeRateFormDialog from 'containers/Dialogs/ExchangeRateFormDialog';
import JournalNumberDialog from 'containers/Dialogs/JournalNumberDialog';
import BillNumberDialog from 'containers/Dialogs/BillNumberDialog';
import PaymentNumberDialog from 'containers/Dialogs/PaymentNumberDialog';
// import BillNumberDialog from 'containers/Dialogs/BillNumberDialog';
import PaymentReceiveNumberDialog from 'containers/Dialogs/PaymentReceiveNumberDialog';
import EstimateNumberDialog from 'containers/Dialogs/EstimateNumberDialog';
import ReceiptNumberDialog from 'containers/Dialogs/ReceiptNumberDialog';
import InvoiceNumberDialog from 'containers/Dialogs/InvoiceNumberDialog';
@@ -18,14 +18,15 @@ export default function DialogsContainer() {
<div>
<AccountFormDialog dialogName={'account-form'} />
<JournalNumberDialog dialogName={'journal-number-form'} />
<BillNumberDialog dialogName={'bill-number-form'} />
<PaymentNumberDialog dialogName={'payment-number-form'} />
{/* <BillNumberDialog dialogName={'bill-number-form'} /> */}
<PaymentReceiveNumberDialog dialogName={'payment-number-form'} />
<EstimateNumberDialog dialogName={'estimate-number-form'} />
<ReceiptNumberDialog dialogName={'receipt-number-form'} />
<InvoiceNumberDialog dialogName={'invoice-number-form'} />
<CurrencyFormDialog dialogName={'currency-form'} />
<UserFormDialog dialogName={'user-form'} />
<ExchangeRateFormDialog dialogName={'exchangeRate-form'} />
<ItemCategoryDialog dialogName={'item-category-form'} />
</div>
);
}
}

View File

@@ -8,61 +8,61 @@ import {
TextArea,
MenuItem,
} from '@blueprintjs/core';
import { Select } from '@blueprintjs/select';
import { pick } from 'lodash';
import * as Yup from 'yup';
import { FormattedMessage as T, useIntl } from 'react-intl';
import { useFormik } from 'formik';
import { compose } from 'utils';
import { useQuery, queryCache } from 'react-query';
import { FormattedMessage as T, useIntl } from 'react-intl';
import classNames from 'classnames';
import { connect } from 'react-redux';
import {
ListSelect,
AccountsSelectList,
FieldRequiredHint,
Hint,
AppToaster,
ErrorMessage,
DialogContent,
} from 'components';
import AppToaster from 'components/AppToaster';
import ErrorMessage from 'components/ErrorMessage';
import { ListSelect, AccountsSelectList } from 'components';
import Dialog from 'components/Dialog';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withDialogRedux from 'components/DialogReduxConnect';
import withItemCategories from 'containers/Items/withItemCategories';
import withItemCategoryDetail from 'containers/Items/withItemCategoryDetail';
import withItemCategoriesActions from 'containers/Items/withItemCategoriesActions';
import withAccounts from 'containers/Accounts/withAccounts';
import withAccountsActions from 'containers/Accounts/withAccountsActions';
import withItemCategoryDetail from 'containers/Items/withItemCategoryDetail';
import withItemCategories from 'containers/Items/withItemCategories';
import withItemCategoriesActions from 'containers/Items/withItemCategoriesActions';
import Icon from 'components/Icon';
import withDialogActions from 'containers/Dialog/withDialogActions';
import { compose } from 'utils';
function ItemCategoryDialog({
dialogName,
payload = {},
isOpen,
// #withDialog
openDialog,
function ItemCategoryFormDialogContent({
// #withDialogActions
closeDialog,
// #withItemCategoryDetail
itemCategoryId,
itemCategory,
// #withItemCategories
categoriesList,
// #withItemCategoriesActions
requestSubmitItemCategory,
requestEditItemCategory,
requestFetchItemCategories,
//# withAccount
accountsList,
// #withItemCategoriesActions
requestSubmitItemCategory,
requestFetchItemCategories,
requestEditItemCategory,
// #withAccountsActions
requestFetchAccounts,
// #ownProp
action,
itemCategoryId,
dialogName,
}) {
const [selectedParentCategory, setParentCategory] = useState(null);
const { formatMessage } = useIntl();
const [selectedParentCategory, setParentCategory] = useState(null);
const fetchList = useQuery(['items-categories-list'], () =>
requestFetchItemCategories(),
@@ -101,34 +101,33 @@ function ItemCategoryDialog({
values,
errors,
touched,
isSubmitting,
setFieldValue,
handleSubmit,
resetForm,
getFieldProps,
isSubmitting,
} = useFormik({
enableReinitialize: true,
initialValues: {
...(payload.action === 'edit' &&
pick(itemCategory, Object.keys(initialValues))),
},
validationSchema,
initialValues: {
...initialValues,
...(action === 'edit' && pick(itemCategory, Object.keys(initialValues))),
},
onSubmit: (values, { setSubmitting }) => {
const afterSubmit = () => {
closeDialog(dialogName);
queryCache.invalidateQueries('items-categories-list');
queryCache.invalidateQueries('accounts-list');
};
if (payload.action === 'edit') {
requestEditItemCategory(payload.id, values)
if (action === 'edit') {
requestEditItemCategory(itemCategoryId, values)
.then((response) => {
afterSubmit(response);
AppToaster.show({
message: formatMessage({
id: 'the_item_category_has_been_successfully_edited',
}),
intent: Intent.SUCCESS,
});
afterSubmit(response);
})
.catch((error) => {
setSubmitting(false);
@@ -136,13 +135,13 @@ function ItemCategoryDialog({
} else {
requestSubmitItemCategory(values)
.then((response) => {
afterSubmit(response);
AppToaster.show({
message: formatMessage({
id: 'the_item_category_has_been_successfully_created',
}),
intent: Intent.SUCCESS,
});
afterSubmit(response);
})
.catch((error) => {
setSubmitting(false);
@@ -150,6 +149,7 @@ function ItemCategoryDialog({
}
},
});
const filterItemCategory = useCallback(
(query, category, _index, exactMatch) => {
const normalizedTitle = category.name.toLowerCase();
@@ -182,12 +182,6 @@ function ItemCategoryDialog({
closeDialog(dialogName);
}, [dialogName, closeDialog]);
// Handle the dialog opening.
const onDialogOpening = useCallback(() => {
fetchList.refetch();
fetchAccounts.refetch();
}, [fetchList, fetchAccounts]);
const onChangeParentCategory = useCallback(
(parentCategory) => {
setParentCategory(parentCategory);
@@ -205,41 +199,15 @@ function ItemCategoryDialog({
[setFieldValue],
);
const onDialogClosed = useCallback(() => {
resetForm();
closeDialog(dialogName);
}, [resetForm, closeDialog, dialogName]);
const requiredSpan = useMemo(() => <span class="required">*</span>, []);
const infoIcon = useMemo(() => <Icon icon="info-circle" iconSize={12} />, []);
return (
<Dialog
name={dialogName}
title={
payload.action === 'edit' ? (
<T id={'edit_category'} />
) : (
<T id={'new_category'} />
)
}
className={classNames(
{
'dialog--loading': fetchList.isFetching || fetchAccounts.isFetching,
},
'dialog--category-form',
)}
isOpen={isOpen}
onClosed={onDialogClosed}
onOpening={onDialogOpening}
isLoading={fetchList.isFetching || fetchAccounts.isFetching}
onClose={handleClose}
>
<DialogContent isLoading={fetchList.isFetching || fetchAccounts.isFetching}>
<form onSubmit={handleSubmit}>
<div className={Classes.DIALOG_BODY}>
{/* ----------- Category name ----------- */}
<FormGroup
label={<T id={'category_name'} />}
labelInfo={requiredSpan}
labelInfo={FieldRequiredHint}
className={'form-group--category-name'}
intent={errors.name && touched.name && Intent.DANGER}
helperText={<ErrorMessage name="name" {...{ errors, touched }} />}
@@ -251,10 +219,10 @@ function ItemCategoryDialog({
{...getFieldProps('name')}
/>
</FormGroup>
{/* ----------- Parent Category ----------- */}
<FormGroup
label={<T id={'parent_category'} />}
labelInfo={infoIcon}
labelInfo={Hint}
className={classNames(
'form-group--select-list',
'form-group--parent-category',
@@ -286,7 +254,7 @@ function ItemCategoryDialog({
labelProp={'name'}
/>
</FormGroup>
{/* ----------- Description ----------- */}
<FormGroup
label={<T id={'description'} />}
className={'form-group--description'}
@@ -302,8 +270,7 @@ function ItemCategoryDialog({
{...getFieldProps('description')}
/>
</FormGroup>
{/* cost account */}
{/* ----------- Cost account ----------- */}
<FormGroup
label={<T id={'cost_account'} />}
inline={true}
@@ -326,8 +293,7 @@ function ItemCategoryDialog({
selectedAccountId={values.cost_account_id}
/>
</FormGroup>
{/* sell Account */}
{/* ----------- Sell account ----------- */}
<FormGroup
label={<T id={'sell_account'} />}
inline={true}
@@ -350,7 +316,7 @@ function ItemCategoryDialog({
selectedAccountId={values.sell_account_id}
/>
</FormGroup>
{/* inventory Account */}
{/* ----------- inventory account ----------- */}
<FormGroup
label={<T id={'inventory_account'} />}
inline={true}
@@ -390,29 +356,16 @@ function ItemCategoryDialog({
type="submit"
disabled={isSubmitting}
>
{payload.action === 'edit' ? (
<T id={'edit'} />
) : (
<T id={'submit'} />
)}
{action === 'edit' ? <T id={'edit'} /> : <T id={'submit'} />}
</Button>
</div>
</div>
</form>
</Dialog>
</DialogContent>
);
}
const mapStateToProps = (state, props) => ({
dialogName: 'item-category-form',
itemCategoryId: props?.payload?.id || null,
});
const withItemCategoryDialog = connect(mapStateToProps);
export default compose(
withDialogRedux(null, 'item-category-form'),
withItemCategoryDialog,
withDialogActions,
withItemCategoryDetail(),
withItemCategories(({ categoriesList }) => ({
@@ -423,4 +376,4 @@ export default compose(
})),
withItemCategoriesActions,
withAccountsActions,
)(ItemCategoryDialog);
)(ItemCategoryFormDialogContent);

View File

@@ -0,0 +1,46 @@
import React, { lazy } from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl';
import { Dialog, DialogSuspense } from 'components';
import withDialogRedux from 'components/DialogReduxConnect';
import { compose } from 'utils';
const ItemCategoryFormDialogContent = lazy(() =>
import('./ItemCategoryFormDialogContent'),
);
/**
* Item Category form dialog.
*/
function ItemCategoryFormDialog({
dialogName,
payload = { action: '', id: null },
isOpen,
}) {
return (
<Dialog
name={dialogName}
title={
payload.action === 'edit' ? (
<T id={'edit_category'} />
) : (
<T id={'new_category'} />
)
}
className={'dialog--category-form'}
isOpen={isOpen}
autoFocus={true}
canEscapeKeyClose={true}
>
<DialogSuspense>
<ItemCategoryFormDialogContent
dialogName={dialogName}
action={payload.action}
itemCategoryId={payload.id}
/>
</DialogSuspense>
</Dialog>
);
}
export default compose(withDialogRedux())(ItemCategoryFormDialog);

View File

@@ -1,138 +0,0 @@
// import React, { useState } from 'react';
// import {
// Button,
// Classes,
// FormGroup,
// InputGroup,
// Intent,
// TextArea,
// } from '@blueprintjs/core';
// import * as Yup from 'yup';
// import { FormattedMessage as T, useIntl } from 'react-intl';
// import { useFormik } from 'formik';
// import { compose } from 'utils';
// import Dialog from 'components/Dialog';
// import useAsync from 'hooks/async';
// import AppToaster from 'components/AppToaster';
// import withDialog from 'containers/Dialogs/withDialog';
// import DialogReduxConnect from 'components/DialogReduxConnect';
// // import ItemFormDialogConnect from 'connectors/ItemFormDialog.connect';
// function ItemFromDialog({
// name,
// payload,
// isOpen,
// submitItemCategory,
// fetchCategory,
// openDialog,
// closeDialog,
// }) {
// const [state, setState] = useState({});
// const { formatMessage } = useIntl();
// const ValidationSchema = Yup.object().shape({
// name: Yup.string().required().label(formatMessage({id:'category_name_'})),
// description: Yup.string().trim(),
// });
// const formik = useFormik({
// enableReinitialize: true,
// initialValues: {},
// validationSchema: ValidationSchema,
// onSubmit: (values) => {
// submitItemCategory({ values })
// .then((response) => {
// AppToaster.show({
// message: formatMessage({id:'the_category_has_been_successfully_created'}),
// });
// })
// .catch((error) => {
// alert(error.message);
// });
// },
// });
// const fetchHook = useAsync(async () => {
// await Promise.all([submitItemCategory]);
// });
// const handleClose = () => {
// closeDialog(name);
// };
// const onDialogOpening = () => {
// fetchHook.execute();
// openDialog(name);
// };
// const onDialogClosed = () => {
// // formik.resetForm();
// closeDialog(name);
// };
// return (
// <Dialog
// name={name}
// title={
// payload.action === 'new' ? <T id={'new'} /> : <T id={'new_category'} />
// }
// className={{
// 'dialog--loading': state.isLoading,
// 'dialog--item-form': true,
// }}
// isOpen={isOpen}
// onClosed={onDialogClosed}
// onOpening={onDialogOpening}
// isLoading={fetchHook.pending}
// >
// <form onSubmit={formik.handleSubmit}>
// <div className={Classes.DIALOG_BODY}>
// <FormGroup
// label={<T id={'category_name'} />}
// className={'form-group--category-name'}
// intent={formik.errors.name && Intent.DANGER}
// helperText={formik.errors.name && formik.errors.name}
// inline={true}
// >
// <InputGroup
// medium={formik.values.toString()}
// intent={formik.errors.name && Intent.DANGER}
// {...formik.getFieldProps('name')}
// />
// </FormGroup>
// <FormGroup
// label={<T id={'description'} />}
// className={'form-group--description'}
// intent={formik.errors.description && Intent.DANGER}
// helperText={formik.errors.description && formik.errors.credential}
// inline={true}
// >
// <TextArea
// growVertically={true}
// large={true}
// {...formik.getFieldProps('description')}
// />
// </FormGroup>
// </div>
// <div className={Classes.DIALOG_FOOTER}>
// <div className={Classes.DIALOG_FOOTER_ACTIONS}>
// <Button onClick={handleClose}>
// <T id={'close'} />
// </Button>
// <Button intent={Intent.PRIMARY} type='submit'>
// {payload.action === 'new' ? (
// <T id={'new'} />
// ) : (
// <T id={'submit'} />
// )}
// </Button>
// </div>
// </div>
// </form>
// </Dialog>
// );
// }
// export default compose(
// // ItemFormDialogConnect,
// withDialog,
// DialogReduxConnect
// )(ItemFromDialog);

View File

@@ -219,6 +219,8 @@ export default {
'The item category has been successfully edited.',
the_item_category_has_been_successfully_deleted:
'The item category has been successfully deleted',
once_delete_these_item_categories_you_will_not_able_restore_them:
"Once you delete these categories, you won't be able to retrieve them later. Are you sure you want to delete them?",
once_delete_these_views_you_will_not_able_restore_them:
"Once you delete the custom view, you won't be able to restore it later. Are you sure you want to delete this view?",
the_custom_view_has_been_successfully_deleted:
@@ -346,7 +348,7 @@ export default {
once_delete_this_currency_you_will_able_to_restore_it: `Once you delete this currency, you won\'t be able to restore it later. Are you sure you want to delete this currency?`,
once_delete_this_exchange_rate_you_will_able_to_restore_it: `Once you delete this exchange rate, you won\'t be able to restore it later. Are you sure you want to delete this exchange rate?`,
once_delete_these_exchange_rates_you_will_not_able_restore_them: `Once you delete these exchange rates, you won't be able to retrieve them later. Are you sure you want to delete them?`,
once_delete_this_item_category_you_will_able_to_restore_it: `Once you delete this item, you won\'t be able to restore it later. Are you sure you want to delete this item?`,
once_delete_this_item_category_you_will_able_to_restore_it: `Once you delete this category, you won\'t be able to restore it later. Are you sure you want to delete this item?`,
select_business_location: 'Select Business Location',
select_base_currency: 'Select Base Currency',
select_fiscal_year: 'Select Fiscal Year',
@@ -807,4 +809,5 @@ export default {
notes: 'Notes',
i_purchase_this_item: 'I purchase this item from a vendor.',
i_sell_this_item: 'I sell this item to a customer.',
select_display_name_as:'Select display name as',
};