mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-15 12:20:31 +00:00
Fix: Item Category Dialog
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
46
client/src/containers/Dialogs/ItemCategoryDialog/index.js
Normal file
46
client/src/containers/Dialogs/ItemCategoryDialog/index.js
Normal 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);
|
||||
@@ -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);
|
||||
@@ -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',
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user