From 5427ac7181a68e87d82d80c44311e394f0e93bc6 Mon Sep 17 00:00:00 2001 From: Mael Thomas Date: Thu, 9 Feb 2017 18:15:25 +0100 Subject: [PATCH] =?UTF-8?q?[cdd]=20Affichage=20des=20=E2=80=A2=20d'aide=20?= =?UTF-8?q?seulement=20quand=20l'aide=20existe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- règles/entités/salariat/Salariat.CDD.yaml | 10 +++-- .../salariat/Salariat.contrats-aidés.yaml | 1 + règles/entités/salariat/Salariat.yaml | 2 + .../cdd/majoration-chomage.yaml | 8 ++-- source/.eslintrc | 2 +- source/actions.js | 2 +- source/components/Aide.js | 39 +++++++++++++++++++ source/components/CDD.css | 1 + source/components/CDD.js | 34 +--------------- .../conversation/{Term.css => Explicable.css} | 6 +-- source/components/conversation/Explicable.js | 39 +++++++++++++++++++ source/components/conversation/Question.js | 21 +++++----- source/components/conversation/Term.js | 22 ----------- source/engine/conversation.js | 4 +- source/engine/rules.js | 4 +- source/reducers.js | 24 +++++------- 16 files changed, 122 insertions(+), 97 deletions(-) create mode 100644 source/components/Aide.js rename source/components/conversation/{Term.css => Explicable.css} (78%) create mode 100644 source/components/conversation/Explicable.js delete mode 100644 source/components/conversation/Term.js diff --git a/règles/entités/salariat/Salariat.CDD.yaml b/règles/entités/salariat/Salariat.CDD.yaml index abe51e4e3..94f6027d8 100644 --- a/règles/entités/salariat/Salariat.CDD.yaml +++ b/règles/entités/salariat/Salariat.CDD.yaml @@ -7,7 +7,9 @@ référence: https://fr.wikipedia.org/wiki/Contrat_de_travail_%C3%A0_dur%C3%A9e_d%C3%A9termin%C3%A9e_en_France # TODO: règle de type : il faut q'un motif et une durée soient sélectionnés pour qu'un contrat soit un CDD. Cela revient à dire que les variables CDD et motif sont obligatoires *dans le contexte* de leur attache -- Variable: durée +- Variable: durée contrat + titre: durée du contrat + question: Quelle est la durée du contrat ? attache: Salariat . CDD contrainte: période description: Durée du contrat de travail @@ -98,6 +100,7 @@ - Variable: événements attache: Salariat . CDD + question: Pensez-vous être confronté à un de ces évéments ? description: Certains événements impactent le prix d'un CDD # au lieu de lister tous les cas, l'alternative est de simplement indiquer qu'ils sont exclusifs, # et les identifier dynamiquement par leur attribut "attache" : @@ -141,6 +144,7 @@ - Variable: complément formation professionnelle employeur - titre: Complément de formation offert par l'employeur + titre: Complément de formation professionnelle offert par l'employeur + question: L'employeur s'engage-t-il à verser un complément de formation professionnelle ? attache: Salariat . CDD - description: L'employeur s'engage à fournir une formation professionnelle, ce qui le dispense de la cotisation CIF CDD + description: L'employeur peut s'engager à fournir un complément de formation professionnelle. Cela le dispensera de l'obligation de payer la cotisation CIF CDD diff --git a/règles/entités/salariat/Salariat.contrats-aidés.yaml b/règles/entités/salariat/Salariat.contrats-aidés.yaml index f062c61d9..191883f56 100644 --- a/règles/entités/salariat/Salariat.contrats-aidés.yaml +++ b/règles/entités/salariat/Salariat.contrats-aidés.yaml @@ -1,6 +1,7 @@ - Variable: contrat aidé attache: Salariat + question: Est-ce un contrat aidé ? choix exclusifs: - contrat unique insertion - emploi avenir diff --git a/règles/entités/salariat/Salariat.yaml b/règles/entités/salariat/Salariat.yaml index f08469e7c..0b21e7a65 100644 --- a/règles/entités/salariat/Salariat.yaml +++ b/règles/entités/salariat/Salariat.yaml @@ -11,6 +11,8 @@ - Variable: salaire de base attache: Salariat + question: Quel est le salaire de base ? + description: Le salaire de base est le salaire régulier présent dans le contrat. Des primes viendront éventuellement le compléter, on parlera alors de salaire brut. contrainte: nombre positif - Variable: Salaire brut diff --git a/règles/rémunération-travail/cdd/majoration-chomage.yaml b/règles/rémunération-travail/cdd/majoration-chomage.yaml index 734de3ec5..11b225eec 100644 --- a/règles/rémunération-travail/cdd/majoration-chomage.yaml +++ b/règles/rémunération-travail/cdd/majoration-chomage.yaml @@ -7,7 +7,7 @@ description: Majoration des contributions patronales d’assurance chômage pour les contrats à durée déterminée courts (CDD) non applicable si: l'une de ces conditions: - - Salariat . CDD . durée > 3 + - Salariat . CDD . durée contrat > 3 - Salariat . CDD . événements . CDD poursuivi en CDI formule: linéaire: @@ -15,10 +15,10 @@ taux: logique numérique: Salariat . CDD . motif . accroissement temporaire activité: - Salariat . CDD . durée <= 1: 3% # TODO 1 mois, pas 1 rien, évidemment - Salariat . CDD . durée <= 3: 1.5% + Salariat . CDD . durée contrat <= 1: 3% # TODO 1 mois, pas 1 rien, évidemment + Salariat . CDD . durée contrat <= 3: 1.5% Salariat . CDD . motif . usage: - Salariat . CDD . durée <= 3: 0.5% + Salariat . CDD . durée contrat <= 3: 0.5% diff --git a/source/.eslintrc b/source/.eslintrc index 3bbf79b75..166103553 100644 --- a/source/.eslintrc +++ b/source/.eslintrc @@ -6,7 +6,7 @@ rules: - 2 - unix semi: - - 2 + - 1 - never no-unused-vars: 1 no-console: 1 diff --git a/source/actions.js b/source/actions.js index a775370bb..42201ab1f 100644 --- a/source/actions.js +++ b/source/actions.js @@ -29,4 +29,4 @@ export const CHANGE_THEME_COLOUR = 'CHANGE_THEME_COLOUR' export function changeThemeColour(colour) {return {type: CHANGE_THEME_COLOUR, colour}} -export const EXPLAIN_TERM = 'EXPLAIN_TERM' +export const EXPLAIN_VARIABLE = 'EXPLAIN_VARIABLE' diff --git a/source/components/Aide.js b/source/components/Aide.js new file mode 100644 index 000000000..94eaab1f2 --- /dev/null +++ b/source/components/Aide.js @@ -0,0 +1,39 @@ +import React, {Component} from 'react' +import {connect} from 'react-redux' +import {findRuleByName} from '../engine/rules' + + +@connect( + state => + ({explained: state.explainedVariable}) +) +export default class Aide extends Component { + render() { + let {explained} = this.props + + if (!explained) return
+ + let rule = findRuleByName(explained), + text = rule.description || rule.titre + + let possibilities = rule['choix exclusifs'] + + return ( +
+

+ {text} +

+ { possibilities && +

+ {possibilities.length} possibilités : +

    + {possibilities.map(p => +
  • {p}
  • + )} +
+

+ } +
+ ) + } +} diff --git a/source/components/CDD.css b/source/components/CDD.css index 91ee00930..5b23a72f1 100644 --- a/source/components/CDD.css +++ b/source/components/CDD.css @@ -35,6 +35,7 @@ } #sim #help { + box-shadow: -1px 1px 15px 1px #eee; border: 1px solid; border-radius: 2px; border-color: #ccc; diff --git a/source/components/CDD.js b/source/components/CDD.js index 95ee2a7ca..c1a00afd1 100644 --- a/source/components/CDD.js +++ b/source/components/CDD.js @@ -6,41 +6,9 @@ import {reduxForm, formValueSelector} from 'redux-form' import {connect} from 'react-redux' import './conversation/conversation.css' import {START_CONVERSATION} from '../actions' -import {findRuleByName} from '../engine/rules' +import Aide from './Aide' -@connect(({form: {conversation}, steps, explainTerm}) => ({conversationState: conversation && conversation.values, steps, explainTerm})) -class Aide extends Component { - render() { - let {steps, conversationState, explainTerm} = this.props - if (!steps.length) return null - let [{dependencyOfVariables, helpText}] = steps - if (!explainTerm) return
- - let rule = findRuleByName(explainTerm), - text = rule.description || rule.titre - - let possibilities = rule['choix exclusifs'] - - return ( -
-

- {text} -

- { possibilities && -

- {possibilities.length} possibilités : -

    - {possibilities.map(p => -
  • {p}
  • - )} -
-

- } -
- ) - } -} let situationSelector = formValueSelector('conversation') @reduxForm( diff --git a/source/components/conversation/Term.css b/source/components/conversation/Explicable.css similarity index 78% rename from source/components/conversation/Term.css rename to source/components/conversation/Explicable.css index fb7a88777..e8cf7bfd6 100644 --- a/source/components/conversation/Term.css +++ b/source/components/conversation/Explicable.css @@ -1,4 +1,4 @@ -.term.defined .icon{ +.explicable .icon{ text-align: center; width: 1.3em; line-height: 1.3em; @@ -9,12 +9,12 @@ border: 1px solid transparent; } -.term.defined:hover .icon { +.explicable:hover .icon { opacity: 1; border-color: white; } -.term.defined .icon:hover { +.explicable .icon:hover { opacity: 1; background: white; color: #4A89DC; diff --git a/source/components/conversation/Explicable.js b/source/components/conversation/Explicable.js new file mode 100644 index 000000000..c84d97443 --- /dev/null +++ b/source/components/conversation/Explicable.js @@ -0,0 +1,39 @@ +import React from 'react' +import classNames from 'classnames' +import './Explicable.css' +import HoverDecorator from '../HoverDecorator' +import {connect} from 'react-redux' +import {EXPLAIN_VARIABLE} from '../../actions' +import {findRuleByName} from '../../engine/rules' + + +@connect(null, dispatch => ({ + explain: variableName => dispatch({type: EXPLAIN_VARIABLE, variableName}) +})) +@HoverDecorator +export default class Explicable extends React.Component { + render(){ + let + {name, hover, label, explain} = this.props, + rule = findRuleByName(name) + + // Rien à expliquer ici, ce n'est pas une règle + if (!rule) return {label} + + let ruleLabel = rule.titre || rule.name + // Rien à expliquer ici, il n'y a pas de champ description dans la règle + if (!rule.description && !rule['choix exclusifs']) return {ruleLabel} + + + return ( + + {ruleLabel} + {e.preventDefault(); e.stopPropagation(); explain(name)}}> + { hover ? 'ℹ' : '•' } + + ) + } +} diff --git a/source/components/conversation/Question.js b/source/components/conversation/Question.js index 8407e367e..ce71cd26b 100644 --- a/source/components/conversation/Question.js +++ b/source/components/conversation/Question.js @@ -1,32 +1,29 @@ import React, {Component} from 'react' -import {connect} from 'react-redux' import {FormDecorator} from './FormDecorator' import {answer, answered} from './userAnswerButtonStyle' import HoverDecorator from '../HoverDecorator' -import Term from './Term' -import {EXPLAIN_TERM} from '../../actions' +import Explicable from './Explicable' +import R from 'ramda' -@connect(null, dispatch => ({ - explainTerm: term => () => dispatch({type: EXPLAIN_TERM, term}) -})) @HoverDecorator class RadioLabel extends Component { render() { - let {choice: {value, label}, input, submit, hover, themeColours, explainTerm} = this.props, + let {value, label, input, submit, hover, themeColours} = this.props, + // value = R.when(R.is(Object), R.prop('value'))(choice), labelStyle = Object.assign( (value === input.value || hover) ? answered(themeColours) : answer(themeColours), ) return ( - ) } @@ -46,8 +43,10 @@ export default class Question extends Component { return ( - { choices.map((choice) => - + { choices.map((choice) => do { + let {value, label} = R.is(String)(choice) ? {value: choice, label: null} : choice; + + } )} ) diff --git a/source/components/conversation/Term.js b/source/components/conversation/Term.js deleted file mode 100644 index 99f532304..000000000 --- a/source/components/conversation/Term.js +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react' -import classNames from 'classnames' -import './Term.css' -import HoverDecorator from '../HoverDecorator' - -@HoverDecorator -export default class Term extends React.Component { - render(){ - let {label, defined, hover, explain} = this.props - return ( - - {label} - {e.preventDefault(); e.stopPropagation(); explain()}}> - { hover ? 'ℹ' : '•' } - - ) - } -} diff --git a/source/engine/conversation.js b/source/engine/conversation.js index a2f76b1b3..f709997fc 100644 --- a/source/engine/conversation.js +++ b/source/engine/conversation.js @@ -1,7 +1,7 @@ -export let constructStepMeta = ({dottedName, name, description}) => ({ +export let constructStepMeta = ({question, dottedName, name}) => ({ // name: dottedName.split(' . ').join('.'), name: dottedName, - question: description || name, + question: question || name, title: name, dependencyOfVariables: ['chai pas'], visible: true, diff --git a/source/engine/rules.js b/source/engine/rules.js index 4e210a3ad..770dc9b27 100644 --- a/source/engine/rules.js +++ b/source/engine/rules.js @@ -42,10 +42,10 @@ let [rules, entityRules] = /**************************************** Méthodes de recherche d'une règle */ -export let findRuleByName = search => console.log('search', search) || +export let findRuleByName = search => [...rules, ...entityRules] .map(enrichRule) - .find( ({name}) => console.log('name', name) || + .find( ({name}) => name === search ) diff --git a/source/reducers.js b/source/reducers.js index d44a21ee7..1f7b0d95d 100644 --- a/source/reducers.js +++ b/source/reducers.js @@ -9,7 +9,7 @@ import Question from './components/conversation/Question' import Input from './components/conversation/Input' import RhetoricalQuestion from './components/conversation/RhetoricalQuestion' -import { STEP_ACTION, UNSUBMIT_ALL, START_CONVERSATION, EXPLAIN_TERM} from './actions' +import { STEP_ACTION, UNSUBMIT_ALL, START_CONVERSATION, EXPLAIN_VARIABLE} from './actions' import R from 'ramda' import {findGroup, findRuleByDottedName, dottedName, parentName} from './engine/rules' @@ -35,9 +35,9 @@ function themeColours(state = computeThemeColours(), {type, colour}) { let situationGate = state => name => formValueSelector('conversation')(state, name) -function explainTerm(state = null, {type, term}) { - if (type == EXPLAIN_TERM) - return term +function explainedVariable(state = null, {type, variableName}) { + if (type == EXPLAIN_VARIABLE) + return variableName else return state } @@ -54,7 +54,7 @@ export default reduceReducers( themeColours, - explainTerm + explainedVariable }), // cross-cutting concerns because here `state` is the whole state tree (state, action) => { @@ -122,17 +122,11 @@ export default reduceReducers( constructStepMeta(group), { component: Question, - choices: group['choix exclusifs'].map(name => { - let rule = findRuleByDottedName( - group.dottedName + ' . ' + name - ) - return { - value: rule.name, - label: rule && rule.titre || name - } - }).concat([{value: 'aucun', label: 'Aucun'}]), + choices: + group['choix exclusifs'].concat( + [{value: 'aucun', label: 'Aucun'}] + ), // defaultValue: 'Non', - helpText: 'Choisissez une réponse' } )] ])