diff --git a/source/components/Rule.css b/source/components/Rule.css index 3847fca1d..10d0e513c 100644 --- a/source/components/Rule.css +++ b/source/components/Rule.css @@ -67,65 +67,128 @@ } #rule-rules section { - margin: 1em 3em + margin: 1em 3em; + font-weight: 500; + font-size: 90%; + color: #444 +} +#rule-rules section h2 { + font-size: 130%; } .node { - margin-top: 1em; padding-left: 1em; -} -.ruleProp > div > .name { - padding: 0 1em; - border: 1px solid black; - background: #df5320 -} -.mecanism { -} -.mecanism > div > .name { - padding: 0 1em; - border: 1px solid black; - background: #d5911a + color: #4B4B66 } +.nodeHead { + margin-bottom: 1em; +} + +.mecanism > .nodeHead .name { + padding: .05em 1em; + background: #d5911a; + color: white; + font-weight: 600; + border-radius: .4em; +} +.ruleProp > .nodeHead .name { + background: #df5320 +} .mecanism li { +} +.mecanism ul { + margin-top: 0; + padding-left: 1em; + list-style-type: none; + border-left: 1px dashed #ccc; +} +.mecanism ul .key { + color: #d5911a; + font-weight: 600; + display: inline-block; + margin-bottom: 1em; +} + +.multiplication li .key { + margin-right: .6em; +} + +.mecanism.list > ul { + list-style-type: disc; +} +.mecanism.list > ul > li { + margin-left: .8em; + padding-left: .3em; +} + +#rule-rules .situationValue { + padding-left: 1em; + font-weight: 600; + color: #333350; +} + +.maximum .description { + font-style: italic; + font-weight: 600; + margin-bottom: .4em; + margin-left: 1em; +} + +.situationValue { + opacity: .6 +} + +.condition { margin-bottom: .6em; } - -#rule-rules .value { - padding-left: 1em; - font-weight: bold; +.node.inlineExpression { + padding-left: 0; + display: inline; +} +.inlineExpression .nodeContent { + /*border-bottom: 1px solid rgba(51, 51, 80, 0.25);*/ + /*border-right: 1px solid rgba(51, 51, 80, 0.25);*/ + /*padding: .5em .6em;*/ + /*border-radius: .3em;*/ +} +.nodeHead { + display: inline-block; +} +.leaf .situationValue { + text-align: center; } -#rule-rules .value.oui { +#rule-rules .situationValue.oui { color: #5ab738; } -#rule-rules .value.non { +#rule-rules .situationValue.non { color: #f22c40; } .variable .name { - padding: 0 1em; - border: 1px solid black; - background: #6666ea; + color: #5B5B73; + text-align: center; + margin-top: 1em; + padding: .05em 1em; + line-height: 1.8em; + border-radius: .4em; + font-weight: 600; + font-size: 90%; + border: 1px solid rgba(51, 51, 80, 0.25); } -.comparison .name { - padding: 0 1em; - border: 1px solid black; - background: #407ee7; -} -.rate .name { - padding: 0 1em; - border: 1px solid black; - background: #407ee7; +.percentage .name { + font-size: 110%; + font-weight: 600; } .operator { margin: .1em .6em; font-size: 150%; - vertical-align: sub; - display: block; + font-weight: 600; + vertical-align: middle; } .json { diff --git a/source/components/Rule.js b/source/components/Rule.js index 49be6d13b..c8b37a9a4 100644 --- a/source/components/Rule.js +++ b/source/components/Rule.js @@ -99,92 +99,6 @@ export default class Rule extends Component { } } -let RuleProp = ({nodeValue, explanation, name}) => -
-
- {name} - -
- { - explanation.category == 'mecanism' && - } -
- -let Mecanism = ({nodeValue, name, explanation}) => -
-
- {name} - -
- {R.contains(name)(["l'une de ces conditions", 'toutes ces conditions']) && - - } - {name == 'multiplication' && - - } - {name == 'le maximum de' && - - } -
- -let Multiplication = ({base, rate}) => -
- - × - { - rate.explanation ? - - : - } - -
- - -let Variable = (yo) => do { - let {nodeValue, variableName} = yo -; - {variableName} - - -} - - -let Comparison = ({nodeValue, text}) => - - {text} - - - - - - - - -let Percentage = ({percentage}) => - - {percentage} - - - - -// let Formula = ({explanation, nodeValue}) => do { -//
-//
-// {expression} -// -//
-//
-// } - let JSONView = ({o, rootKey}) => (
do { - let valeur = data == null ? - '?' - : ( R.is(Number)(data) ? - Math.round(data) - : ( data ? 'oui' : 'non') - ) +let treatValue = data => data == null ? + '?' + : ( R.is(Number)(data) ? + Math.round(data) + : ( data ? 'oui' : 'non') + ) - ;←  - {valeur} +let NodeValue = ({data}) => + ←  + {treatValue(data)} -} + + +// Un élément du graphe de calcul qui a une valeur interprétée (à afficher) +export let Node = ({classes, name, value, child}) => +
+ {name && + + {name} + + + } + {child} + {!name && } +
+ + + +// Un élément du graphe de calcul qui a une valeur interprétée (à afficher) +export let Leaf = ({classes, name, value}) => + + {name && + + {name} + + } + diff --git a/source/engine/traverse.js b/source/engine/traverse.js index 55f2678e2..45d7a8beb 100644 --- a/source/engine/traverse.js +++ b/source/engine/traverse.js @@ -6,7 +6,7 @@ import knownMecanisms from './known-mecanisms.yaml' import { Parser } from 'nearley' import Grammar from './grammar.ne' import variablesInDevelopment from './variablesInDevelopment.yaml' -import {NodeValue} from './traverse-common-jsx' +import {Node, Leaf} from './traverse-common-jsx' @@ -76,11 +76,11 @@ let fillVariableNode = (rule, situationGate) => (parseResult) => { type: 'boolean | numeric', explanation: null, missingVariables: known ? [] : [variableName], - jsx: - - {variableName} - - + jsx: } } @@ -135,16 +135,17 @@ let treat = (situationGate, rule) => rawNode => { category: 'calcExpression', type: 'numeric', explanation: filledExplanation, - jsx: -
-
- Éxpression de calcul - -
- {filledExplanation[0].jsx} - {parseResult.operator} - {filledExplanation[1].jsx} -
+ jsx: + {filledExplanation[0].jsx} + {parseResult.operator} + {filledExplanation[1].jsx} +
+ } + /> } } if (parseResult.category == 'comparison') { @@ -179,12 +180,17 @@ let treat = (situationGate, rule) => rawNode => { category: 'comparison', type: 'boolean', explanation: filledExplanation, - jsx: -
- {filledExplanation[0].jsx} - {parseResult.operator} - {filledExplanation[1].jsx} -
+ jsx: + {filledExplanation[0].jsx} + {parseResult.operator} + {filledExplanation[1].jsx} + + } + /> } } } @@ -236,16 +242,16 @@ let treat = (situationGate, rule) => rawNode => { }) // Reduce but don't use R.reduced to set the nodeValue : we need to treat all the nodes )(v) return {...result, - jsx: -
-
- {result.name} - -
+ jsx: - {result.explanation.map(item =>
  • {item.jsx}
  • )} - -
    + {result.explanation.map(item =>
  • {item.jsx}
  • )} + + } + /> } } if (k === 'toutes ces conditions') { @@ -281,7 +287,7 @@ let treat = (situationGate, rule) => rawNode => { percentage: rate, explanation: null, jsx: - + {rate} }), @@ -320,12 +326,12 @@ let treat = (situationGate, rule) => rawNode => { conditionValue: conditionNode.nodeValue, type: 'boolean', explanation: childNumericalLogic, - jsx: + jsx:
    {conditionNode.jsx} - - ---> {childNumericalLogic.jsx} - - +
    + {childNumericalLogic.jsx} +
    +
    }], } }, { @@ -336,16 +342,16 @@ let treat = (situationGate, rule) => rawNode => { explanation: [] }), node => ({...node, - jsx: -
    -
    - logique numérique - -
    + jsx: - {node.explanation.map(item =>
  • {item.jsx}
  • )} - -
    + {node.explanation.map(item =>
  • {item.jsx}
  • )} + + } + /> }) )) @@ -363,7 +369,7 @@ let treat = (situationGate, rule) => rawNode => { nodeValue: transformPercentage(v), explanation: null, jsx: - + {v} } @@ -386,14 +392,16 @@ let treat = (situationGate, rule) => rawNode => { val = node => node.nodeValue, base = reTreat(v['assiette']), rate = v['taux'] ? reTreat({taux: v['taux']}) : {nodeValue: 1}, //TODO parser le taux dans le parser ? - facteur = v['facteur'] ? reTreat(v['facteur']) : {nodeValue: 1} - - return { - nodeValue: (val(rate) === 0 || val(rate) === false || val(base) === 0 || val(facteur) === 0) ? + facteur = v['facteur'] ? reTreat(v['facteur']) : {nodeValue: 1}, + // OUCH :-o ! + nodeValue = (val(rate) === 0 || val(rate) === false || val(base) === 0 || val(facteur) === 0) ? 0 : (val(rate) == null || val(base) == null || val(facteur) == null) ? null - : val(base) * val(rate) * val(facteur), + : val(base) * val(rate) * val(facteur) + + return { + nodeValue, category: 'mecanism', name: 'multiplication', type: 'numeric', @@ -404,13 +412,29 @@ let treat = (situationGate, rule) => rawNode => { //TODO limit: 'plafond' //TODO introduire 'prorata' ou 'multiplicateur', pour sémantiser les opérandes ? }, - jsx: -
    - {base.jsx} - × - {rate && rate.jsx} - {facteur && facteur.jsx} -
    + jsx: +
  • + assiette: + {base.jsx} +
  • + {rate.nodeValue != 1 && +
  • + taux: + {rate.jsx} +
  • } + {facteur.nodeValue != 1 && +
  • + facteur: + {facteur.jsx} +
  • } + + } + /> } } @@ -427,16 +451,21 @@ let treat = (situationGate, rule) => rawNode => { name: 'le maximum de', nodeValue, explanation: contenders, - jsx: -
    -
    - le maximum de - -
    + jsx: - {contenders.map(item =>
  • {item.jsx}
  • )} - -
    + {contenders.map((item, i) => +
  • +
    {v[i].description}
    + {item.jsx} +
  • + )} + + } + /> } } @@ -460,14 +489,14 @@ let treatRuleRoot = (situationGate, rule) => R.evolve({ // -> Voilà les attribu type: 'boolean', nodeValue: child.nodeValue, explanation: child, - jsx: -
    -
    - non applicable si - -
    - { child.jsx } -
    + jsx: } } , @@ -488,14 +517,14 @@ let treatRuleRoot = (situationGate, rule) => R.evolve({ // -> Voilà les attribu nodeValue: nodeValue, explanation: child, shortCircuit: R.pathEq(['non applicable si', 'nodeValue'], true), - jsx: -
    -
    - formula - -
    - { child.jsx } -
    + jsx: } } ,