From 5171cf7ef5abd6e8c405a3168a60b8ebe75dd455 Mon Sep 17 00:00:00 2001 From: elforjani3 Date: Thu, 18 Feb 2021 17:57:30 +0200 Subject: [PATCH 1/2] refactoring: exchange rate dialog. --- .../ExchangeRateForm.js | 114 ++++++++ .../ExchangeRateForm.schema.js | 18 ++ .../ExchangeRateFormContent.js | 13 + .../ExchangeRateFormDialogContent.js | 258 +----------------- .../ExchangeRateFormFields.js | 88 ++++++ .../ExchangeRateFormFooter.js | 35 +++ .../ExchangeRateFormProvider.js | 52 ++++ .../Dialogs/ExchangeRateFormDialog/index.js | 4 +- client/src/hooks/query/index.js | 3 +- 9 files changed, 337 insertions(+), 248 deletions(-) create mode 100644 client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateForm.js create mode 100644 client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateForm.schema.js create mode 100644 client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormContent.js create mode 100644 client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormFields.js create mode 100644 client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormFooter.js create mode 100644 client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormProvider.js diff --git a/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateForm.js b/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateForm.js new file mode 100644 index 000000000..bec5b7b6b --- /dev/null +++ b/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateForm.js @@ -0,0 +1,114 @@ +import React, { useMemo } from 'react'; +import { Intent } from '@blueprintjs/core'; +import { Formik } from 'formik'; +import moment from 'moment'; +import { FormattedMessage as T, useIntl } from 'react-intl'; +import { AppToaster } from 'components'; +import { + CreateExchangeRateFormSchema, + EditExchangeRateFormSchema, +} from './ExchangeRateForm.schema'; +import ExchangeRateFormContent from './ExchangeRateFormContent'; +import { useExchangeRateFromContext } from './ExchangeRateFormProvider'; +import withDialogActions from 'containers/Dialog/withDialogActions'; + +import { compose, transformToForm } from 'utils'; + +const defaultInitialValues = { + exchange_rate: '', + currency_code: '', + date: moment(new Date()).format('YYYY-MM-DD'), +}; + +/** + * Exchange rate form. + */ +function ExchangeRateForm({ + // #withDialogActions + closeDialog, +}) { + const { formatMessage } = useIntl(); + const { + createExchangeRateMutate, + editExchangeRateMutate, + isNewMode, + dialogName, + exchangeRate, + } = useExchangeRateFromContext(); + + // Form validation schema in create and edit mode. + const validationSchema = isNewMode + ? CreateExchangeRateFormSchema + : EditExchangeRateFormSchema; + const initialValues = useMemo( + () => ({ + ...defaultInitialValues, + ...transformToForm(exchangeRate, defaultInitialValues), + }), + [], + ); + + // Transformers response errors. + const transformErrors = (errors, { setErrors }) => { + if ( + errors.find((error) => error.type === 'EXCHANGE.RATE.DATE.PERIOD.DEFINED') + ) { + setErrors({ + exchange_rate: formatMessage({ + id: 'there_is_exchange_rate_in_this_date_with_the_same_currency', + }), + }); + } + }; + + // Handle the form submit. + const handleFormSubmit = (values, { setSubmitting, setErrors }) => { + setSubmitting(true); + + // Handle close the dialog after success response. + const afterSubmit = () => { + closeDialog(dialogName); + }; + const onSuccess = ({ response }) => { + AppToaster.show({ + message: formatMessage({ + id: !isNewMode + ? 'the_exchange_rate_has_been_edited_successfully' + : 'the_exchange_rate_has_been_created_successfully', + }), + intent: Intent.SUCCESS, + }); + afterSubmit(response); + }; + // Handle the response error. + const onError = (error) => { + const { + response: { + data: { errors }, + }, + } = error; + + transformErrors(errors, { setErrors }); + setSubmitting(false); + }; + if (isNewMode) { + createExchangeRateMutate(values).then(onSuccess).catch(onError); + } else { + editExchangeRateMutate([exchangeRate.id, values]) + .then(onSuccess) + .catch(onError); + } + }; + + return ( + + + + ); +} + +export default compose(withDialogActions)(ExchangeRateForm); diff --git a/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateForm.schema.js b/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateForm.schema.js new file mode 100644 index 000000000..29ced17ca --- /dev/null +++ b/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateForm.schema.js @@ -0,0 +1,18 @@ +import * as Yup from 'yup'; +import { formatMessage } from 'services/intl'; +import { DATATYPES_LENGTH } from 'common/dataTypes'; + +const Schema = 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' })), +}); + +export const CreateExchangeRateFormSchema = Schema; +export const EditExchangeRateFormSchema = Schema; diff --git a/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormContent.js b/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormContent.js new file mode 100644 index 000000000..3557ad92b --- /dev/null +++ b/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormContent.js @@ -0,0 +1,13 @@ +import React from 'react'; +import { Form } from 'formik'; +import ExchangeRateFormFields from './ExchangeRateFormFields'; +import ExchangeRateFormFooter from './ExchangeRateFormFooter'; + +export default function ExchangeRateFormContent() { + return ( +
+ + + + ); +} diff --git a/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormDialogContent.js b/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormDialogContent.js index cc99f3d70..ad2a39e69 100644 --- a/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormDialogContent.js +++ b/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormDialogContent.js @@ -1,35 +1,9 @@ -import React, { useState, useMemo, useCallback } from 'react'; -import { - Button, - Classes, - FormGroup, - InputGroup, - Intent, - Position, -} 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, - ErrorMessage, - DialogContent, - FieldRequiredHint, - CurrencySelectList, -} from 'components'; -import classNames from 'classnames'; +import React from 'react'; + +import ExchangeRateForm from './ExchangeRateForm'; +import { ExchangeRateFormProvider } from './ExchangeRateFormProvider'; + 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'; import 'style/pages/ExchangeRate/ExchangeRateDialog.scss'; @@ -38,226 +12,20 @@ import 'style/pages/ExchangeRate/ExchangeRateDialog.scss'; * Exchange rate form content. */ 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_edited_successfully', - }), - 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_created_successfully', - }), - 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); +export default compose(withExchangeRateDetail)(ExchangeRateFormDialogContent); diff --git a/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormFields.js b/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormFields.js new file mode 100644 index 000000000..1b5ae13a9 --- /dev/null +++ b/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormFields.js @@ -0,0 +1,88 @@ +import React from 'react'; +import { Classes, FormGroup, InputGroup, Position } from '@blueprintjs/core'; +import { FastField } from 'formik'; +import { DateInput } from '@blueprintjs/datetime'; +import { FormattedMessage as T } from 'react-intl'; +import { + momentFormatter, + tansformDateValue, + handleDateChange, + inputIntent, +} from 'utils'; +import { + ErrorMessage, + FieldRequiredHint, + CurrencySelectList, +} from 'components'; +import { useExchangeRateFromContext } from './ExchangeRateFormProvider'; + +import classNames from 'classnames'; + +export default function ExchangeRateFormFields() { + const { action, currencies } = useExchangeRateFromContext(); + + return ( +
+ {/* ----------- Date ----------- */} + + {({ form, field: { value }, meta: { error, touched } }) => ( + } + labelInfo={FieldRequiredHint} + className={classNames('form-group--select-list', Classes.FILL)} + intent={inputIntent({ error, touched })} + helperText={} + inline={true} + > + { + form.setFieldValue('date', formattedDate); + })} + popoverProps={{ position: Position.BOTTOM, minimal: true }} + disabled={action === 'edit'} + /> + + )} + + {/* ----------- Currency Code ----------- */} + + {({ form, field: { value }, meta: { error, touched } }) => ( + } + labelInfo={} + className={classNames('form-group--currency', Classes.FILL)} + intent={inputIntent({ error, touched })} + helperText={} + inline={true} + > + { + form.setFieldValue('currency_code', currency_code); + }} + disabled={action === 'edit'} + /> + + )} + + + {/*------------ Exchange Rate -----------*/} + + {({ form, field, meta: { error, touched } }) => ( + } + labelInfo={} + intent={inputIntent({ error, touched })} + helperText={} + inline={true} + > + + + )} + +
+ ); +} diff --git a/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormFooter.js b/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormFooter.js new file mode 100644 index 000000000..d0790a5f6 --- /dev/null +++ b/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormFooter.js @@ -0,0 +1,35 @@ +import React from 'react'; +import { useFormikContext } from 'formik'; + +import { Button, Classes, Intent } from '@blueprintjs/core'; +import { FormattedMessage as T } from 'react-intl'; +import { useExchangeRateFromContext } from './ExchangeRateFormProvider'; +import withDialogActions from 'containers/Dialog/withDialogActions'; +import { compose } from 'utils'; + +function ExchangeRateFormFooter({ + // #withDialogActions + closeDialog, +}) { + const { isSubmitting } = useFormikContext(); + const { dialogName, action } = useExchangeRateFromContext(); + + const handleClose = () => { + closeDialog(dialogName); + }; + + return ( +
+
+ + +
+
+ ); +} + +export default compose(withDialogActions)(ExchangeRateFormFooter); diff --git a/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormProvider.js b/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormProvider.js new file mode 100644 index 000000000..3c2cf8829 --- /dev/null +++ b/client/src/containers/Dialogs/ExchangeRateFormDialog/ExchangeRateFormProvider.js @@ -0,0 +1,52 @@ +import React, { createContext, useContext } from 'react'; +import { + useCreateExchangeRate, + useEdiExchangeRate, + useCurrencies, + useExchangeRates, +} from 'hooks/query'; +import { DialogContent } from 'components'; + +const ExchangeRateFormContext = createContext(); + +/** + * Exchange rate Form page provider. + */ +function ExchangeRateFormProvider({ + exchangeRate, + action, + dialogName, + ...props +}) { + // Create and edit exchange rate mutations. + const { mutateAsync: createExchangeRateMutate } = useCreateExchangeRate(); + const { mutateAsync: editExchangeRateMutate } = useEdiExchangeRate(); + + // Load Currencies list. + const { data: currencies, isFetching: isCurrenciesLoading } = useCurrencies(); + const { isFetching: isExchangeRatesLoading } = useExchangeRates(); + + const isNewMode = !exchangeRate; + + // Provider state. + const provider = { + createExchangeRateMutate, + editExchangeRateMutate, + dialogName, + exchangeRate, + action, + currencies, + isExchangeRatesLoading, + isNewMode, + }; + + return ( + + + + ); +} + +const useExchangeRateFromContext = () => useContext(ExchangeRateFormContext); + +export { ExchangeRateFormProvider, useExchangeRateFromContext }; diff --git a/client/src/containers/Dialogs/ExchangeRateFormDialog/index.js b/client/src/containers/Dialogs/ExchangeRateFormDialog/index.js index 044447c54..3c4c8f6ff 100644 --- a/client/src/containers/Dialogs/ExchangeRateFormDialog/index.js +++ b/client/src/containers/Dialogs/ExchangeRateFormDialog/index.js @@ -16,7 +16,7 @@ const ExchangeRateFormDialogContent = lazy(() => */ function ExchangeRateFormDialog({ dialogName, - payload = { action: '', id: null }, + payload = { action: '', id: null , exchangeRate:"" }, isOpen, }) { return ( @@ -38,7 +38,7 @@ function ExchangeRateFormDialog({ diff --git a/client/src/hooks/query/index.js b/client/src/hooks/query/index.js index 640214bfd..98eb3dc85 100644 --- a/client/src/hooks/query/index.js +++ b/client/src/hooks/query/index.js @@ -17,4 +17,5 @@ export * from './receipts'; export * from './paymentReceives'; export * from './paymentMades'; export * from './settings'; -export * from './users'; \ No newline at end of file +export * from './users'; +export * from './exchangeRates'; \ No newline at end of file From 4b0c266f3484134896ae4ac377a8009c12dbd02b Mon Sep 17 00:00:00 2001 From: elforjani3 Date: Thu, 18 Feb 2021 17:58:01 +0200 Subject: [PATCH 2/2] refactoring: exchanges rates list. --- .../ExchangeRateBulkDeleteAlert.js | 71 ++++++ .../ExchangeRates/ExchangeRateDeleteAlert.js | 76 +++++++ .../ExchangeRates/ExchangeRateTable.js | 214 +++++------------- .../ExchangeRates/ExchangeRatesAlerts.js | 12 + .../ExchangeRates/ExchangeRatesList.js | 211 ++--------------- .../ExchangeRates/ExchangeRatesProvider.js | 35 +++ .../containers/ExchangeRates/components.js | 94 ++++++++ client/src/hooks/query/exchangeRates.js | 78 +++++++ client/src/routes/dashboard.js | 1 + 9 files changed, 437 insertions(+), 355 deletions(-) create mode 100644 client/src/containers/Alerts/ExchangeRates/ExchangeRateBulkDeleteAlert.js create mode 100644 client/src/containers/Alerts/ExchangeRates/ExchangeRateDeleteAlert.js create mode 100644 client/src/containers/ExchangeRates/ExchangeRatesAlerts.js create mode 100644 client/src/containers/ExchangeRates/ExchangeRatesProvider.js create mode 100644 client/src/containers/ExchangeRates/components.js create mode 100644 client/src/hooks/query/exchangeRates.js diff --git a/client/src/containers/Alerts/ExchangeRates/ExchangeRateBulkDeleteAlert.js b/client/src/containers/Alerts/ExchangeRates/ExchangeRateBulkDeleteAlert.js new file mode 100644 index 000000000..73e60e689 --- /dev/null +++ b/client/src/containers/Alerts/ExchangeRates/ExchangeRateBulkDeleteAlert.js @@ -0,0 +1,71 @@ +import React, { useState } from 'react'; +import { FormattedMessage as T, useIntl } from 'react-intl'; +import { Intent, Alert } from '@blueprintjs/core'; +import { size } from 'lodash'; +import { AppToaster } from 'components'; + +import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect'; +import withAlertActions from 'containers/Alert/withAlertActions'; + +import { compose } from 'utils'; + +/** + * Exchange rate bulk delete alert. + */ +function ExchangeRateBulkDeleteAlert({ + name, + + // #withAlertStoreConnect + isOpen, + payload: { exchangeRatesIds }, + + // #withAlertActions + closeAlert, +}) { + // handle cancel item bulk delete alert. + const handleCancelBulkDelete = () => { + closeAlert(name); + }; + + // handle confirm Exchange Rates bulk delete. + // const handleConfirmBulkDelete = () => { + // bulkDeleteExchangeRate(exchangeRatesIds) + // .then(() => { + // AppToaster.show({ + // message: formatMessage({ + // id: 'the_exchange_rates_has_been_successfully_deleted', + // }), + // intent: Intent.SUCCESS, + // }); + // }) + // .catch(({ errors }) => { + // handleDeleteErrors(errors); + // }); + // }; + + return ( + } + confirmButtonText={ + + } + icon="trash" + intent={Intent.DANGER} + isOpen={isOpen} + onCancel={handleCancelBulkDelete} + // onConfirm={} + // loading={isLoading} + > +

+ +

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, +)(ExchangeRateBulkDeleteAlert); diff --git a/client/src/containers/Alerts/ExchangeRates/ExchangeRateDeleteAlert.js b/client/src/containers/Alerts/ExchangeRates/ExchangeRateDeleteAlert.js new file mode 100644 index 000000000..e13bd0faa --- /dev/null +++ b/client/src/containers/Alerts/ExchangeRates/ExchangeRateDeleteAlert.js @@ -0,0 +1,76 @@ +import React from 'react'; +import { + FormattedMessage as T, + FormattedHTMLMessage, + useIntl, +} from 'react-intl'; +import { Intent, Alert } from '@blueprintjs/core'; +import { AppToaster } from 'components'; + +import { useDeleteExchangeRate } from 'hooks/query'; +import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect'; +import withAlertActions from 'containers/Alert/withAlertActions'; + +import { compose } from 'utils'; + +/** + * exchange rate delete alerts. + */ +function ExchangeRateDeleteAlert({ + name, + + // #withAlertStoreConnect + isOpen, + payload: { exchangeRateId }, + + // #withAlertActions + closeAlert, +}) { + const { + mutateAsync: deleteExchangeRate, + isLoading, + } = useDeleteExchangeRate(); + const { formatMessage } = useIntl(); + + // Handle cancel delete exchange rate alert. + const handleCancelExchangeRateDelete = () => closeAlert(name); + + const handelConfirmExchangeRateDelete = () => { + deleteExchangeRate(exchangeRateId) + .then((response) => { + AppToaster.show({ + message: formatMessage({ + id: 'the_exchange_rates_has_been_deleted_successfully', + }), + intent: Intent.SUCCESS, + }); + closeAlert(name); + }) + .catch(() => { + closeAlert(name); + }); + }; + + return ( + } + confirmButtonText={} + intent={Intent.DANGER} + isOpen={isOpen} + onCancel={handleCancelExchangeRateDelete} + onConfirm={handelConfirmExchangeRateDelete} + loading={isLoading} + > +

+ +

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, +)(ExchangeRateDeleteAlert); diff --git a/client/src/containers/ExchangeRates/ExchangeRateTable.js b/client/src/containers/ExchangeRates/ExchangeRateTable.js index c3c2f9a26..8813fa2e2 100644 --- a/client/src/containers/ExchangeRates/ExchangeRateTable.js +++ b/client/src/containers/ExchangeRates/ExchangeRateTable.js @@ -1,183 +1,75 @@ -import React, { useCallback, useMemo, useState } from 'react'; -import { - Button, - Popover, - Menu, - MenuItem, - Position, - Intent, -} from '@blueprintjs/core'; -import { FormattedMessage as T, useIntl } from 'react-intl'; -import moment from 'moment'; -import classNames from 'classnames'; +import React from 'react'; -import { CLASSES } from 'common/classes'; +import { DataTable } from 'components'; +import TableSkeletonRows from 'components/Datatable/TableSkeletonRows'; -import { DataTable, Icon, Money } from 'components'; -import LoadingIndicator from 'components/LoadingIndicator'; +import { useExchangeRatesContext } from './ExchangeRatesProvider'; +import { useExchangeRatesTableColumns, ActionMenuList } from './components'; import withDialogActions from 'containers/Dialog/withDialogActions'; -import withExchangeRatesActions from 'containers/ExchangeRates/withExchangeRatesActions'; -import withExchangeRates from 'containers/ExchangeRates/withExchangeRates'; +import withAlertActions from 'containers/Alert/withAlertActions'; import { compose } from 'utils'; +/** + * Exchange rates table. + */ function ExchangeRateTable({ - // #withExchangeRates - exchangeRatesList, - exchangeRatesLoading, - exchangeRatesPageination, + // #ownProps + tableProps, + // #withDialogActions. openDialog, - // own properties - loading, - onFetchData, - onDeleteExchangeRate, - onSelectedRowsChange, + // #withAlertActions + openAlert, }) { - const [initialMount, setInitialMount] = useState(false); - const { formatMessage } = useIntl(); + const { + isExchangeRatesFetching, + isExchangeRatesLoading, - const handelEditExchangeRate = useCallback( - (exchange_rate) => () => { - openDialog('exchangeRate-form', { action: 'edit', id: exchange_rate.id }); - }, - [openDialog], - ); + exchangesRates, + pagination, + } = useExchangeRatesContext(); - const handleDeleteExchangeRate = (exchange_rate) => () => { - onDeleteExchangeRate(exchange_rate); + // Table columns. + const columns = useExchangeRatesTableColumns(); + + // Handle delete exchange rate. + const handleDeleteExchangeRate = ({ id }) => { + openAlert('exchange-rate-delete', { exchangeRateId: id }); }; - const actionMenuList = useCallback( - (ExchangeRate) => ( - - } - text={formatMessage({ id: 'edit_exchange_rate' })} - onClick={handelEditExchangeRate(ExchangeRate)} - /> - } - /> - - ), - [handelEditExchangeRate, handleDeleteExchangeRate, formatMessage], - ); - - const rowContextMenu = (cell) => { - return actionMenuList(cell.row.original); + // Handle Edit exchange rate. + const handelEditExchangeRate = (exchangeRate) => { + openDialog('exchangeRate-form', { + action: 'edit', + exchangeRate: exchangeRate, + }); }; - const columns = useMemo( - () => [ - { - id: 'date', - Header: formatMessage({ id: 'date' }), - accessor: (r) => moment(r.date).format('YYYY MMM DD'), - width: 150, - }, - { - id: 'currency_code', - Header: formatMessage({ id: 'currency_code' }), - accessor: 'currency_code', - className: 'currency_code', - width: 150, - }, - { - id: 'exchange_rate', - Header: formatMessage({ id: 'exchange_rate' }), - accessor: (r) => ( - - ), - className: 'exchange_rate', - width: 150, - }, - { - id: 'actions', - Header: '', - Cell: ({ cell }) => ( - -