diff --git a/source/components/conversation/FormDecorator.js b/source/components/conversation/FormDecorator.js index 147dbad9d..f20b926ba 100644 --- a/source/components/conversation/FormDecorator.js +++ b/source/components/conversation/FormDecorator.js @@ -3,10 +3,10 @@ import classNames from 'classnames' import { connect } from 'react-redux' import { Field, change } from 'redux-form' import { stepAction } from '../../actions' -import StepAnswer from './StepAnswer' import { capitalise0 } from '../../utils' import R from 'ramda' import Explicable from 'Components/conversation/Explicable' +import IgnoreStepButton from './IgnoreStepButton' /* This higher order component wraps "Form" components (e.g. Question.js), that represent user inputs, @@ -24,7 +24,7 @@ export var FormDecorator = formType => RenderField => }), dispatch => ({ stepAction: (name, step) => dispatch(stepAction(name, step)), - setFormValue: (field, value) => + setFormValue: (field, value) => console.log(field, value) || dispatch(change('conversation', field, value)) }) ) @@ -33,42 +33,9 @@ export var FormDecorator = formType => RenderField => helpVisible: false } render() { - let { - stepAction, - themeColours, - setFormValue, - /* Une étape déjà répondue est marquée 'folded'. Dans ce dernier cas, un résumé - de la réponse est affiché */ - unfolded, - fieldName, - inverted - } = this.props, - { - 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, - // formerly in conversation-steps - valueType, - human, - helpText - } = this.props.step + let { unfolded } = this.props, + { helpText } = this.props.step - /* Nos propriétés personnalisées à envoyer au RenderField. - Elles sont regroupées dans un objet précis pour pouvoir être enlevées des - props passées à ce dernier, car React 15.2 n'aime pas les attributes inconnus - des balises html, dans notre cas. - */ - let stepProps = { - ...this.props.step, - inverted, - //TODO hack, enables redux-form/CHANGE to update the form state before the traverse functions are run - submit: () => setTimeout(() => stepAction('fold', fieldName), 1), - setFormValue: (value, name = fieldName) => setFormValue(name, value) - } - - /* There won't be any answer zone here, widen the question zone */ - let wideQuestion = formType == 'rhetorical-question' && !possibleChoice - - let { pre = v => v, test, error } = valueType ? valueType.validator : {}, - validate = test && (v => (v && test(pre(v)) ? undefined : error)) return (
{this.state.helpVisible && this.renderHelpBox(helpText)} @@ -77,51 +44,50 @@ export var FormDecorator = formType => RenderField => visibility: this.state.helpVisible ? 'hidden' : 'visible' }} > - {this.renderHeader( - unfolded, - valueType, - human, - helpText, - wideQuestion - )} - {unfolded && ( -
- -
- )} + {/* 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()}
) } - /* - < Le titre de ma question > ----------- < (? bulle d'aide) OU résultat > - */ - renderHeader(unfolded, valueType, human, helpText, wideQuestion) { - let { step: { subquestion }, fieldName, inversion } = this.props - return ( - - {unfolded - ? this.renderQuestion( - unfolded, - helpText, - wideQuestion, - subquestion, - fieldName, - inversion - ) - : this.renderTitleAndAnswer(valueType, human)} - - ) - } + renderUnfolded() { + let { + setFormValue, + stepAction, + step: { + subquestion, + 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, + defaultValue, + valueType + }, + fieldName, + inversion, + inverted, + themeColours + } = this.props + + /* Nos propriétés personnalisées à envoyer au RenderField. + Elles sont regroupées dans un objet précis pour pouvoir être enlevées des + props passées à ce dernier, car React 15.2 n'aime pas les attributes inconnus + des balises html, dans notre cas. + */ + let submit = () => setTimeout(() => stepAction('fold', fieldName), 1), + stepProps = { + ...this.props.step, + inverted, + //TODO hack, enables redux-form/CHANGE to update the form state before the traverse functions are run + submit, + setFormValue: (value, name = fieldName) => setFormValue(name, value) + } + + /* There won't be any answer zone here, widen the question zone */ + let wideQuestion = formType == 'rhetorical-question' && !possibleChoice + + let { pre = v => v, test, error } = valueType ? valueType.validator : {}, + validate = test && (v => (v && test(pre(v)) ? undefined : error)) - renderQuestion(unfolded, helpText, wideQuestion, subquestion, fieldName, inversion) { let question = (

RenderField =>

) return ( -
- {inversion ? ( - question - ) : ( - {question} - )} -
+
+
+
+ {inversion ? ( + question + ) : ( + {question} + )} +
+
+ {defaultValue && ( + { + setFormValue(fieldName, '' + defaultValue) + submit() + }} + /> + )} +
+
+ +
) } - renderTitleAndAnswer(valueType, human) { + renderFolded() { let { - step, stepAction, situationGate, themeColours, @@ -180,7 +166,7 @@ export var FormDecorator = formType => RenderField => {' '} Modifier - {/* */} + {}
) } diff --git a/source/components/conversation/IgnoreStepButton.css b/source/components/conversation/IgnoreStepButton.css new file mode 100644 index 000000000..90963ea23 --- /dev/null +++ b/source/components/conversation/IgnoreStepButton.css @@ -0,0 +1,22 @@ + +#ignore, #ignore:visited { + cursor: pointer; + color: #444; + font-weight: 200; + text-decoration: none; + border-bottom: 1px solid #aaa; + font-size: 80%; + line-height: 1.2em; + font-style: italic; +} + +#ignoreIcon { + font-size: 80%; + font-weight: bold; + background: #ddd; + color: white; + margin-right: .6em; + padding: .5em .4em; + border-radius: .2em; + transition: .2s opacity; +} diff --git a/source/components/conversation/IgnoreStepButton.js b/source/components/conversation/IgnoreStepButton.js index 7637794cb..36574b514 100644 --- a/source/components/conversation/IgnoreStepButton.js +++ b/source/components/conversation/IgnoreStepButton.js @@ -1,13 +1,16 @@ import React, { Component } from 'react' +import './IgnoreStepButton.css' +import HoverDecorator from 'Components/HoverDecorator' +@HoverDecorator export default class IgnoreStepButton extends Component { componentDidMount() { // removeEventListener will need the exact same function instance this.boundHandleKeyDown = this.handleKeyDown.bind(this) - + window.addEventListener('keydown', this.boundHandleKeyDown) } - handleKeyDown({key}) { + handleKeyDown({ key }) { if (key !== 'Escape') return this.props.action() } @@ -15,8 +18,13 @@ export default class IgnoreStepButton extends Component { window.removeEventListener('keydown', this.boundHandleKeyDown) } render() { - return - passer - + return ( +
+ Échap + + passer + +
+ ) } } diff --git a/source/components/conversation/conversation.css b/source/components/conversation/conversation.css index f3c6ced49..0e80acfa5 100644 --- a/source/components/conversation/conversation.css +++ b/source/components/conversation/conversation.css @@ -106,7 +106,7 @@ /* END Group items animation */ /* Group ignore buttons */ -.form-group .header .ignore { +.form-group .header #ignore { margin-left: 3em; } @@ -126,14 +126,20 @@ } .step-question { + max-width: 70%; +} + +.unfoldedHeader { margin-bottom: 2em; + display: flex; + justify-content: space-between; + align-items: center; } .step h1 { border: 2px solid #333350; color: #333350; display: inline-block; - max-width: 75%; font-size: 110%; font-weight: 600; padding: .6em 1em; @@ -263,23 +269,6 @@ vertical-align: middle; } -.ignore, .ignore:visited { - cursor: pointer; - color: #888; - font-weight: 200; - text-decoration: none; - border-bottom: 1px solid #ccc; - font-size: 80%; - line-height: 1.2em; - font-style: italic; -} - -/* step ignore buttons */ -fieldset > .ignore { - position: absolute; - bottom: 0em; -} - .step input[type=radio] { display : none; }