From 913245d202dea4958f21d0a18a15476d3ac5c28a Mon Sep 17 00:00:00 2001 From: "a.bouhuolia" Date: Mon, 14 Feb 2022 15:22:07 +0200 Subject: [PATCH] feat: abstruct exchange rate input group component. --- .../ExchangeRate/ExchangeRateInput.js | 52 ++++++++++++++ src/components/ExchangeRate/index.js | 1 + src/components/Forms/FFormGroup.tsx | 49 ++++++++++++++ src/components/Forms/FMoneyInputGroup.js | 36 ++++++++++ src/components/Forms/index.js | 4 +- src/components/index.js | 2 +- .../CustomerForm/CustomerFinancialPanel.js | 1 - .../InvoiceForm/InvoiceFormHeaderFields.js | 67 +++---------------- 8 files changed, 151 insertions(+), 61 deletions(-) create mode 100644 src/components/ExchangeRate/ExchangeRateInput.js create mode 100644 src/components/ExchangeRate/index.js create mode 100644 src/components/Forms/FFormGroup.tsx create mode 100644 src/components/Forms/FMoneyInputGroup.js diff --git a/src/components/ExchangeRate/ExchangeRateInput.js b/src/components/ExchangeRate/ExchangeRateInput.js new file mode 100644 index 000000000..cc3e4b9ae --- /dev/null +++ b/src/components/ExchangeRate/ExchangeRateInput.js @@ -0,0 +1,52 @@ +import React from 'react'; +import styled from 'styled-components'; +import { ControlGroup } from '@blueprintjs/core'; + +import { FlagTag } from '../Tags'; +import { FMoneyInputGroup, FFormGroup } from '../Forms'; + +export function ExchangeRateInputGroup({ + fromCurrency, + toCurrency, + inputGroupProps, + formGroupProps, + name, +}) { + return ( + + + + 1 {fromCurrency} = + + + + {toCurrency} + + + + ); +} + +const ExchangeRateField = styled(FMoneyInputGroup)` + max-width: 88px; +`; + +const ExchangeRateSideIcon = styled.div` + display: flex; + align-items: center; + font-size: 12px; + line-height: 1; +`; + +const ExchangeRatePrepend = styled(ExchangeRateSideIcon)` + padding-right: 8px; +`; + +const ExchangeRateAppend = styled(ExchangeRateSideIcon)` + padding-left: 8px; +`; diff --git a/src/components/ExchangeRate/index.js b/src/components/ExchangeRate/index.js new file mode 100644 index 000000000..ea982a466 --- /dev/null +++ b/src/components/ExchangeRate/index.js @@ -0,0 +1 @@ +export * from './ExchangeRateInput'; \ No newline at end of file diff --git a/src/components/Forms/FFormGroup.tsx b/src/components/Forms/FFormGroup.tsx new file mode 100644 index 000000000..633ebec99 --- /dev/null +++ b/src/components/Forms/FFormGroup.tsx @@ -0,0 +1,49 @@ +import React from 'react'; +import { FieldMetaProps, FieldInputProps, useField } from 'formik'; +import { + FormGroup as PBFormGroup, + Intent, + FormGroupProps as PBFormGroupProps, +} from '@blueprintjs/core'; + +export interface FormGroupProps extends PBFormGroupProps { + name: string; + children: React.ReactElement; +} + +/** + * Transformes field props to form group. + * @param {Omit} props + * @param {FieldInputProps} field + * @param {FieldMetaProps} meta + * @returns {PBFormGroupProps} + */ +const fieldToFormGroup = ( + props: Omit, + field: FieldInputProps, + meta: FieldMetaProps +): PBFormGroupProps => { + const showError = meta.touched && meta.error; + + return { + intent: showError ? Intent.DANGER : Intent.NONE, + helperText: showError ? meta.error : '', + ...props, + }; +}; + +/** + * Form group. + * @param {FormGroupProps} + * @returns {React.JSX} + */ +export function FFormGroup({ children, ...props }: FormGroupProps): JSX.Element { + const [field, meta] = useField(props.name); + + return ( + + ); +} \ No newline at end of file diff --git a/src/components/Forms/FMoneyInputGroup.js b/src/components/Forms/FMoneyInputGroup.js new file mode 100644 index 000000000..2bc69fd35 --- /dev/null +++ b/src/components/Forms/FMoneyInputGroup.js @@ -0,0 +1,36 @@ +import React from 'react'; +import { Intent } from '@blueprintjs/core'; +import { Field, getIn } from 'formik'; +import { CurrencyInput } from './MoneyInputGroup'; + +const fieldToMoneyInputGroup = ({ + field: { onBlur: onFieldBlur, ...field }, + form: { setFieldValue, touched, errors }, + onBlur, + ...props +}) => { + const fieldError = getIn(errors, field.name); + const showError = getIn(touched, field.name) && !!fieldError; + + return { + intent: showError ? Intent.DANGER : Intent.NONE, + onBlurValue: + onBlur ?? + function (e) { + onFieldBlur(e ?? field.name); + }, + ...field, + onChange: (value) => { + setFieldValue(field.name, value); + }, + ...props, + }; +}; + +function FieldToMoneyInputGroup({ ...props }) { + return ; +} + +export function FMoneyInputGroup({ ...props }) { + return ; +} diff --git a/src/components/Forms/index.js b/src/components/Forms/index.js index c531c474b..c6221811d 100644 --- a/src/components/Forms/index.js +++ b/src/components/Forms/index.js @@ -1,2 +1,4 @@ export * from './FormObserver'; -export * from './FormikObserver'; \ No newline at end of file +export * from './FormikObserver'; +export * from './FMoneyInputGroup' +export * from './FFormGroup' \ No newline at end of file diff --git a/src/components/index.js b/src/components/index.js index 08c1b44ff..bb40a47ed 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -98,7 +98,7 @@ export * from './FinancialStatement'; export * from './FinancialReport'; export * from './FinancialSheet'; export * from './FeatureGuard'; - +export * from './ExchangeRate' const Hint = FieldHint; const T = FormattedMessage; diff --git a/src/containers/Customers/CustomerForm/CustomerFinancialPanel.js b/src/containers/Customers/CustomerForm/CustomerFinancialPanel.js index 4193487bb..86eda3909 100644 --- a/src/containers/Customers/CustomerForm/CustomerFinancialPanel.js +++ b/src/containers/Customers/CustomerForm/CustomerFinancialPanel.js @@ -110,7 +110,6 @@ export default function CustomerFinancialPanel() { onCurrencySelected={(currency) => { form.setFieldValue('currency_code', currency.currency_code); }} - disabled={true} /> )} diff --git a/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.js b/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.js index b9eb52470..760ffcab2 100644 --- a/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.js +++ b/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.js @@ -9,7 +9,6 @@ import { DateInput } from '@blueprintjs/datetime'; import { FastField, Field, ErrorMessage } from 'formik'; import { FormattedMessage as T, Col, Row, If } from 'components'; import { momentFormatter, compose, tansformDateValue } from 'utils'; -import { upperCase } from 'lodash'; import classNames from 'classnames'; import styled from 'styled-components'; @@ -25,8 +24,7 @@ import { ListSelect, Icon, InputPrependButton, - MoneyInputGroup, - FlagTag, + ExchangeRateInputGroup, } from 'components'; import { useInvoiceFormContext } from './InvoiceFormProvider'; @@ -121,42 +119,14 @@ function InvoiceFormHeaderFields({ )} - {/* ----------- Exchange reate ----------- */} - - - - {({ - form: { values, setFieldValue }, - field, - meta: { error, touched }, - }) => ( - } - > - - - 1 USD = - - { - setFieldValue('exchange_rate', value); - }} - intent={inputIntent({ error, touched })} - /> - - LYD - - - - )} - - + {/* ----------- Exchange rate ----------- */} + + @@ -309,25 +279,6 @@ export default compose( })), )(InvoiceFormHeaderFields); -const ExchangeRateField = styled.div` - display: flex; - justify-content: flex-end; - align-items: center; - max-width: 366px; - .bp3-input-group .bp3-input { - width: 88px; - margin: 0 5px; - } -`; - -const ExchangeRateTag = styled.div` - display: flex; - align-items: center; - cursor: pointer; - font-size: 10px; - line-height: 1.6; -`; - const ControlCustomerGroup = styled(ControlGroup)` display: flex; align-items: center;