Modification du state pour le nouveau design

pull/206/head
Mael 2018-03-12 16:22:16 +01:00 committed by Laurent Bossavit
parent 4384552583
commit d00e44257f
2 changed files with 68 additions and 88 deletions

View File

@ -23,7 +23,7 @@ import { connect } from 'react-redux'
import { RuleValue } from './rule/RuleValueVignette'
export let salaries = ['salaire net', 'salaire de base', 'salaire total']
let popularTargetNames = [...salaries, 'aides employeur']
export let popularTargetNames = [...salaries, 'aides employeur']
@translate()
@reduxForm({
@ -35,11 +35,11 @@ let popularTargetNames = [...salaries, 'aides employeur']
formValueSelector('conversation')(state, dottedName),
targets: state.analysis ? state.analysis.targets : [],
flatRules: state.flatRules
targetNames: state.targetNames
conversationTargetNames: state.conversationTargetNames
}),
dispatch => ({
startConversation: (targetNames, fromScratch = false) =>
dispatch({ type: 'START_CONVERSATION', targetNames, fromScratch })
setConversationTargets: (targetNames, fromScratch = false) =>
dispatch({ type: 'SET_CONVERSATION_TARGETS', targetNames, fromScratch })
})
)
export default class TargetSelection extends Component {
@ -70,8 +70,12 @@ export default class TargetSelection extends Component {
)
) : (
<>
<p>Estimation par défaut un CDI non cadre ... </p>
<BlueButton onClick={this.props.setSelectingTargets}>
<p>Estimation par défaut pour un CDI non cadre ... </p>
<BlueButton
onClick={() => {
this.props.setSelectingTargets()
}}
>
Personnaliser
</BlueButton>
</>
@ -88,11 +92,11 @@ export default class TargetSelection extends Component {
let popularTargets = popularTargetNames.map(curry(findRuleByName)(flatRules)),
{
targets,
targetNames,
conversationTargetNames,
textColourOnWhite,
startConversation
setConversationTargets
} = this.props,
optionIsChecked = s => targetNames.includes(s.name),
optionIsChecked = s => (conversationTargetNames || []).includes(s.name),
visibleCheckbox = s =>
this.props.selectingTargets && s.dottedName !== this.state.activeInput,
toggleTarget = target =>
@ -111,9 +115,9 @@ export default class TargetSelection extends Component {
checked={optionIsChecked(s)}
onClick={() => this.props.showConversation()}
onChange={() =>
startConversation(
setConversationTargets(
toggleTarget(s.name)(
targetNames.filter(
conversationTargetNames.filter(
t => !this.state.activeInput.includes(t)
)
)
@ -172,9 +176,9 @@ export default class TargetSelection extends Component {
className="targetValue"
style={{ width: '6em' }}
onClick={() => {
this.props.startConversation(
reject(equals(s.name), popularTargetNames)
)
// this.props.setConversationTargets(
// reject(equals(s.name), popularTargetNames)
// )
this.setState({ activeInput: s.dottedName })
}}

View File

@ -16,7 +16,8 @@ import reduceReducers from 'reduce-reducers'
import { reducer as formReducer, formValueSelector } from 'redux-form'
import {
rules, rulesFr,
rules,
rulesFr,
enrichRule,
findRuleByName,
collectDefaults,
@ -26,7 +27,6 @@ import { getNextSteps } from 'Engine/generateQuestions'
import computeThemeColours from 'Components/themeColours'
import {
STEP_ACTION,
START_CONVERSATION,
EXPLAIN_VARIABLE,
CHANGE_THEME_COLOUR,
CHANGE_LANG
@ -36,6 +36,8 @@ import { analyseMany, parseAll } from 'Engine/traverse'
import ReactPiwik from 'Components/Tracker'
import { popularTargetNames } from './components/TargetSelection'
// assume "wraps" a given situation function with one that overrides its values with
// the given assumptions
export let assume = (evaluator, assumptions) => state => name => {
@ -43,20 +45,6 @@ export let assume = (evaluator, assumptions) => state => name => {
return userInput != null ? userInput : assumptions[name]
}
let nextWithoutDefaults = (
state,
analysis,
targetNames,
intermediateSituation
) => {
let reanalysis = analyseMany(state.parsedRules, targetNames)(
intermediateSituation(state)
),
nextSteps = getNextSteps(intermediateSituation(state), reanalysis)
return { currentQuestion: head(nextSteps), nextSteps }
}
export let reduceSteps = (tracker, flatRules, answerSource) => (
state,
action
@ -69,8 +57,9 @@ export let reduceSteps = (tracker, flatRules, answerSource) => (
// TODO
if (action.type == CHANGE_LANG) {
if (action.lang == 'fr') { flatRules = rulesFr }
else flatRules = rules
if (action.lang == 'fr') {
flatRules = rulesFr
} else flatRules = rules
return {
...state,
flatRules
@ -78,19 +67,18 @@ export let reduceSteps = (tracker, flatRules, answerSource) => (
}
if (
![START_CONVERSATION, STEP_ACTION, 'USER_INPUT_UPDATE'].includes(
!['SET_CONVERSATION_TARGETS', STEP_ACTION, 'USER_INPUT_UPDATE'].includes(
action.type
)
)
return state
let targetNames =
action.type == START_CONVERSATION
let conversationTargetNames =
action.type == 'SET_CONVERSATION_TARGETS'
? action.targetNames
: state.targetNames || []
: state.conversationTargetNames
let sim =
targetNames.length === 1 ? findRuleByName(flatRules, targetNames[0]) : {},
let sim = {},
// Hard assumptions cannot be changed, they are used to specialise a simulator
// before the user sees the first question
hardAssumptions = pathOr({}, ['simulateur', 'hypothèses'], sim),
@ -99,8 +87,7 @@ export let reduceSteps = (tracker, flatRules, answerSource) => (
rulesDefaults = collectDefaults(flatRules),
situationWithDefaults = assume(intermediateSituation, rulesDefaults)
console.log('targnames', targetNames)
let analysis = analyseMany(state.parsedRules, targetNames)(
let analysis = analyseMany(state.parsedRules, state.targetNames)(
situationWithDefaults(state)
)
@ -108,38 +95,23 @@ export let reduceSteps = (tracker, flatRules, answerSource) => (
return { ...state, analysis, situationGate: situationWithDefaults(state) }
}
let nextWithDefaults = getNextSteps(situationWithDefaults(state), analysis),
assumptionsMade = !isEmpty(rulesDefaults),
done = nextWithDefaults.length == 0
let nextStepsAnalysis = analyseMany(
state.parsedRules,
conversationTargetNames
)(intermediateSituation(state)),
nextSteps = getNextSteps(intermediateSituation(state), nextStepsAnalysis)
let newState = {
...state,
targetNames,
conversationTargetNames,
analysis,
situationGate: situationWithDefaults(state),
explainedVariable: null,
done,
...(done && assumptionsMade
? // The simulation is "over" - except we can now fill in extra questions
// where the answers were previously given default reasonable assumptions
nextWithoutDefaults(state, analysis, targetNames, intermediateSituation)
: {
currentQuestion: head(nextWithDefaults),
nextSteps: nextWithDefaults
})
nextSteps,
currentQuestion: head(nextSteps)
}
if (action.type == START_CONVERSATION) {
return {
...newState,
/* when objectives change, reject them from answered questions
Hack : 'salaire de base' is the only inversable variable, so the only
one that could be the next target AND already in the answered steps */
foldedSteps: action.fromScratch
? []
: reject(contains('salaire de base'))(state.foldedSteps)
}
}
if (action.type == 'SET_CONVERSATION_TARGETS') return newState
if (action.type == STEP_ACTION && action.name == 'fold') {
tracker.push([
@ -203,36 +175,40 @@ function currentExample(state = null, { type, situation, name }) {
}
}
export default (initialRules) => reduceReducers(
combineReducers({
sessionId: (id = Math.floor(Math.random() * 1000000000000) + '') => id,
// this is handled by redux-form, pas touche !
form: formReducer,
export default initialRules =>
reduceReducers(
combineReducers({
sessionId: (id = Math.floor(Math.random() * 1000000000000) + '') => id,
// this is handled by redux-form, pas touche !
form: formReducer,
/* Have forms been filled or ignored ?
/* Have forms been filled or ignored ?
false means the user is reconsidering its previous input */
foldedSteps: (steps = []) => steps,
currentQuestion: (state = null) => state,
nextSteps: (state = []) => state,
foldedSteps: (steps = []) => steps,
currentQuestion: (state = null) => state,
nextSteps: (state = []) => state,
parsedRules: (state = null) => state,
flatRules: (state = null) => state,
analysis: (state = null) => state,
parsedRules: (state = null) => state,
flatRules: (state = null) => state,
analysis: (state = null) => state,
targetNames: (state = null) => state,
targetNames: (state = popularTargetNames) => state,
conversationTargetNames: (state = []) => state,
situationGate: (state = name => null) => state,
situationGate: (state = name => null) => state,
done: (state = null) => state,
iframe: (state = false) => state,
iframe: (state = false) => state,
themeColours,
themeColours,
explainedVariable,
explainedVariable,
currentExample
}),
// cross-cutting concerns because here `state` is the whole state tree
reduceSteps(ReactPiwik, initialRules, formatInputs(initialRules, formValueSelector))
)
currentExample
}),
// cross-cutting concerns because here `state` is the whole state tree
reduceSteps(
ReactPiwik,
initialRules,
formatInputs(initialRules, formValueSelector)
)
)