fix: il faut différencier les réponses multiples de la expression sous forme d’objet Publicodes

pull/3115/head
Jalil Arfaoui 2024-08-28 19:58:47 +02:00
parent 738a6162bc
commit 363828dbd9
6 changed files with 75 additions and 17 deletions

View File

@ -1,5 +1,6 @@
import { isObject } from 'effect/Predicate'
import { DottedName } from 'modele-social'
import Engine, { PublicodesExpression } from 'publicodes'
import { PublicodesExpression } from 'publicodes'
import React, { useCallback } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { useDispatch, useSelector } from 'react-redux'
@ -16,7 +17,10 @@ import { useEngine } from '@/components/utils/EngineContext'
import { Button } from '@/design-system/buttons'
import { Grid } from '@/design-system/layout'
import { H3 } from '@/design-system/typography/heading'
import { enregistreLaRéponse } from '@/store/actions/actions'
import {
enregistreLaRéponse,
enregistreLesRéponses,
} from '@/store/actions/actions'
import { estSurLaPremièreQuestionRépondueSelector } from '@/store/selectors/estSurLaPremièreQuestionRépondue.selector'
import { situationSelector } from '@/store/selectors/simulationSelectors'
import { evaluateQuestion } from '@/utils'
@ -72,7 +76,16 @@ export function QuestionEnCours({
value: PublicodesExpression | undefined,
dottedName: DottedName
) => {
dispatch(enregistreLaRéponse(dottedName, value))
if (value && isObject(value) && 'batchUpdate' in value) {
dispatch(
enregistreLesRéponses(
dottedName,
value.batchUpdate as Record<string, PublicodesExpression>
)
)
} else {
dispatch(enregistreLaRéponse(dottedName, value))
}
}
const isDateQuestion =

View File

@ -151,7 +151,7 @@ export default function RuleInput<Names extends string = DottedName>({
<>
<SelectCommune
{...commonProps}
onChange={(c) => commonProps.onChange(c)}
onChange={(c) => commonProps.onChange({ batchUpdate: c })} // 😭
value={value as Evaluation<string>}
/>
<Spacing md />

View File

@ -1,6 +1,3 @@
import { pipe } from 'effect'
import { isNumber, isString } from 'effect/Predicate'
import * as R from 'effect/Record'
import { DottedName } from 'modele-social'
import { PublicodesExpression } from 'publicodes'
@ -22,17 +19,8 @@ export function updateSituation(
const objectifsExclusifs = config['objectifs exclusifs'] ?? []
const nouvellesValeurs =
isString(value) || isNumber(value)
? { [dottedName]: value }
: pipe(
value,
R.mapKeys((suffixe) => `${dottedName} . ${suffixe}`),
R.map((valeur) => (isString(valeur) ? `'${valeur}'` : valeur)) // 😭
)
if (!objectifsExclusifs.includes(dottedName)) {
return { ...currentSituation, ...nouvellesValeurs }
return { ...currentSituation, [dottedName]: value }
}
const objectifsToReset = objectifsExclusifs.filter(

View File

@ -0,0 +1,24 @@
import { pipe } from 'effect'
import { isString } from 'effect/Predicate'
import * as R from 'effect/Record'
import { DottedName } from 'modele-social'
import { PublicodesExpression } from 'publicodes'
import { SimulationConfig } from '@/domaine/SimulationConfig'
import { Situation } from '@/domaine/Situation'
import { ImmutableType } from '@/types/utils'
export function updateSituationMultiple(
config: ImmutableType<SimulationConfig>,
currentSituation: Situation,
préfixe: DottedName,
valeurs: Record<string, PublicodesExpression>
): Situation {
const nouvellesValeurs = pipe(
valeurs,
R.mapKeys((suffixe) => `${préfixe} . ${suffixe}`),
R.map((valeur) => (isString(valeur) ? `'${valeur}'` : valeur)) // 😭
)
return { ...currentSituation, ...nouvellesValeurs }
}

View File

@ -21,6 +21,7 @@ export type Action =
| typeof vaÀLaQuestionSuivante
| typeof ajusteLaSituation
| typeof enregistreLaRéponse
| typeof enregistreLesRéponses
| typeof deleteFromSituation
| typeof updateUnit
| typeof batchUpdateSituation
@ -79,6 +80,16 @@ export const enregistreLaRéponse = (
value,
} as const)
export const enregistreLesRéponses = (
règle: DottedName,
valeurs: Record<string, PublicodesExpression>
) =>
({
type: 'ENREGISTRE_LES_RÉPONSES',
règle,
valeurs,
}) as const
export const deleteFromSituation = (fieldName: DottedName) =>
({
type: 'DELETE_FROM_SITUATION',

View File

@ -4,6 +4,7 @@ import { SimulationConfig } from '@/domaine/SimulationConfig'
import { Situation } from '@/domaine/Situation'
import { updateSituation } from '@/domaine/updateSituation'
import { updateSituationMulti } from '@/domaine/updateSituationMulti'
import { updateSituationMultiple } from '@/domaine/updateSituationMultiple'
import { Action } from '@/store/actions/actions'
import { omit, reject } from '@/utils'
@ -87,6 +88,27 @@ export function simulationReducer(
}
}
case 'ENREGISTRE_LES_RÉPONSES': {
const déjàDansLesQuestionsRépondues = state.answeredQuestions.includes(
action.règle
)
const answeredQuestions = déjàDansLesQuestionsRépondues
? state.answeredQuestions
: [...state.answeredQuestions, action.règle]
return {
...state,
answeredQuestions,
situation: updateSituationMultiple(
state.config,
state.situation,
action.règle,
action.valeurs
),
}
}
case 'DELETE_FROM_SITUATION': {
const newState = {
...state,