From 3184bd7e75bc0800ff4945a29d964cc6b555ef63 Mon Sep 17 00:00:00 2001 From: elforjani3 Date: Sat, 7 Nov 2020 14:59:05 +0200 Subject: [PATCH 1/3] Fix: CurrencySelectList --- client/src/components/CurrencySelectList.js | 60 ++++ client/src/components/index.js | 3 + .../ExchangeRateFormDialogContent.js | 261 ++++++++++++++++++ .../containers/Expenses/ExpenseFormHeader.js | 50 +--- 4 files changed, 329 insertions(+), 45 deletions(-) create mode 100644 client/src/components/CurrencySelectList.js create mode 100644 client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormDialogContent.js diff --git a/client/src/components/CurrencySelectList.js b/client/src/components/CurrencySelectList.js new file mode 100644 index 000000000..dbcf8a43f --- /dev/null +++ b/client/src/components/CurrencySelectList.js @@ -0,0 +1,60 @@ +import React, { useCallback, useState, useEffect, useMemo } from 'react'; +import { FormattedMessage as T } from 'react-intl'; +import { ListSelect } from 'components'; +import { MenuItem } from '@blueprintjs/core'; + +export default function CurrencySelectList({ + currenciesList, + selectedCurrencyCode, + defaultSelectText = , + onCurrencySelected, + ...restProps +}) { + const [selectedCurrency, setSelectedCurrency] = useState(null); + + // Filters currencies list. + const filterCurrencies = (query, currency, _index, exactMatch) => { + const normalizedTitle = currency.currency_code.toLowerCase(); + const normalizedQuery = query.toLowerCase(); + + if (exactMatch) { + return normalizedTitle === normalizedQuery; + } else { + return ( + `${currency.currency_code} ${normalizedTitle}`.indexOf( + normalizedQuery, + ) >= 0 + ); + } + }; + + const onCurrencySelect = useCallback((currency) => { + setSelectedCurrency({ ...currency }); + onCurrencySelected && onCurrencySelected(currency); + }); + + const currencyCodeRenderer = useCallback((CurrencyCode, { handleClick }) => { + return ( + + ); + }, []); + + return ( + + ); +} diff --git a/client/src/components/index.js b/client/src/components/index.js index 31a83a3c1..00f0948bb 100644 --- a/client/src/components/index.js +++ b/client/src/components/index.js @@ -31,6 +31,8 @@ import Col from './Grid/Col'; import CloudLoadingIndicator from './CloudLoadingIndicator'; import MoneyExchangeRate from './MoneyExchangeRate'; import ContactSelecetList from './ContactSelecetList'; +import CurrencySelectList from './CurrencySelectList' + const Hint = FieldHint; @@ -69,4 +71,5 @@ export { CloudLoadingIndicator, MoneyExchangeRate, ContactSelecetList , + CurrencySelectList }; diff --git a/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormDialogContent.js b/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormDialogContent.js new file mode 100644 index 000000000..26aac7e70 --- /dev/null +++ b/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormDialogContent.js @@ -0,0 +1,261 @@ +import React, { useState, useMemo, useCallback } from 'react'; +import { + Button, + Classes, + FormGroup, + InputGroup, + Intent, + Position, + MenuItem, +} from '@blueprintjs/core'; +import { pick } from 'lodash'; +import * as Yup from 'yup'; +import { useFormik } from 'formik'; +import { useQuery, queryCache } from 'react-query'; +import moment from 'moment'; +import { DateInput } from '@blueprintjs/datetime'; +import { FormattedMessage as T, useIntl } from 'react-intl'; +import { momentFormatter, tansformDateValue } from 'utils'; +import { + AppToaster, + Dialog, + ErrorMessage, + ListSelect, + DialogContent, + FieldRequiredHint, + CurrencySelectList, +} from 'components'; +import classNames from 'classnames'; +import withExchangeRateDetail from 'containers/ExchangeRates/withExchangeRateDetail'; +import withExchangeRatesActions from 'containers/ExchangeRates/withExchangeRatesActions'; + +import withCurrencies from 'containers/Currencies/withCurrencies'; +import withCurrenciesActions from 'containers/Currencies/withCurrenciesActions'; +import withDialogActions from 'containers/Dialog/withDialogActions'; + +import { compose } from 'utils'; + +function ExchangeRateFormDialogContent({ + // #withDialogActions + closeDialog, + + // #withCurrencies + currenciesList, + + //#WithExchangeRateDetail + exchangeRate, + + // #withExchangeRatesActions + requestSubmitExchangeRate, + requestEditExchangeRate, + + // #wihtCurrenciesActions + requestFetchCurrencies, + + // #ownProp + action, + exchangeRateId, + dialogName, +}) { + const { formatMessage } = useIntl(); + const [selectedItems, setSelectedItems] = useState({}); + + const fetchCurrencies = useQuery( + 'currencies', + () => requestFetchCurrencies(), + { enabled: true }, + ); + + const validationSchema = Yup.object().shape({ + exchange_rate: Yup.number() + .required() + .label(formatMessage({ id: 'exchange_rate_' })), + currency_code: Yup.string() + .max(3) + .required(formatMessage({ id: 'currency_code_' })), + date: Yup.date() + .required() + .label(formatMessage({ id: 'date' })), + }); + + const initialValues = useMemo( + () => ({ + exchange_rate: '', + currency_code: '', + date: moment(new Date()).format('YYYY-MM-DD'), + }), + [], + ); + + const { + values, + touched, + errors, + isSubmitting, + handleSubmit, + getFieldProps, + setFieldValue, + resetForm, + } = useFormik({ + enableReinitialize: true, + validationSchema, + initialValues: { + ...initialValues, + ...(action === 'edit' && pick(exchangeRate, Object.keys(initialValues))), + }, + onSubmit: (values, { setSubmitting, setErrors }) => { + if (action === 'edit') { + requestEditExchangeRate(exchangeRateId, values) + .then((response) => { + closeDialog(dialogName); + AppToaster.show({ + message: formatMessage({ + id: 'the_exchange_rate_has_been_successfully_edited', + }), + intent: Intent.SUCCESS, + }); + setSubmitting(false); + queryCache.invalidateQueries('exchange-rates-table'); + }) + .catch((error) => { + setSubmitting(false); + }); + } else { + requestSubmitExchangeRate(values) + .then((response) => { + closeDialog(dialogName); + AppToaster.show({ + message: formatMessage({ + id: 'the_exchange_rate_has_been_successfully_created', + }), + intent: Intent.SUCCESS, + }); + setSubmitting(false); + queryCache.invalidateQueries('exchange-rates-table'); + }) + .catch((errors) => { + if ( + errors.find((e) => e.type === 'EXCHANGE.RATE.DATE.PERIOD.DEFINED') + ) { + setErrors({ + exchange_rate: formatMessage({ + id: + 'there_is_exchange_rate_in_this_date_with_the_same_currency', + }), + }); + } + }); + } + }, + }); + + const handleClose = useCallback(() => { + closeDialog(dialogName); + resetForm(); + }, [dialogName, closeDialog]); + + const handleDateChange = useCallback( + (date_filed) => (date) => { + const formatted = moment(date).format('YYYY-MM-DD'); + setFieldValue(date_filed, formatted); + }, + [setFieldValue], + ); + + const onItemsSelect = useCallback( + (filedName) => { + return (filed) => { + setSelectedItems({ + ...selectedItems, + [filedName]: filed, + }); + setFieldValue(filedName, filed.currency_code); + }; + }, + [setFieldValue, selectedItems], + ); + return ( + +
+
+ } + inline={true} + labelInfo={FieldRequiredHint} + intent={errors.date && touched.date && Intent.DANGER} + helperText={} + > + + + } + labelInfo={FieldRequiredHint} + className={classNames('form-group--select-list', Classes.FILL)} + inline={true} + intent={ + errors.currency_code && touched.currency_code && Intent.DANGER + } + helperText={ + + } + > + + + } + labelInfo={FieldRequiredHint} + intent={ + errors.exchange_rate && touched.exchange_rate && Intent.DANGER + } + helperText={ + + } + inline={true} + > + + +
+
+
+ + +
+
+
+
+ ); +} + +export default compose( + withDialogActions, + withExchangeRatesActions, + withExchangeRateDetail, + withCurrenciesActions, + withCurrencies(({ currenciesList }) => ({ currenciesList })), +)(ExchangeRateFormDialogContent); diff --git a/client/src/containers/Expenses/ExpenseFormHeader.js b/client/src/containers/Expenses/ExpenseFormHeader.js index 1f128b644..e9b525dee 100644 --- a/client/src/containers/Expenses/ExpenseFormHeader.js +++ b/client/src/containers/Expenses/ExpenseFormHeader.js @@ -14,7 +14,7 @@ import moment from 'moment'; import { momentFormatter, compose, tansformDateValue } from 'utils'; import classNames from 'classnames'; import { - ListSelect, + CurrencySelectList, ContactSelecetList, ErrorMessage, AccountsSelectList, @@ -42,28 +42,6 @@ function ExpenseFormHeader({ [setFieldValue], ); - const currencyCodeRenderer = useCallback((item, { handleClick }) => { - return ( - - ); - }, []); - - // Filters Currency code. - const filterCurrencyCode = (query, currency, _index, exactMatch) => { - const normalizedTitle = currency.currency_code.toLowerCase(); - const normalizedQuery = query.toLowerCase(); - - if (exactMatch) { - return normalizedTitle === normalizedQuery; - } else { - return ( - `${currency.currency_code} ${normalizedTitle}`.indexOf( - normalizedQuery, - ) >= 0 - ); - } - }; - // Handles change account. const onChangeAccount = useCallback( (account) => { @@ -91,17 +69,6 @@ function ExpenseFormHeader({ [accountsList], ); - const CustomerRenderer = useCallback( - (cutomer, { handleClick }) => ( - - ), - [], - ); - // handle change customer const onChangeCustomer = useCallback( (filedName) => { @@ -205,17 +172,10 @@ function ExpenseFormHeader({ } > - } - itemRenderer={currencyCodeRenderer} - itemPredicate={filterCurrencyCode} - popoverProps={{ minimal: true }} - onItemSelect={onItemsSelect('currency_code')} - selectedItem={values.currency_code} - selectedItemProp={'currency_code'} - defaultText={} - labelProp={'currency_code'} + From 9302a4e68e34899ec7a57ca93c6a3ec13fefe007 Mon Sep 17 00:00:00 2001 From: elforjani3 Date: Sat, 7 Nov 2020 15:01:22 +0200 Subject: [PATCH 2/3] Fix :Conditions within Entries items --- .../src/containers/Purchases/Bill/BillForm.js | 32 +++++++++++++++---- .../containers/Sales/Estimate/EstimateForm.js | 16 ++++++++-- .../containers/Sales/Invoice/InvoiceForm.js | 20 +++++++++--- .../containers/Sales/Receipt/ReceiptForm.js | 15 ++++++++- client/src/lang/en/index.js | 2 ++ 5 files changed, 71 insertions(+), 14 deletions(-) diff --git a/client/src/containers/Purchases/Bill/BillForm.js b/client/src/containers/Purchases/Bill/BillForm.js index 4c1b838ba..bf8d7087c 100644 --- a/client/src/containers/Purchases/Bill/BillForm.js +++ b/client/src/containers/Purchases/Bill/BillForm.js @@ -11,7 +11,7 @@ import moment from 'moment'; import { Intent } from '@blueprintjs/core'; import classNames from 'classnames'; import { FormattedMessage as T, useIntl } from 'react-intl'; -import { pick } from 'lodash'; +import { pick, sumBy } from 'lodash'; import { CLASSES } from 'common/classes'; import BillFormHeader from './BillFormHeader'; @@ -215,11 +215,25 @@ function BillForm({ ...initialValues, }, onSubmit: (values, { setSubmitting, setErrors, resetForm }) => { - setSubmitting(true); + const entries = values.entries.filter( + (item) => item.item_id && item.quantity, + ); + const totalQuantity = sumBy(entries, (entry) => parseInt(entry.quantity)); + + if (totalQuantity === 0) { + AppToaster.show({ + message: formatMessage({ + id: 'quantity_cannot_be_zero_or_empty', + }), + intent: Intent.DANGER, + }); + setSubmitting(false); + return; + } const form = { ...values, - entries: values.entries.filter((item) => item.item_id && item.quantity), + entries, }; const requestForm = { ...form }; if (bill && bill.id) { @@ -311,16 +325,20 @@ function BillForm({ }, []); // Clear page subtitle once unmount bill form page. - useEffect(() => () => { - changePageSubtitle(''); - }, [changePageSubtitle]); + useEffect( + () => () => { + changePageSubtitle(''); + }, + [changePageSubtitle], + ); return (
+ onBillNumberChanged={handleBillNumberChanged} + /> item.item_id && item.quantity, ); + + const totalQuantity = sumBy(entries, (entry) => parseInt(entry.quantity)); + + if (totalQuantity === 0) { + AppToaster.show({ + message: formatMessage({ + id: 'quantity_cannot_be_zero_or_empty', + }), + intent: Intent.DANGER, + }); + setSubmitting(false); + return; + } const form = { ...values, entries, @@ -277,7 +290,6 @@ const EstimateForm = ({ } }, }); - useEffect(() => { formik.setFieldValue('estimate_number', estimateNumber); }, [estimateNumber]); diff --git a/client/src/containers/Sales/Invoice/InvoiceForm.js b/client/src/containers/Sales/Invoice/InvoiceForm.js index be611ec40..bee436764 100644 --- a/client/src/containers/Sales/Invoice/InvoiceForm.js +++ b/client/src/containers/Sales/Invoice/InvoiceForm.js @@ -10,7 +10,7 @@ import { useFormik } from 'formik'; import moment from 'moment'; import { Intent, FormGroup, TextArea } from '@blueprintjs/core'; import { FormattedMessage as T, useIntl } from 'react-intl'; -import { pick } from 'lodash'; +import { pick, sumBy } from 'lodash'; import classNames from 'classnames'; import { CLASSES } from 'common/classes'; @@ -97,8 +97,7 @@ function InvoiceForm({ due_date: Yup.date() .required() .label(formatMessage({ id: 'due_date_' })), - invoice_no: Yup.string() - .label(formatMessage({ id: 'invoice_no_' })), + invoice_no: Yup.string().label(formatMessage({ id: 'invoice_no_' })), reference_no: Yup.string().min(1).max(255), status: Yup.string().required(), invoice_message: Yup.string() @@ -127,7 +126,7 @@ function InvoiceForm({ is: (quantity, rate) => quantity || rate, then: Yup.number().required(), }), - discount: Yup.number().nullable().min(0).max(100), + discount: Yup.number().nullable().min(0).max(100), description: Yup.string().nullable(), }), ), @@ -232,6 +231,18 @@ function InvoiceForm({ const entries = values.entries.filter( (item) => item.item_id && item.quantity, ); + const totalQuantity = sumBy(entries, (entry) => parseInt(entry.quantity)); + + if (totalQuantity === 0) { + AppToaster.show({ + message: formatMessage({ + id: 'quantity_cannot_be_zero_or_empty', + }), + intent: Intent.DANGER, + }); + setSubmitting(false); + return; + } const form = { ...values, entries, @@ -279,6 +290,7 @@ function InvoiceForm({ } }, }); + useEffect(() => { formik.setFieldValue('invoice_no', invoiceNumber); }, [invoiceNumber]); diff --git a/client/src/containers/Sales/Receipt/ReceiptForm.js b/client/src/containers/Sales/Receipt/ReceiptForm.js index eeb3afc7d..93e9a2414 100644 --- a/client/src/containers/Sales/Receipt/ReceiptForm.js +++ b/client/src/containers/Sales/Receipt/ReceiptForm.js @@ -11,7 +11,7 @@ import { useFormik } from 'formik'; import moment from 'moment'; import { Intent, FormGroup, TextArea } from '@blueprintjs/core'; import { FormattedMessage as T, useIntl } from 'react-intl'; -import { pick } from 'lodash'; +import { pick,sumBy } from 'lodash'; import classNames from 'classnames'; import { CLASSES } from 'common/classes'; @@ -229,6 +229,19 @@ function ReceiptForm({ const entries = values.entries.filter( (item) => item.item_id && item.quantity, ); + + const totalQuantity = sumBy(entries, (entry) => parseInt(entry.quantity)); + + if (totalQuantity === 0) { + AppToaster.show({ + message: formatMessage({ + id: 'quantity_cannot_be_zero_or_empty', + }), + intent: Intent.DANGER, + }); + setSubmitting(false); + return; + } const form = { ...values, entries, diff --git a/client/src/lang/en/index.js b/client/src/lang/en/index.js index 2793350a2..d9ba48e51 100644 --- a/client/src/lang/en/index.js +++ b/client/src/lang/en/index.js @@ -789,4 +789,6 @@ export default { sale_invoice_number_is_exists: 'Sale invoice number is exists', bill_number_exists:'Bill number exists', ok: 'Ok!', + quantity_cannot_be_zero_or_empty: 'Quantity cannot be zero or empty.', + }; From 6a0395507858218c7a1bd297148ef9f65f824c4a Mon Sep 17 00:00:00 2001 From: elforjani3 Date: Sat, 7 Nov 2020 15:03:00 +0200 Subject: [PATCH 3/3] Fix: Folding dialogue components. --- .../AccountFormDialogContent.js | 0 .../index.js} | 0 .../CurencyFormDialogContent.js | 0 .../index.js} | 4 + .../Dialogs/ExchangeRateDialog.container.js | 33 -- .../index.js} | 0 .../Dialogs/ExchangeRateFormDialogContent.js | 294 ------------------ .../UserFormDialogContent.js | 0 .../index.js} | 0 9 files changed, 4 insertions(+), 327 deletions(-) rename client/src/containers/Dialogs/{ => AccountFormDialog}/AccountFormDialogContent.js (100%) rename client/src/containers/Dialogs/{AccountFormDialog.js => AccountFormDialog/index.js} (100%) rename client/src/containers/Dialogs/{ => CurrencyFormDialog}/CurencyFormDialogContent.js (100%) rename client/src/containers/Dialogs/{CurrencyFormDialog.js => CurrencyFormDialog/index.js} (96%) delete mode 100644 client/src/containers/Dialogs/ExchangeRateDialog.container.js rename client/src/containers/Dialogs/{ExchangeRateFormDialog.js => ExchangeRateFormDialog/index.js} (100%) delete mode 100644 client/src/containers/Dialogs/ExchangeRateFormDialogContent.js rename client/src/containers/Dialogs/{ => UserFormDialog}/UserFormDialogContent.js (100%) rename client/src/containers/Dialogs/{UserFormDialog.js => UserFormDialog/index.js} (100%) diff --git a/client/src/containers/Dialogs/AccountFormDialogContent.js b/client/src/containers/Dialogs/AccountFormDialog/AccountFormDialogContent.js similarity index 100% rename from client/src/containers/Dialogs/AccountFormDialogContent.js rename to client/src/containers/Dialogs/AccountFormDialog/AccountFormDialogContent.js diff --git a/client/src/containers/Dialogs/AccountFormDialog.js b/client/src/containers/Dialogs/AccountFormDialog/index.js similarity index 100% rename from client/src/containers/Dialogs/AccountFormDialog.js rename to client/src/containers/Dialogs/AccountFormDialog/index.js diff --git a/client/src/containers/Dialogs/CurencyFormDialogContent.js b/client/src/containers/Dialogs/CurrencyFormDialog/CurencyFormDialogContent.js similarity index 100% rename from client/src/containers/Dialogs/CurencyFormDialogContent.js rename to client/src/containers/Dialogs/CurrencyFormDialog/CurencyFormDialogContent.js diff --git a/client/src/containers/Dialogs/CurrencyFormDialog.js b/client/src/containers/Dialogs/CurrencyFormDialog/index.js similarity index 96% rename from client/src/containers/Dialogs/CurrencyFormDialog.js rename to client/src/containers/Dialogs/CurrencyFormDialog/index.js index 48c6757cb..19a1a82fc 100644 --- a/client/src/containers/Dialogs/CurrencyFormDialog.js +++ b/client/src/containers/Dialogs/CurrencyFormDialog/index.js @@ -7,6 +7,10 @@ import { compose } from 'utils'; const CurrencyFormDialogContent = lazy(() => import('./CurencyFormDialogContent'), ); + +/** + * Currency form dialog. + */ function CurrencyFormDialog({ dialogName, payload = { action: '', id: null }, diff --git a/client/src/containers/Dialogs/ExchangeRateDialog.container.js b/client/src/containers/Dialogs/ExchangeRateDialog.container.js deleted file mode 100644 index d107d266b..000000000 --- a/client/src/containers/Dialogs/ExchangeRateDialog.container.js +++ /dev/null @@ -1,33 +0,0 @@ -// import { connect } from 'react-redux'; -// import { compose } from 'utils'; - -// import withDialogActions from 'containers/Dialog/withDialogActions'; -// import withDialogRedux from 'components/DialogReduxConnect'; -// import withExchangeRateDetail from 'containers/ExchangeRates/withExchangeRateDetail'; -// import withExchangeRatesActions from 'containers/ExchangeRates/withExchangeRatesActions'; -// import withExchangeRates from 'containers/ExchangeRates/withExchangeRates'; -// import withCurrencies from 'containers/Currencies/withCurrencies'; - -// const mapStateToProps = (state, props) => ({ -// dialogName: 'exchangeRate-form', -// exchangeRateId: -// props.payload.action === 'edit' && props.payload.id -// ? props.payload.id -// : null, -// }); - -// const withExchangeRateDialog = connect(mapStateToProps); - -// export default compose( -// withDialogRedux(null, 'exchangeRate-form'), -// withExchangeRateDialog, -// withCurrencies(({ currenciesList }) => ({ -// currenciesList, -// })), -// withExchangeRatesActions, -// withExchangeRateDetail, -// withExchangeRates(({ exchangeRatesList }) => ({ -// exchangeRatesList, -// })), -// withDialogActions, -// ); diff --git a/client/src/containers/Dialogs/ExchangeRateFormDialog.js b/client/src/containers/Dialogs/ExchangeRateFormDialog/index.js similarity index 100% rename from client/src/containers/Dialogs/ExchangeRateFormDialog.js rename to client/src/containers/Dialogs/ExchangeRateFormDialog/index.js diff --git a/client/src/containers/Dialogs/ExchangeRateFormDialogContent.js b/client/src/containers/Dialogs/ExchangeRateFormDialogContent.js deleted file mode 100644 index e640ecbd0..000000000 --- a/client/src/containers/Dialogs/ExchangeRateFormDialogContent.js +++ /dev/null @@ -1,294 +0,0 @@ -import React, { useState, useMemo, useCallback } from 'react'; -import { - Button, - Classes, - FormGroup, - InputGroup, - Intent, - Position, - MenuItem, -} from '@blueprintjs/core'; -import { pick } from 'lodash'; -import * as Yup from 'yup'; -import { useFormik } from 'formik'; -import { useQuery, queryCache } from 'react-query'; -import moment from 'moment'; -import { DateInput } from '@blueprintjs/datetime'; -import { FormattedMessage as T, useIntl } from 'react-intl'; -import { momentFormatter, tansformDateValue } from 'utils'; -import { - AppToaster, - Dialog, - ErrorMessage, - ListSelect, - DialogContent, - FieldRequiredHint, -} from 'components'; -import classNames from 'classnames'; -import withExchangeRateDetail from 'containers/ExchangeRates/withExchangeRateDetail'; -import withExchangeRatesActions from 'containers/ExchangeRates/withExchangeRatesActions'; - -import withCurrencies from 'containers/Currencies/withCurrencies'; -import withCurrenciesActions from 'containers/Currencies/withCurrenciesActions'; -import withDialogActions from 'containers/Dialog/withDialogActions'; - -import { compose } from 'utils'; - -function ExchangeRateFormDialogContent({ - // #withDialogActions - closeDialog, - - // #withCurrencies - currenciesList, - - //#WithExchangeRateDetail - exchangeRate, - - // #withExchangeRatesActions - requestSubmitExchangeRate, - requestEditExchangeRate, - - // #wihtCurrenciesActions - requestFetchCurrencies, - - // #ownProp - action, - exchangeRateId, - dialogName, -}) { - const { formatMessage } = useIntl(); - const [selectedItems, setSelectedItems] = useState({}); - - const fetchCurrencies = useQuery( - 'currencies', - () => requestFetchCurrencies(), - { enabled: true }, - ); - - const validationSchema = Yup.object().shape({ - exchange_rate: Yup.number() - .required() - .label(formatMessage({ id: 'exchange_rate_' })), - currency_code: Yup.string() - .max(3) - .required(formatMessage({ id: 'currency_code_' })), - date: Yup.date() - .required() - .label(formatMessage({ id: 'date' })), - }); - - const initialValues = useMemo( - () => ({ - exchange_rate: '', - currency_code: '', - date: moment(new Date()).format('YYYY-MM-DD'), - }), - [], - ); - - const { - values, - touched, - errors, - isSubmitting, - handleSubmit, - getFieldProps, - setFieldValue, - resetForm, - } = useFormik({ - enableReinitialize: true, - validationSchema, - initialValues: { - ...initialValues, - ...(action === 'edit' && pick(exchangeRate, Object.keys(initialValues))), - }, - onSubmit: (values, { setSubmitting, setErrors }) => { - if (action === 'edit') { - requestEditExchangeRate(exchangeRateId, values) - .then((response) => { - closeDialog(dialogName); - AppToaster.show({ - message: formatMessage({ - id: 'the_exchange_rate_has_been_successfully_edited', - }), - intent: Intent.SUCCESS, - }); - setSubmitting(false); - queryCache.invalidateQueries('exchange-rates-table'); - }) - .catch((error) => { - setSubmitting(false); - }); - } else { - requestSubmitExchangeRate(values) - .then((response) => { - closeDialog(dialogName); - AppToaster.show({ - message: formatMessage({ - id: 'the_exchange_rate_has_been_successfully_created', - }), - intent: Intent.SUCCESS, - }); - setSubmitting(false); - queryCache.invalidateQueries('exchange-rates-table'); - }) - .catch((errors) => { - if ( - errors.find((e) => e.type === 'EXCHANGE.RATE.DATE.PERIOD.DEFINED') - ) { - setErrors({ - exchange_rate: formatMessage({ - id: - 'there_is_exchange_rate_in_this_date_with_the_same_currency', - }), - }); - } - }); - } - }, - }); - - const handleClose = useCallback(() => { - closeDialog(dialogName); - resetForm(); - }, [dialogName, closeDialog]); - - const handleDateChange = useCallback( - (date_filed) => (date) => { - const formatted = moment(date).format('YYYY-MM-DD'); - setFieldValue(date_filed, formatted); - }, - [setFieldValue], - ); - - const onItemsSelect = useCallback( - (filedName) => { - return (filed) => { - setSelectedItems({ - ...selectedItems, - [filedName]: filed, - }); - setFieldValue(filedName, filed.currency_code); - }; - }, - [setFieldValue, selectedItems], - ); - - const filterCurrencyCode = (query, currency, _index, exactMatch) => { - const normalizedTitle = currency.currency_code.toLowerCase(); - const normalizedQuery = query.toLowerCase(); - - if (exactMatch) { - return normalizedTitle === normalizedQuery; - } else { - return ( - `${currency.currency_code} ${normalizedTitle}`.indexOf( - normalizedQuery, - ) >= 0 - ); - } - }; - - const currencyCodeRenderer = useCallback((CurrencyCode, { handleClick }) => { - return ( - - ); - }, []); - - return ( - - -
- } - inline={true} - labelInfo={FieldRequiredHint} - intent={errors.date && touched.date && Intent.DANGER} - helperText={} - > - - - } - labelInfo={FieldRequiredHint} - className={classNames('form-group--select-list', Classes.FILL)} - inline={true} - intent={ - errors.currency_code && touched.currency_code && Intent.DANGER - } - helperText={ - - } - > - } - itemRenderer={currencyCodeRenderer} - itemPredicate={filterCurrencyCode} - popoverProps={{ minimal: true }} - onItemSelect={onItemsSelect('currency_code')} - selectedItem={values.currency_code} - selectedItemProp={'currency_code'} - defaultText={} - labelProp={'currency_code'} - disabled={action === 'edit'} - /> - - } - labelInfo={FieldRequiredHint} - intent={ - errors.exchange_rate && touched.exchange_rate && Intent.DANGER - } - helperText={ - - } - inline={true} - > - - -
-
-
- - -
-
- -
- ); -} - -export default compose( - withDialogActions, - withExchangeRatesActions, - withExchangeRateDetail, - withCurrenciesActions, - withCurrencies(({ currenciesList }) => ({ currenciesList })), -)(ExchangeRateFormDialogContent); diff --git a/client/src/containers/Dialogs/UserFormDialogContent.js b/client/src/containers/Dialogs/UserFormDialog/UserFormDialogContent.js similarity index 100% rename from client/src/containers/Dialogs/UserFormDialogContent.js rename to client/src/containers/Dialogs/UserFormDialog/UserFormDialogContent.js diff --git a/client/src/containers/Dialogs/UserFormDialog.js b/client/src/containers/Dialogs/UserFormDialog/index.js similarity index 100% rename from client/src/containers/Dialogs/UserFormDialog.js rename to client/src/containers/Dialogs/UserFormDialog/index.js