Merge pull request #123 from sgmap/fix-input-with-comma

Traiter correctement les nombres à virgules
pull/124/merge
Mael 2017-11-13 11:11:31 +01:00 committed by GitHub
commit 87e2bfaf71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 21 additions and 125 deletions

View File

@ -1,7 +1,7 @@
import R from 'ramda'
import React, {Component} from 'react'
import Helmet from 'react-helmet'
import {formValueSelector, reset} from 'redux-form'
import {reset} from 'redux-form'
import {connect} from 'react-redux'
import {Redirect, Link, withRouter} from 'react-router-dom'
import classNames from 'classnames'
@ -17,12 +17,9 @@ import {makeQuestion} from 'Engine/generateQuestions'
import ReactPiwik from './Tracker'
let situationSelector = formValueSelector('conversation')
@withRouter
@connect(
state => ({
situation: variableName => situationSelector(state, variableName),
currentQuestion: state.currentQuestion,
foldedSteps: state.foldedSteps,
extraSteps: state.extraSteps,
@ -63,7 +60,7 @@ export default class extends Component {
let
{started} = this.state,
{foldedSteps, extraSteps, currentQuestion, situation, situationGate, themeColours} = this.props,
{foldedSteps, extraSteps, currentQuestion, situationGate, themeColours} = this.props,
sim = path =>
R.path(R.unless(R.is(Array), R.of)(path))(this.rule.simulateur || {}),
reinitalise = () => {
@ -115,8 +112,8 @@ export default class extends Component {
<Conversation initialValues={ R.pathOr({},['simulateur','par défaut'], sim) }
{...{
reinitalise,
currentQuestion: currentQuestion && buildUnfoldedStep(situation)(currentQuestion),
foldedSteps: R.map(buildStep(situation), foldedSteps),
currentQuestion: currentQuestion && buildUnfoldedStep(situationGate)(currentQuestion),
foldedSteps: R.map(buildStep(situationGate), foldedSteps),
extraSteps: R.map(buildStep(situationGate), extraSteps),
textColourOnWhite: themeColours.textColourOnWhite}}/>
}

View File

@ -1,84 +0,0 @@
import React, {Component} from 'react'
import GroupTitle from './GroupTitle'
import classnames from 'classnames'
import { connect } from 'react-redux'
import { change} from 'redux-form'
import {submitStep, editStep} from '../actions'
import ReactCSSTransitionGroup from 'react-addons-css-transition-group'
import IgnoreStepButton from './Forms/IgnoreStepButton'
import conversationData from '../conversation-steps'
import {formValueSelector} from 'redux-form'
import StepAnswer from './Forms/StepAnswer'
/* Groups can be used only to avoid repeating conditions for all its children,
or to gather a set of questions that will be eventually collapsed to a final @value,
marked with the 'explicit' class */
@connect(state => ({
steps: state.steps,
formValue: field => formValueSelector('advancedQuestions')(state, field),
themeColours: state.themeColours
}), dispatch => ({
editStep: name => dispatch(editStep(name)),
submitStep: (name, ignored) => dispatch(submitStep(name, ignored)),
setFormValue: (field, value) => dispatch(change('advancedQuestions', field, value)),
}))
export default class Group extends Component {
render() {
let {visible, steps, foldTrigger, children, text, themeColours: {colour}} = this.props,
folded = foldTrigger ? steps.get(foldTrigger) && steps.get(foldTrigger) != 'editing' : false
if (!visible) return null
return (
<div className={classnames('form-group', {folded, unfolded: !folded, explicit: text})}>
{this.renderHeader(folded)}
<div className="group-content" style={!folded && text ? {borderLeft: '1px dashed' + colour} : {}}>
<ReactCSSTransitionGroup
transitionName="group-animated"
transitionEnterTimeout={300}
transitionLeaveTimeout={200} >
{!folded && <ul className="group-items">
{children.map(child =>
<li key={child.props.name}>
{child}
</li>)}
</ul>}
</ReactCSSTransitionGroup>
</div>
</div>
)
}
renderHeader(folded) {
let {
steps, foldTrigger, editStep, setFormValue, submitStep,
text, valueType, formValue, themeColours
} = this.props
if (!text) return null
let
headerClick = () => editStep(foldTrigger),
{defaultValue, human} = conversationData[foldTrigger],
ignoreGroup = () => {
setFormValue(foldTrigger, defaultValue)
submitStep(foldTrigger, true)
},
value = formValue(foldTrigger),
ignored = steps.get(name) === 'ignored'
return (
<div className="header">
<GroupTitle themeColours={themeColours} {...{text, folded}} onClick={headerClick} />
{ !folded && <IgnoreStepButton action={ignoreGroup} /> }
{ folded &&
<StepAnswer {...{value, human, valueType, ignored, themeColours}} />
}
</div>
)
}
}

View File

@ -1,14 +0,0 @@
import steps from './conversation-steps'
export default values =>
values == null ? {} :
Object.keys(values).reduce((final, next) => {
let value = values[next],
{valueType = {}, validator} = steps[next],
{pre = (v => v), test, error} = Object.assign({}, validator, valueType.validator)
if (!test) return final
let valid = test(pre(value))
return Object.assign(final, valid ? null : {[next]: error})
}, {})

View File

@ -29,7 +29,7 @@ let jours = {
}
let nombre = {
human: value => value,
human: value => value.replace(/./g, ','),
validator: int
}

View File

@ -9,24 +9,9 @@ import SelectAtmp from 'Components/conversation/select/SelectTauxRisque'
import formValueTypes from 'Components/conversation/formValueTypes'
import {analyseSituation} from './traverse'
import {formValueSelector} from 'redux-form'
import {rules, findRuleByDottedName} from './rules'
import {collectNodeMissing, evaluateNode} from './evaluation'
let situationGate = state =>
name => formValueSelector('conversation')(state, name)
export let analyse = rootVariable => R.pipe(
situationGate,
// une liste des objectifs de la simulation (des 'rules' aussi nommées 'variables')
analyseSituation(rules, rootVariable)
)
/*
COLLECTE DES VARIABLES MANQUANTES
*********************************

View File

@ -4,7 +4,7 @@ import { combineReducers } from 'redux'
import reduceReducers from 'reduce-reducers'
import {reducer as formReducer, formValueSelector} from 'redux-form'
import {rules, findRuleByName } from 'Engine/rules'
import {rules, findRuleByName, findRuleByDottedName } from 'Engine/rules'
import {nextSteps, makeQuestion} from 'Engine/generateQuestions'
import computeThemeColours from 'Components/themeColours'
import { STEP_ACTION, START_CONVERSATION, EXPLAIN_VARIABLE, CHANGE_THEME_COLOUR} from './actions'
@ -13,8 +13,20 @@ import {analyseTopDown} from 'Engine/traverse'
import ReactPiwik from 'Components/Tracker';
// Our situationGate retrieves data from the "conversation" form
let fromConversation = state => name => formValueSelector('conversation')(state, name)
import formValueTypes from 'Components/conversation/formValueTypes'
let fromConversation = flatRules => state => name => {
// Our situationGate retrieves data from the "conversation" form
// The search below is to apply input conversions such as replacing "," with "."
if (name.startsWith("sys.")) return null
let rule = findRuleByDottedName(flatRules, name),
format = rule ? formValueTypes[rule.format] : null,
pre = format && format.validator.pre ? format.validator.pre : R.identity,
value = formValueSelector('conversation')(state, name)
return value && pre(value)
}
// assume "wraps" a given situation function with one that overrides its values with
// the given assumptions
@ -153,5 +165,5 @@ export default reduceReducers(
}),
// cross-cutting concerns because here `state` is the whole state tree
reduceSteps(ReactPiwik, rules, fromConversation)
reduceSteps(ReactPiwik, rules, fromConversation(rules))
)