Première unité affichée sur la page règle
parent
4cab6b464b
commit
a7c6cb25fa
|
@ -0,0 +1,37 @@
|
|||
import React from 'react'
|
||||
import { memoizeWith } from 'ramda'
|
||||
import { serialiseUnit } from 'Engine/units'
|
||||
|
||||
const NumberFormat = memoizeWith(JSON.stringify, Intl.NumberFormat)
|
||||
|
||||
let numberFormatter = style => (value, language) =>
|
||||
NumberFormat(language, {
|
||||
style,
|
||||
currency: 'EUR',
|
||||
maximumFractionDigits: 2,
|
||||
minimumFractionDigits: 2
|
||||
}).format(value)
|
||||
|
||||
let booleanTranslations = {
|
||||
fr: { true: 'Oui', false: 'Non' },
|
||||
en: { true: 'Yes', false: 'No' }
|
||||
}
|
||||
|
||||
let formats = {
|
||||
'€': numberFormatter('currency'),
|
||||
boolean: (value, language = 'fr') => booleanTranslations[language][value],
|
||||
object: value => JSON.stringify(value)
|
||||
}
|
||||
|
||||
export default ({ nodeValue, unit }) => {
|
||||
let valueType = typeof nodeValue,
|
||||
unitText = unit && serialiseUnit(unit)
|
||||
return nodeValue == undefined ? null : (
|
||||
<div css="border: 2px dashed chartreuse">
|
||||
{(formats[valueType !== 'number' ? valueType : unitText] ||
|
||||
numberFormatter('decimal'))(nodeValue)}
|
||||
|
||||
{unit && unitText}
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -15,7 +15,6 @@ import {
|
|||
analysisWithDefaultsSelector,
|
||||
getRuleFromAnalysis
|
||||
} from 'Selectors/analyseSelectors'
|
||||
import { humanValue } from 'Engine/rules'
|
||||
|
||||
const AnswerList = ({
|
||||
answers,
|
||||
|
@ -57,7 +56,7 @@ const AnswerList = ({
|
|||
<span
|
||||
className="answerContent"
|
||||
style={{ borderBottomColor: colours.textColourOnWhite }}>
|
||||
{humanValue(answer)(language)}
|
||||
{answer}
|
||||
</span>
|
||||
</button>{' '}
|
||||
</td>
|
||||
|
|
|
@ -40,7 +40,10 @@ export default compose(withTranslation())(
|
|||
displayFormula =
|
||||
formula &&
|
||||
!!Object.keys(formula).length &&
|
||||
!path(['formule', 'explanation', 'une possibilité'], rule)
|
||||
!path(['formule', 'explanation', 'une possibilité'], rule) &&
|
||||
formula.explanation?.category !== 'number'
|
||||
|
||||
console.log(formula)
|
||||
return (
|
||||
<div id="algorithm">
|
||||
<section id="rule-rules" className={classNames({ showValues })}>
|
||||
|
|
|
@ -36,7 +36,7 @@ let Namespace = ({ ns, flatRules, colour, sitePaths }) => {
|
|||
to={
|
||||
sitePaths.documentation.index + '/' + encodeRuleName(ruleName)
|
||||
}>
|
||||
{rule.icon && <span>{emoji(rule.icon)} </span>}
|
||||
{rule.icons && <span>{emoji(rule.icons)} </span>}
|
||||
{ruleText}
|
||||
</Link>
|
||||
{' › '}
|
||||
|
|
|
@ -21,10 +21,8 @@ h2 small {
|
|||
}
|
||||
|
||||
#rule #ruleValue {
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
font-size: 200%;
|
||||
color: inherit;
|
||||
margin-bottom: 0.6em;
|
||||
margin-top: 0.4em;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ import Examples from './Examples'
|
|||
import RuleHeader from './Header'
|
||||
import References from './References'
|
||||
import './Rule.css'
|
||||
import { serializeUnit } from 'Engine/units'
|
||||
import Value from 'Components/Value'
|
||||
|
||||
let LazySource = React.lazy(() => import('./RuleSource'))
|
||||
|
||||
|
@ -64,7 +64,6 @@ export default compose(
|
|||
namespaceRules = findRuleByNamespace(flatRules, dottedName)
|
||||
|
||||
let displayedRule = analysedExample || analysedRule
|
||||
debugger
|
||||
return (
|
||||
<>
|
||||
{this.state.viewSource ? (
|
||||
|
@ -102,26 +101,12 @@ export default compose(
|
|||
/>
|
||||
|
||||
<section id="rule-content">
|
||||
{!isNil(displayedRule.nodeValue) && (
|
||||
<div id="ruleValue">
|
||||
<span className="ui__ valeur">
|
||||
{displayedRule.humanValue(
|
||||
displayedRule.nodeValue,
|
||||
language
|
||||
)}
|
||||
{displayedRule.unit && (
|
||||
<span>{serializeUnit(displayedRule.unit)}</span>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
<div id="ruleValue">
|
||||
<Value {...displayedRule} />
|
||||
</div>
|
||||
{displayedRule.defaultValue != null && (
|
||||
<div id="ruleDefault">
|
||||
Valeur par défaut :{' '}
|
||||
{displayedRule.humanValue(
|
||||
displayedRule.defaultValue,
|
||||
language
|
||||
)}
|
||||
Valeur par défaut : {displayedRule.defaultValue}
|
||||
</div>
|
||||
)}
|
||||
{!valuesToShow && (
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
/* Those are postprocessor functions for the Nearley grammar.ne.
|
||||
The advantage of putting them here is to get prettier's JS formatting, since Nealrey doesn't support it https://github.com/kach/nearley/issues/310 */
|
||||
|
||||
import { inferUnit } from 'Engine/units'
|
||||
|
||||
export let operation = operationType => ([A, , operator, , B]) => ({
|
||||
[operator]: {
|
||||
operationType,
|
||||
explanation: [A, B],
|
||||
unit: inferUnit(operator, A.unit, B.unit)
|
||||
explanation: [A, B]
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// Séparation artificielle, temporaire, entre ces deux types de règles
|
||||
import valueFormats from 'Engine/valueFormats'
|
||||
import {
|
||||
assoc,
|
||||
chain,
|
||||
|
@ -26,7 +24,8 @@ import {
|
|||
take,
|
||||
toPairs,
|
||||
trim,
|
||||
when
|
||||
when,
|
||||
groupBy
|
||||
} from 'ramda'
|
||||
import rawRules from 'Règles/base.yaml'
|
||||
import translations from 'Règles/externalized.yaml'
|
||||
|
@ -41,12 +40,7 @@ Functions working on one rule */
|
|||
|
||||
export let enrichRule = rule => {
|
||||
try {
|
||||
let formatKey = rule['format'] || 'booléen',
|
||||
format = valueFormats[formatKey]
|
||||
if (!format) {
|
||||
console.log(`The '${format}' rule format is unknown`)
|
||||
throw new Error(format)
|
||||
}
|
||||
let unit = rule.unité && parseUnit(rule.unité)
|
||||
return {
|
||||
...rule,
|
||||
type: possibleVariableTypes.find(t => has(t, rule) || rule.type === t),
|
||||
|
@ -59,9 +53,7 @@ export let enrichRule = rule => {
|
|||
examples: rule['exemples'],
|
||||
icons: rule['icônes'],
|
||||
summary: rule['résumé'],
|
||||
format,
|
||||
humanValue: format.human,
|
||||
...(rule.unité ? { unit: parseUnit(rule.unité) } : {})
|
||||
unit
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
|
@ -197,19 +189,6 @@ export let nestedSituationToPathMap = situation => {
|
|||
return fromPairs(rec(situation, []))
|
||||
}
|
||||
|
||||
export let formatInputs = (flatRules, pathValueMap) =>
|
||||
mapObjIndexed((value, path) => {
|
||||
// Our situationGate retrieves data from the "conversation" form
|
||||
// The search below is to apply input conversions such as replacing "," with "."
|
||||
if (name.startsWith('sys.')) return null
|
||||
|
||||
let rule = findRuleByDottedName(flatRules, path),
|
||||
format = rule ? valueFormats[rule.format] : null,
|
||||
pre = format && format.validator.pre ? format.validator.pre : identity
|
||||
|
||||
return pre(value)
|
||||
}, pathValueMap)
|
||||
|
||||
/* Traduction */
|
||||
|
||||
export let translateAll = (translations, flatRules) => {
|
||||
|
@ -255,6 +234,7 @@ export let translateAll = (translations, flatRules) => {
|
|||
export let rules = translateAll(translations, rawRules).map(rule =>
|
||||
enrichRule(rule)
|
||||
)
|
||||
|
||||
export let rulesFr = rawRules.map(rule => enrichRule(rule))
|
||||
|
||||
export let findParentDependency = (rules, rule) => {
|
||||
|
|
|
@ -267,7 +267,7 @@ export let treatRuleRoot = (rules, rule) => {
|
|||
...parsedRoot,
|
||||
evaluate,
|
||||
parsed: true,
|
||||
unit: root.formule?.explanation?.unit
|
||||
unit: root.unit || parsedRoot.formule?.explanation?.unit
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,7 +327,8 @@ export let getTargets = (target, rules) => {
|
|||
|
||||
export let parseAll = flatRules => {
|
||||
let treatOne = rule => treatRuleRoot(flatRules, rule)
|
||||
return map(treatOne, flatRules)
|
||||
let parsed = map(treatOne, flatRules)
|
||||
return parsed
|
||||
}
|
||||
|
||||
export let analyseMany = (parsedRules, targetNames) => situationGate => {
|
||||
|
|
|
@ -18,7 +18,8 @@ import {
|
|||
map,
|
||||
multiply,
|
||||
propOr,
|
||||
subtract
|
||||
subtract,
|
||||
fromPairs
|
||||
} from 'ramda'
|
||||
import React from 'react'
|
||||
import { evaluateNode, makeJsx, mergeMissing, rewriteNode } from './evaluation'
|
||||
|
@ -49,6 +50,8 @@ import {
|
|||
treatVariableTransforms
|
||||
} from './treatVariable'
|
||||
|
||||
import { inferUnit } from 'Engine/units'
|
||||
|
||||
export let nearley = () => new Parser(Grammar.ParserRules, Grammar.ParserStart)
|
||||
|
||||
export let treatString = (rules, rule) => rawNode => {
|
||||
|
@ -107,9 +110,11 @@ export let treatObject = (rules, rule, treatOptions) => rawNode => {
|
|||
'=': [equals],
|
||||
'!=': [(a, b) => !equals(a, b), '≠']
|
||||
},
|
||||
operationDispatch = map(
|
||||
([f, symbol]) => mecanismOperation(f, symbol || k),
|
||||
knownOperations
|
||||
operationDispatch = fromPairs(
|
||||
Object.entries(knownOperations).map(([k, [f, symbol]]) => [
|
||||
k,
|
||||
mecanismOperation(k, f, symbol)
|
||||
])
|
||||
)
|
||||
|
||||
let dispatch = {
|
||||
|
@ -155,7 +160,7 @@ export let treatObject = (rules, rule, treatOptions) => rawNode => {
|
|||
return action(treat(rules, rule, treatOptions), k, v)
|
||||
}
|
||||
|
||||
let mecanismOperation = (operatorFunction, symbol) => (recurse, k, v) => {
|
||||
let mecanismOperation = (k, operatorFunction, symbol) => (recurse, k, v) => {
|
||||
let evaluate = (cache, situation, parsedRules, node) => {
|
||||
let explanation = map(
|
||||
curry(evaluateNode)(cache, situation, parsedRules),
|
||||
|
@ -177,6 +182,8 @@ let mecanismOperation = (operatorFunction, symbol) => (recurse, k, v) => {
|
|||
|
||||
let explanation = v.explanation.map(recurse)
|
||||
|
||||
let unit = inferUnit(k, explanation[0].unit, explanation[1].unit)
|
||||
|
||||
let jsx = (nodeValue, explanation) => (
|
||||
<Node
|
||||
classes={'inlineExpression ' + k}
|
||||
|
@ -185,7 +192,8 @@ let mecanismOperation = (operatorFunction, symbol) => (recurse, k, v) => {
|
|||
<span className="nodeContent">
|
||||
<span className="fa fa" />
|
||||
{makeJsx(explanation[0])}
|
||||
<span className="operator">{symbol}</span>
|
||||
<span className="operator">{symbol || k}</span>
|
||||
|
||||
{makeJsx(explanation[1])}
|
||||
</span>
|
||||
}
|
||||
|
@ -196,8 +204,9 @@ let mecanismOperation = (operatorFunction, symbol) => (recurse, k, v) => {
|
|||
...v,
|
||||
evaluate,
|
||||
jsx,
|
||||
operator: symbol,
|
||||
operator: symbol || k,
|
||||
// is this useful ? text: rawNode,
|
||||
explanation
|
||||
explanation,
|
||||
unit
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,10 @@ import {
|
|||
import { getSituationValue } from './variables'
|
||||
|
||||
export let treatVariable = (rules, rule, filter) => ({ fragments }) => {
|
||||
let variablePartialName = fragments.join(' . '),
|
||||
dottedName = disambiguateRuleReference(rules, rule, variablePartialName),
|
||||
variable = findRuleByDottedName(rules, dottedName)
|
||||
|
||||
let evaluate = (cache, situation, parsedRules, node) => {
|
||||
let dottedName = node.dottedName,
|
||||
// On va vérifier dans le cache courant, dict, si la variable n'a pas été déjà évaluée
|
||||
|
@ -18,8 +22,7 @@ export let treatVariable = (rules, rule, filter) => ({ fragments }) => {
|
|||
cached = cache[cacheName]
|
||||
|
||||
if (cached) return cached
|
||||
let variable = findRuleByDottedName(parsedRules, dottedName),
|
||||
variableHasFormula = variable.formule != null,
|
||||
let variableHasFormula = variable.formule != null,
|
||||
variableHasCond =
|
||||
variable['applicable si'] != null ||
|
||||
variable['non applicable si'] != null ||
|
||||
|
@ -72,9 +75,6 @@ export let treatVariable = (rules, rule, filter) => ({ fragments }) => {
|
|||
}
|
||||
}
|
||||
|
||||
let variablePartialName = fragments.join(' . '),
|
||||
dottedName = disambiguateRuleReference(rules, rule, variablePartialName)
|
||||
|
||||
return {
|
||||
evaluate,
|
||||
//eslint-disable-next-line react/display-name
|
||||
|
@ -91,7 +91,8 @@ export let treatVariable = (rules, rule, filter) => ({ fragments }) => {
|
|||
name: variablePartialName,
|
||||
category: 'variable',
|
||||
fragments,
|
||||
dottedName
|
||||
dottedName,
|
||||
unit: variable.unit
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
import { remove, isEmpty } from 'ramda'
|
||||
|
||||
export let parseUnit = string => {
|
||||
let [a, b = ''] = string.split('/')
|
||||
return {
|
||||
numerators: a !== '' ? [a] : [],
|
||||
denominators: b !== '' ? [b] : []
|
||||
}
|
||||
let [a, b = ''] = string.split('/'),
|
||||
result = {
|
||||
numerators: a !== '' ? [a] : [],
|
||||
denominators: b !== '' ? [b] : []
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export let serializeUnit = ({ numerators, denominators }) => {
|
||||
export let serialiseUnit = ({ numerators, denominators }) => {
|
||||
let n = !isEmpty(numerators)
|
||||
let d = !isEmpty(denominators)
|
||||
return n && !d
|
||||
|
|
|
@ -1,18 +1,7 @@
|
|||
import { number, int } from './validators'
|
||||
import { memoizeWith } from 'ramda'
|
||||
|
||||
const NumberFormat = memoizeWith(JSON.stringify, Intl.NumberFormat)
|
||||
|
||||
let numberFormatter = style => (value, language) =>
|
||||
NumberFormat(language, {
|
||||
style,
|
||||
currency: 'EUR',
|
||||
maximumFractionDigits: 2,
|
||||
minimumFractionDigits: 2
|
||||
}).format(value)
|
||||
|
||||
let pourcentage = {
|
||||
human: numberFormatter('decimal'),
|
||||
human: () => null,
|
||||
validator: number
|
||||
}
|
||||
|
||||
|
@ -27,12 +16,12 @@ let jours = {
|
|||
}
|
||||
|
||||
let nombre = {
|
||||
human: numberFormatter('decimal'),
|
||||
human: () => null,
|
||||
validator: int
|
||||
}
|
||||
|
||||
let euros = {
|
||||
human: numberFormatter('currency'),
|
||||
human: () => null,
|
||||
validator: number
|
||||
}
|
||||
|
||||
|
|
|
@ -43,11 +43,11 @@
|
|||
nom: distance journalière
|
||||
description: Une estimation basse de la distance parcourue à vélo par un salarié pour se rendre à son travail.
|
||||
formule: 4
|
||||
unité: km
|
||||
unité: km/jour
|
||||
- espace: contrat salarié . indemnité kilométrique vélo
|
||||
nom: jours travaillés
|
||||
formule: 218
|
||||
unité: jours
|
||||
unité: jour
|
||||
|
||||
- espace: contrat salarié . indemnité kilométrique vélo
|
||||
nom: active
|
||||
|
|
Loading…
Reference in New Issue