diff --git a/package.json b/package.json index 14be39b23..9a535cb60 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "react-helmet": "^5.2.0", "react-highlight-words": "^0.11.0", "react-hot-loader": "^4.3.11", - "react-i18next": "^7.13.0", + "react-i18next": "^8.3.0", "react-redux": "^5.0.7", "react-router": "^4.2.0", "react-router-dom": "^4.2.2", @@ -48,7 +48,7 @@ "redux": "^3.7.2", "redux-form": "^7.4.2", "redux-thunk": "^2.3.0", - "reselect": "^3.0.1", + "reselect": "^4.0.0", "screenfull": "^3.3.2" }, "scripts": { @@ -71,10 +71,9 @@ }, "devDependencies": { "@babel/core": "^7.1.0", - "@babel/plugin-proposal-decorators": "^7.1.0", + "@babel/plugin-proposal-class-properties": "^7.1.0", "@babel/plugin-proposal-object-rest-spread": "^7.0.0", "@babel/plugin-proposal-optional-chaining": "^7.0.0", - "@babel/plugin-syntax-decorators": "^7.1.0", "@babel/polyfill": "^7.0.0", "@babel/preset-env": "^7.1.0", "@babel/preset-flow": "^7.0.0-beta.51", @@ -84,8 +83,6 @@ "babel-eslint": "^9.0.0", "babel-loader": "^8.0.2", "babel-plugin-syntax-dynamic-import": "^6.18.0", - "babel-plugin-transform-class-properties": "^6.24.1", - "babel-plugin-transform-decorators": "^6.24.1", "babel-plugin-transform-do-expressions": "^6.22.0", "babel-plugin-webpack-alias": "^2.1.2", "chai": "^4.1.2", diff --git a/source/.babelrc b/source/.babelrc index 806b13c79..d1fea7046 100644 --- a/source/.babelrc +++ b/source/.babelrc @@ -13,11 +13,10 @@ "@babel/flow" ], "plugins": [ - ["@babel/plugin-proposal-decorators", { "legacy": true }], - "transform-do-expressions", + "@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-optional-chaining", "@babel/plugin-proposal-object-rest-spread", - "transform-class-properties", + "transform-do-expressions", "syntax-dynamic-import", "react-hot-loader/babel", ["webpack-alias", { "config": "./source/webpack.dev.js" }] diff --git a/source/components/Aide.js b/source/components/Aide.js index daf0e4995..a583892e4 100644 --- a/source/components/Aide.js +++ b/source/components/Aide.js @@ -2,55 +2,60 @@ import { EXPLAIN_VARIABLE } from 'Actions/actions' import withColours from 'Components/utils/withColours' import marked from 'Engine/marked' import { findRuleByDottedName } from 'Engine/rules' +import { compose } from 'ramda' import React, { Component } from 'react' import { connect } from 'react-redux' import { flatRulesSelector } from 'Selectors/analyseSelectors' import './Aide.css' import References from './rule/References' -@connect( - state => ({ - explained: state.explainedVariable, - flatRules: flatRulesSelector(state) - }), - dispatch => ({ - stopExplaining: () => dispatch({ type: EXPLAIN_VARIABLE }) - }) + +export default compose( + connect( + state => ({ + explained: state.explainedVariable, + flatRules: flatRulesSelector(state) + }), + dispatch => ({ + stopExplaining: () => dispatch({ type: EXPLAIN_VARIABLE }) + }) + ), + withColours +)( + class Aide extends Component { + renderExplanationMarkdown(explanation, term) { + return marked(`### ${term} \n\n${explanation}`) + } + render() { + let { flatRules, explained, stopExplaining, colours } = this.props + + if (!explained) return
+ + let rule = findRuleByDottedName(flatRules, explained), + text = rule.description, + refs = rule.références + + return ( +
+
+ +

+ {refs && ( +

+

Pour en savoir plus:

+ +
+ )} +
+
+ ) + } + } ) -@withColours -export default class Aide extends Component { - renderExplanationMarkdown(explanation, term) { - return marked(`### ${term} \n\n${explanation}`) - } - render() { - let { flatRules, explained, stopExplaining, colours } = this.props - - if (!explained) return
- - let rule = findRuleByDottedName(flatRules, explained), - text = rule.description, - refs = rule.références - - return ( -
-
- -

- {refs && ( -

-

Pour en savoir plus:

- -
- )} -
-
- ) - } -} diff --git a/source/components/AnimatedTargetValue.js b/source/components/AnimatedTargetValue.js index 544d805a4..3bc17e04d 100644 --- a/source/components/AnimatedTargetValue.js +++ b/source/components/AnimatedTargetValue.js @@ -1,34 +1,32 @@ -import React, { Component } from 'react' import withLanguage from 'Components/utils/withLanguage' - -import './AnimatedTargetValue.css' +import React, { Component } from 'react' import ReactCSSTransitionGroup from 'react-addons-css-transition-group' +import './AnimatedTargetValue.css' -@withLanguage -class AnimatedTargetValue extends Component { - render() { - let { value, language } = this.props - let formattedValue = - value == null - ? '' - : Intl.NumberFormat(language, { - style: 'currency', - currency: 'EUR', - maximumFractionDigits: 0, - minimumFractionDigits: 0 - }).format(value) - return ( - - - {' '} - {formattedValue} - - - ) +export default withLanguage( + class AnimatedTargetValue extends Component { + render() { + let { value, language } = this.props + let formattedValue = + value == null + ? '' + : Intl.NumberFormat(language, { + style: 'currency', + currency: 'EUR', + maximumFractionDigits: 0, + minimumFractionDigits: 0 + }).format(value) + return ( + + + {' '} + {formattedValue} + + + ) + } } -} - -export default AnimatedTargetValue +) diff --git a/source/components/Feedback/PageFeedback.js b/source/components/Feedback/PageFeedback.js index 56927466d..50c836307 100644 --- a/source/components/Feedback/PageFeedback.js +++ b/source/components/Feedback/PageFeedback.js @@ -2,7 +2,7 @@ import withTracker from 'Components/utils/withTracker' import React, { Component } from 'react' -import { Trans, translate } from 'react-i18next' +import { Trans, withI18n } from 'react-i18next' import { withRouter } from 'react-router-dom' import { compose } from 'redux' import safeLocalStorage from '../../storage/safeLocalStorage' @@ -93,37 +93,36 @@ class PageFeedback extends Component { return ( !this.props.blacklist.includes(this.props.location.pathname) && (
- {!this.state.showForm && - !this.state.showThanks && ( - <> -
- {this.props.customMessage || ( - - Cette page vous a-t-elle été utile ? - - )}{' '} - {' '} - -
- {' '} - - )} + +
+ {' '} + + )} {this.state.showThanks && (
@@ -150,7 +149,7 @@ const PageFeedbackWithRouter = ({ location, ...props }) => ( ) export default compose( - translate(), + withI18n(), withTracker, withRouter )(PageFeedbackWithRouter) diff --git a/source/components/LangSwitcher.js b/source/components/LangSwitcher.js index 4c4c2960d..e0372a587 100644 --- a/source/components/LangSwitcher.js +++ b/source/components/LangSwitcher.js @@ -1,7 +1,7 @@ -import PropTypes from 'prop-types' +import { compose } from 'ramda' import React, { Component } from 'react' import emoji from 'react-easy-emoji' -import { translate } from 'react-i18next' +import { withI18n } from 'react-i18next' import { connect } from 'react-redux' import { withRouter } from 'react-router' @@ -10,37 +10,38 @@ const languageCodeToEmoji = { fr: '🇫🇷' } -@withRouter -@translate() -@connect( - null, - dispatch => ({ - changeLanguage: lang => dispatch({ type: 'SWITCH_LANG', lang }) - }) -) -export default class LangSwitcher extends Component { - static contextTypes = { - i18n: PropTypes.object.isRequired - } - getUnusedLanguageCode = () => { - let languageCode = this.context.i18n.language - return !languageCode || languageCode === 'fr' ? 'en' : 'fr' - } +export default compose( + withRouter, + withI18n(), + connect( + null, + dispatch => ({ + changeLanguage: lang => dispatch({ type: 'SWITCH_LANG', lang }) + }) + ) +)( + class LangSwitcher extends Component { + getUnusedLanguageCode = () => { + let languageCode = this.props.i18n.language + return !languageCode || languageCode === 'fr' ? 'en' : 'fr' + } - changeLanguage = () => { - let nextLanguage = this.getUnusedLanguageCode() - this.props.changeLanguage(nextLanguage) - this.context.i18n.changeLanguage(nextLanguage) - this.forceUpdate() + changeLanguage = () => { + let nextLanguage = this.getUnusedLanguageCode() + this.props.changeLanguage(nextLanguage) + this.props.i18n.changeLanguage(nextLanguage) + this.forceUpdate() + } + render() { + const languageCode = this.getUnusedLanguageCode() + return ( + + ) + } } - render() { - const languageCode = this.getUnusedLanguageCode() - return ( - - ) - } -} +) diff --git a/source/components/LegalNotice.js b/source/components/LegalNotice.js index 9cd50a329..97d5fc25d 100644 --- a/source/components/LegalNotice.js +++ b/source/components/LegalNotice.js @@ -1,10 +1,9 @@ import Overlay from 'Components/Overlay' import { ScrollToTop } from 'Components/utils/Scroll' import React, { Component } from 'react' -import { Trans } from 'react-i18next' -import translate from 'react-i18next/dist/commonjs/translate' +import { Trans, withI18n } from 'react-i18next' -export const LegalNoticeContent = translate()(() => ( +export const LegalNoticeContent = withI18n()(() => ( <>

Mentions légales diff --git a/source/components/PreviousSimulationBanner.js b/source/components/PreviousSimulationBanner.js index 179192857..6a660fe05 100644 --- a/source/components/PreviousSimulationBanner.js +++ b/source/components/PreviousSimulationBanner.js @@ -5,7 +5,7 @@ import { } from 'Actions/actions' import { compose } from 'ramda' import React from 'react' -import { Trans, translate } from 'react-i18next' +import { Trans, withI18n } from 'react-i18next' import { connect } from 'react-redux' import { noUserInputSelector } from 'Selectors/analyseSelectors' import { LinkButton } from 'Ui/Button' @@ -33,7 +33,8 @@ const PreviousSimulationBanner = ({ Retrouver ma simulation - .{' '} + + .{' '} Effacer @@ -41,7 +42,7 @@ const PreviousSimulationBanner = ({ ) export default compose( - translate(), + withI18n(), connect( state => ({ previousSimulation: state.previousSimulation, diff --git a/source/components/ProgressTip.js b/source/components/ProgressTip.js index 0e77f4740..7d0ad2497 100644 --- a/source/components/ProgressTip.js +++ b/source/components/ProgressTip.js @@ -4,27 +4,28 @@ import { connect } from 'react-redux' import { nextStepsSelector } from 'Selectors/analyseSelectors' import './ProgressTip.css' -@connect(state => ({ +export default connect(state => ({ nextSteps: nextStepsSelector(state) -})) -export default class ProgressTip extends Component { - render() { - let { nextSteps } = this.props, - nbQuestions = nextSteps.length - if (nbQuestions === 0) return null +}))( + class ProgressTip extends Component { + render() { + let { nextSteps } = this.props, + nbQuestions = nextSteps.length + if (nbQuestions === 0) return null - return ( -
-

- {nbQuestions === 1 ? ( - dernière question ! - ) : ( - - moins de {{ nbQuestions }} questions - - )} -

-
- ) + return ( +
+

+ {nbQuestions === 1 ? ( + dernière question ! + ) : ( + + moins de {{ nbQuestions }} questions + + )} +

+
+ ) + } } -} +) diff --git a/source/components/RulePage.js b/source/components/RulePage.js index 3da6a80a3..aa9dd7057 100644 --- a/source/components/RulePage.js +++ b/source/components/RulePage.js @@ -8,7 +8,7 @@ import { } from 'Engine/rules.js' import { compose, head, path } from 'ramda' import React, { Component } from 'react' -import { Trans, translate } from 'react-i18next' +import { Trans, withI18n } from 'react-i18next' import { connect } from 'react-redux' import { withRouter } from 'react-router' import { Link, Redirect } from 'react-router-dom' @@ -20,80 +20,88 @@ import Namespace from './rule/Namespace' import Rule from './rule/Rule' import './RulePage.css' import SearchButton from './SearchButton' -@connect(state => ({ - themeColours: state.themeColours, - valuesToShow: !noUserInputSelector(state), - flatRules: flatRulesSelector(state) -})) -@translate() -class RulePage extends Component { - render() { - let { flatRules } = this.props, - name = path(['match', 'params', 'name'], this.props), - decodedRuleName = decodeRuleName(name) - if (decodedRuleName.includes(' . ')) { - if (!findRuleByDottedName(flatRules, decodedRuleName)) - return +export default compose( + connect(state => ({ + themeColours: state.themeColours, + valuesToShow: !noUserInputSelector(state), + flatRules: flatRulesSelector(state) + })), + withI18n() +)( + class RulePage extends Component { + render() { + let { flatRules } = this.props, + name = path(['match', 'params', 'name'], this.props), + decodedRuleName = decodeRuleName(name) - return this.renderRule(decodedRuleName) + if (decodedRuleName.includes(' . ')) { + if (!findRuleByDottedName(flatRules, decodedRuleName)) + return + + return this.renderRule(decodedRuleName) + } + + let rules = findRulesByName(flatRules, decodedRuleName) + if (!rules.length) return + if (rules.length > 1) + return + let dottedName = head(rules).dottedName + return this.renderRule(dottedName) } - - let rules = findRulesByName(flatRules, decodedRuleName) - if (!rules.length) return - if (rules.length > 1) - return - let dottedName = head(rules).dottedName - return this.renderRule(dottedName) - } - renderRule(dottedName) { - return ( -
- -
- - + renderRule(dottedName) { + return ( +
+ +
+ + +
+
- -
- ) + ) + } } -} - -@connect( - null, - dispatch => ({ - setExample: compose( - dispatch, - setExample - ) - }) ) -@withRouter -@translate() // Triggers rerender when the language changes -class BackToSimulation extends Component { - render() { - let { colour, setExample, visible } = this.props - return ( - { - setExample(null) - }} - style={{ color: colour, visibility: visible ? 'visible' : 'hidden' }}> -