🎨 Améliore l'explication des règles avec remplacement

Pour pouvoir comprendre quels sont les remplacements actifs en cours.

Fix #1708
Fix betagouv/publicodes#52
pull/1714/head
Johan Girod 2021-09-13 15:03:27 +02:00
parent 2a3be412b8
commit 7be8195a9e
4 changed files with 70 additions and 18 deletions

View File

@ -97,17 +97,17 @@ const CotisationsSection: Partial<Record<DottedName, Array<string>>> = {
function Distribution() {
const targetUnit = useSelector(targetUnitSelector)
const engine = useEngine()
const distribution = (Object.entries(
CotisationsSection
).map(([section, cotisations]) => [
section,
cotisations
.map((c) => engine.evaluate({ valeur: c, unité: targetUnit }))
.reduce(
(acc, evaluation) => acc + ((evaluation?.nodeValue as number) || 0),
0
),
]) as Array<[DottedName, number]>)
const distribution = (
Object.entries(CotisationsSection).map(([section, cotisations]) => [
section,
cotisations
.map((c) => engine.evaluate({ valeur: c, unité: targetUnit }))
.reduce(
(acc, evaluation) => acc + ((evaluation?.nodeValue as number) || 0),
0
),
]) as Array<[DottedName, number]>
)
.filter(([, value]) => value > 0)
.sort(([, a], [, b]) => b - a)

View File

@ -1,10 +1,57 @@
import { VariationNode } from 'publicodes/source/mecanisms/variations'
import { useState } from 'react'
import emoji from 'react-easy-emoji'
import Variations from './Variations'
import Explanation from '../Explanation'
import Overlay from '../Overlay'
import { RuleLinkWithContext } from '../RuleLink'
import { NodeValuePointer } from './common'
import { EvaluatedNode } from 'publicodes/source/AST/types'
export default function Replacement(node: VariationNode) {
export default function Replacement(node: VariationNode & EvaluatedNode) {
const applicableReplacement = node.explanation.find(
(ex) => ex.satisfied
)?.consequence
const replacedNode = node.explanation.slice(-1)[0].consequence
return <Explanation node={applicableReplacement || replacedNode} />
const replacedNode = node.explanation.slice(-1)[0].consequence as {
dottedName: string
}
const [displayReplacements, changeDisplayReplacement] = useState(false)
return (
<>
<Explanation node={replacedNode} />
&nbsp;
{applicableReplacement && (
<NodeValuePointer
data={(applicableReplacement as any).nodeValue}
unit={(applicableReplacement as any).unit}
/>
)}
&nbsp;
<button
onClick={() => changeDisplayReplacement(true)}
className="ui__ simple small button"
>
{emoji('🔄')}
</button>
{displayReplacements && (
<Overlay onClose={() => changeDisplayReplacement(false)}>
<h3>Remplacement existant</h3>
<p>
Un ou plusieurs remplacements ciblent la règle{' '}
<RuleLinkWithContext dottedName={replacedNode.dottedName} /> à cet
endroit. Sa valeur est calculée selon la formule suivante :
</p>
<Variations {...node} />
<div style={{ marginTop: '1rem' }} />
<p>
<a href="https://publi.codes/documentation/principes-de-base#remplacement">
En savoir plus sur le remplacement dans publicodes
</a>
</p>
</Overlay>
)}
</>
)
}

View File

@ -2,13 +2,18 @@ import classnames from 'classnames'
import { useState } from 'react'
import emoji from 'react-easy-emoji'
import styled from 'styled-components'
import { EvaluatedNode } from 'publicodes/source/AST/types'
import { VariationNode } from 'publicodes/dist/types/mecanisms/variations'
import Explanation from '../Explanation'
import writtenNumbers from '../writtenNumbers'
import { CapitalizeFirstLetter, InlineMecanismName, Mecanism } from './common'
export default function Variations({ nodeValue, explanation, unit }) {
let [expandedVariation, toggleVariation] = useState(null)
export default function Variations({
nodeValue,
explanation,
unit,
}: VariationNode & EvaluatedNode) {
const [expandedVariation, toggleVariation] = useState<null | number>(null)
return (
<StyledComponent>
<Mecanism

View File

@ -37,7 +37,7 @@ export function ConstantNode({ nodeValue, type, fullPrecision, unit }) {
</span>
)
} else {
return <span className="value">{nodeValue}</span>
return <span className="value">{formatValue({ nodeValue, unit })}</span>
}
}