Extraction de FoldedStep depuis FormDecorator

pull/256/head
Mael 2018-06-11 17:59:50 +02:00
parent 6cf3ac2531
commit 3854666a90
7 changed files with 99 additions and 117 deletions

View File

@ -23,8 +23,8 @@ export default class Simu extends Component {
return (
<div id="simu">
{/*<FoldedSteps />*/}
<div id="focusZone">
<FoldedSteps />
{/*<GoToAnswers />*/}
<TargetSelection colours={colours} />
{conversationStarted && (

View File

@ -1,6 +1,5 @@
import React, { Component } from 'react'
import { translate } from 'react-i18next'
import { pick } from 'ramda'
import Aide from '../Aide'
import { reduxForm } from 'redux-form'
import { getInputComponent } from 'Engine/generateQuestions'
@ -33,9 +32,7 @@ export default class Conversation extends Component {
<Aide />
<div id="currentQuestion">
{currentQuestion &&
getInputComponent({ unfolded: true })(flatRules, targetNames)(
currentQuestion
)}
getInputComponent(flatRules, targetNames)(currentQuestion)}
</div>
</div>
)

View File

@ -0,0 +1,48 @@
import React from 'react'
import { findRuleByDottedName } from 'Engine/rules'
import { capitalise0 } from '../../utils'
import { connect } from 'react-redux'
import { Trans, translate } from 'react-i18next'
import {
flatRulesSelector,
validatedSituationSelector
} from 'Selectors/analyseSelectors'
import { stepAction } from '../../actions'
import { LinkButton } from 'Components/ui/Button'
@translate()
@connect(
state => ({
flatRules: flatRulesSelector(state),
situation: validatedSituationSelector(state)
}),
dispatch => ({
stepAction: (name, step, source) => dispatch(stepAction(name, step, source))
})
)
export default class FoldedStep extends React.Component {
render() {
let { stepAction, dottedName, flatRules, t, situation } = this.props
let { title } = findRuleByDottedName(flatRules, dottedName),
answer = situation[dottedName],
eventualEnumAnswerRule = findRuleByDottedName(
flatRules,
dottedName + ' . ' + answer
),
translatedAnswer =
(eventualEnumAnswerRule && eventualEnumAnswerRule.title) || t(answer)
return (
<div className="foldedQuestion">
<span className="borderWrapper">
<span className="title">{capitalise0(title)}</span>
<span className="answer">{translatedAnswer}</span>
</span>
<LinkButton onClick={() => stepAction('unfold', dottedName, 'unfold')}>
<i className="fa fa-pencil" aria-hidden="true" />
<Trans>Modifier</Trans>
</LinkButton>
</div>
)
}
}

View File

@ -1,7 +1,4 @@
import { getInputComponent } from 'Engine/generateQuestions'
//import styles from './.css'
// css in conversation.Css
import { isEmpty, map, pick } from 'ramda'
import React, { Component } from 'react'
import { Trans, translate } from 'react-i18next'
import { connect } from 'react-redux'
@ -9,19 +6,17 @@ import { animateScroll, Element, scroller } from 'react-scroll'
import { reset } from 'redux-form'
import { resetSimulation } from '../../actions'
import { LinkButton, SimpleButton } from '../ui/Button'
import withColours from '../withColours'
import { isEmpty } from 'ramda'
import { flatRulesSelector } from 'Selectors/analyseSelectors'
import FoldedStep from './FoldedStep'
@withColours
@connect(
pick([
'currentQuestion',
'foldedSteps',
'situationGate',
'targetNames',
'nextSteps',
'analysis',
'flatRules'
]),
state => ({
foldedSteps: state.conversationSteps.foldedSteps,
targetNames: state.targetNames,
flatRules: flatRulesSelector(state)
}),
{
resetSimulation,
resetForm: () => reset('conversation')
@ -34,7 +29,7 @@ export default class FoldedSteps extends Component {
this.props.resetForm()
}
render() {
let { foldedSteps, targetNames, flatRules } = this.props
let { foldedSteps } = this.props
if (isEmpty(foldedSteps || [])) return null
return (
@ -45,16 +40,14 @@ export default class FoldedSteps extends Component {
<Trans i18nKey="resetAll">Tout effacer</Trans>
</LinkButton>
</div>
{map(
getInputComponent({ unfolded: false })(flatRules, targetNames),
foldedSteps
)}
{foldedSteps.map(dottedName => (
<FoldedStep key={dottedName} dottedName={dottedName} />
))}
</div>
)
}
}
@withColours
@connect(state => ({
foldedSteps: state.foldedSteps,
conversationStarted: state.conversationStarted

View File

@ -1,14 +1,11 @@
import React, { Component } from 'react'
import { Trans, translate } from 'react-i18next'
import { translate } from 'react-i18next'
import classNames from 'classnames'
import { connect } from 'react-redux'
import { Field, change } from 'redux-form'
import { stepAction } from '../../actions'
import { capitalise0 } from '../../utils'
import Explicable from 'Components/conversation/Explicable'
import { LinkButton} from 'Components/ui/Button'
import IgnoreStepButton from './IgnoreStepButton'
import { findRuleByDottedName } from 'Engine/rules'
export let buildValidationFunction = valueType => {
let validator = valueType ? valueType.validator : {},
@ -27,7 +24,7 @@ export var FormDecorator = formType => RenderField =>
@connect(
//... this helper directly to the redux state to avoid passing more props
state => ({
situationGate: state.situationGate,
themeColours: state.themeColours,
flatRules: state.flatRules
}),
dispatch => ({
@ -43,20 +40,6 @@ export var FormDecorator = formType => RenderField =>
helpVisible: false
}
render() {
let { unfolded } = this.props
return (
<div className={classNames({ step: unfolded }, formType)}>
<div>
{/* Une étape déjà répondue est marquée 'folded'. Dans ce dernier cas, un résumé
de la réponse est affiché */}
{unfolded ? this.renderUnfolded() : this.renderFolded()}
</div>
</div>
)
}
renderUnfolded() {
let {
setFormValue,
stepAction,
@ -93,69 +76,40 @@ export var FormDecorator = formType => RenderField =>
{this.props.question}
</h1>
)
return (
<div>
<div className="unfoldedHeader">
<div className="step-question">
{inversion ? (
question
) : (
<Explicable dottedName={fieldName}>{question}</Explicable>
<div className={classNames('step', formType)}>
<div>
<div className="unfoldedHeader">
<div className="step-question">
{inversion ? (
question
) : (
<Explicable dottedName={fieldName}>{question}</Explicable>
)}
<div
className="step-subquestion"
dangerouslySetInnerHTML={{ __html: subquestion }}
/>
</div>
{defaultValue != null && (
<IgnoreStepButton
action={() => {
setFormValue(fieldName, '' + defaultValue)
submit('ignore')
}}
/>
)}
<div
className="step-subquestion"
dangerouslySetInnerHTML={{ __html: subquestion }}
/>
</div>
{defaultValue != null && (
<IgnoreStepButton
action={() => {
setFormValue(fieldName, '' + defaultValue)
submit('ignore')
}}
<fieldset>
<Field
component={RenderField}
name={fieldName}
{...stepProps}
themeColours={themeColours}
/>
)}
</fieldset>
</div>
<fieldset>
<Field
component={RenderField}
name={fieldName}
{...stepProps}
themeColours={themeColours}
/>
</fieldset>
</div>
)
}
renderFolded() {
let {
stepAction,
situationGate,
title,
dottedName,
fieldName,
fieldTitle,
flatRules,
t
} = this.props
let answer = situationGate(fieldName),
rule = findRuleByDottedName(flatRules, dottedName + ' . ' + answer),
translatedAnswer = (rule && rule.title) || t(answer)
return (
<div className="foldedQuestion">
<span className="borderWrapper">
<span className="title">{capitalise0(fieldTitle || title)}</span>
<span className="answer">{translatedAnswer}</span>
</span>
<LinkButton
onClick={() => stepAction('unfold', dottedName, 'unfold')}
>
<i className="fa fa-pencil" aria-hidden="true" />
<Trans>Modifier</Trans>
</LinkButton>
</div>
)
}

View File

@ -50,9 +50,7 @@ import {
*/
export let collectMissingVariablesByTarget = targets =>
fromPairs(
targets.map(target => [target.dottedName, target.missingVariables])
)
fromPairs(targets.map(target => [target.dottedName, target.missingVariables]))
export let getNextSteps = missingVariablesByTarget => {
let byCount = ([, [count]]) => count
@ -87,8 +85,7 @@ let buildVariantTree = (allRules, path) => {
let rec = path => {
let node = findRuleByDottedName(allRules, path),
variant = isVariant(node),
variants =
variant && unless(is(Array), prop('possibilités'))(variant),
variants = variant && unless(is(Array), prop('possibilités'))(variant),
shouldBeExpanded = variant && true, //variants.find( v => relevantPaths.find(rp => contains(path + ' . ' + v)(rp) )),
canGiveUp = variant && !variant['choix obligatoire']
@ -111,10 +108,7 @@ let buildPossibleInversion = (rule, rules, targetNames) => {
if (!inversion) return null
let inversionObjects = query('formule . inversion . avec').map(i =>
findRuleByDottedName(
rules,
disambiguateRuleReference(rules, rule, i)
)
findRuleByDottedName(rules, disambiguateRuleReference(rules, rule, i))
),
inversions = reject(({ name }) => targetNames.includes(name))(
[rule].concat(inversionObjects)
@ -128,15 +122,11 @@ let buildPossibleInversion = (rule, rules, targetNames) => {
// This function takes the unknown rule and finds which React component should be displayed to get a user input through successive if statements
// That's not great, but we won't invest more time until we have more diverse input components and a better type system.
export let getInputComponent = ({ unfolded }) => (
rules,
targetNames
) => dottedName => {
export let getInputComponent = (rules, targetNames) => dottedName => {
let rule = findRuleByDottedName(rules, dottedName)
let commonProps = {
key: dottedName,
unfolded,
fieldName: dottedName,
...pick(['dottedName', 'title', 'question', 'defaultValue'], rule)
}

View File

@ -57,7 +57,7 @@ let validatedStepsSelector = state => [
state.activeTargetInput
]
let validatedSituationSelector = createSelector(
export let validatedSituationSelector = createSelector(
[formattedSituationSelector, validatedStepsSelector],
(situation, validatedSteps) => pick(validatedSteps, situation)
)