Possibilité de définir des groupes d'objectifs nommés dans sim.yaml

Pour par exemple séparer l'entreprise du dirigeant
Attention, le composant TargetSelection est beaucoup trop complexe, il
mérite d'être séparé en plein de plus petits composants
pull/525/head
Mael 2019-04-26 16:09:22 +02:00 committed by Johan Girod
parent d560cd5944
commit ff8a5b165c
No known key found for this signature in database
GPG Key ID: 9E27B57DA2E8AE12
6 changed files with 122 additions and 77 deletions

View File

@ -5,45 +5,45 @@
font-size: 180%;
}
#targetSelection #targets {
#targetSelection .targets {
list-style: none;
padding: 0;
margin: 0;
}
#targetSelection #targets > li:last-child {
#targetSelection .targets > li:last-child {
margin-bottom: -1rem;
}
#targetSelection #targets > li:first-child {
#targetSelection .targets > li:first-child {
border-top: none;
margin-top: -1rem;
}
#targetSelection #targets > li.small-target * {
#targetSelection .targets > li.small-target * {
font-size: 1rem;
font-weight: normal;
}
#targetSelection #targets > li.small-target {
#targetSelection .targets > li.small-target {
border-top: none;
}
#targetSelection #targets > li.small-target .targetInput {
#targetSelection .targets > li.small-target .targetInput {
border-width: 1px;
padding-top: 0;
padding-bottom: 0;
}
#targetSelection #targets > li {
#targetSelection .targets > li {
border-top: 1px solid rgba(255, 255, 255, 0.5);
padding: 0.6rem 1rem;
margin-left: -1rem;
margin-right: -1rem;
}
#targetSelection #targets > li .main {
#targetSelection .targets > li .main {
display: flex;
align-items: center;
justify-content: space-between;
}
#targetSelection #targets > li p {
#targetSelection .targets > li p {
margin: 0.2em 0 0;
font-style: italic;
opacity: 0.8;
@ -54,7 +54,7 @@
display: flex;
align-items: center;
}
#targetSelection #targets > li.small-target .header p {
#targetSelection .targets > li.small-target .header p {
display: none;
}

View File

@ -7,8 +7,9 @@ import withColours from 'Components/utils/withColours'
import withLanguage from 'Components/utils/withLanguage'
import withSitePaths from 'Components/utils/withSitePaths'
import { encodeRuleName } from 'Engine/rules'
import { compose, isEmpty, isNil, propEq } from 'ramda'
import { compose, isEmpty, isNil, propEq, toPairs } from 'ramda'
import React, { Component, PureComponent } from 'react'
import emoji from 'react-easy-emoji'
import { withTranslation } from 'react-i18next'
import { connect } from 'react-redux'
import { Link } from 'react-router-dom'
@ -86,9 +87,14 @@ export default compose(
firstStepCompleted,
conversationStarted,
analysis,
explanation
explanation,
activeInput,
setActiveInput,
setFormValue,
objectifs
} = this.props,
inversionFail = analysis.cache.inversionFail
inversionFail = analysis.cache.inversionFail,
targets = analysis?.targets || []
return (
<div id="targetSelection">
@ -99,64 +105,86 @@ export default compose(
/>
)}
<PeriodSwitch />
<section
className="ui__ plain card"
style={{
marginTop: '.6em',
color: colours.textColour
}}>
{this.renderOutputList()}
</section>
{(Array.isArray(objectifs)
? [[null, objectifs]]
: toPairs(objectifs)
).map(([groupName, groupTargets]) => (
<>
{groupName && <h2>{emoji(groupName)}</h2>}
<section
className="ui__ plain card"
style={{
marginTop: '.6em',
color: colours.textColour,
background: `linear-gradient(
60deg,
${colours.darkColour} 0%,
${colours.colour} 100%
)`
}}>
<Targets
{...{
conversationStarted,
activeInput,
setActiveInput,
setFormValue,
inversionFail,
targets: targets.filter(({ dottedName }) =>
groupTargets.includes(dottedName)
),
initialRender: this.state.initialRender
}}
/>
</section>
</>
))}
<QuickLinks show={firstStepCompleted && !conversationStarted} />
{firstStepCompleted && explanation}
</div>
)
}
renderOutputList() {
let {
conversationStarted,
activeInput,
setActiveInput,
setFormValue,
analysis
} = this.props,
targets = analysis ? analysis.targets : [],
inversionFail = analysis.cache.inversionFail
return (
<div>
<ul id="targets">
{targets
.map(target => target.explanation || target)
.filter(target => {
return (
target.isApplicable !== false &&
(target.question || target.nodeValue)
)
})
.map(target => (
<Target
key={target.dottedName}
initialRender={this.state.initialRender}
{...{
conversationStarted,
target,
setFormValue,
activeInput,
setActiveInput,
targets,
inversionFail
}}
/>
))}
</ul>
</div>
)
}
}
)
let Targets = ({
conversationStarted,
activeInput,
setActiveInput,
setFormValue,
inversionFail,
targets,
initialRender
}) => (
<div>
<ul className="targets">
{targets
.map(target => target.explanation || target)
.filter(target => {
return (
target.isApplicable !== false &&
(target.question || target.nodeValue)
)
})
.map(target => (
<Target
key={target.dottedName}
initialRender={initialRender}
{...{
conversationStarted,
target,
setFormValue,
activeInput,
setActiveInput,
targets,
inversionFail
}}
/>
))}
</ul>
</div>
)
const Target = ({
target,
activeInput,

View File

@ -1,13 +1,15 @@
objectifs:
- entreprise . chiffre d'affaires
- entreprise . charges
- entreprise . bénéfice
- entreprise . part du dirigeant
- entreprise . rémunération totale du dirigeant
- contrat salarié . cotisations
- contrat salarié . réduction ACRE
- impôt . neutre
- contrat salarié . salaire . net après impôt
🏢 Votre entreprise:
- entreprise . chiffre d'affaires
- entreprise . charges
- entreprise . rémunération du dirigeant
- entreprise . bénéfice
- entreprise . résultat net
👩‍💼 Votre revenu:
- entreprise . rémunération totale du dirigeant
- contrat salarié . cotisations
- impôt . neutre
- contrat salarié . salaire . net après impôt
questions à l'affiche:
Année d'activité: entreprise . année d'activité

View File

@ -2728,11 +2728,11 @@
période: flexible
formule:
somme:
- rémunération totale du dirigeant / part du dirigeant
- rémunération totale du dirigeant / rémunération du dirigeant
- charges
- espace: entreprise
nom: part du dirigeant
nom: rémunération du dirigeant
description: |
C'est la part du chiffre d'affaires après charges qui est allouée à la rémunération du dirigeant. Plus cette part est élevée, plus la rémunération du dirigeant augmente, et plus le bénéfice de l'entreprise diminue !
question: Quelle part du chiffre d'affaires après charge est allouée à la rémunération du dirigeant ?

View File

@ -22,8 +22,12 @@ import {
intersection,
isEmpty,
isNil,
map,
mergeDeepWith,
pick
pick,
pipe,
toPairs,
unnest
} from 'ramda'
import { getFormValues } from 'redux-form'
import { createSelector, createSelectorCreator, defaultMemoize } from 'reselect'
@ -54,7 +58,18 @@ export let ruleDefaultsSelector = createSelector(
rules => collectDefaults(rules)
)
export let targetNamesSelector = state => state.simulation?.config.objectifs
export let targetNamesSelector = state => {
let objectifs = state.simulation?.config.objectifs
if (!objectifs) return null
if (Array.isArray(objectifs)) return objectifs
// the objectives are organized in groups
else
return pipe(
toPairs,
map(([, groupObjectives]) => groupObjectives),
unnest
)(objectifs)
}
export let situationSelector = createDeepEqualSelector(
getFormValues('conversation'),

View File

@ -30,7 +30,7 @@ const AssimiléSalarié = ({ t }) => (
</Helmet>
<h1>
<T k="simulateurs.assimilé-salarié.titre">
Simulateur de revenus pour assimilé salarié
Simulateur de revenus assimilé salarié
</T>
</h1>
<Warning simulateur="assimilé-salarié" />