Skip to content

Commit

Permalink
Ajout des règles dans le state Redux
Browse files Browse the repository at this point in the history
Déplace la logique de changement de période d'un component vers un reducer
  • Loading branch information
mquandalle committed Sep 18, 2019
1 parent 8c9a401 commit 0ddc2d0
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 74 deletions.
33 changes: 10 additions & 23 deletions source/components/PeriodSwitch.js
@@ -1,36 +1,23 @@
import { findRuleByDottedName } from 'Engine/rules'
import React, { useCallback, useEffect } from 'react'
import React from 'react'
import { Trans } from 'react-i18next'
import { useDispatch, useSelector } from 'react-redux'
import {
flatRulesSelector,
situationSelector
} from 'Selectors/analyseSelectors'
import { situationSelector } from 'Selectors/analyseSelectors'
import './PeriodSwitch.css'

export default function PeriodSwitch() {
const dispatch = useDispatch()
const rules = useSelector(flatRulesSelector)
const situation = useSelector(situationSelector)
const initialPeriod = useSelector(
state => state.simulation?.config?.situation?.période
const defaultPeriod = useSelector(
state => state.simulation?.config?.situation?.période || 'année'
)
const currentPeriod = situation.période
useEffect(() => {
!currentPeriod && updatePeriod(initialPeriod || 'année')
}, [currentPeriod, initialPeriod, updatePeriod])
const updatePeriod = useCallback(
toPeriod => {
const needConversion = Object.keys(situation).filter(dottedName => {
const rule = findRuleByDottedName(rules, dottedName)
return rule?.période === 'flexible'
})
dispatch({ type: 'UPDATE_PERIOD', toPeriod, needConversion })
},
[dispatch, rules, situation]
)
let periods = ['mois', 'année']
if (initialPeriod === 'année') {
const updatePeriod = toPeriod => dispatch({ type: 'UPDATE_PERIOD', toPeriod })

if (!currentPeriod) {
updatePeriod(defaultPeriod)
}
if (defaultPeriod === 'année') {
periods.reverse()
}

Expand Down
57 changes: 35 additions & 22 deletions source/reducers/rootReducer.js
Expand Up @@ -17,6 +17,7 @@ import { combineReducers } from 'redux'
import i18n from '../i18n'
import inFranceAppReducer from './inFranceAppReducer'
import storageReducer from './storageReducer'
import { findRuleByDottedName } from 'Engine/rules'
import type { Action } from 'Types/ActionsTypes'

function explainedVariable(state = null, { type, variableName = null }) {
Expand Down Expand Up @@ -99,14 +100,14 @@ function conversationSteps(
return state
}

function updateSituation(situation, { fieldName, value, objectifs }) {
const removePreviousTarget = objectifs.includes(fieldName)
? omit(objectifs)
function updateSituation(situation, { fieldName, value, config }) {
const removePreviousTarget = config.objectifs.includes(fieldName)
? omit(config.objectifs)
: identity
return { ...removePreviousTarget(situation), [fieldName]: value }
}

function updatePeriod(situation, { toPeriod, needConversion }) {
function updatePeriod(situation, { toPeriod, rules }) {
const currentPeriod = situation['période']
if (currentPeriod === toPeriod) {
return situation
Expand All @@ -115,6 +116,11 @@ function updatePeriod(situation, { toPeriod, needConversion }) {
throw new Error('Oups, changement de période invalide')
}

const needConversion = Object.keys(situation).filter(dottedName => {
const rule = findRuleByDottedName(rules, dottedName)
return rule?.période === 'flexible'
})

const updatedSituation = Object.entries(situation)
.filter(([fieldName]) => needConversion.includes(fieldName))
.map(([fieldName, value]) => [
Expand Down Expand Up @@ -148,15 +154,15 @@ function simulation(state = null, action) {
situation: updateSituation(state.situation, {
fieldName: action.fieldName,
value: action.value,
objectifs: state.config.objectifs
config: state.config
})
}
case 'UPDATE_PERIOD':
return {
...state,
situation: updatePeriod(state.situation, {
toPeriod: action.toPeriod,
needConversion: action.needConversion
rules: action.rules
})
}
}
Expand Down Expand Up @@ -195,19 +201,26 @@ const existingCompanyReducer = (state, action) => {
}
return newState
}
export default reduceReducers(
existingCompanyReducer,
storageReducer,
combineReducers({
sessionId: defaultTo(Math.floor(Math.random() * 1000000000000) + ''),
conversationSteps,
lang,
simulation,
explainedVariable,
previousSimulation: defaultTo(null),
currentExample,
situationBranch,
activeTargetInput,
inFranceApp: inFranceAppReducer
})
)
export default (state, action) => {
// Enrich the action
if (action.type === 'UPDATE_PERIOD') {
action.rules = state.rules
}
return reduceReducers(
existingCompanyReducer,
storageReducer,
combineReducers({
sessionId: defaultTo(Math.floor(Math.random() * 1000000000000) + ''),
conversationSteps,
lang,
rules: defaultTo(null),
simulation,
explainedVariable,
previousSimulation: defaultTo(null),
currentExample,
situationBranch,
activeTargetInput,
inFranceApp: inFranceAppReducer
})
)(state, action)
}
20 changes: 5 additions & 15 deletions source/selectors/analyseSelectors.js
Expand Up @@ -5,9 +5,7 @@ import {
import {
collectDefaults,
disambiguateExampleSituation,
findRuleByDottedName,
rules as baseRulesEn,
rulesFr as baseRulesFr
findRuleByDottedName
} from 'Engine/rules'
import { analyse, analyseMany, parseAll } from 'Engine/traverse'
import {
Expand Down Expand Up @@ -38,18 +36,10 @@ import { mapOrApply } from '../utils'
// create a "selector creator" that uses deep equal instead of ===
const createDeepEqualSelector = createSelectorCreator(defaultMemoize, equals)

/*
*
* We must here compute parsedRules, flatRules, analyse which contains both targets and cache objects
*
*
* */

export let flatRulesSelector = createSelector(
state => state.lang,
(state, props) => props && props.rules,
(lang, rules) => rules || (lang === 'en' ? baseRulesEn : baseRulesFr)
)
// We must here compute parsedRules, flatRules, analyse which contains both targets and cache objects
export let flatRulesSelector = (state, props) => {
return props?.rules || state?.rules
}

export let parsedRulesSelector = createSelector(
[flatRulesSelector],
Expand Down
7 changes: 5 additions & 2 deletions source/sites/mon-entreprise.fr/App.js
Expand Up @@ -38,6 +38,7 @@ import Landing from './pages/Landing/Landing.js'
import SocialSecurity from './pages/SocialSecurity'
import ÉconomieCollaborative from './pages/ÉconomieCollaborative'
import { constructLocalizedSitePath } from './sitePaths'
import { rules as baseRulesEn, rulesFr as baseRulesFr } from 'Engine/rules'

if (process.env.NODE_ENV === 'production') {
Raven.config(
Expand All @@ -60,6 +61,7 @@ function InFranceRoute({ basename, language }) {
setToSessionStorage('lang', language)
}, [language])
const paths = constructLocalizedSitePath(language)
const rules = language === 'en' ? baseRulesEn : baseRulesFr
return (
<Provider
basename={basename}
Expand All @@ -68,12 +70,13 @@ function InFranceRoute({ basename, language }) {
sitePaths={paths}
reduxMiddlewares={middlewares}
onStoreCreated={store => {
persistEverything()(store)
persistEverything({ except: ['rules'] })(store)
persistSimulation(store)
}}
initialStore={{
...retrievePersistedState(),
previousSimulation: retrievePersistedSimulation()
previousSimulation: retrievePersistedSimulation(),
rules
}}>
<RouterSwitch />
</Provider>
Expand Down
20 changes: 9 additions & 11 deletions test/conversation.test.js
Expand Up @@ -9,7 +9,7 @@ import {
} from '../source/selectors/analyseSelectors'
let baseState = {
conversationSteps: { foldedSteps: [] },
form: { conversation: { values: {} } }
simulation: { situation: {} }
}

describe('conversation', function() {
Expand Down Expand Up @@ -48,14 +48,11 @@ describe('conversation', function() {
rules = rawRules.map(enrichRule)

let step1 = merge(baseState, {
rules,
simulation: { config: { objectifs: ['startHere'] } }
})
let step2 = reducers(
assocPath(
['form', 'conversation', 'values'],
{ top: { aa: '1' } },
step1
),
assocPath(['simulation', 'situation'], { 'top . aa': '1' }, step1),
{
type: 'STEP_ACTION',
name: 'fold',
Expand All @@ -65,8 +62,8 @@ describe('conversation', function() {

let step3 = reducers(
assocPath(
['form', 'conversation', 'values'],
{ top: { bb: '1', aa: '1' } },
['simulation', 'situation'],
{ 'top . aa': '1', 'top . bb': '1' },
step2
),
{
Expand All @@ -86,7 +83,7 @@ describe('conversation', function() {
step: 'top . bb'
})

expect(currentQuestionSelector(lastStep, { rules })).to.equal('top . bb')
expect(currentQuestionSelector(lastStep)).to.equal('top . bb')
expect(lastStep.conversationSteps).to.have.property('foldedSteps')
expect(lastStep.conversationSteps.foldedSteps).to.have.lengthOf(0)
})
Expand Down Expand Up @@ -129,12 +126,13 @@ describe('conversation', function() {
rules = rawRules.map(enrichRule)

let step1 = merge(baseState, {
rules,
simulation: { config: { objectifs: ['net'] } }
})
expect(currentQuestionSelector(step1, { rules })).to.equal('brut')
expect(currentQuestionSelector(step1)).to.equal('brut')

let step2 = reducers(
assocPath(['form', 'conversation', 'values', 'brut'], '2300', step1),
assocPath(['simulation', 'situation', 'brut'], '2300', step1),
{
type: 'STEP_ACTION',
name: 'fold',
Expand Down
3 changes: 2 additions & 1 deletion test/ficheDePaieSelector.test.js
Expand Up @@ -3,14 +3,15 @@
import { expect } from 'chai'
// $FlowFixMe
import salariéConfig from 'Components/simulationConfigs/salarié.yaml'
import { getRuleFromAnalysis } from 'Engine/rules'
import { getRuleFromAnalysis, rules } from 'Engine/rules'
import { analysisWithDefaultsSelector } from 'Selectors/analyseSelectors'
import {
analysisToCotisationsSelector,
COTISATION_BRANCHE_ORDER
} from 'Selectors/ficheDePaieSelectors'

let state = {
rules,
simulation: {
config: salariéConfig,
situation: {
Expand Down
1 change: 1 addition & 0 deletions test/real-rules.test.js
Expand Up @@ -10,6 +10,7 @@ let runExamples = (examples, rule) =>
examples.map(ex => {
let runExample = exampleAnalysisSelector(
{
rules,
currentExample: {
situation: ex.situation,
dottedName: rule.dottedName
Expand Down

0 comments on commit 0ddc2d0

Please sign in to comment.