🔥 Supprime FormDecorator

pull/1022/head
Maxime Quandalle 2020-05-06 05:56:53 +02:00
parent 9ab3641dfa
commit a6d848e01d
5 changed files with 94 additions and 85 deletions

View File

@ -17,7 +17,6 @@ export default function CurrencyInput({
debounce: debounceTimeout,
currencySymbol = '€',
onChange,
onSubmit,
language,
className,
...forwardedProps

View File

@ -1,10 +1,14 @@
import { goToQuestion, validateStepWithValue } from 'Actions/actions'
import {
goToQuestion,
updateSituation,
validateStepWithValue
} from 'Actions/actions'
import RuleInput from 'Components/conversation/RuleInput'
import QuickLinks from 'Components/QuickLinks'
import * as Animate from 'Components/ui/animate'
import { EngineContext } from 'Components/utils/EngineContext'
import { useNextQuestions } from 'Components/utils/useNextQuestion'
import { default as React, useContext, useEffect } from 'react'
import React, { useContext } from 'react'
import emoji from 'react-easy-emoji'
import { Trans } from 'react-i18next'
import { useDispatch, useSelector } from 'react-redux'
@ -14,7 +18,7 @@ import {
} from 'Selectors/simulationSelectors'
import Aide from './Aide'
import './conversation.css'
import FormDecorator from './FormDecorator'
import { ExplicableRule } from './Explicable'
export type ConversationProps = {
customEndMessages?: React.ReactNode
@ -37,26 +41,50 @@ export default function Conversation({ customEndMessages }: ConversationProps) {
)
const goToPrevious = () =>
dispatch(goToQuestion(previousAnswers.slice(-1)[0]))
const handleKeyDown = ({ key }: React.KeyboardEvent) => {
if (['Escape'].includes(key)) {
setDefault()
}
}
const submit = source =>
const submit = (source: string) => {
dispatch({
type: 'STEP_ACTION',
name: 'fold',
step: currentQuestion,
source
})
const DecoratedInputComponent = FormDecorator(RuleInput)
}
const setFormValue = value => {
dispatch(goToQuestion(currentQuestion))
dispatch(updateSituation(currentQuestion, value))
}
const handleKeyDown = ({ key }: React.KeyboardEvent) => {
if (key === 'Escape') {
setDefault()
} else if (key === 'Enter') {
submit('enter')
}
}
return currentQuestion ? (
<>
<Aide />
<div tabIndex={0} style={{ outline: 'none' }} onKeyDown={handleKeyDown}>
<Animate.fadeIn>
<DecoratedInputComponent dottedName={currentQuestion} />
<div className="step">
<h3>
{rules[currentQuestion].question}{' '}
<ExplicableRule dottedName={currentQuestion} />
</h3>
<fieldset>
<RuleInput
dottedName={currentQuestion}
value={situation[currentQuestion]}
onChange={setFormValue}
onSubmit={submit}
rules={rules}
/>
</fieldset>
</div>
</Animate.fadeIn>
<div className="ui__ answer-group">
{previousAnswers.length > 0 && (
@ -70,7 +98,15 @@ export default function Conversation({ customEndMessages }: ConversationProps) {
</>
)}
{currentQuestionIsAnswered ? (
<SendButton onSubmit={submit} />
<button
className="ui__ plain small button"
css="margin-left: 1.2rem"
onClick={() => submit('accept')}
>
<span className="text">
<Trans>Suivant</Trans>
</span>
</button>
) : (
<button
onClick={setDefault}
@ -89,7 +125,7 @@ export default function Conversation({ customEndMessages }: ConversationProps) {
{emoji('🌟')}{' '}
<Trans i18nKey="simulation-end.title">
Vous avez complété cette simulation
</Trans>{' '}
</Trans>
</h3>
<p>
{customEndMessages ? (
@ -103,33 +139,3 @@ export default function Conversation({ customEndMessages }: ConversationProps) {
</div>
)
}
type SendButtonProps = {
onSubmit: (cause: string) => void
}
function SendButton({ onSubmit }: SendButtonProps) {
useEffect(() => {
const handleKeyDown = ({ key }: KeyboardEvent) => {
if (key !== 'Enter') return
onSubmit('enter')
}
window.addEventListener('keydown', handleKeyDown)
return () => {
window.removeEventListener('keydown', handleKeyDown)
}
}, [onSubmit])
return (
<button
className="ui__ plain button "
css="margin-left: 1.2rem"
onClick={() => onSubmit('accept')}
>
<span className="text">
<Trans>Suivant</Trans>
</span>
</button>
)
}

View File

@ -24,35 +24,37 @@ export default function Input({
return (
<div className="step input">
<InputSuggestions
suggestions={suggestions}
onFirstClick={value => {
onChange(value)
}}
onSecondClick={() => onSubmit?.('suggestion')}
unit={unit}
/>
<NumberFormat
autoFocus={autoFocus}
className="suffixed"
id={'step-' + dottedName}
placeholder={defaultValue?.nodeValue ?? defaultValue}
thousandSeparator={thousandSeparator}
decimalSeparator={decimalSeparator}
allowEmptyFormatting={true}
style={{ border: `1px solid ${colors.textColorOnWhite}` }}
onValueChange={({ floatValue }) => {
debouncedOnChange(floatValue)
}}
value={value}
autoComplete="off"
/>
<span className="suffix">
{formatValue({ nodeValue: value ?? 0, unit }, { language }).replace(
/[\d,.]*/g,
''
)}
</span>
<div>
<InputSuggestions
suggestions={suggestions}
onFirstClick={value => {
onChange(value)
}}
onSecondClick={() => onSubmit?.('suggestion')}
unit={unit}
/>
<NumberFormat
autoFocus={autoFocus}
className="suffixed"
id={'step-' + dottedName}
placeholder={defaultValue?.nodeValue ?? defaultValue}
thousandSeparator={thousandSeparator}
decimalSeparator={decimalSeparator}
allowEmptyFormatting={true}
style={{ border: `1px solid ${colors.textColorOnWhite}` }}
onValueChange={({ floatValue }) => {
debouncedOnChange(floatValue)
}}
value={value}
autoComplete="off"
/>
<span className="suffix">
{formatValue({ nodeValue: value ?? 0, unit }, { language }).replace(
/[\d,.]*/g,
''
)}
</span>
</div>
</div>
)
}

View File

@ -12,11 +12,6 @@ import { useTranslation } from 'react-i18next'
import { DottedName } from 'Rules'
import DateInput from './DateInput'
export const binaryOptionChoices = [
{ value: 'non', label: 'Non' },
{ value: 'oui', label: 'Oui' }
]
type Value = string | number | object | boolean | null
export type RuleInputProps = {
rules: ParsedRules
@ -27,7 +22,7 @@ export type RuleInputProps = {
autoFocus?: boolean
value?: Value
className?: string
onSubmit?: (value: Value) => void
onSubmit?: (source: string) => void
}
// This function takes the unknown rule and finds which React component should
@ -55,7 +50,6 @@ export default function RuleInput({
dottedName,
value,
onChange,
onSubmit,
autoFocus,
className,
title: rule.title,
@ -67,12 +61,13 @@ export default function RuleInput({
return (
<Question
{...commonProps}
onSubmit={onSubmit}
choices={buildVariantTree(rules, dottedName)}
/>
)
}
if (rule.API && rule.API === 'géo')
return <SelectGéo {...{ ...commonProps }} />
return <SelectGéo {...{ ...commonProps }} onSubmit={onSubmit} />
if (rule.API) throw new Error("Le seul API implémenté est l'API géo")
if (rule.dottedName == 'contrat salarié . ATMP . taux collectif ATMP')
@ -83,7 +78,7 @@ export default function RuleInput({
<DateInput
value={commonProps.value}
onChange={commonProps.onChange}
onSubmit={commonProps.onSubmit}
onSubmit={onSubmit}
suggestions={commonProps.suggestions}
/>
)
@ -98,7 +93,14 @@ export default function RuleInput({
}
/>
) : (
<Question {...commonProps} choices={binaryOptionChoices} />
<Question
{...commonProps}
choices={[
{ value: 'non', label: 'Non' },
{ value: 'oui', label: 'Oui' }
]}
onSubmit={onSubmit}
/>
)
}
@ -125,7 +127,7 @@ export default function RuleInput({
return <PercentageField {...commonProps} debounce={600} />
}
return <Input {...commonProps} unit={unit} />
return <Input {...commonProps} unit={unit} onSubmit={onSubmit} />
}
const getVariant = (rule: ParsedRule) =>

View File

@ -71,7 +71,7 @@
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
align-items: flex-end;
align-items: baseline;
}
.step .input > :first-child {
text-align: right;