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 composantspull/525/head
parent
d560cd5944
commit
ff8a5b165c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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é
|
||||
|
|
|
@ -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 ?
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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é" />
|
||||
|
|
Loading…
Reference in New Issue