import React, { useState, useMemo, useCallback } from 'react'; import { Button, Classes, FormGroup, InputGroup, Intent, 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 classNames from 'classnames'; import { connect } from 'react-redux'; 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 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'; function ItemCategoryDialog({ dialogName, payload = {}, isOpen, // #withDialog openDialog, closeDialog, // #withItemCategoryDetail itemCategoryId, itemCategory, // #withItemCategories categoriesList, //# withAccount accountsList, // #withItemCategoriesActions requestSubmitItemCategory, requestFetchItemCategories, requestEditItemCategory, // #withAccountsActions requestFetchAccounts, }) { const [selectedParentCategory, setParentCategory] = useState(null); const { formatMessage } = useIntl(); const fetchList = useQuery(['items-categories-list'], () => requestFetchItemCategories(), ); const fetchAccounts = useQuery( 'accounts-list', () => requestFetchAccounts(), { enabled: false }, ); const validationSchema = Yup.object().shape({ name: Yup.string() .required() .label(formatMessage({ id: 'category_name_' })), parent_category_id: Yup.string().nullable(), cost_account_id: Yup.number() .required() .label(formatMessage({ id: 'cost_account_' })), sell_account_id: Yup.number() .required() .label(formatMessage({ id: 'sell_account_' })), inventory_account_id: Yup.number() .required() .label(formatMessage({ id: 'inventory_account_' })), description: Yup.string().trim().nullable(), }); const initialValues = useMemo( () => ({ name: '', description: '', parent_category_id: null, cost_account_id: null, sell_account_id: null, inventory_account_id: null, }), [], ); // Formik const { values, errors, touched, setFieldValue, handleSubmit, resetForm, getFieldProps, isSubmitting, } = useFormik({ enableReinitialize: true, initialValues: { ...(payload.action === 'edit' && pick(itemCategory, Object.keys(initialValues))), }, validationSchema, onSubmit: (values, { setSubmitting }) => { const afterSubmit = () => { closeDialog(dialogName); queryCache.invalidateQueries('items-categories-table'); queryCache.invalidateQueries('accounts-list'); }; if (payload.action === 'edit') { requestEditItemCategory(payload.id, values) .then((response) => { afterSubmit(response); AppToaster.show({ message: formatMessage({ id: 'the_item_category_has_been_successfully_edited', }), intent: Intent.SUCCESS, }); }) .catch((error) => { setSubmitting(false); }); } else { requestSubmitItemCategory(values) .then((response) => { afterSubmit(response); AppToaster.show({ message: formatMessage({ id: 'the_item_category_has_been_successfully_created', }), intent: Intent.SUCCESS, }); }) .catch((error) => { setSubmitting(false); }); } }, }); const filterItemCategory = useCallback( (query, category, _index, exactMatch) => { const normalizedTitle = category.name.toLowerCase(); const normalizedQuery = query.toLowerCase(); if (exactMatch) { return normalizedTitle === normalizedQuery; } else { return normalizedTitle.indexOf(normalizedQuery) >= 0; } }, [], ); const parentCategoryItem = useCallback( (category, { handleClick, modifiers, query }) => { return ( ); }, [], ); // Handle the dialog closing. const handleClose = useCallback(() => { closeDialog(dialogName); }, [dialogName, closeDialog]); // Handle the dialog opening. const onDialogOpening = useCallback(() => { fetchList.refetch(); fetchAccounts.refetch(); }, [fetchList, fetchAccounts]); const onChangeParentCategory = useCallback( (parentCategory) => { setParentCategory(parentCategory); setFieldValue('parent_category_id', parentCategory.id); }, [setFieldValue], ); const onItemAccountSelect = useCallback( (filedName) => { return (account) => { setFieldValue(filedName, account.id); }; }, [setFieldValue], ); const onDialogClosed = useCallback(() => { resetForm(); closeDialog(dialogName); }, [resetForm, closeDialog, dialogName]); const requiredSpan = useMemo(() => *, []); const infoIcon = useMemo(() => , []); return ( ) : ( ) } className={classNames( { 'dialog--loading': fetchList.isFetching || fetchAccounts.isFetching, }, 'dialog--category-form', )} isOpen={isOpen} onClosed={onDialogClosed} onOpening={onDialogOpening} isLoading={fetchList.isFetching || fetchAccounts.isFetching} onClose={handleClose} >
} labelInfo={requiredSpan} className={'form-group--category-name'} intent={errors.name && touched.name && Intent.DANGER} helperText={} inline={true} > } labelInfo={infoIcon} className={classNames( 'form-group--select-list', 'form-group--parent-category', Classes.FILL, )} inline={true} helperText={ } intent={ errors.parent_category_id && touched.parent_category_id && Intent.DANGER } > } itemRenderer={parentCategoryItem} itemPredicate={filterItemCategory} popoverProps={{ minimal: true }} onItemSelect={onChangeParentCategory} selectedItem={values.parent_category_id} selectedItemProp={'id'} defaultText={} labelProp={'name'} /> } className={'form-group--description'} intent={errors.description && touched.description && Intent.DANGER} helperText={ } inline={true} >