refactor: réduction générale mois par mois

pull/3233/head
Alice Dahan 2024-11-18 14:09:37 +01:00 committed by liliced
parent 2c0ed9b5d0
commit e070a1c506
2 changed files with 186 additions and 155 deletions

View File

@ -1,39 +1,22 @@
import { formatValue, PublicodesExpression } from 'publicodes'
import { useTranslation } from 'react-i18next'
import { styled } from 'styled-components'
import { ExplicableRule } from '@/components/conversation/Explicable'
import NumberInput from '@/components/conversation/NumberInput'
import { Condition } from '@/components/EngineValue/Condition'
import { useEngine } from '@/components/utils/EngineContext'
import { SearchIcon, WarningIcon } from '@/design-system/icons'
import { Tooltip } from '@/design-system/tooltip'
import Répartition from './components/Répartition'
import RéductionGénéraleMoisParMoisRow from './components/RéductionGénéraleMoisParMoisRow'
import Warnings from './components/Warnings'
import WarningSalaireTrans from './components/WarningSalaireTrans'
import {
MonthState,
réductionGénéraleDottedName,
rémunérationBruteDottedName,
} from './utils'
import { MonthState, réductionGénéraleDottedName } from './utils'
type RémunérationBruteInput = {
unité: string
valeur: number
type Props = {
data: MonthState[]
onChange: (monthIndex: number, rémunérationBrute: number) => void
}
export default function RéductionGénéraleMoisParMois({
data,
onChange,
}: {
data: MonthState[]
onChange: (monthIndex: number, rémunérationBrute: number) => void
}) {
const engine = useEngine()
const { t, i18n } = useTranslation()
const language = i18n.language
const displayedUnit = '€'
}: Props) {
const { t } = useTranslation()
const months = [
t('janvier'),
@ -50,31 +33,6 @@ export default function RéductionGénéraleMoisParMois({
t('décembre'),
]
const onRémunérationChange = (
monthIndex: number,
rémunérationBrute: RémunérationBruteInput
) => {
onChange(monthIndex, rémunérationBrute.valeur)
}
// TODO: enlever les 4 premières props après résolution de #3123
const ruleInputProps = {
dottedName: rémunérationBruteDottedName,
suggestions: {},
description: undefined,
question: undefined,
engine,
'aria-labelledby': 'simu-update-explaining',
formatOptions: {
maximumFractionDigits: 0,
},
displayedUnit,
unit: {
numerators: ['€'],
denominators: [],
},
}
return (
<>
<StyledTable style={{ width: '100%' }}>
@ -95,102 +53,17 @@ export default function RéductionGénéraleMoisParMois({
</thead>
<tbody>
{data.length > 0 &&
months.map((monthName, monthIndex) => {
const tooltip = (
<Répartition
contexte={{
[rémunérationBruteDottedName]:
data[monthIndex].rémunérationBrute,
[réductionGénéraleDottedName]:
data[monthIndex].réductionGénérale +
data[monthIndex].régularisation,
}}
/>
)
return (
<tr key={`month-${monthIndex}`}>
<th scope="row">{monthName}</th>
<td>
<NumberInput
{...ruleInputProps}
id={`${rémunérationBruteDottedName.replace(
/\s|\./g,
'_'
)}-${monthName}`}
aria-label={`${engine.getRule(rémunérationBruteDottedName)
?.title} (${monthName})`}
onChange={(rémunérationBrute?: PublicodesExpression) =>
onRémunérationChange(
monthIndex,
rémunérationBrute as RémunérationBruteInput
)
}
value={data[monthIndex].rémunérationBrute}
formatOptions={{
maximumFractionDigits: 2,
}}
/>
</td>
<td
id={`${réductionGénéraleDottedName.replace(
/\s|\./g,
'_'
)}-${monthName}`}
>
{data[monthIndex].réductionGénérale ? (
<Tooltip tooltip={tooltip}>
<StyledDiv>
{formatValue(
{
nodeValue: data[monthIndex].réductionGénérale,
},
{
displayedUnit,
language,
}
)}
<SearchIcon />
</StyledDiv>
</Tooltip>
) : (
<StyledDiv>
{formatValue(0, { displayedUnit, language })}
<Condition
expression={`${rémunérationBruteDottedName} > 1.6 * SMIC`}
contexte={{
[rémunérationBruteDottedName]:
data[monthIndex].rémunérationBrute,
}}
>
<Tooltip tooltip={<WarningSalaireTrans />}>
<span className="sr-only">{t('Attention')}</span>
<StyledWarningIcon aria-label={t('Attention')} />
</Tooltip>
</Condition>
</StyledDiv>
)}
</td>
<td
id={`${réductionGénéraleDottedName.replace(
/\s|\./g,
'_'
)}__régularisation-${monthName}`}
>
{formatValue(
{
nodeValue: data[monthIndex].régularisation,
},
{
displayedUnit,
language,
}
)}
</td>
</tr>
)
})}
months.map((monthName, monthIndex) => (
<RéductionGénéraleMoisParMoisRow
key={`month-${monthIndex}`}
monthName={monthName}
data={data[monthIndex]}
index={monthIndex}
onChange={(monthIndex: number, rémunérationBrute: number) => {
onChange(monthIndex, rémunérationBrute)
}}
/>
))}
</tbody>
</StyledTable>
@ -220,13 +93,3 @@ const StyledTable = styled.table`
font-weight: normal;
}
`
const StyledDiv = styled.div`
display: flex;
align-items: center;
gap: ${({ theme }) => theme.spacings.sm};
`
const StyledWarningIcon = styled(WarningIcon)`
margin-top: ${({ theme }) => theme.spacings.xxs};
`

View File

@ -0,0 +1,168 @@
import { formatValue, PublicodesExpression } from 'publicodes'
import { useTranslation } from 'react-i18next'
import { styled } from 'styled-components'
import NumberInput from '@/components/conversation/NumberInput'
import { Condition } from '@/components/EngineValue/Condition'
import { useEngine } from '@/components/utils/EngineContext'
import { SearchIcon, WarningIcon } from '@/design-system/icons'
import { Tooltip } from '@/design-system/tooltip'
import {
MonthState,
réductionGénéraleDottedName,
rémunérationBruteDottedName,
} from '../utils'
import Répartition from './Répartition'
import WarningSalaireTrans from './WarningSalaireTrans'
type Props = {
monthName: string
data: MonthState
index: number
onChange: (monthIndex: number, rémunérationBrute: number) => void
}
type RémunérationBruteInput = {
unité: string
valeur: number
}
export default function RéductionGénéraleMoisParMoisRow({
monthName,
data,
index,
onChange,
}: Props) {
const { t, i18n } = useTranslation()
const language = i18n.language
const displayedUnit = '€'
const engine = useEngine()
const onRémunérationChange = (
monthIndex: number,
rémunérationBrute: RémunérationBruteInput
) => {
onChange(monthIndex, rémunérationBrute.valeur)
}
// TODO: enlever les 4 premières props après résolution de #3123
const ruleInputProps = {
dottedName: rémunérationBruteDottedName,
suggestions: {},
description: undefined,
question: undefined,
engine,
'aria-labelledby': 'simu-update-explaining',
formatOptions: {
maximumFractionDigits: 0,
},
displayedUnit,
unit: {
numerators: ['€'],
denominators: [],
},
}
const tooltip = (
<Répartition
contexte={{
[rémunérationBruteDottedName]: data.rémunérationBrute,
[réductionGénéraleDottedName]:
data.réductionGénérale + data.régularisation,
}}
/>
)
return (
<tr>
<th scope="row">{monthName}</th>
<td>
<NumberInput
{...ruleInputProps}
id={`${rémunérationBruteDottedName.replace(
/\s|\./g,
'_'
)}-${monthName}`}
aria-label={`${engine.getRule(rémunérationBruteDottedName)
?.title} (${monthName})`}
onChange={(rémunérationBrute?: PublicodesExpression) =>
onRémunérationChange(
index,
rémunérationBrute as RémunérationBruteInput
)
}
value={data.rémunérationBrute}
formatOptions={{
maximumFractionDigits: 2,
}}
/>
</td>
<td
id={`${réductionGénéraleDottedName.replace(
/\s|\./g,
'_'
)}-${monthName}`}
>
{data.réductionGénérale ? (
<Tooltip tooltip={tooltip}>
<StyledDiv>
{formatValue(
{
nodeValue: data.réductionGénérale,
},
{
displayedUnit,
language,
}
)}
<SearchIcon />
</StyledDiv>
</Tooltip>
) : (
<StyledDiv>
{formatValue(0, { displayedUnit, language })}
<Condition
expression={`${rémunérationBruteDottedName} > 1.6 * SMIC`}
contexte={{
[rémunérationBruteDottedName]: data.rémunérationBrute,
}}
>
<Tooltip tooltip={<WarningSalaireTrans />}>
<span className="sr-only">{t('Attention')}</span>
<StyledWarningIcon aria-label={t('Attention')} />
</Tooltip>
</Condition>
</StyledDiv>
)}
</td>
<td
id={`${réductionGénéraleDottedName.replace(
/\s|\./g,
'_'
)}__régularisation-${monthName}`}
>
{formatValue(
{
nodeValue: data.régularisation,
},
{
displayedUnit,
language,
}
)}
</td>
</tr>
)
}
const StyledDiv = styled.div`
display: flex;
align-items: center;
gap: ${({ theme }) => theme.spacings.sm};
`
const StyledWarningIcon = styled(WarningIcon)`
margin-top: ${({ theme }) => theme.spacings.xxs};
`