mirror of
https://github.com/betagouv/mon-entreprise
synced 2025-02-13 06:05:02 +00:00
Quand une variable est destinée à être saisie par l'utilisateur, on veut qu'il saisisse 50, pas 0.5 pour exprimer 50%. On pourrait lui faire saisir 50 et convertir en direct vers la vraie valeur de 0.5, mais c'est compliqué aujourd'hui dans reduxForm (l'attribut "normalize" ne suffit pas, car la valeur 0.5 sera visible après un bref instant de debounce). Je pense qu'il serai quand même mieux que nous stockions les variables qui sont des ratios comme 0.5 et que l'UI se charge d'afficher et de faire saisir ces valeurs sous forme 50%.
106 lines
2.4 KiB
JavaScript
106 lines
2.4 KiB
JavaScript
import { React, T } from 'Components'
|
|
import { memoizeWith } from 'ramda'
|
|
import { serialiseUnit } from 'Engine/units'
|
|
import withLanguage from './utils/withLanguage'
|
|
|
|
const NumberFormat = memoizeWith(
|
|
(...args) => JSON.stringify(args),
|
|
Intl.NumberFormat
|
|
)
|
|
|
|
export let numberFormatter = ({
|
|
style,
|
|
maximumFractionDigits,
|
|
minimumFractionDigits = 0,
|
|
language
|
|
}) => value =>
|
|
NumberFormat(language, {
|
|
style,
|
|
currency: 'EUR',
|
|
maximumFractionDigits,
|
|
minimumFractionDigits
|
|
}).format(value)
|
|
|
|
// let booleanTranslations = { true: '✅', false: '❌' }
|
|
|
|
let booleanTranslations = {
|
|
fr: { true: 'Oui', false: 'Non' },
|
|
en: { true: 'Yes', false: 'No' }
|
|
}
|
|
|
|
let style = customStyle => `
|
|
font-family: 'Courier New', Courier, monospace;
|
|
|
|
${customStyle}
|
|
`
|
|
|
|
export default withLanguage(
|
|
({
|
|
nodeValue: value,
|
|
unit,
|
|
nilValueSymbol,
|
|
maximumFractionDigits,
|
|
minimumFractionDigits,
|
|
children,
|
|
negative,
|
|
language,
|
|
customCSS = ''
|
|
}) => {
|
|
/* Either an entire rule object is passed, or just the right attributes and the value as a JSX child*/
|
|
let nodeValue = value === undefined ? children : value
|
|
|
|
if (
|
|
(nilValueSymbol !== undefined && nodeValue === 0) ||
|
|
Number.isNaN(nodeValue) ||
|
|
nodeValue === null
|
|
)
|
|
return (
|
|
<span css={style(customCSS)} className="value">
|
|
-
|
|
</span>
|
|
)
|
|
let valueType = typeof nodeValue,
|
|
unitText =
|
|
unit !== null && (typeof unit == 'object' ? serialiseUnit(unit) : unit),
|
|
formattedValue =
|
|
valueType === 'string' ? (
|
|
<T>{nodeValue}</T>
|
|
) : valueType === 'object' ? (
|
|
nodeValue.nom
|
|
) : valueType === 'boolean' ? (
|
|
booleanTranslations[language][nodeValue]
|
|
) : unitText === '€' ? (
|
|
numberFormatter({
|
|
style: 'currency',
|
|
maximumFractionDigits,
|
|
minimumFractionDigits,
|
|
language
|
|
})(nodeValue)
|
|
) : unitText === '%' ? (
|
|
numberFormatter({ style: 'percent', maximumFractionDigits: 3 })(
|
|
nodeValue
|
|
)
|
|
) : unitText === '(%)' ? (
|
|
numberFormatter({ style: 'percent', maximumFractionDigits: 3 })(
|
|
nodeValue / 100
|
|
)
|
|
) : (
|
|
<>
|
|
{numberFormatter({
|
|
style: 'decimal',
|
|
minimumFractionDigits,
|
|
maximumFractionDigits
|
|
})(nodeValue)}
|
|
|
|
{unitText}
|
|
</>
|
|
)
|
|
|
|
return nodeValue == undefined ? null : (
|
|
<span css={style(customCSS)} className="value">
|
|
{negative ? '-' : ''}
|
|
{formattedValue}
|
|
</span>
|
|
)
|
|
}
|
|
)
|