[cdd] Affichage des • d'aide seulement quand l'aide existe
parent
39c018ea54
commit
5427ac7181
|
@ -7,7 +7,9 @@
|
|||
référence: https://fr.wikipedia.org/wiki/Contrat_de_travail_%C3%A0_dur%C3%A9e_d%C3%A9termin%C3%A9e_en_France
|
||||
# TODO: règle de type : il faut q'un motif et une durée soient sélectionnés pour qu'un contrat soit un CDD. Cela revient à dire que les variables CDD et motif sont obligatoires *dans le contexte* de leur attache
|
||||
|
||||
- Variable: durée
|
||||
- Variable: durée contrat
|
||||
titre: durée du contrat
|
||||
question: Quelle est la durée du contrat ?
|
||||
attache: Salariat . CDD
|
||||
contrainte: période
|
||||
description: Durée du contrat de travail
|
||||
|
@ -98,6 +100,7 @@
|
|||
|
||||
- Variable: événements
|
||||
attache: Salariat . CDD
|
||||
question: Pensez-vous être confronté à un de ces évéments ?
|
||||
description: Certains événements impactent le prix d'un CDD
|
||||
# au lieu de lister tous les cas, l'alternative est de simplement indiquer qu'ils sont exclusifs,
|
||||
# et les identifier dynamiquement par leur attribut "attache" :
|
||||
|
@ -141,6 +144,7 @@
|
|||
|
||||
|
||||
- Variable: complément formation professionnelle employeur
|
||||
titre: Complément de formation offert par l'employeur
|
||||
titre: Complément de formation professionnelle offert par l'employeur
|
||||
question: L'employeur s'engage-t-il à verser un complément de formation professionnelle ?
|
||||
attache: Salariat . CDD
|
||||
description: L'employeur s'engage à fournir une formation professionnelle, ce qui le dispense de la cotisation CIF CDD
|
||||
description: L'employeur peut s'engager à fournir un complément de formation professionnelle. Cela le dispensera de l'obligation de payer la cotisation CIF CDD
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
- Variable: contrat aidé
|
||||
attache: Salariat
|
||||
question: Est-ce un contrat aidé ?
|
||||
choix exclusifs:
|
||||
- contrat unique insertion
|
||||
- emploi avenir
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
- Variable: salaire de base
|
||||
attache: Salariat
|
||||
question: Quel est le salaire de base ?
|
||||
description: Le salaire de base est le salaire régulier présent dans le contrat. Des primes viendront éventuellement le compléter, on parlera alors de salaire brut.
|
||||
contrainte: nombre positif
|
||||
|
||||
- Variable: Salaire brut
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
description: Majoration des contributions patronales d’assurance chômage pour les contrats à durée déterminée courts (CDD)
|
||||
non applicable si:
|
||||
l'une de ces conditions:
|
||||
- Salariat . CDD . durée > 3
|
||||
- Salariat . CDD . durée contrat > 3
|
||||
- Salariat . CDD . événements . CDD poursuivi en CDI
|
||||
formule:
|
||||
linéaire:
|
||||
|
@ -15,10 +15,10 @@
|
|||
taux:
|
||||
logique numérique:
|
||||
Salariat . CDD . motif . accroissement temporaire activité:
|
||||
Salariat . CDD . durée <= 1: 3% # TODO 1 mois, pas 1 rien, évidemment
|
||||
Salariat . CDD . durée <= 3: 1.5%
|
||||
Salariat . CDD . durée contrat <= 1: 3% # TODO 1 mois, pas 1 rien, évidemment
|
||||
Salariat . CDD . durée contrat <= 3: 1.5%
|
||||
Salariat . CDD . motif . usage:
|
||||
Salariat . CDD . durée <= 3: 0.5%
|
||||
Salariat . CDD . durée contrat <= 3: 0.5%
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ rules:
|
|||
- 2
|
||||
- unix
|
||||
semi:
|
||||
- 2
|
||||
- 1
|
||||
- never
|
||||
no-unused-vars: 1
|
||||
no-console: 1
|
||||
|
|
|
@ -29,4 +29,4 @@ export const CHANGE_THEME_COLOUR = 'CHANGE_THEME_COLOUR'
|
|||
export function changeThemeColour(colour) {return {type: CHANGE_THEME_COLOUR, colour}}
|
||||
|
||||
|
||||
export const EXPLAIN_TERM = 'EXPLAIN_TERM'
|
||||
export const EXPLAIN_VARIABLE = 'EXPLAIN_VARIABLE'
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
import React, {Component} from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
import {findRuleByName} from '../engine/rules'
|
||||
|
||||
|
||||
@connect(
|
||||
state =>
|
||||
({explained: state.explainedVariable})
|
||||
)
|
||||
export default class Aide extends Component {
|
||||
render() {
|
||||
let {explained} = this.props
|
||||
|
||||
if (!explained) return <section id="help" />
|
||||
|
||||
let rule = findRuleByName(explained),
|
||||
text = rule.description || rule.titre
|
||||
|
||||
let possibilities = rule['choix exclusifs']
|
||||
|
||||
return (
|
||||
<section id="help" className="active">
|
||||
<p>
|
||||
{text}
|
||||
</p>
|
||||
{ possibilities &&
|
||||
<p>
|
||||
{possibilities.length} possibilités :
|
||||
<ul>
|
||||
{possibilities.map(p =>
|
||||
<li key={p}>{p}</li>
|
||||
)}
|
||||
</ul>
|
||||
</p>
|
||||
}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
}
|
|
@ -35,6 +35,7 @@
|
|||
}
|
||||
|
||||
#sim #help {
|
||||
box-shadow: -1px 1px 15px 1px #eee;
|
||||
border: 1px solid;
|
||||
border-radius: 2px;
|
||||
border-color: #ccc;
|
||||
|
|
|
@ -6,41 +6,9 @@ import {reduxForm, formValueSelector} from 'redux-form'
|
|||
import {connect} from 'react-redux'
|
||||
import './conversation/conversation.css'
|
||||
import {START_CONVERSATION} from '../actions'
|
||||
import {findRuleByName} from '../engine/rules'
|
||||
import Aide from './Aide'
|
||||
|
||||
@connect(({form: {conversation}, steps, explainTerm}) => ({conversationState: conversation && conversation.values, steps, explainTerm}))
|
||||
class Aide extends Component {
|
||||
render() {
|
||||
let {steps, conversationState, explainTerm} = this.props
|
||||
if (!steps.length) return null
|
||||
let [{dependencyOfVariables, helpText}] = steps
|
||||
|
||||
if (!explainTerm) return <section id="help" />
|
||||
|
||||
let rule = findRuleByName(explainTerm),
|
||||
text = rule.description || rule.titre
|
||||
|
||||
let possibilities = rule['choix exclusifs']
|
||||
|
||||
return (
|
||||
<section id="help" className="active">
|
||||
<p>
|
||||
{text}
|
||||
</p>
|
||||
{ possibilities &&
|
||||
<p>
|
||||
{possibilities.length} possibilités :
|
||||
<ul>
|
||||
{possibilities.map(p =>
|
||||
<li key={p}>{p}</li>
|
||||
)}
|
||||
</ul>
|
||||
</p>
|
||||
}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
}
|
||||
let situationSelector = formValueSelector('conversation')
|
||||
|
||||
@reduxForm(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.term.defined .icon{
|
||||
.explicable .icon{
|
||||
text-align: center;
|
||||
width: 1.3em;
|
||||
line-height: 1.3em;
|
||||
|
@ -9,12 +9,12 @@
|
|||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.term.defined:hover .icon {
|
||||
.explicable:hover .icon {
|
||||
opacity: 1;
|
||||
border-color: white;
|
||||
}
|
||||
|
||||
.term.defined .icon:hover {
|
||||
.explicable .icon:hover {
|
||||
opacity: 1;
|
||||
background: white;
|
||||
color: #4A89DC;
|
|
@ -0,0 +1,39 @@
|
|||
import React from 'react'
|
||||
import classNames from 'classnames'
|
||||
import './Explicable.css'
|
||||
import HoverDecorator from '../HoverDecorator'
|
||||
import {connect} from 'react-redux'
|
||||
import {EXPLAIN_VARIABLE} from '../../actions'
|
||||
import {findRuleByName} from '../../engine/rules'
|
||||
|
||||
|
||||
@connect(null, dispatch => ({
|
||||
explain: variableName => dispatch({type: EXPLAIN_VARIABLE, variableName})
|
||||
}))
|
||||
@HoverDecorator
|
||||
export default class Explicable extends React.Component {
|
||||
render(){
|
||||
let
|
||||
{name, hover, label, explain} = this.props,
|
||||
rule = findRuleByName(name)
|
||||
|
||||
// Rien à expliquer ici, ce n'est pas une règle
|
||||
if (!rule) return <span>{label}</span>
|
||||
|
||||
let ruleLabel = rule.titre || rule.name
|
||||
// Rien à expliquer ici, il n'y a pas de champ description dans la règle
|
||||
if (!rule.description && !rule['choix exclusifs']) return <span>{ruleLabel}</span>
|
||||
|
||||
|
||||
return (
|
||||
<span
|
||||
className={classNames('explicable')} >
|
||||
{ruleLabel}
|
||||
<span
|
||||
className="icon"
|
||||
onClick={e => {e.preventDefault(); e.stopPropagation(); explain(name)}}>
|
||||
{ hover ? 'ℹ' : '•' }</span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,32 +1,29 @@
|
|||
import React, {Component} from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
import {FormDecorator} from './FormDecorator'
|
||||
import {answer, answered} from './userAnswerButtonStyle'
|
||||
import HoverDecorator from '../HoverDecorator'
|
||||
import Term from './Term'
|
||||
import {EXPLAIN_TERM} from '../../actions'
|
||||
import Explicable from './Explicable'
|
||||
import R from 'ramda'
|
||||
|
||||
@connect(null, dispatch => ({
|
||||
explainTerm: term => () => dispatch({type: EXPLAIN_TERM, term})
|
||||
}))
|
||||
@HoverDecorator
|
||||
class RadioLabel extends Component {
|
||||
|
||||
render() {
|
||||
let {choice: {value, label}, input, submit, hover, themeColours, explainTerm} = this.props,
|
||||
let {value, label, input, submit, hover, themeColours} = this.props,
|
||||
// value = R.when(R.is(Object), R.prop('value'))(choice),
|
||||
labelStyle =
|
||||
Object.assign(
|
||||
(value === input.value || hover) ? answered(themeColours) : answer(themeColours),
|
||||
)
|
||||
|
||||
return (
|
||||
<label
|
||||
<label key={value}
|
||||
style={labelStyle}
|
||||
className="radio" >
|
||||
<input
|
||||
type="radio" {...input} onClick={submit}
|
||||
value={value} checked={value === input.value ? 'checked' : ''} />
|
||||
<Term label={label} defined={true} explain={explainTerm(value)}/>
|
||||
<Explicable name={value} label={label}/>
|
||||
</label>
|
||||
)
|
||||
}
|
||||
|
@ -46,8 +43,10 @@ export default class Question extends Component {
|
|||
|
||||
return (
|
||||
<span>
|
||||
{ choices.map((choice) =>
|
||||
<RadioLabel key={choice.value} {...{choice, input, submit, themeColours}}/>
|
||||
{ choices.map((choice) => do {
|
||||
let {value, label} = R.is(String)(choice) ? {value: choice, label: null} : choice;
|
||||
<RadioLabel key={value} {...{value, label, input, submit, themeColours}}/>
|
||||
}
|
||||
)}
|
||||
</span>
|
||||
)
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
import React from 'react'
|
||||
import classNames from 'classnames'
|
||||
import './Term.css'
|
||||
import HoverDecorator from '../HoverDecorator'
|
||||
|
||||
@HoverDecorator
|
||||
export default class Term extends React.Component {
|
||||
render(){
|
||||
let {label, defined, hover, explain} = this.props
|
||||
return (
|
||||
<span
|
||||
className={classNames('term', {defined})}
|
||||
>
|
||||
{label}
|
||||
<span
|
||||
className="icon"
|
||||
onClick={e => {e.preventDefault(); e.stopPropagation(); explain()}}>
|
||||
{ hover ? 'ℹ' : '•' }</span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
export let constructStepMeta = ({dottedName, name, description}) => ({
|
||||
export let constructStepMeta = ({question, dottedName, name}) => ({
|
||||
// name: dottedName.split(' . ').join('.'),
|
||||
name: dottedName,
|
||||
question: description || name,
|
||||
question: question || name,
|
||||
title: name,
|
||||
dependencyOfVariables: ['chai pas'],
|
||||
visible: true,
|
||||
|
|
|
@ -42,10 +42,10 @@ let [rules, entityRules] =
|
|||
/****************************************
|
||||
Méthodes de recherche d'une règle */
|
||||
|
||||
export let findRuleByName = search => console.log('search', search) ||
|
||||
export let findRuleByName = search =>
|
||||
[...rules, ...entityRules]
|
||||
.map(enrichRule)
|
||||
.find( ({name}) => console.log('name', name) ||
|
||||
.find( ({name}) =>
|
||||
name === search
|
||||
)
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import Question from './components/conversation/Question'
|
|||
import Input from './components/conversation/Input'
|
||||
import RhetoricalQuestion from './components/conversation/RhetoricalQuestion'
|
||||
|
||||
import { STEP_ACTION, UNSUBMIT_ALL, START_CONVERSATION, EXPLAIN_TERM} from './actions'
|
||||
import { STEP_ACTION, UNSUBMIT_ALL, START_CONVERSATION, EXPLAIN_VARIABLE} from './actions'
|
||||
import R from 'ramda'
|
||||
|
||||
import {findGroup, findRuleByDottedName, dottedName, parentName} from './engine/rules'
|
||||
|
@ -35,9 +35,9 @@ function themeColours(state = computeThemeColours(), {type, colour}) {
|
|||
let situationGate = state =>
|
||||
name => formValueSelector('conversation')(state, name)
|
||||
|
||||
function explainTerm(state = null, {type, term}) {
|
||||
if (type == EXPLAIN_TERM)
|
||||
return term
|
||||
function explainedVariable(state = null, {type, variableName}) {
|
||||
if (type == EXPLAIN_VARIABLE)
|
||||
return variableName
|
||||
else return state
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ export default reduceReducers(
|
|||
|
||||
themeColours,
|
||||
|
||||
explainTerm
|
||||
explainedVariable
|
||||
}),
|
||||
// cross-cutting concerns because here `state` is the whole state tree
|
||||
(state, action) => {
|
||||
|
@ -122,17 +122,11 @@ export default reduceReducers(
|
|||
constructStepMeta(group),
|
||||
{
|
||||
component: Question,
|
||||
choices: group['choix exclusifs'].map(name => {
|
||||
let rule = findRuleByDottedName(
|
||||
group.dottedName + ' . ' + name
|
||||
)
|
||||
return {
|
||||
value: rule.name,
|
||||
label: rule && rule.titre || name
|
||||
}
|
||||
}).concat([{value: 'aucun', label: 'Aucun'}]),
|
||||
choices:
|
||||
group['choix exclusifs'].concat(
|
||||
[{value: 'aucun', label: 'Aucun'}]
|
||||
),
|
||||
// defaultValue: 'Non',
|
||||
helpText: 'Choisissez une réponse'
|
||||
}
|
||||
)]
|
||||
])
|
||||
|
|
Loading…
Reference in New Issue