mon-entreprise/source/components/TargetSelection.js

226 lines
5.9 KiB
JavaScript
Raw Normal View History

2017-11-15 09:49:55 +00:00
import React, { Component } from 'react'
import { Trans, translate } from 'react-i18next'
import formValueTypes from 'Components/conversation/formValueTypes'
import { rules, findRuleByName } from 'Engine/rules'
import { propEq, contains, without, curry, append, ifElse } from 'ramda'
import './TargetSelection.css'
import BlueButton from './BlueButton'
import { Field, reduxForm, formValueSelector, change } from 'redux-form'
2018-03-29 09:50:34 +00:00
import { Link } from 'react-router-dom'
import { connect } from 'react-redux'
import { RuleValue } from './rule/RuleValueVignette'
2018-03-14 17:20:09 +00:00
import classNames from 'classnames'
import { buildValidationFunction } from './conversation/FormDecorator'
2018-03-15 11:18:21 +00:00
export let salaries = ['salaire total', 'salaire de base', 'salaire net']
export let popularTargetNames = [...salaries, 'aides employeur']
@translate()
@reduxForm({
form: 'conversation'
})
@connect(
state => ({
getTargetValue: dottedName =>
formValueSelector('conversation')(state, dottedName),
targets: state.analysis ? state.analysis.targets : [],
flatRules: state.flatRules
conversationTargetNames: state.conversationTargetNames
}),
dispatch => ({
setFormValue: (field, name) =>
dispatch(change('conversation', field, name)),
setConversationTargets: (targetNames, fromScratch = false) =>
dispatch({ type: 'SET_CONVERSATION_TARGETS', targetNames, fromScratch })
})
)
2017-11-15 09:49:55 +00:00
export default class TargetSelection extends Component {
state = {
2018-03-12 09:38:29 +00:00
activeInput: null
}
2017-11-15 09:49:55 +00:00
render() {
let { targets, conversationTargetNames, colours } = this.props
2018-03-22 16:41:45 +00:00
this.firstEstimationComplete = this.state.activeInput && targets.length > 0
2017-11-15 09:49:55 +00:00
return (
2018-03-14 17:20:09 +00:00
<div id="targetSelection">
2018-03-12 09:38:29 +00:00
<section
2018-03-14 17:20:09 +00:00
id="targetsContainer"
2018-03-12 09:38:29 +00:00
style={{
background: colours.colour,
color: colours.textColour
2018-03-12 09:38:29 +00:00
}}
>
{this.renderOutputList()}
</section>
{!this.firstEstimationComplete && (
<h1>
Entrez un salaire mensuel{' '}
<i
style={{ color: colours.textColourOnWhite }}
className="fa fa-calendar"
aria-hidden="true"
/>
</h1>
)}
{this.firstEstimationComplete && (
<div id="action">
2018-03-22 16:41:45 +00:00
{conversationTargetNames ? (
!conversationTargetNames.length && (
2018-03-29 10:18:33 +00:00
<p>Cochez ce que vous voulez affiner</p>
)
2018-03-01 14:32:14 +00:00
) : (
2018-03-12 09:38:29 +00:00
<>
2018-03-29 10:18:33 +00:00
<p>
<b>Estimation approximative</b> <br /> pour une situation par
défaut (CDI non cadre).
2018-03-29 10:18:33 +00:00
</p>
<BlueButton
onClick={() => {
2018-03-22 16:41:45 +00:00
this.props.setConversationTargets([])
}}
>
2018-03-29 10:18:33 +00:00
Affiner le calcul
2018-03-12 09:38:29 +00:00
</BlueButton>
</>
2018-03-01 14:32:14 +00:00
)}
</div>
)}
2018-03-14 17:20:09 +00:00
</div>
2017-11-15 09:49:55 +00:00
)
}
renderOutputList() {
2018-03-01 14:32:14 +00:00
let popularTargets = popularTargetNames.map(curry(findRuleByName)(flatRules)),
{
conversationTargetNames,
2018-03-01 14:32:14 +00:00
textColourOnWhite,
setConversationTargets
2018-03-01 14:32:14 +00:00
} = this.props,
optionIsChecked = s => (conversationTargetNames || []).includes(s.name),
2018-03-01 14:32:14 +00:00
visibleCheckbox = s =>
2018-03-22 16:41:45 +00:00
conversationTargetNames && s.dottedName !== this.state.activeInput,
2018-03-01 14:32:14 +00:00
toggleTarget = target =>
ifElse(contains(target), without(target), append(target))
2017-11-15 09:49:55 +00:00
return (
<div>
2018-03-22 17:54:19 +00:00
<ul id="targets">
{popularTargets.map(s => (
2018-03-22 17:54:19 +00:00
<li key={s.name}>
{visibleCheckbox(s) && (
<input
id={s.name}
type="checkbox"
checked={optionIsChecked(s)}
onChange={() =>
setConversationTargets(
toggleTarget(s.name)(
(conversationTargetNames || []).filter(
t => !this.state.activeInput.includes(t)
2018-03-01 14:32:14 +00:00
)
)
2018-03-22 17:54:19 +00:00
)
}
/>
2018-03-22 17:54:19 +00:00
)}
{conversationTargetNames && (
<label htmlFor={s.name} key={s.name}>
<i
style={{
visibility: visibleCheckbox(s) ? 'visible' : 'hidden'
}}
className={`fa fa${
optionIsChecked(s) ? '-check' : ''
}-square-o fa-2x`}
/>
</label>
)}
<span className="texts">
2018-03-29 09:50:34 +00:00
<span className="optionTitle">
<Link to={'/règle/' + s.dottedName}>{s.title || s.name}</Link>
</span>
2018-03-22 17:54:19 +00:00
<p>{s['résumé']}</p>
</span>
<TargetInputOrValue
{...{
s,
targets: this.props.targets,
firstEstimationComplete: this.firstEstimationComplete,
activeInput: this.state.activeInput,
setActiveInput: name => this.setState({ activeInput: name }),
setFormValue: this.props.setFormValue
}}
/>
</li>
))}
2018-03-22 17:54:19 +00:00
</ul>
</div>
2017-11-15 09:49:55 +00:00
)
}
}
let validate = buildValidationFunction(formValueTypes['euros'])
let InputComponent = ({ input, meta: { dirty, error } }) => (
<span>
{dirty && error && <span className="input-error">{error}</span>}
<input type="number" {...input} autoFocus />
</span>
)
let TargetInputOrValue = ({
s,
targets,
firstEstimationComplete,
activeInput,
setActiveInput,
clearFormValue
}) => (
<span className="targetInputOrValue">
{activeInput === s.dottedName ? (
<Field
name={s.dottedName}
component={InputComponent}
type="text"
validate={validate}
/>
) : (
<TargetValue {...{ targets, s, activeInput, setActiveInput }} />
)}
{(firstEstimationComplete || s.question) && <span className="unit"></span>}
</span>
)
@connect(
() => ({}),
dispatch => ({
setFormValue: (field, name) => dispatch(change('conversation', field, name))
})
)
class TargetValue extends Component {
render() {
let { targets, s, setFormValue, activeInput, setActiveInput } = this.props,
rule = targets.find(propEq('dottedName', s.dottedName)),
value = rule && rule.nodeValue,
humanValue = value != null && value.toFixed(0)
return (
<span
className={classNames({
editable: s.question,
attractClick: s.question && targets.length === 0
})}
onClick={() => {
if (!s.question) return
if (value != null) {
setFormValue(s.dottedName, humanValue + '')
setFormValue(activeInput, '')
}
setActiveInput(s.dottedName)
}}
>
<RuleValue value={value} />
</span>
)
}
}