From ef8df374cc27b53acea44c0b3a9f6e48bc7fcbb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Rialland?= Date: Thu, 21 Apr 2022 10:25:59 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Remplace=20ImpositionSwitch=20par?= =?UTF-8?q?=20un=20RuleInput=20=E2=9C=A8=20Refacto=20useSelection?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../règles/entreprise/imposition.yaml | 2 + .../components/conversation/ChoicesInput.tsx | 52 +++++++++++------- site/source/pages/Simulateurs/Indépendant.tsx | 55 ++++--------------- 3 files changed, 46 insertions(+), 63 deletions(-) diff --git a/modele-social/règles/entreprise/imposition.yaml b/modele-social/règles/entreprise/imposition.yaml index 8549eb8b7..67ef9caaa 100644 --- a/modele-social/règles/entreprise/imposition.yaml +++ b/modele-social/règles/entreprise/imposition.yaml @@ -13,6 +13,8 @@ entreprise . imposition: - catégorie juridique . EI alors: "'IR'" - sinon: "'IS'" + meta: + affichage: toggle entreprise . imposition . IR: valeur: imposition = 'IR' diff --git a/site/source/components/conversation/ChoicesInput.tsx b/site/source/components/conversation/ChoicesInput.tsx index 8836d6e75..314e803e4 100644 --- a/site/source/components/conversation/ChoicesInput.tsx +++ b/site/source/components/conversation/ChoicesInput.tsx @@ -1,4 +1,3 @@ -import { useDebounce } from '@/components/utils' import Emoji from '@/components/utils/Emoji' import { Radio, @@ -11,7 +10,12 @@ import { Item, Select } from '@/design-system/field/Select' import { Spacing } from '@/design-system/layout' import { H4 } from '@/design-system/typography/heading' import { DottedName } from 'modele-social' -import { EvaluatedNode, RuleNode, serializeEvaluation } from 'publicodes' +import { + EvaluatedNode, + Evaluation, + RuleNode, + serializeEvaluation, +} from 'publicodes' import { createContext, Fragment, @@ -19,6 +23,7 @@ import { useCallback, useContext, useEffect, + useRef, useState, } from 'react' import { Trans, useTranslation } from 'react-i18next' @@ -229,29 +234,38 @@ export function useSelection({ onChange, missing, }: InputProps) { - const defaultValue = serializeEvaluation({ - nodeValue: value, - } as EvaluatedNode) - const [currentSelection, setCurrentSelection] = useState( - missing ? null : defaultValue + const serializeValue = (nodeValue: Evaluation) => + serializeEvaluation({ nodeValue } as EvaluatedNode) + + const defaultValue = serializeValue(value) + const [currentSelection, setCurrentSelection] = useState( + (!missing && defaultValue) || null ) + + const debounce = useRef() const handleChange = useCallback( - (value: Key) => { - setCurrentSelection(value.toString()) + (val: Key) => { + val = val.toString() + setCurrentSelection(val) + + debounce.current != null && clearTimeout(debounce.current) + debounce.current = setTimeout(() => { + onChange(val) + }, 300) }, - [setCurrentSelection] + [onChange] ) - const debouncedSelection = useDebounce(currentSelection, 300) + + const lastValue = useRef(value) useEffect(() => { - if ( - debouncedSelection && - (missing || - serializeEvaluation({ nodeValue: value } as EvaluatedNode) !== - debouncedSelection) - ) { - onChange(debouncedSelection) + if (lastValue.current !== value) { + const newSelection = serializeValue(value) + if (newSelection && newSelection !== currentSelection) { + handleChange(newSelection) + } + lastValue.current = value } - }, [debouncedSelection]) + }, [currentSelection, handleChange, value]) return { currentSelection, handleChange, defaultValue } } diff --git a/site/source/pages/Simulateurs/Indépendant.tsx b/site/source/pages/Simulateurs/Indépendant.tsx index 4b8fc14e9..d204826b8 100644 --- a/site/source/pages/Simulateurs/Indépendant.tsx +++ b/site/source/pages/Simulateurs/Indépendant.tsx @@ -8,12 +8,9 @@ import Simulation, { SimulationGoals, } from '@/components/Simulation' import IndépendantExplanation from '@/components/simulationExplanation/IndépendantExplanation' -import { useEngine } from '@/components/utils/EngineContext' -import { Radio, ToggleGroup } from '@/design-system/field' -import { DottedName } from 'modele-social' import { useDispatch } from 'react-redux' import { SelectSimulationYear } from '@/components/SelectSimulationYear' -import { useEffect, useState } from 'react' +import RuleInput from '@/components/conversation/RuleInput' export function IndépendantPLSimulation() { return ( @@ -44,6 +41,8 @@ export function EntrepriseIndividuelle() { } export default function IndépendantSimulation() { + const dispatch = useDispatch() + return ( <> - + { + dispatch( + updateSituation('entreprise . imposition', imposition) + ) + }} + /> @@ -120,42 +126,3 @@ function IndépendantSimulationGoals({ ) } - -function ImpositionSwitch() { - const dispatch = useDispatch() - const engine = useEngine() - const engineImposition = engine.evaluate('entreprise . imposition') - .nodeValue as string - const [currentImposition, setCurrentImposition] = useState(engineImposition) - - useEffect(() => { - if (currentImposition !== engineImposition) { - setCurrentImposition(engineImposition) - } - }, [currentImposition, engineImposition]) - - return ( - { - setCurrentImposition(imposition) - dispatch(updateSituation('entreprise . imposition', `'${imposition}'`)) - }} - > - {(['IR', 'IS'] as const).map((imposition) => ( - - - { - engine.getRule( - `entreprise . imposition . ${imposition}` as DottedName - ).title - } - - - ))} - - ) -}