diff --git a/source/components/Rule.css b/source/components/Rule.css
index 1702828ea..15a2db395 100644
--- a/source/components/Rule.css
+++ b/source/components/Rule.css
@@ -166,13 +166,29 @@
align-items: center;
}
.dictionaryPanel {
- width: 35%;
+ width: 33%;
border: 1px dashed #aaa;
margin: 1em;
- padding: .6em 1em;
+ padding: 0em 1.5em;
min-height: 6em;
border-radius: .3em;
-
+}
+.dictionaryPanel h3 {
+ color: #333350
+}
+.dictionaryPanel blockquote {
+ font-style: italic;
+ border-left: 4px solid #eee;
+ padding-left: 1em;
+ margin-left: 0;
+}
+.dictionaryPanel blockquote p {
+ color: #666;
+}
+.dictionaryPanel code {
+ border: 1px solid #aaa;
+ padding: .05em .3em;
+ border-radius: .3em;
}
#rule-rules section {
@@ -200,6 +216,12 @@
font-weight: 600;
border-radius: .4em;
}
+[data-term-definition] {
+ cursor: pointer;
+}
+[data-term-definition]:hover {
+ opacity: .8
+}
.ruleProp > .nodeHead .name {
background: #df5320
}
@@ -275,6 +297,7 @@
font-weight: 600;
font-size: 90%;
border: 1px solid rgba(51, 51, 80, 0.25);
+ white-space: nowrap
}
diff --git a/source/components/Rule.js b/source/components/Rule.js
index ef8cbe149..36b7d27db 100644
--- a/source/components/Rule.js
+++ b/source/components/Rule.js
@@ -13,6 +13,7 @@ import destinataires from '../../règles/destinataires/destinataires.yaml'
import references from '../../règles/références/références.yaml'
import {capitalise0} from '../utils'
import knownMecanisms from '../engine/known-mecanisms.yaml'
+import marked from '../engine/marked'
// situationGate function useful for testing :
let testingSituationGate = v => // eslint-disable-line no-unused-vars
@@ -128,24 +129,27 @@ export default class Rule extends Component {
let AttachDictionary = dictionary => Decorated =>
class extends React.Component {
state = {
+ term: null,
explanation: null
}
- explain = explanation =>
- this.setState({explanation})
componentDidMount() {
let decoratedNode = ReactDOM.findDOMNode(this.decorated)
decoratedNode.addEventListener('click', e => {
- let term = e.target.dataset['termDefinition']
- this.explain(R.path([term, 'description'], dictionary))
+ let term = e.target.dataset['termDefinition'],
+ explanation = R.path([term, 'description'], dictionary)
+ this.setState({explanation, term})
})
}
+ renderExplanationMarkdown(explanation, term) {
+ return marked(`### Mécanisme: ${term}\n\n${explanation}`)
+ }
render(){
+ let {explanation, term} = this.state
return (
this.decorated = decorated} {...this.props} explain={this.explain}/>
- {this.state.explanation &&
-
- {this.state.explanation}
+ {explanation &&
+
}
diff --git a/source/engine/known-mecanisms.yaml b/source/engine/known-mecanisms.yaml
index 0274d5018..5e02afc9e 100644
--- a/source/engine/known-mecanisms.yaml
+++ b/source/engine/known-mecanisms.yaml
@@ -1,20 +1,30 @@
+# Liste et description des différents mécanismes compris par le moteur.
+# La description peut être rédigée en markdown :-)
+
l'une de ces conditions:
description: |
- C'est un 'ou' logique.
+ C'est un `ou` logique.
+
Contient une liste de conditions.
- Renvoie vrai si l'une des conditions sont vraies.
+
+ Renvoie vrai si l'une des conditions est vraie.
toutes ces conditions:
description: |
- C'est un 'et' logique.
+ C'est un `et` logique.
+
Contient une liste de conditions.
+
Renvoie vrai si toutes les conditions vraies.
logique numérique:
description: |
Contient une liste de couples condition-conséquence.
- Un par un, si la condition est vraie, alors on choisit la conséquence.
- Cette conséquence peut elle-même être un mécanisme "logique numérique" ou plus simplement un taux.
- Si aucune condition n'est vraie, alors ce mécanisme renvoie implilcitement 'non applicable' (ce qui peut se traduire par la valeur 0 si nous sommes dans un contexte numérique).
+
+ Couple par couple, si la condition est vraie, alors on choisit la conséquence.
+
+ Cette conséquence peut elle-même être un mécanisme `logique numérique` ou plus simplement un `taux`.
+
+ Si aucune condition n'est vraie, alors ce mécanisme renvoie implicitement `non applicable` (ce qui peut se traduire par la valeur `0` si nous sommes dans un contexte numérique).
taux:
description: |
@@ -23,22 +33,51 @@ taux:
multiplication:
description: |
C'est une multiplication un peu améliorée, très utile pour exprimer les cotisations, souvent linéaires.
- Sa propriété 'assiette' est multipliée par un pourcentage, 'taux', ou par un 'facteur' quand ce nom est plus approprié.
- La multiplication peut être plafonnée : ce plafond sépare l'assiette en deux, et la partie au-dessus du plafond est tout simplement ignorée.
- Dans ce cas, elle se comporte comme une barème en taux marginaux à deux tranches, la deuxième au taux nul et allant de 'plafond' à l'infini.
+ Sa propriété `assiette` est multipliée par un pourcentage, `taux`, ou par un `facteur` quand ce nom est plus approprié.
+
+ La multiplication peut être plafonnée : ce plafond sépare l'assiette en deux, et la partie au-dessus du plafond est tout simplement ignorée. Dans ce cas, elle se comporte comme une barème en taux marginaux à deux tranches, la deuxième au taux nul et allant de `plafond` à l'infini.
le maximum de:
description: |
- Calcule le maximum de la liste de propositions fournie.
+ Renvoie l'élément de la liste de propositions fournie qui la la plus grande valeur.
+
Ces propositions doivent avoir un mécanisme de calcul ou être une valeur numérique.
- Il est conseillé de renseigner une description de chaque propositions par exemple quand elles représentent des méthodes de calcul alternatives parmi lesquelles il faut en choisir une.
+
+ Il est conseillé de renseigner une description de chaque proposition par exemple quand elles représentent des méthodes de calcul alternatives parmi lesquelles il faut en choisir une.
somme:
description: |
C'est tout simplement la somme de chaque terme de la liste.
+##########################################
+# Ce qu'on appelle aujourd'hui des RuleProp
+# Et qui deviendront des mécanismes classiques normalement par la suite #TODO
+
+formule:
+ description: |
+ C'est la formule de calcul d'une variable. Elle renvoie une valeur numérique ou un 'non', exprimant le fait que la variable n'est pas applicable, ce qui vaut implicitement 0.
+
+ Cette doit faire appel à fera appel à des mécanismes de calcul : par exemple `multiplication`, le plus commun pour les variables de type `Cotisation`.
+
+
+non applicable si:
+ description: |
+ Si cette variable est vraie, c'est que la variable n'est pas applicable pour la situation saisie.
+
+ > Pour une cotisation sociale, cela signifie qu'elle ne me concerne pas, que je n'ai pas à la verser.
+
+ La formule est donc à ignorer.
+
+
+
+
+
+
+
+
+
# à venir
# barème:
# description: |
diff --git a/source/engine/marked.js b/source/engine/marked.js
new file mode 100644
index 000000000..972e7aa5f
--- /dev/null
+++ b/source/engine/marked.js
@@ -0,0 +1,10 @@
+import marked from 'marked'
+
+let customMarked = new marked.Renderer()
+customMarked.link = ( href, title, text ) =>
+ `${ text }`
+marked.setOptions({
+ renderer: customMarked
+})
+
+export default marked
diff --git a/source/engine/rules.js b/source/engine/rules.js
index 57ccab637..c8b9edcb3 100644
--- a/source/engine/rules.js
+++ b/source/engine/rules.js
@@ -2,15 +2,7 @@
import rawRules from './load-rules'
import R from 'ramda'
import possibleVariableTypes from './possibleVariableTypes.yaml'
-import marked from 'marked'
-
-
-let customMarked = new marked.Renderer()
-customMarked.link = ( href, title, text ) =>
- `${ text }`
-marked.setOptions({
- renderer: customMarked
-})
+import marked from './marked'
/***********************************
Méthodes agissant sur une règle */
diff --git a/source/engine/traverse-common-jsx.js b/source/engine/traverse-common-jsx.js
index 57134e4df..81fc34b56 100644
--- a/source/engine/traverse-common-jsx.js
+++ b/source/engine/traverse-common-jsx.js
@@ -3,42 +3,44 @@ import R from 'ramda'
import classNames from 'classnames'
let treatValue = data =>
- data == null
- ? '?'
- : R.is(Number)(data) ? Math.round(data) : data ? 'oui' : 'non'
+ data == null
+ ? '?'
+ : R.is(Number)(data) ? Math.round(data) : data ? 'oui' : 'non'
let NodeValue = ({data}) => (
-
- ←
- {treatValue(data)}
-
+
+ ←
+ {treatValue(data)}
+
)
// Un élément du graphe de calcul qui a une valeur interprétée (à afficher)
export class Node extends React.Component {
render() {
- let {classes, name, value, child, termDefinition} = this.props
+ let
+ {classes, name, value, child} = this.props,
+ termDefinition = R.contains('mecanism', classes) && name
return (
-
- {name &&
-
- {name}
-
- }
- {child}
- {!name && }
-
+
+ {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}
- }
-
+
+ {name &&
+
+ {name}
+ }
+
)
diff --git a/source/engine/traverse.js b/source/engine/traverse.js
index d1ba3b0ce..ce94cb398 100644
--- a/source/engine/traverse.js
+++ b/source/engine/traverse.js
@@ -248,7 +248,6 @@ let treat = (situationGate, rule) => rawNode => {
)(v)
return {...result,
jsx: