2017-01-10 18:22:44 +00:00
import React from 'react'
2016-11-15 18:46:17 +00:00
import { combineReducers } from 'redux'
2017-01-10 18:22:44 +00:00
import reduceReducers from 'reduce-reducers'
import { reducer as formReducer , formValueSelector } from 'redux-form'
2017-01-20 10:52:39 +00:00
import { analyseSituation , variableType } from './engine/traverse'
2017-02-16 10:45:40 +00:00
import { euro , months } from './components/conversation/formValueTypes.js'
2017-01-10 18:22:44 +00:00
import Question from './components/conversation/Question'
import Input from './components/conversation/Input'
import RhetoricalQuestion from './components/conversation/RhetoricalQuestion'
2017-02-09 17:15:25 +00:00
import { STEP _ACTION , UNSUBMIT _ALL , START _CONVERSATION , EXPLAIN _VARIABLE } from './actions'
2017-01-10 18:22:44 +00:00
import R from 'ramda'
2017-01-23 18:06:46 +00:00
2017-03-01 19:27:35 +00:00
import { findGroup , findRuleByDottedName , dottedName , parentName , collectMissingVariables } from './engine/rules'
2017-01-24 15:22:40 +00:00
import { constructStepMeta } from './engine/conversation'
2017-01-10 18:22:44 +00:00
import computeThemeColours from './components/themeColours'
function themeColours ( state = computeThemeColours ( ) , { type , colour } ) {
if ( type == 'CHANGE_THEME_COLOUR' )
return computeThemeColours ( colour )
else return state
}
2017-01-26 12:19:04 +00:00
let situationGate = state =>
name => formValueSelector ( 'conversation' ) ( state , name )
2017-02-09 17:38:51 +00:00
function explainedVariable ( state = null , { type , variableName = null } ) {
switch ( type ) {
case EXPLAIN _VARIABLE :
2017-02-09 17:15:25 +00:00
return variableName
2017-02-09 17:38:51 +00:00
default :
return state
}
2017-02-08 16:50:22 +00:00
}
2017-01-10 18:22:44 +00:00
export default reduceReducers (
combineReducers ( {
// this is handled by redux-form, pas touche !
form : formReducer ,
/ * H a v e f o r m s b e e n f i l l e d o r i g n o r e d ?
false means the user is reconsidering its previous input * /
2017-03-13 15:15:19 +00:00
steps : ( steps = [ ] ) => steps ,
submittedSteps : ( steps = [ ] ) => steps ,
2017-01-10 18:22:44 +00:00
analysedSituation : ( state = [ ] ) => state ,
2017-02-08 16:50:22 +00:00
themeColours ,
2017-02-09 17:15:25 +00:00
explainedVariable
2017-01-10 18:22:44 +00:00
} ) ,
// cross-cutting concerns because here `state` is the whole state tree
( state , action ) => {
if ( action . type == STEP _ACTION || action . type == START _CONVERSATION ) {
2017-03-01 19:27:35 +00:00
// pour débugguer :
2017-01-26 12:19:04 +00:00
window . situationGate = situationGate ( state )
2017-03-13 15:15:19 +00:00
let newlySubmittedSteps =
action . newState == 'filled'
? [ {
... state . steps . find ( s => s . name === action . name ) ,
state : 'filled'
} ]
: [ ]
2017-01-10 18:22:44 +00:00
// on calcule la prochaine étape, à ajouter sur la pile
2017-01-26 12:19:04 +00:00
let
2017-03-01 19:27:35 +00:00
// une liste des objectifs de la simulation (des 'rules' aussi nommées 'variables')
2017-01-26 12:19:04 +00:00
analysedSituation = analyseSituation (
situationGate ( state )
) ,
2017-03-01 19:27:35 +00:00
// y = console.log('analysedSituation', JSON.stringify(analysedSituation)),
// on collecte les variables manquantes : celles qui sont nécessaires pour
// remplir les objectifs de la simulation (calculer des cotisations) mais qui n'ont pas
// encore été renseignées
missingVariables = collectMissingVariables ( 'groupByMissingVariable' , analysedSituation ) ,
2017-02-10 14:12:00 +00:00
2017-01-23 18:06:46 +00:00
missingVariablesList = R . keys ( missingVariables ) ,
2017-03-13 15:15:19 +00:00
/ *
Certaines variables manquantes peuvent être factorisées dans des groupes .
Par exemple , au lieu de :
q1 : "Pensez vous porlonger le CDD en CDI" ,
r1 : Oui | Non
q2 : "Pensez-vous qu'une rupture pour faute grave est susceptible d'arriver"
r2 : Oui | Non
on préfère :
q : "Pensez-vous être confronté à l'un de ces événements ?"
r : Prolongation du CDD en CDI | Rupture pour faute grave
* /
2017-01-24 15:22:40 +00:00
groups = R . groupBy (
2017-01-26 12:19:04 +00:00
parentName
2017-01-24 15:22:40 +00:00
) ( missingVariablesList ) ,
2017-03-13 15:15:19 +00:00
// on va maintenant construire la liste des composants React qui afficheront les questions à l'utilisateur pour que l'on obtienne les variables manquantes
2017-03-01 19:27:35 +00:00
steps = R . pipe (
2017-01-24 15:22:40 +00:00
R . mapObjIndexed ( ( variables , group ) =>
R . pipe (
findGroup ,
R . cond ( [
// Pas de groupe trouvé : ce sont des variables individuelles
2017-01-26 10:27:24 +00:00
[ R . isNil , ( ) => variables . map ( dottedName => {
let rule = findRuleByDottedName ( dottedName )
2017-01-24 15:22:40 +00:00
return Object . assign ( constructStepMeta ( rule ) ,
2017-02-13 14:50:51 +00:00
rule . format == 'nombre positif' ||
rule . format == 'période' ?
2017-01-24 15:22:40 +00:00
{
component : Input ,
2017-02-16 10:45:40 +00:00
valueType : rule . format == 'nombre positif' ? euro : months ,
2017-01-24 15:22:40 +00:00
attributes : {
inputMode : 'numeric' ,
placeholder : 'votre réponse'
2017-02-16 13:15:45 +00:00
} ,
suggestions : rule . suggestions
2017-01-24 15:22:40 +00:00
} : {
component : Question ,
2017-01-26 12:19:04 +00:00
choices : [
{ value : 'non' , label : 'Non' } ,
{ value : 'oui' , label : 'Oui' }
2017-02-13 15:20:26 +00:00
]
2017-01-24 15:22:40 +00:00
}
) } ) ] ,
[ R . T , group =>
Object . assign (
constructStepMeta ( group ) ,
{
component : Question ,
2017-02-09 17:15:25 +00:00
choices :
2017-02-13 14:50:51 +00:00
group [ 'une possibilité' ] . concat (
2017-03-13 12:35:38 +00:00
group [ 'langue au chat possible' ] === 'oui' ?
2017-02-13 15:20:26 +00:00
[ { value : '_' , label : 'Aucun' } ] : [ ]
)
2017-01-24 15:22:40 +00:00
}
) ]
] )
) ( group )
) ,
R . values ,
R . unnest
2017-01-26 12:19:04 +00:00
) ( groups )
2017-01-23 18:06:46 +00:00
2017-03-13 15:15:19 +00:00
console . log ( 'submittedSteps' , newlySubmittedSteps )
return {
... state ,
steps ,
submittedSteps : state . submittedSteps . concat ( newlySubmittedSteps ) ,
analysedSituation
}
2017-01-26 12:19:04 +00:00
2017-01-10 18:22:44 +00:00
} else {
return state
}
2016-11-15 18:46:17 +00:00
2017-01-10 18:22:44 +00:00
}
)