diff --git a/.gitignore b/.gitignore index 1f829970b..3d5d935fe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .tags* node_modules/ +dist/ diff --git a/règles/entités/salariat/Salariat.CDD.yaml b/règles/entités/salariat/Salariat.CDD.yaml index 58dd9cefc..b5ac77e58 100644 --- a/règles/entités/salariat/Salariat.CDD.yaml +++ b/règles/entités/salariat/Salariat.CDD.yaml @@ -109,6 +109,7 @@ - Variable: événements attache: Salariat . CDD + titre: Événement de contrat question: Pensez-vous être confronté à l'un de ces événements ? 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, diff --git a/source/components/CDD.js b/source/components/CDD.js index 38165c316..7f027da79 100644 --- a/source/components/CDD.js +++ b/source/components/CDD.js @@ -12,39 +12,39 @@ let situationSelector = formValueSelector('conversation') @reduxForm({form: 'conversation', destroyOnUnmount: false}) @connect( - state => ({ - situation: variableName => situationSelector(state, variableName), - steps: state.steps, - themeColours: state.themeColours, - analysedSituation: state.analysedSituation, -}), - dispatch => ({ - startConversation: () => dispatch({type: START_CONVERSATION}), -}), + state => ({ + situation: variableName => situationSelector(state, variableName), + steps: state.submittedSteps.concat(state.steps), + themeColours: state.themeColours, + analysedSituation: state.analysedSituation, + }), + dispatch => ({ + startConversation: () => dispatch({type: START_CONVERSATION}), + }), ) export default class CDD extends Component { componentDidMount() { this.props.startConversation() } render() { - let {steps} = this.props + let {steps, situation} = this.props let conversation = steps.map(step => ( - - )) + + )) return ( -
- -

Simulateur CDD

-
-
- {conversation} -
- -
- -
+
+ +

Simulateur CDD

+
+
+ {conversation} +
+ +
+ +
) } } diff --git a/source/components/conversation/FormDecorator.js b/source/components/conversation/FormDecorator.js index 42143a800..668a2a5e0 100644 --- a/source/components/conversation/FormDecorator.js +++ b/source/components/conversation/FormDecorator.js @@ -16,8 +16,6 @@ to understand those precious higher order components. export var FormDecorator = formType => RenderField => @connect( //... this helper directly to the redux state to avoid passing more props state => ({ - steps: state.steps, - answers: state.form.conversation && state.form.conversation.values, themeColours: state.themeColours }), dispatch => ({ @@ -31,12 +29,14 @@ export var FormDecorator = formType => RenderField => } render() { let { + stepAction, + themeColours, + setFormValue + } = this.props, + { name, visible, - steps, - stepAction, possibleChoice, // should be found in the question set theoritically, but it is used for a single choice question -> the question itself is dynamic and cannot be input as code, - themeColours, // formerly in conversation-steps valueType, attributes, @@ -45,11 +45,10 @@ export var FormDecorator = formType => RenderField => human, helpText, suggestions, - setFormValue, subquestion - } = this.props + } = this.props.step - this.step = steps.find(s => s.name == name) + this.step = this.props.step /* La saisie peut être cachée car ce n'est pas encore son tour, ou parce qu'elle a déjà été remplie. Dans ce dernier cas, un résumé @@ -82,7 +81,7 @@ export var FormDecorator = formType => RenderField => let wideQuestion = formType == 'rhetorical-question' && !possibleChoice return ( -
+
{this.state.helpVisible && this.renderHelpBox(helpText)}
{this.renderHeader(unfolded, valueType, human, helpText, wideQuestion, subquestion)} @@ -129,16 +128,24 @@ export var FormDecorator = formType => RenderField => let { name, stepAction, - answers, + answer, themeColours } = this.props, - value = answers[name], ignored = this.step.state === 'ignored' - return ( - stepAction(name, 'editing')}> -

{this.props.title}

- + + {this.props.step.title} + {answer} + + stepAction(name, 'editing')} + className="fa fa-pencil-square-o" + aria-hidden="true"> + + Modifier + + + {/* */} ) } diff --git a/source/components/conversation/StepAnswer.js b/source/components/conversation/StepAnswer.js index 326382172..6fa2f3535 100644 --- a/source/components/conversation/StepAnswer.js +++ b/source/components/conversation/StepAnswer.js @@ -9,7 +9,6 @@ export default class StepAnswer extends Component { } = this.props, // Show a beautiful answer to the user, rather than the technical form value humanFunc = human || valueType && valueType.human || (v => v) - return ( {humanFunc(value)} diff --git a/source/components/conversation/conversation.css b/source/components/conversation/conversation.css index de0fa60a9..bd926fe1f 100644 --- a/source/components/conversation/conversation.css +++ b/source/components/conversation/conversation.css @@ -4,7 +4,7 @@ } .step { - opacity: .2; + opacity: 1; } .step:first-child { @@ -92,12 +92,32 @@ margin-bottom: 1em; border-radius: 1.4em; position: relative; - cursor: pointer; } -/* The unfolded step is the currently focused -question : make it visible with colors */ -.step.unfolded h1 { - cursor: default; + +.fact { + width: 80%; + margin-bottom: 1em; + clear: both; +} +.fact .title { + font-weight: 600; + border-bottom: 1px solid #aaa; +} +.fact .answer { + float: right; +} + +.fact .edit { + margin-left: 2em; + font-size: 75%; + cursor: pointer; + font-weight: bold; + padding: .1em .6em; + border-radius: 2px; +} +.step.completed .edit:hover { + background: #333350; + color: white; } .step-subquestion { diff --git a/source/engine/conversation.js b/source/engine/conversation.js index d96cbd093..d20b14d1f 100644 --- a/source/engine/conversation.js +++ b/source/engine/conversation.js @@ -1,7 +1,7 @@ import React from 'react' import Explicable from '../components/conversation/Explicable' -export let constructStepMeta = ({question, subquestion, dottedName, name}) => ({ +export let constructStepMeta = ({titre, question, subquestion, dottedName, name}) => ({ // name: dottedName.split(' . ').join('.'), name: dottedName, // question: question || name, @@ -10,7 +10,7 @@ export let constructStepMeta = ({question, subquestion, dottedName, name}) => ({ name={name} lightBackground={true} />, - title: name, + title: titre || name, dependencyOfVariables: ['chai pas'], subquestion, diff --git a/source/reducers.js b/source/reducers.js index cf328b025..2b25224eb 100644 --- a/source/reducers.js +++ b/source/reducers.js @@ -17,15 +17,6 @@ import {constructStepMeta} from './engine/conversation' import computeThemeColours from './components/themeColours' -function steps(steps = [], {type}) { - switch (type) { - case UNSUBMIT_ALL: - return [] - default: - return steps - } -} - function themeColours(state = computeThemeColours(), {type, colour}) { if (type == 'CHANGE_THEME_COLOUR') return computeThemeColours(colour) @@ -51,7 +42,9 @@ export default reduceReducers( /* Have forms been filled or ignored ? false means the user is reconsidering its previous input */ - steps, + steps: (steps=[]) => steps, + + submittedSteps: (steps=[]) => steps, analysedSituation: (state = []) => state, @@ -66,6 +59,15 @@ export default reduceReducers( // pour débugguer : window.situationGate = situationGate(state) + let newlySubmittedSteps = + action.newState == 'filled' + ? [{ + ...state.steps.find(s => s.name === action.name), + state: 'filled' + }] + : [] + + // on calcule la prochaine étape, à ajouter sur la pile let // une liste des objectifs de la simulation (des 'rules' aussi nommées 'variables') @@ -82,11 +84,25 @@ export default reduceReducers( missingVariablesList = R.keys(missingVariables), + /* + Certaines variables manquantes peuvent être factorisées dans des groupes. + Par exemple, au lieu de : + + q1: "Pensez vous porlonger le CDD en CDI", + r1: Oui | Non + q2: "Pensez-vous qu'une rupture pour faute grave est susceptible d'arriver" + r2: Oui | Non + + on préfère : + + q: "Pensez-vous être confronté à l'un de ces événements ?" + r: Prolongation du CDD en CDI | Rupture pour faute grave + */ groups = R.groupBy( parentName )(missingVariablesList), - // on va maintenant construire la liste des composants React correspondant aux questions pour obtenir les variables manquantes + // on va maintenant construire la liste des composants React qui afficheront les questions à l'utilisateur pour que l'on obtienne les variables manquantes steps = R.pipe( R.mapObjIndexed((variables, group) => R.pipe( @@ -133,7 +149,13 @@ export default reduceReducers( R.unnest )(groups) - return {...state, steps, analysedSituation} + console.log('submittedSteps', newlySubmittedSteps) + return { + ...state, + steps, + submittedSteps: state.submittedSteps.concat(newlySubmittedSteps), + analysedSituation + } } else { return state