parent
38d2e12b64
commit
0fcade76e1
|
@ -5,6 +5,7 @@ import { getFormatersFromUnit } from 'Engine/format'
|
|||
import React from 'react'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { situationSelector } from 'Selectors/analyseSelectors'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
/*
|
||||
This higher order component wraps "Form" components (e.g. Question.js), that represent user inputs,
|
||||
|
@ -15,9 +16,10 @@ to understand those precious higher order components.
|
|||
*/
|
||||
|
||||
export const FormDecorator = formType => RenderField =>
|
||||
function({ fieldName, question, inversion, unit, ...otherProps }) {
|
||||
function FormStep({ fieldName, question, inversion, unit, ...otherProps }) {
|
||||
const dispatch = useDispatch()
|
||||
const situation = useSelector(situationSelector)
|
||||
const { language } = useTranslation().i18n
|
||||
|
||||
const submit = source =>
|
||||
dispatch({
|
||||
|
@ -30,7 +32,7 @@ export const FormDecorator = formType => RenderField =>
|
|||
dispatch(updateSituation(fieldName, normalize(value)))
|
||||
}
|
||||
|
||||
const { format, normalize } = getFormatersFromUnit(unit)
|
||||
const { format, normalize } = getFormatersFromUnit(unit, language)
|
||||
const value = format(situation[fieldName])
|
||||
|
||||
return (
|
||||
|
@ -48,6 +50,7 @@ export const FormDecorator = formType => RenderField =>
|
|||
setFormValue={setFormValue}
|
||||
submit={submit}
|
||||
format={format}
|
||||
normalize={normalize}
|
||||
unit={unit}
|
||||
{...otherProps}
|
||||
/>
|
||||
|
|
|
@ -2,7 +2,7 @@ import classnames from 'classnames'
|
|||
import { T } from 'Components'
|
||||
import withColours from 'Components/utils/withColours'
|
||||
import { compose } from 'ramda'
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import React, { useCallback } from 'react'
|
||||
import { usePeriod } from 'Selectors/analyseSelectors'
|
||||
import { debounce } from '../../utils'
|
||||
import { FormDecorator } from './FormDecorator'
|
||||
|
@ -33,7 +33,7 @@ export default compose(
|
|||
<InputSuggestions
|
||||
suggestions={suggestions}
|
||||
onFirstClick={value => {
|
||||
setFormValue(format(value))
|
||||
setFormValue(value)
|
||||
}}
|
||||
onSecondClick={() => submit('suggestion')}
|
||||
rulePeriod={rulePeriod}
|
||||
|
@ -45,7 +45,7 @@ export default compose(
|
|||
type="text"
|
||||
key={value}
|
||||
autoFocus
|
||||
defaultValue={value}
|
||||
value={format(value)}
|
||||
onChange={evt => {
|
||||
debouncedSetFormValue(evt.target.value)
|
||||
}}
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
import { serialiseUnit } from 'Engine/units'
|
||||
import { memoizeWith } from 'ramda'
|
||||
|
||||
export const formatCurrency = (value, language) => {
|
||||
return value == null
|
||||
? ''
|
||||
: Intl.NumberFormat(language, {
|
||||
style: 'currency',
|
||||
currency: 'EUR',
|
||||
maximumFractionDigits: 0,
|
||||
minimumFractionDigits: 0
|
||||
})
|
||||
.format(value)
|
||||
.replace(/^(-)?€/, '$1€\u00A0')
|
||||
}
|
||||
|
||||
const sanitizeValue = language => value =>
|
||||
language === 'fr' ? String(value).replace(',', '.') : value
|
||||
|
||||
export const formatPercentage = value => +(value * 100).toFixed(2)
|
||||
export const normalizePercentage = value => value / 100
|
||||
|
||||
export const getFormatersFromUnit = (unit, language = 'en') => {
|
||||
const serializedUnit = typeof unit == 'object' ? serialiseUnit(unit) : unit
|
||||
const sanitize = sanitizeValue(language)
|
||||
switch (serializedUnit) {
|
||||
case '%':
|
||||
return {
|
||||
format: numberFormatter({ style: 'percent', language }).replace(
|
||||
' %',
|
||||
''
|
||||
),
|
||||
normalize: v => normalizePercentage(language)(sanitize(v))
|
||||
}
|
||||
default:
|
||||
return {
|
||||
format: x =>
|
||||
Number(x)
|
||||
? numberFormatter({ style: 'decimal', language })(Number(x))
|
||||
: x,
|
||||
normalize: x => sanitize(x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const NumberFormat = memoizeWith(
|
||||
(...args) => JSON.stringify(args),
|
||||
Intl.NumberFormat
|
||||
)
|
||||
|
||||
export let numberFormatter = ({
|
||||
style,
|
||||
maximumFractionDigits = 2,
|
||||
minimumFractionDigits = 0,
|
||||
language
|
||||
}) => value =>
|
||||
NumberFormat(language, {
|
||||
style,
|
||||
currency: 'EUR',
|
||||
maximumFractionDigits,
|
||||
minimumFractionDigits
|
||||
}).format(value)
|
||||
|
||||
export function formatValue({
|
||||
maximumFractionDigits,
|
||||
minimumFractionDigits,
|
||||
language,
|
||||
unit,
|
||||
value
|
||||
}) {
|
||||
const serializedUnit = typeof unit == 'object' ? serialiseUnit(unit) : unit
|
||||
|
||||
switch (serializedUnit) {
|
||||
case '€':
|
||||
return numberFormatter({
|
||||
style: 'currency',
|
||||
maximumFractionDigits,
|
||||
minimumFractionDigits,
|
||||
language
|
||||
})(value)
|
||||
case '%':
|
||||
return numberFormatter({ style: 'percent', maximumFractionDigits })(value)
|
||||
default:
|
||||
if (typeof value !== 'number') {
|
||||
return value
|
||||
}
|
||||
return (
|
||||
numberFormatter({
|
||||
style: 'decimal',
|
||||
minimumFractionDigits,
|
||||
maximumFractionDigits
|
||||
})(value) +
|
||||
(typeof serializedUnit === 'string' ? `\u00A0${serializedUnit}` : '')
|
||||
)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue