Refacto de `DetailsRowCards` (#2479)

* feat: refacto

* fix: Sorting issue + typage

* fix

* fix: Reset ACRE AE value

* feat: Renommage pour compréhension
pull/2480/head
Benjamin Arias 2023-01-26 20:55:23 +01:00 committed by GitHub
parent e5ee859303
commit 5449a64d34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 125 additions and 444 deletions

View File

@ -93,7 +93,9 @@ const AllerPlusLoinRevenus = ({
answerQuestion(DOTTEDNAME_ACRE, acreValuePassed ? 'oui' : 'non')
)
if (AEAcreValue !== null) {
if (!acreValuePassed) {
setIsAutoEntrepreneurACREEnabled(false)
} else if (AEAcreValue !== null) {
setIsAutoEntrepreneurACREEnabled(AEAcreValue)
}
}}

View File

@ -1,4 +1,4 @@
import Engine, { formatValue } from 'publicodes'
import Engine from 'publicodes'
import { ReactNode } from 'react'
import styled from 'styled-components'
@ -11,9 +11,16 @@ import RuleLink from '@/components/RuleLink'
import { HelpIcon } from '@/design-system/icons'
import { Grid } from '@/design-system/layout'
import { BestOption, getBestOption } from '../utils'
import { OptionType, getBestOption } from '../utils'
import StatusCard from './StatusCard'
const getStatusLabelsArray = (statusArray: OptionType[]) =>
statusArray.map((statusOption) => statusOption.type)
const getGridSizes = (statusArray: OptionType[]) => {
return { sizeXs: 12, sizeLg: 4 * statusArray.length }
}
const DetailsRowCards = ({
engines: [assimiléEngine, autoEntrepreneurEngine, indépendantEngine],
dottedName,
@ -40,469 +47,136 @@ const DetailsRowCards = ({
valeur: dottedName,
...(unit && { unité: unit }),
})
const assimiléValue = formatValue(assimiléEvaluation, {
precision: 0,
}) as string
const indépendantEvaluation = indépendantEngine.evaluate({
valeur: dottedName,
...(unit && { unité: unit }),
})
const indépendantValue = formatValue(indépendantEvaluation, {
precision: 0,
}) as string
const autoEntrepreneurEvaluation = autoEntrepreneurEngine.evaluate({
valeur: dottedName,
...(unit && { unité: unit }),
})
const autoEntrepreneurValue = formatValue(autoEntrepreneurEvaluation, {
precision: 0,
}) as string
const options: BestOption[] = [
const options: OptionType[] = [
{
type: 'sasu',
value: assimiléEvaluation.nodeValue,
value: Math.round(assimiléEvaluation.nodeValue as number),
engine: assimiléEngine,
documentationPath: '/simulateurs/comparaison-régimes-sociaux/SASU',
},
{
type: 'ei',
value: indépendantEvaluation.nodeValue,
value: Math.round(indépendantEvaluation.nodeValue as number),
engine: indépendantEngine,
documentationPath: '/simulateurs/comparaison-régimes-sociaux/EI',
},
{
type: 'ae',
value: autoEntrepreneurEvaluation.nodeValue,
value: Math.round(autoEntrepreneurEvaluation.nodeValue as number),
engine: autoEntrepreneurEngine,
documentationPath:
'/simulateurs/comparaison-régimes-sociaux/auto-entrepreneur',
},
]
const bestOptionValue = bestOption ?? getBestOption(options)
if (
assimiléValue === indépendantValue &&
indépendantValue === autoEntrepreneurValue
) {
return (
<Grid container spacing={4}>
<Grid item xs={12} lg={12}>
<StatusCard
status={['sasu', 'ei', 'ae']}
footerContent={footers?.sasu}
>
<WhenNotApplicable dottedName={dottedName} engine={assimiléEngine}>
<DisabledLabel>Ne s'applique pas</DisabledLabel>
</WhenNotApplicable>
<WhenApplicable dottedName={dottedName} engine={assimiléEngine}>
<StyledDiv>
<span>
<Value
linkToRule={false}
expression={dottedName}
engine={assimiléEngine}
precision={0}
unit={unit}
/>
{label && ' '}
{label && label}
</span>
<StyledRuleLink
documentationPath="/simulateurs/comparaison-régimes-sociaux/SASU"
dottedName={dottedName}
engine={assimiléEngine}
>
<HelpIcon />
</StyledRuleLink>
{warnings?.sasu && warnings?.sasu}
</StyledDiv>
{evolutionDottedName && (
<Precisions>
<Value
linkToRule={false}
expression={evolutionDottedName}
engine={assimiléEngine}
precision={0}
unit={unit}
/>{' '}
{evolutionLabel}
</Precisions>
)}
{!evolutionDottedName && evolutionLabel && (
<Precisions>{evolutionLabel}</Precisions>
)}
</WhenApplicable>
</StatusCard>
</Grid>
</Grid>
)
}
const sortedStatus = [...options]
.reduce((acc: OptionType[][], option: OptionType) => {
const newAcc = [...acc]
const sameValues = options.filter(
(optionFiltered) => optionFiltered.value === option.value
)
// Avoid duplicates
if (
!newAcc.find((arrayOfStatus) =>
arrayOfStatus.some(
(statusObject: OptionType) => statusObject.value === option.value
)
)
) {
return [...newAcc, sameValues]
}
if (assimiléValue === indépendantValue) {
return (
<Grid container spacing={4}>
<Grid item xs={12} lg={8}>
<StatusCard
status={['sasu', 'ei']}
isBestOption={bestOptionValue === 'sasu'}
footerContent={footers?.sasu}
>
<WhenNotApplicable dottedName={dottedName} engine={assimiléEngine}>
<DisabledLabel>Ne s'applique pas</DisabledLabel>
</WhenNotApplicable>
<WhenApplicable dottedName={dottedName} engine={assimiléEngine}>
<span>
<Value
linkToRule={false}
expression={dottedName}
engine={assimiléEngine}
precision={0}
unit={unit}
/>
{label && ' '}
{label && label}
</span>
<StyledRuleLink
documentationPath="/simulateurs/comparaison-régimes-sociaux/SASU"
dottedName={dottedName}
engine={assimiléEngine}
>
<HelpIcon />
</StyledRuleLink>
{warnings?.sasu || warnings?.ei
? warnings?.sasu
? warnings?.sasu
: warnings?.ei
: ''}
{evolutionDottedName && (
<Precisions>
<Value
linkToRule={false}
expression={evolutionDottedName}
engine={assimiléEngine}
precision={0}
unit={unit}
/>{' '}
{evolutionLabel}
</Precisions>
)}
{!evolutionDottedName && evolutionLabel && (
<Precisions>{evolutionLabel}</Precisions>
)}
</WhenApplicable>
</StatusCard>
</Grid>
<Grid item xs={12} lg={4}>
<StatusCard
status={['ae']}
footerContent={footers?.ei}
isBestOption={bestOptionValue === 'ae'}
>
<WhenNotApplicable
dottedName={dottedName}
engine={autoEntrepreneurEngine}
>
<DisabledLabel>Ne s'applique pas</DisabledLabel>
</WhenNotApplicable>
<WhenApplicable
dottedName={dottedName}
engine={autoEntrepreneurEngine}
>
<span>
<Value
linkToRule={false}
expression={dottedName}
engine={autoEntrepreneurEngine}
precision={0}
unit={unit}
/>
{label && ' '}
{label && label}
</span>
<StyledRuleLink
documentationPath="/simulateurs/comparaison-régimes-sociaux/auto-entrepreneur"
dottedName={dottedName}
engine={autoEntrepreneurEngine}
>
<HelpIcon />
</StyledRuleLink>
{warnings?.ae && warnings?.ae}
{evolutionDottedName && (
<Precisions>
<Value
linkToRule={false}
expression={evolutionDottedName}
engine={autoEntrepreneurEngine}
precision={0}
unit={unit}
/>{' '}
{evolutionLabel}
</Precisions>
)}
{!evolutionDottedName && evolutionLabel && (
<Precisions>{evolutionLabel}</Precisions>
)}
</WhenApplicable>
</StatusCard>
</Grid>
</Grid>
)
}
if (indépendantValue === autoEntrepreneurValue) {
return (
<Grid container spacing={4}>
<Grid item xs={12} lg={4}>
<StatusCard
status={['sasu']}
footerContent={footers?.sasu}
isBestOption={bestOptionValue === 'sasu'}
>
<WhenNotApplicable dottedName={dottedName} engine={assimiléEngine}>
<DisabledLabel>Ne s'applique pas</DisabledLabel>
</WhenNotApplicable>
<WhenApplicable dottedName={dottedName} engine={assimiléEngine}>
<span>
<Value
linkToRule={false}
expression={dottedName}
engine={assimiléEngine}
precision={0}
unit={unit}
/>
{label && ' '}
{label && label}
</span>
<StyledRuleLink
dottedName={dottedName}
engine={assimiléEngine}
documentationPath="/simulateurs/comparaison-régimes-sociaux/SASU"
>
<HelpIcon />
</StyledRuleLink>
{warnings?.sasu && warnings?.sasu}
{evolutionDottedName && (
<Precisions>
<Value
linkToRule={false}
expression={evolutionDottedName}
engine={assimiléEngine}
precision={0}
unit={unit}
/>{' '}
{evolutionLabel}
</Precisions>
)}
{!evolutionDottedName && evolutionLabel && (
<Precisions>{evolutionLabel}</Precisions>
)}
</WhenApplicable>
</StatusCard>
</Grid>
<Grid item xs={12} lg={8}>
<StatusCard
status={['ei', 'ae']}
footerContent={footers?.ei}
isBestOption={bestOptionValue === 'ei'}
>
<WhenNotApplicable
dottedName={dottedName}
engine={indépendantEngine}
>
<DisabledLabel>Ne s'applique pas</DisabledLabel>
</WhenNotApplicable>
<WhenApplicable dottedName={dottedName} engine={indépendantEngine}>
<span>
<Value
linkToRule={false}
expression={dottedName}
engine={indépendantEngine}
precision={0}
unit={unit}
/>
{label && ' '}
{label && label}
</span>
<StyledRuleLink
dottedName={dottedName}
engine={indépendantEngine}
documentationPath="/simulateurs/comparaison-régimes-sociaux/EI"
>
<HelpIcon />
</StyledRuleLink>
{warnings?.ei || warnings?.ae
? warnings?.ei
? warnings?.ei
: warnings?.ae
: ''}
{evolutionDottedName && (
<Precisions>
<Value
linkToRule={false}
expression={evolutionDottedName}
engine={indépendantEngine}
precision={0}
unit={unit}
/>{' '}
{evolutionLabel}
</Precisions>
)}
{!evolutionDottedName && evolutionLabel && (
<Precisions>{evolutionLabel}</Precisions>
)}
</WhenApplicable>
</StatusCard>
</Grid>
</Grid>
)
}
return newAcc
}, [] as OptionType[][])
.filter((arrayOfStatus: OptionType[]) => arrayOfStatus.length > 0)
return (
<Grid container spacing={4}>
<Grid item xs={12} lg={4}>
<StatusCard
status={['sasu']}
footerContent={footers?.sasu}
isBestOption={bestOptionValue === 'sasu'}
>
<WhenNotApplicable dottedName={dottedName} engine={assimiléEngine}>
<DisabledLabel>Ne s'applique pas</DisabledLabel>
</WhenNotApplicable>
<WhenApplicable dottedName={dottedName} engine={assimiléEngine}>
<span>
<Value
linkToRule={false}
expression={dottedName}
engine={assimiléEngine}
precision={0}
unit={unit}
/>
{label && ' '}
{label && label}
</span>
<StyledRuleLink
dottedName={dottedName}
engine={assimiléEngine}
documentationPath="/simulateurs/comparaison-régimes-sociaux/SASU"
>
<HelpIcon />
</StyledRuleLink>
{warnings?.sasu && warnings?.sasu}
{evolutionDottedName && (
<Precisions>
<Value
linkToRule={false}
expression={evolutionDottedName}
engine={assimiléEngine}
precision={0}
unit={unit}
/>{' '}
{evolutionLabel}
</Precisions>
)}
{!evolutionDottedName && evolutionLabel && (
<Precisions>{evolutionLabel}</Precisions>
)}
</WhenApplicable>
</StatusCard>
</Grid>
<Grid item xs={12} lg={4}>
<StatusCard
status={['ei']}
footerContent={footers?.ei}
isBestOption={bestOptionValue === 'ei'}
>
<WhenNotApplicable dottedName={dottedName} engine={indépendantEngine}>
<DisabledLabel>Ne s'applique pas</DisabledLabel>
</WhenNotApplicable>
<WhenApplicable dottedName={dottedName} engine={indépendantEngine}>
<span>
<Value
linkToRule={false}
expression={dottedName}
engine={indépendantEngine}
precision={0}
unit={unit}
/>
{label && ' '}
{label && label}
</span>
<StyledRuleLink
dottedName={dottedName}
engine={indépendantEngine}
documentationPath="/simulateurs/comparaison-régimes-sociaux/EI"
>
<HelpIcon />
</StyledRuleLink>
{warnings?.ei && warnings?.ei}
{evolutionDottedName && (
<Precisions>
<Value
linkToRule={false}
expression={evolutionDottedName}
engine={indépendantEngine}
precision={0}
unit={unit}
/>{' '}
{evolutionLabel}
</Precisions>
)}
{!evolutionDottedName && evolutionLabel && (
<Precisions>{evolutionLabel}</Precisions>
)}
</WhenApplicable>
</StatusCard>
</Grid>
<Grid item xs={12} lg={4}>
<StatusCard
status={['ae']}
footerContent={footers?.ae}
isBestOption={bestOptionValue === 'ae'}
>
<WhenNotApplicable
dottedName={dottedName}
engine={autoEntrepreneurEngine}
{sortedStatus.map((statusArray: OptionType[]) => {
const statusObject: OptionType = statusArray[0]
const { sizeXs, sizeLg } = getGridSizes(statusArray)
return (
<Grid
key={`${dottedName}-${statusObject.type}`}
item
xs={sizeXs}
lg={sizeLg}
>
<DisabledLabel>Ne s'applique pas</DisabledLabel>
</WhenNotApplicable>
<WhenApplicable
dottedName={dottedName}
engine={autoEntrepreneurEngine}
>
<span>
<Value
linkToRule={false}
expression={dottedName}
engine={autoEntrepreneurEngine}
precision={0}
unit={unit}
/>
{label && ' '}
{label && label}
</span>
<StyledRuleLink
dottedName={dottedName}
engine={autoEntrepreneurEngine}
documentationPath="/simulateurs/comparaison-régimes-sociaux/auto-entrepreneur"
<StatusCard
status={getStatusLabelsArray(statusArray)}
footerContent={footers?.[statusObject.type]}
isBestOption={
statusArray.length !== 3 &&
bestOptionValue === statusObject.type
}
>
<HelpIcon />
</StyledRuleLink>
{warnings?.ae && warnings?.ae}
{evolutionDottedName && (
<Precisions>
<Value
linkToRule={false}
expression={evolutionDottedName}
engine={autoEntrepreneurEngine}
precision={0}
unit={unit}
/>{' '}
{evolutionLabel}
</Precisions>
)}
{!evolutionDottedName && evolutionLabel && (
<Precisions>{evolutionLabel}</Precisions>
)}
</WhenApplicable>
</StatusCard>
</Grid>
<WhenNotApplicable
dottedName={dottedName}
engine={statusObject.engine}
>
<DisabledLabel>Ne s'applique pas</DisabledLabel>
</WhenNotApplicable>
<WhenApplicable
dottedName={dottedName}
engine={statusObject.engine}
>
<StyledDiv>
<span>
<Value
linkToRule={false}
expression={dottedName}
engine={statusObject.engine}
precision={0}
unit={unit}
/>
{label && ' '}
{label && label}
</span>
<StyledRuleLink
documentationPath={statusObject.documentationPath}
dottedName={dottedName}
engine={statusObject.engine}
>
<HelpIcon />
</StyledRuleLink>
{warnings?.[statusObject.type] &&
warnings?.[statusObject.type]}
</StyledDiv>
{evolutionDottedName && (
<Precisions>
<Value
linkToRule={false}
expression={evolutionDottedName}
engine={statusObject.engine}
precision={0}
unit={unit}
/>{' '}
{evolutionLabel}
</Precisions>
)}
{!evolutionDottedName && evolutionLabel && (
<Precisions>{evolutionLabel}</Precisions>
)}
</WhenApplicable>
</StatusCard>
</Grid>
)
})}
</Grid>
)
}

View File

@ -12,7 +12,7 @@ import { H2 } from '@/design-system/typography/heading'
import { StyledLink } from '@/design-system/typography/link'
import { Body } from '@/design-system/typography/paragraphs'
import { BestOption, getBestOption } from '../utils'
import { OptionType, getBestOption } from '../utils'
import AllerPlusLoinRevenus from './AllerPlusLoinRevenus'
import StatusCard from './StatusCard'
import WarningTooltip from './WarningTooltip'
@ -40,7 +40,7 @@ const RevenuAprèsImpot = ({
unité: '€/mois',
}).nodeValue
const options: BestOption[] = [
const options: OptionType[] = [
{
type: 'sasu',
value: assimiléValue,

View File

@ -1,16 +1,22 @@
import Engine from 'publicodes'
import { DottedName } from '@/../../modele-social'
export type ValueType =
| string
| number
| boolean
| null
| Record<string, unknown>
export type BestOption = {
export type OptionType = {
type: 'sasu' | 'ei' | 'ae'
value?: ValueType
engine?: Engine<DottedName>
documentationPath?: string
}
export const getBestOption = (options: BestOption[]) => {
const sortedOptions = options.sort(
(option1: BestOption, option2: BestOption) => {
export const getBestOption = (options: OptionType[]) => {
const sortedOptions = [...options].sort(
(option1: OptionType, option2: OptionType) => {
if (option1.value === null || option1.value === undefined) {
return 1
}
@ -19,7 +25,6 @@ export const getBestOption = (options: BestOption[]) => {
}
if (option1.value === option2.value) return 0
// console.log(option1.value, option2.value, option1.value > option2.value)
return option1.value > option2.value ? -1 : 1
}