Remplace ImpositionSwitch par un RuleInput

 Refacto useSelection
pull/2105/head
Jérémy Rialland 2022-04-21 10:25:59 +02:00 committed by Johan Girod
parent ced376d12e
commit ef8df374cc
3 changed files with 46 additions and 63 deletions

View File

@ -13,6 +13,8 @@ entreprise . imposition:
- catégorie juridique . EI
alors: "'IR'"
- sinon: "'IS'"
meta:
affichage: toggle
entreprise . imposition . IR:
valeur: imposition = 'IR'

View File

@ -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<Names extends string = DottedName>({
onChange,
missing,
}: InputProps<Names>) {
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<string | null>(
(!missing && defaultValue) || null
)
const debounce = useRef<NodeJS.Timeout>()
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 }
}

View File

@ -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 (
<>
<Simulation
@ -55,7 +54,14 @@ export default function IndépendantSimulation() {
legend="Vos revenus d'indépendant"
toggles={
<>
<ImpositionSwitch />
<RuleInput
dottedName="entreprise . imposition"
onChange={(imposition) => {
dispatch(
updateSituation('entreprise . imposition', imposition)
)
}}
/>
<PeriodSwitch />
</>
@ -120,42 +126,3 @@ function IndépendantSimulationGoals({
</SimulationGoals>
)
}
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 (
<ToggleGroup
value={currentImposition}
onChange={(imposition) => {
setCurrentImposition(imposition)
dispatch(updateSituation('entreprise . imposition', `'${imposition}'`))
}}
>
{(['IR', 'IS'] as const).map((imposition) => (
<span
key={imposition}
className={currentImposition !== imposition ? 'print-hidden' : ''}
>
<Radio value={imposition}>
{
engine.getRule(
`entreprise . imposition . ${imposition}` as DottedName
).title
}
</Radio>
</span>
))}
</ToggleGroup>
)
}