Ajout du select et du radio inline

pull/2077/head
Jérémy Rialland 2022-03-09 11:56:05 +01:00 committed by Johan Girod
parent d285b56ccf
commit e0d291dbf9
4 changed files with 146 additions and 18 deletions

View File

@ -33,6 +33,7 @@ lieu d'exercice:
possibilités:
- métropole
- outre-mer
type: radio inline
lieu d'exercice . métropole:
titre: En métropole
@ -60,6 +61,7 @@ début d'activité:
- octobre 2021
- novembre 2021
- décembre 2021
type: select
début d'activité . avant 2021:
début d'activité . janvier 2021:

View File

@ -4,6 +4,7 @@ import { Markdown } from '@/components/utils/markdown'
import ButtonHelp from '@/design-system/buttons/ButtonHelp'
import { Radio, RadioGroup, ToggleGroup } from '@/design-system/field'
import { RadioBlock } from '@/design-system/field/Radio/Radio'
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'
@ -188,7 +189,35 @@ export function OuiNonInput<Names extends string = DottedName>(
)
}
function useSelection<Names extends string = DottedName>({
const relativeDottedName = (childDottedName: string, rootDottedName: string) =>
childDottedName.replace(rootDottedName + ' . ', '')
export const SelectAnswerInput = <Names extends string = DottedName>({
choice,
...props
}: { choice: Choice } & InputProps<Names>) => {
const { handleChange, defaultValue, currentSelection } = useSelection(props)
return (
<Select
label={props.title}
onSelectionChange={handleChange}
defaultSelectedKey={defaultValue}
selectedKey={currentSelection}
>
{choice.children.map((node) => (
<Item
key={`'${relativeDottedName(node.dottedName, props.dottedName)}'`}
textValue={node.title}
>
{node.title}
</Item>
))}
</Select>
)
}
export function useSelection<Names extends string = DottedName>({
value,
onChange,
missing,

View File

@ -13,7 +13,12 @@ import Engine, {
RuleNode,
} from 'publicodes'
import React, { useContext } from 'react'
import { Choice, MultipleAnswerInput, OuiNonInput } from './ChoicesInput'
import {
Choice,
MultipleAnswerInput,
OuiNonInput,
SelectAnswerInput,
} from './ChoicesInput'
import DateInput from './DateInput'
import ParagrapheInput from './ParagrapheInput'
import SelectPaysDétachement from './select/SelectPaysDétachement'
@ -103,6 +108,14 @@ export default function RuleInput<
...props,
}
if (rule.rawNode.type === 'select') {
return (
<SelectAnswerInput
{...commonProps}
choice={buildVariantTree(engine, dottedName)}
/>
)
}
if (
isMetadata<RuleWithMetadata<Metadata>>(rule.rawNode) &&
rule.rawNode.metadata.component === 'ToggleRadioBlock'
@ -115,6 +128,16 @@ export default function RuleInput<
/>
)
}
if (rule.rawNode.type === 'radio inline') {
return (
<MultipleAnswerInput
{...commonProps}
choice={buildVariantTree(engine, dottedName)}
type="toggle"
inline
/>
)
}
if (getVariant(engine.getRule(dottedName))) {
return (
<MultipleAnswerInput

View File

@ -5,13 +5,36 @@ import RuleInput from '@/components/conversation/RuleInput'
import { useState, useCallback } from 'react'
import Value from '@/components/EngineValue'
import { H3 } from '@/design-system/typography/heading'
import { Trans } from 'react-i18next'
import { Grid } from '@mui/material'
import { Button } from '@/design-system/buttons'
import { Spacing } from '@/design-system/layout'
import { useLocation } from 'react-router'
const covidEngine = new Engine(exonerationCovid)
export default function ExonérationCovid() {
const rootDottedNames = [
'secteur',
"début d'activité",
"lieu d'exercice",
] as const
const location = useLocation()
const searchParams = new URLSearchParams(location.search)
const params = Object.fromEntries(searchParams.entries()) as {
[key in typeof rootDottedNames[number]]?: string
}
const [situation, setSituation] = useState<
Partial<Record<DottedNames, PublicodesExpression | undefined>>
>({})
>(() => {
const defaultSituation = { ...params }
covidEngine.setSituation(defaultSituation)
return defaultSituation
})
const updateSituation = useCallback(
(name: DottedNames, value: PublicodesExpression | undefined) => {
const newSituation = { ...situation, [name]: value }
@ -21,26 +44,77 @@ export default function ExonérationCovid() {
[situation]
)
const step2 = rootDottedNames.every((names) => params[names])
return (
<>
<EngineProvider value={covidEngine}>
<H3>{covidEngine.getRule('secteur').rawNode.question}</H3>
<RuleInput
dottedName={'secteur'}
onChange={(value) => updateSituation('secteur', value)}
/>
{step2 ? (
<>Page 2</>
) : (
<>
<H3>{covidEngine.getRule('secteur').rawNode.question}</H3>
<RuleInput
dottedName={'secteur'}
onChange={(value) => updateSituation('secteur', value)}
/>
<H3>{covidEngine.getRule("début d'activité").rawNode.question}</H3>
<RuleInput
dottedName="début d'activité"
onChange={(value) => updateSituation("début d'activité", value)}
/>
<H3>{covidEngine.getRule("début d'activité").rawNode.question}</H3>
<Spacing sm />
<H3>{covidEngine.getRule("lieu d'exercice").rawNode.question}</H3>
<RuleInput
dottedName="lieu d'exercice"
onChange={(value) => updateSituation("début d'activité", value)}
/>
<Grid item xs={12} sm={6}>
<RuleInput
dottedName="début d'activité"
onChange={(value) => updateSituation("début d'activité", value)}
/>
</Grid>
<H3>{covidEngine.getRule("lieu d'exercice").rawNode.question}</H3>
<RuleInput
dottedName="lieu d'exercice"
onChange={(value) => updateSituation("lieu d'exercice", value)}
/>
</>
)}
<Spacing lg />
<Grid container justifyContent="end">
<Grid item xs={6} sm="auto">
{step2 ? (
<Button
size="XS"
to={{
pathname: location.pathname,
search: '',
}}
>
{' '}
<Trans>Précédent</Trans>
</Button>
) : (
<Button
size="XS"
light
isDisabled={!rootDottedNames.every((names) => situation[names])}
to={() => {
rootDottedNames.forEach((key) =>
searchParams.append(key, situation[key]?.toString() ?? '')
)
return {
pathname: location.pathname,
search: searchParams.toString(),
}
}}
>
<Trans>Suivant</Trans>
</Button>
)}
</Grid>
</Grid>
<Spacing lg />
<hr />