🎨 ✨ Format the currencies depending on the locale
Add a withLanguage HOC for abstracting the language implementationpull/226/head
parent
e1eb3d367c
commit
7ab7c6c7eb
|
@ -17,6 +17,12 @@ env:
|
|||
browser: true
|
||||
commonjs: true
|
||||
es6: true
|
||||
|
||||
overrides:
|
||||
files: "*.test.js"
|
||||
env:
|
||||
mocha: true
|
||||
|
||||
extends:
|
||||
- eslint:recommended
|
||||
- plugin:react/recommended
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import Enzyme from 'enzyme'
|
||||
import Adapter from 'enzyme-adapter-react-16'
|
||||
import chai from 'chai'
|
||||
import sinonChai from 'sinon-chai'
|
||||
|
||||
chai.use(sinonChai)
|
||||
Enzyme.configure({ adapter: new Adapter() })
|
||||
|
||||
// Setup Intl in "en" and "fr" for testing
|
||||
// var areIntlLocalesSupported = require('intl-locales-supported')
|
||||
|
||||
// var localesMyAppSupports = ['en', 'fr']
|
||||
global.Intl = require('intl')
|
||||
require('intl/locale-data/jsonp/en.js')
|
||||
require('intl/locale-data/jsonp/fr.js')
|
37
index.html
37
index.html
|
@ -1,21 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="initial-scale=1">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="google-site-verification" content="C03WwnrJP0FLqf83ibMBA7_N-TLQcwsJaAhqKXppxaE" />
|
||||
<title>Simulateur d'embauche</title>
|
||||
<meta name="description" content="Simulation du prix d'une embauche en France" data-react-helmet="true"> <!-- data-helmet pour que React Helmet puisse écraser ce meta par défaut -->
|
||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans:200,300,400,500,600,700' rel='stylesheet' type='text/css'>
|
||||
<link rel="manifest" href="/manifest.webmanifest">
|
||||
<meta name="theme-color" content="#2975d1">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="js" />
|
||||
<script src="https://use.fontawesome.com/1da10bbdec.js"></script>
|
||||
<script type="text/javascript" src="/dist/bundle.js"></script>
|
||||
</body>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="initial-scale=1">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="google-site-verification" content="C03WwnrJP0FLqf83ibMBA7_N-TLQcwsJaAhqKXppxaE" />
|
||||
<title>Simulateur d'embauche</title>
|
||||
<meta name="description" content="Simulation du prix d'une embauche en France" data-react-helmet="true">
|
||||
<!-- data-helmet pour que React Helmet puisse écraser ce meta par défaut -->
|
||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans:200,300,400,500,600,700' rel='stylesheet' type='text/css'>
|
||||
<link rel="manifest" href="/manifest.webmanifest">
|
||||
<meta name="theme-color" content="#2975d1">
|
||||
</head>
|
||||
|
||||
</html>
|
||||
<body>
|
||||
<div id="js" />
|
||||
<script src="https://use.fontawesome.com/1da10bbdec.js"></script>
|
||||
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en,Intl.~locale.fr"></script>
|
||||
<script type="text/javascript" src="/dist/bundle.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
48
package.json
48
package.json
|
@ -6,9 +6,12 @@
|
|||
"url": "git@github.com:betagouv/syso.git"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.10.0 <10.0.0"
|
||||
"node": ">=8.10.0"
|
||||
},
|
||||
"browserslist": ["> 1% in FR", "not ie < 11"],
|
||||
"browserslist": [
|
||||
"> 1% in FR",
|
||||
"not ie < 11"
|
||||
],
|
||||
"dependencies": {
|
||||
"@babel/core": "=7.0.0-beta.46",
|
||||
"@babel/plugin-proposal-decorators": "=7.0.0-beta.46",
|
||||
|
@ -34,8 +37,6 @@
|
|||
"daggy": "^1.2.0",
|
||||
"dedent-js": "^1.0.1",
|
||||
"deep-assign": "^2.0.0",
|
||||
"eslint": "^4.19.0",
|
||||
"eslint-plugin-react": "^7.7.0",
|
||||
"express": "^4.16.3",
|
||||
"fantasy-combinators": "0.0.1",
|
||||
"fantasy-land": "^3.5.0",
|
||||
|
@ -54,8 +55,6 @@
|
|||
"json-loader": "^0.5.7",
|
||||
"live-server": "^1.2.0",
|
||||
"marked": "^0.3.17",
|
||||
"mocha": "^5.0.4",
|
||||
"mocha-webpack": "^2.0.0-beta.0",
|
||||
"nearley": "^2.13.0",
|
||||
"nearley-loader": "^2.0.0",
|
||||
"npm": "^5.7.1",
|
||||
|
@ -98,28 +97,31 @@
|
|||
"yaml-loader": "^0.5.0"
|
||||
},
|
||||
"scripts": {
|
||||
"pretest":
|
||||
"LIST=`git diff --name-only HEAD..HEAD^ | grep .*\\.js | grep -v json`; if [ \"$LIST\" ]; then eslint $LIST; fi",
|
||||
"pretest": "LIST=`git diff --name-only HEAD..HEAD^ | grep .*\\.js | grep -v json`; if [ \"$LIST\" ]; then eslint $LIST; fi",
|
||||
"start": "node source/server.js",
|
||||
"externalize": "node source/externalize.js",
|
||||
"compile": "webpack --config source/webpack.prod.js",
|
||||
"test":
|
||||
"mocha-webpack --webpack-config source/webpack.test.js --require source-map-support/register --require test/helpers/browser.js \"test/**/*.test.js\"",
|
||||
"test-watch":
|
||||
"mocha-webpack --webpack-config source/webpack.test.js --require source-map-support/register --require test/helpers/browser.js \"test/**/*.test.js\" --watch",
|
||||
"test-meca":
|
||||
"mocha-webpack --webpack-config source/webpack.test.js --require source-map-support/register --require test/helpers/browser.js test/mecanisms.test.js --watch",
|
||||
"test-rules":
|
||||
"mocha-webpack --webpack-config source/webpack.test.js --require source-map-support/register --require test/helpers/browser.js test/real-rules.test.js --watch",
|
||||
"test-inversions":
|
||||
"mocha-webpack --webpack-config source/webpack.test.js --require source-map-support/register --require test/helpers/browser.js \"test/inversion.test.js\" --watch",
|
||||
"test": "mocha-webpack --webpack-config source/webpack.test.js --require source-map-support/register --include componentTestSetup.js --require test/helpers/browser.js \"./{,!(node_modules)/**/}!(webpack).test.js\"",
|
||||
"test-watch": "mocha-webpack --webpack-config source/webpack.test.js --require source-map-support/register --require test/helpers/browser.js \"test/**/*.test.js\" --watch",
|
||||
"test-meca": "mocha-webpack --webpack-config source/webpack.test.js --require source-map-support/register --require test/helpers/browser.js test/mecanisms.test.js --watch",
|
||||
"test-rules": "mocha-webpack --webpack-config source/webpack.test.js --require source-map-support/register --require test/helpers/browser.js test/real-rules.test.js --watch",
|
||||
"test-inversions": "mocha-webpack --webpack-config source/webpack.test.js --require source-map-support/register --require test/helpers/browser.js \"test/inversion.test.js\" --watch",
|
||||
"test-components": "mocha-webpack --webpack-config source/webpack.test.js --require source-map-support/register --include componentTestSetup.js --require test/helpers/browser.js \"source/components/**/*.test.js\" --watch",
|
||||
"heroku-postbuild": "yarn install --production=false && yarn compile",
|
||||
"eslint":
|
||||
"LIST=`git diff --cached --name-only HEAD | grep .*\\.js | grep -v json`; if [ \"$LIST\" ]; then eslint $LIST; fi",
|
||||
"eslint-check":
|
||||
"eslint --print-config .eslintrc | eslint-config-prettier-check"
|
||||
"eslint": "LIST=`git diff --cached --name-only HEAD | grep .*\\.js | grep -v json`; if [ \"$LIST\" ]; then eslint $LIST; fi",
|
||||
"eslint-check": "eslint --print-config .eslintrc | eslint-config-prettier-check"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint-config-prettier": "^2.9.0"
|
||||
"enzyme": "^3.3.0",
|
||||
"enzyme-adapter-react-16": "^1.1.1",
|
||||
"eslint": "^4.19.0",
|
||||
"eslint-config-prettier": "^2.9.0",
|
||||
"eslint-plugin-react": "^7.7.0",
|
||||
"intl": "^1.2.5",
|
||||
"intl-locales-supported": "^1.0.0",
|
||||
"mocha": "^5.0.4",
|
||||
"mocha-webpack": "^2.0.0-beta.0",
|
||||
"sinon": "^4.5.0",
|
||||
"sinon-chai": "^3.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
.currencyInput__container {
|
||||
display: flex !important;
|
||||
align-items: baseline;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.currencyInput__input {
|
||||
height: inherit;
|
||||
border: none;
|
||||
text-align: inherit;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
min-width: 0;
|
||||
color: inherit;
|
||||
background-color: inherit;
|
||||
font-size: inherit;
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
import React, { Component } from 'react'
|
||||
import { dissoc } from 'ramda'
|
||||
import classnames from 'classnames'
|
||||
import './CurrencyInput.css'
|
||||
|
||||
let isCurrencyPrefixed = language =>
|
||||
!!Intl.NumberFormat(language, {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
})
|
||||
.format(12)
|
||||
.match(/€.*12/)
|
||||
|
||||
class CurrencyInput extends Component {
|
||||
state = {
|
||||
value: ''
|
||||
}
|
||||
static getDerivedStateFromProps(nextProps) {
|
||||
return {
|
||||
value: nextProps.value
|
||||
}
|
||||
}
|
||||
getSnapshotBeforeUpdate = () => {
|
||||
return this.input.selectionStart
|
||||
}
|
||||
componentDidMount() {
|
||||
this.adaptInputSize()
|
||||
}
|
||||
adaptInputSize = () => {
|
||||
if (this.input && isCurrencyPrefixed(this.props.language))
|
||||
this.input.style.width = this.input.value.length + 0.2 + 'ch'
|
||||
}
|
||||
componentDidUpdate = (_, __, cursorPosition) => {
|
||||
this.input.selectionStart = cursorPosition
|
||||
this.input.selectionEnd = cursorPosition
|
||||
this.adaptInputSize()
|
||||
}
|
||||
focusInput = () => {
|
||||
this.input.focus()
|
||||
}
|
||||
handleChange = event => {
|
||||
let value = event.target.value
|
||||
value = value
|
||||
.replace(/,/g, '.')
|
||||
.replace(/[^\d.]/g, '')
|
||||
.replace(/\.(.*)\.(.*)/g, '$1.$2')
|
||||
|
||||
this.setState({ value }, this.adaptInputSize)
|
||||
if (value.endsWith('.')) {
|
||||
return
|
||||
}
|
||||
if (this.props.onChange) {
|
||||
event.target.value = value
|
||||
this.props.onChange(event)
|
||||
}
|
||||
}
|
||||
render() {
|
||||
let forwardedProps = dissoc(
|
||||
['onChange', 'value', 'language', 'className'],
|
||||
this.props
|
||||
)
|
||||
return (
|
||||
<div
|
||||
onClick={this.focusInput}
|
||||
className={classnames(
|
||||
this.props.className,
|
||||
'currencyInput__container'
|
||||
)}>
|
||||
{isCurrencyPrefixed(this.props.language) && '€'}
|
||||
<input
|
||||
{...forwardedProps}
|
||||
className="currencyInput__input"
|
||||
onChange={this.handleChange}
|
||||
ref={ref => (this.input = ref)}
|
||||
value={this.state.value}
|
||||
/>
|
||||
{!isCurrencyPrefixed(this.props.language) && <> €</>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default CurrencyInput
|
|
@ -0,0 +1,68 @@
|
|||
import CurrencyInput from './CurrencyInput'
|
||||
import React from 'react'
|
||||
import { shallow } from 'enzyme'
|
||||
import { expect } from 'chai'
|
||||
import { spy, match } from 'sinon'
|
||||
|
||||
let getInput = component => shallow(component).find('input')
|
||||
describe('CurrencyInput', () => {
|
||||
it('should render an input', () => {
|
||||
expect(getInput(<CurrencyInput />)).to.have.length(1)
|
||||
})
|
||||
it('should accept both . and , as decimal separator', () => {
|
||||
let onChange = spy()
|
||||
const input = getInput(<CurrencyInput value={0} onChange={onChange} />)
|
||||
input.simulate('change', { target: { value: '12.1' } })
|
||||
expect(onChange).to.have.been.calledWith(
|
||||
match.hasNested('target.value', '12.1')
|
||||
)
|
||||
input.simulate('change', { target: { value: '12,1' } })
|
||||
expect(onChange).to.have.been.calledWith(
|
||||
match.hasNested('target.value', '12.1')
|
||||
)
|
||||
})
|
||||
it('should not accept negative number', () => {
|
||||
let onChange = spy()
|
||||
const input = getInput(<CurrencyInput value={0} onChange={onChange} />)
|
||||
input.simulate('change', { target: { value: '-12' } })
|
||||
expect(onChange).to.have.been.calledWith(
|
||||
match.hasNested('target.value', '12')
|
||||
)
|
||||
})
|
||||
|
||||
it('should not accept anything else than number', () => {
|
||||
let onChange = spy()
|
||||
const input = getInput(<CurrencyInput value={0} onChange={onChange} />)
|
||||
input.simulate('change', { target: { value: '*1/2abc3' } })
|
||||
expect(onChange).to.have.been.calledWith(
|
||||
match.hasNested('target.value', '123')
|
||||
)
|
||||
})
|
||||
it('should pass other props to the input', () => {
|
||||
const input = getInput(<CurrencyInput autoFocus />)
|
||||
expect(input.prop('autoFocus')).to.be.true
|
||||
})
|
||||
it('should not call onChange while the decimal part is being written', () => {
|
||||
let onChange = spy()
|
||||
const input = getInput(<CurrencyInput value={0} onChange={onChange} />)
|
||||
input.simulate('change', { target: { value: '111,' } })
|
||||
expect(onChange).not.to.have.been.called
|
||||
})
|
||||
|
||||
it('should change the position of the currency symbol depending on the language', () => {
|
||||
const inputFr = shallow(<CurrencyInput value={0} language="fr" />)
|
||||
expect(
|
||||
inputFr
|
||||
.children()
|
||||
.last()
|
||||
.text()
|
||||
).to.includes('€')
|
||||
const inputEn = shallow(<CurrencyInput value={0} language="en" />)
|
||||
expect(
|
||||
inputEn
|
||||
.children()
|
||||
.first()
|
||||
.text()
|
||||
).to.includes('€')
|
||||
})
|
||||
})
|
|
@ -1,6 +1,4 @@
|
|||
import {
|
||||
curry,
|
||||
evolve,
|
||||
path,
|
||||
propEq,
|
||||
pathEq,
|
||||
|
@ -14,20 +12,19 @@ import {
|
|||
pathOr,
|
||||
toPairs,
|
||||
keys,
|
||||
head,
|
||||
find
|
||||
} from 'ramda'
|
||||
import React, { Component } from 'react'
|
||||
import { Trans, translate } from 'react-i18next'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import { withRouter } from 'react-router'
|
||||
import { Link } from 'react-router-dom'
|
||||
import withLanguage from './withLanguage'
|
||||
import { formValueSelector } from 'redux-form'
|
||||
import './Results.css'
|
||||
import '../engine/mecanismViews/Somme.css'
|
||||
|
||||
import { capitalise0, humanFigure } from '../utils'
|
||||
import { capitalise0 } from '../utils'
|
||||
import { nameLeaf, encodeRuleName, findRuleByDottedName } from 'Engine/rules'
|
||||
|
||||
// Filtered variables and rules can't be filtered in a uniform way, for now
|
||||
|
@ -70,6 +67,12 @@ export let byBranch = analysis => {
|
|||
return result
|
||||
}
|
||||
|
||||
let formatCurrency = language => number =>
|
||||
Intl.NumberFormat(language, {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(number)
|
||||
|
||||
@withRouter
|
||||
@connect(state => ({
|
||||
analysis: state.analysis,
|
||||
|
@ -79,6 +82,7 @@ export let byBranch = analysis => {
|
|||
inversions: formValueSelector('conversation')(state, 'inversions')
|
||||
}))
|
||||
@translate()
|
||||
@withLanguage
|
||||
export default class ResultsGrid extends Component {
|
||||
render() {
|
||||
let {
|
||||
|
@ -86,7 +90,8 @@ export default class ResultsGrid extends Component {
|
|||
situationGate,
|
||||
targetNames,
|
||||
inversions,
|
||||
flatRules
|
||||
flatRules,
|
||||
language
|
||||
} = this.props,
|
||||
rules = flatRules
|
||||
|
||||
|
@ -123,6 +128,7 @@ export default class ResultsGrid extends Component {
|
|||
flatRules,
|
||||
'contrat salarié . avantages salarié'
|
||||
)
|
||||
let formatLocalizedCurrency = formatCurrency(language)
|
||||
|
||||
return (
|
||||
<div className="somme resultsGrid">
|
||||
|
@ -140,7 +146,7 @@ export default class ResultsGrid extends Component {
|
|||
colSpan={(relevantSalaries.size - 1) * 2}
|
||||
className="element value"
|
||||
id="sommeBase">
|
||||
{humanFigure(2)(base)}{' '}
|
||||
{formatLocalizedCurrency(base)}{' '}
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -158,7 +164,7 @@ export default class ResultsGrid extends Component {
|
|||
className="element value"
|
||||
id="sommeBase">
|
||||
<span className="operator">+ </span>
|
||||
{humanFigure(2)(avan)}{' '}
|
||||
{formatLocalizedCurrency(avan)}{' '}
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -176,21 +182,20 @@ export default class ResultsGrid extends Component {
|
|||
className="element value"
|
||||
id="sommeBase">
|
||||
<span className="operator">= </span>
|
||||
{humanFigure(2)(brut)}{' '}
|
||||
{formatLocalizedCurrency(brut)}{' '}
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{toPairs(results).map(([branch, values]) => {
|
||||
let props = {
|
||||
key: branch,
|
||||
branch,
|
||||
values,
|
||||
analysis,
|
||||
rules,
|
||||
relevantSalaries
|
||||
}
|
||||
return <Row {...props} />
|
||||
return <Row key={branch} {...props} />
|
||||
})}
|
||||
<ReductionRow
|
||||
node={fromDict('contrat salarié . réductions de cotisations')}
|
||||
|
@ -204,7 +209,7 @@ export default class ResultsGrid extends Component {
|
|||
=
|
||||
</td>
|
||||
<td key="net" className="element value">
|
||||
{humanFigure(2)(net)}{' '}
|
||||
{formatLocalizedCurrency(net)}{' '}
|
||||
<span className="annotation">
|
||||
<Trans>Salaire net</Trans>
|
||||
</span>
|
||||
|
@ -216,7 +221,7 @@ export default class ResultsGrid extends Component {
|
|||
=
|
||||
</td>,
|
||||
<td key="total" className="element value">
|
||||
{humanFigure(2)(total)}{' '}
|
||||
{formatLocalizedCurrency(total)}{' '}
|
||||
<span className="annotation">
|
||||
<Trans>Salaire chargé</Trans>
|
||||
</span>
|
||||
|
@ -231,25 +236,31 @@ export default class ResultsGrid extends Component {
|
|||
}
|
||||
|
||||
@translate()
|
||||
@withLanguage
|
||||
class Row extends Component {
|
||||
static contextTypes = {
|
||||
i18n: PropTypes.object.isRequired
|
||||
}
|
||||
state = {
|
||||
folded: true
|
||||
}
|
||||
render() {
|
||||
let { rules, branch, values, analysis, relevantSalaries } = this.props,
|
||||
let {
|
||||
rules,
|
||||
branch,
|
||||
values,
|
||||
analysis,
|
||||
relevantSalaries,
|
||||
language,
|
||||
t
|
||||
} = this.props,
|
||||
detail = byName(values),
|
||||
ruleData = mapObjIndexed(
|
||||
(v, k, o) => findRuleByDottedName(rules, k),
|
||||
(v, k) => findRuleByDottedName(rules, k),
|
||||
detail
|
||||
),
|
||||
{ i18n } = this.context
|
||||
formatLocalizedCurrency = formatCurrency(language)
|
||||
|
||||
let title = name => {
|
||||
let node = ruleData[name]
|
||||
return node.title || capitalise0(i18n.t(node.name))
|
||||
return node.title || capitalise0(t(node.name))
|
||||
}
|
||||
|
||||
let aggregateRow = (
|
||||
|
@ -257,8 +268,8 @@ class Row extends Component {
|
|||
key="aggregateRow"
|
||||
onClick={() => this.setState({ folded: !this.state.folded })}>
|
||||
<td key="category" className="element category name">
|
||||
{capitalise0(i18n.t(branch))} <span className="unfoldIndication">
|
||||
{this.state.folded ? i18n.t('déplier') + ' >' : i18n.t('replier')}
|
||||
{capitalise0(t(branch))} <span className="unfoldIndication">
|
||||
{this.state.folded ? t('déplier') + ' >' : t('replier')}
|
||||
</span>
|
||||
</td>
|
||||
{this.state.folded ? (
|
||||
|
@ -269,7 +280,7 @@ class Row extends Component {
|
|||
-
|
||||
</td>
|
||||
<td key="value1" className="element value">
|
||||
{humanFigure(2)(cell(branch, 'salarié', analysis))}
|
||||
{formatLocalizedCurrency(cell(branch, 'salarié', analysis))}
|
||||
</td>
|
||||
</>
|
||||
)}
|
||||
|
@ -279,7 +290,7 @@ class Row extends Component {
|
|||
+
|
||||
</td>
|
||||
<td key="value2" className="element value">
|
||||
{humanFigure(2)(cell(branch, 'employeur', analysis))}
|
||||
{formatLocalizedCurrency(cell(branch, 'employeur', analysis))}
|
||||
</td>
|
||||
</>
|
||||
)}
|
||||
|
@ -305,7 +316,9 @@ class Row extends Component {
|
|||
-
|
||||
</td>
|
||||
<td key="value1" className="element value">
|
||||
{humanFigure(2)(subCell(detail, subCellName, 'salarié'))}
|
||||
{formatLocalizedCurrency(
|
||||
subCell(detail, subCellName, 'salarié')
|
||||
)}
|
||||
</td>
|
||||
</>
|
||||
)}
|
||||
|
@ -315,7 +328,9 @@ class Row extends Component {
|
|||
+
|
||||
</td>
|
||||
<td key="value2" className="element value">
|
||||
{humanFigure(2)(subCell(detail, subCellName, 'employeur'))}
|
||||
{formatLocalizedCurrency(
|
||||
subCell(detail, subCellName, 'employeur')
|
||||
)}
|
||||
</td>
|
||||
</>
|
||||
)}
|
||||
|
@ -330,25 +345,23 @@ class Row extends Component {
|
|||
// TODO Ce code est beaucoup trop spécifique
|
||||
// C'est essentiellement une copie de Row
|
||||
@translate()
|
||||
@withLanguage
|
||||
class ReductionRow extends Component {
|
||||
static contextTypes = {
|
||||
i18n: PropTypes.object.isRequired
|
||||
}
|
||||
state = {
|
||||
folded: true
|
||||
}
|
||||
render() {
|
||||
let { relevantSalaries, node } = this.props,
|
||||
{ i18n } = this.context
|
||||
let { relevantSalaries, node, language, t } = this.props
|
||||
if (!relevantSalaries.has('salaire total')) return null
|
||||
let value = node && node.nodeValue ? node.nodeValue : 0
|
||||
let formatLocalizedCurrency = formatCurrency(language)
|
||||
let aggregateRow = (
|
||||
<tr
|
||||
key="aggregateRowReductions"
|
||||
onClick={() => this.setState({ folded: !this.state.folded })}>
|
||||
<td key="category" className="element category name">
|
||||
<Trans>Réductions</Trans> <span className="unfoldIndication">
|
||||
{this.state.folded ? i18n.t('déplier') + ' >' : i18n.t('replier')}
|
||||
{this.state.folded ? t('déplier') + ' >' : t('replier')}
|
||||
</span>
|
||||
</td>
|
||||
{this.state.folded ? (
|
||||
|
@ -359,7 +372,7 @@ class ReductionRow extends Component {
|
|||
+
|
||||
</td>
|
||||
<td key="value1" className="element value">
|
||||
{humanFigure(2)(0)}
|
||||
{formatLocalizedCurrency(0)}
|
||||
</td>
|
||||
</>
|
||||
)}
|
||||
|
@ -369,7 +382,7 @@ class ReductionRow extends Component {
|
|||
-
|
||||
</td>
|
||||
<td key="value2" className="element value">
|
||||
{humanFigure(2)(value)}
|
||||
{formatLocalizedCurrency(value)}
|
||||
</td>
|
||||
</>
|
||||
)}
|
||||
|
@ -393,7 +406,7 @@ class ReductionRow extends Component {
|
|||
+
|
||||
</td>
|
||||
<td key="value1" className="element value">
|
||||
{humanFigure(2)(0)}
|
||||
{formatLocalizedCurrency(0)}
|
||||
</td>
|
||||
</>
|
||||
)}
|
||||
|
@ -403,7 +416,7 @@ class ReductionRow extends Component {
|
|||
-
|
||||
</td>
|
||||
<td key="value2" className="element value">
|
||||
{humanFigure(2)(value)}
|
||||
{formatLocalizedCurrency(value)}
|
||||
</td>
|
||||
</>
|
||||
)}
|
||||
|
|
|
@ -5,7 +5,7 @@ import ReactPiwik from './Tracker'
|
|||
import ReactCSSTransitionGroup from 'react-addons-css-transition-group'
|
||||
import Smiley from './SatisfactionSmiley'
|
||||
import TypeFormEmbed from './TypeFormEmbed'
|
||||
import PropTypes from 'prop-types'
|
||||
import withLanguage from './withLanguage'
|
||||
import { Trans, translate } from 'react-i18next'
|
||||
|
||||
@connect(state => ({
|
||||
|
@ -15,15 +15,13 @@ import { Trans, translate } from 'react-i18next'
|
|||
conversationStarted: state.conversationStarted
|
||||
}))
|
||||
@translate()
|
||||
@withLanguage
|
||||
export default class Sondage extends Component {
|
||||
state = {
|
||||
visible: false,
|
||||
showForm: false,
|
||||
askFeedbackTime: 'AFTER_FIRST_ESTIMATE'
|
||||
}
|
||||
static contextTypes = {
|
||||
i18n: PropTypes.object.isRequired
|
||||
}
|
||||
static getDerivedStateFromProps(nextProps, currentState) {
|
||||
let feedbackAlreadyAsked = !!document.cookie.includes('feedback_asked=true')
|
||||
let conditions = {
|
||||
|
@ -57,7 +55,8 @@ export default class Sondage extends Component {
|
|||
this.setCookie()
|
||||
}
|
||||
render() {
|
||||
let { satisfaction, showForm, visible, askFeedbackTime } = this.state
|
||||
let { satisfaction, showForm, visible, askFeedbackTime } = this.state,
|
||||
{ language } = this.props
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -67,7 +66,7 @@ export default class Sondage extends Component {
|
|||
exterieur: false,
|
||||
satisfaction,
|
||||
answertiming: askFeedbackTime,
|
||||
language: this.context.i18n.language
|
||||
language
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -80,23 +80,25 @@
|
|||
#targetSelection .targetInputOrValue {
|
||||
font-size: 125%;
|
||||
display: flex;
|
||||
height: 1.6em;
|
||||
justify-content: flex-end;
|
||||
margin-left: .6em;
|
||||
align-items: flex-end;
|
||||
margin-left: 0.6em;
|
||||
}
|
||||
|
||||
#targetSelection .editable {
|
||||
border-bottom: 1px dashed #ffffff91;
|
||||
min-width: 2.5em;
|
||||
height: inherit;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#targetSelection .attractClick,
|
||||
#targetSelection input[type='number'] {
|
||||
width: 5em !important;
|
||||
#targetSelection .targetInput {
|
||||
width: 5.5em !important;
|
||||
display: inline-block;
|
||||
height: 1.6em;
|
||||
text-align: right;
|
||||
font-weight: 600;
|
||||
font-weight: 700;
|
||||
padding: 0;
|
||||
padding: 0em 0.5em;
|
||||
background: white;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React, { Component } from 'react'
|
||||
import { Trans, translate } from 'react-i18next'
|
||||
import formValueTypes from 'Components/conversation/formValueTypes'
|
||||
import { findRuleByName } from 'Engine/rules'
|
||||
import { propEq, curry } from 'ramda'
|
||||
import './TargetSelection.css'
|
||||
|
@ -11,8 +10,9 @@ import { connect } from 'react-redux'
|
|||
import { RuleValue } from './rule/RuleValueVignette'
|
||||
import classNames from 'classnames'
|
||||
import ProgressCircle from './ProgressCircle/ProgressCircle'
|
||||
import withLanguage from './withLanguage'
|
||||
import InputSuggestions from 'Components/conversation/InputSuggestions'
|
||||
import { buildValidationFunction } from './conversation/FormDecorator'
|
||||
import CurrencyInput from './CurrencyInput/CurrencyInput'
|
||||
export let salaries = ['salaire total', 'salaire de base', 'salaire net']
|
||||
export let popularTargetNames = [...salaries, 'aides employeur']
|
||||
|
||||
|
@ -65,7 +65,9 @@ export default class TargetSelection extends Component {
|
|||
<Trans>Estimation approximative</Trans>
|
||||
</b>{' '}
|
||||
<br />
|
||||
<Trans i18nKey="defaults">pour un CDI non cadre</Trans>
|
||||
<Trans i18nKey="defaults">
|
||||
pour une situation par défaut (CDI non cadre).
|
||||
</Trans>
|
||||
</p>
|
||||
<BlueButton onClick={this.props.startConversation}>
|
||||
<Trans>Affiner le calcul</Trans>
|
||||
|
@ -143,37 +145,32 @@ let Header = ({ target, conversationStarted, isActiveInput }) => {
|
|||
)
|
||||
}
|
||||
|
||||
let validate = buildValidationFunction(formValueTypes['euros'])
|
||||
let InputComponent = ({ input, meta: { dirty, error } }) => (
|
||||
<span>
|
||||
{dirty && error && <span className="input-error">{error}</span>}
|
||||
<input type="number" {...input} autoFocus />
|
||||
</span>
|
||||
)
|
||||
let TargetInputOrValue = ({
|
||||
target,
|
||||
targets,
|
||||
firstEstimationComplete,
|
||||
activeInput,
|
||||
setActiveInput
|
||||
}) => (
|
||||
<span className="targetInputOrValue">
|
||||
{activeInput === target.dottedName ? (
|
||||
<Field
|
||||
name={target.dottedName}
|
||||
component={InputComponent}
|
||||
type="text"
|
||||
validate={validate}
|
||||
/>
|
||||
) : (
|
||||
<TargetValue {...{ targets, target, activeInput, setActiveInput }} />
|
||||
)}
|
||||
{(firstEstimationComplete || target.question) && (
|
||||
<span className="unit">€</span>
|
||||
)}
|
||||
</span>
|
||||
)
|
||||
let CurrencyField = props => {
|
||||
return (
|
||||
<CurrencyInput
|
||||
className="targetInput"
|
||||
autoFocus
|
||||
{...props.input}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
let TargetInputOrValue = withLanguage(
|
||||
({ target, targets, activeInput, setActiveInput, language }) => (
|
||||
<span className="targetInputOrValue">
|
||||
{activeInput === target.dottedName ? (
|
||||
<Field
|
||||
name={target.dottedName}
|
||||
component={CurrencyField}
|
||||
language={language}
|
||||
/>
|
||||
) : (
|
||||
<TargetValue {...{ targets, target, activeInput, setActiveInput }} />
|
||||
)}
|
||||
</span>
|
||||
)
|
||||
)
|
||||
@connect(
|
||||
() => ({}),
|
||||
dispatch => ({
|
||||
|
@ -190,9 +187,7 @@ class TargetValue extends Component {
|
|||
setActiveInput
|
||||
} = this.props,
|
||||
targetWithValue = targets.find(propEq('dottedName', target.dottedName)),
|
||||
value = targetWithValue && targetWithValue.nodeValue,
|
||||
humanValue = value != null && value.toFixed(0)
|
||||
|
||||
value = targetWithValue && targetWithValue.nodeValue
|
||||
return (
|
||||
<span
|
||||
className={classNames({
|
||||
|
@ -202,10 +197,9 @@ class TargetValue extends Component {
|
|||
onClick={() => {
|
||||
if (!target.question) return
|
||||
if (value != null) {
|
||||
setFormValue(target.dottedName, humanValue + '')
|
||||
setFormValue(target.dottedName, Math.floor(value) + '')
|
||||
setFormValue(activeInput, '')
|
||||
}
|
||||
|
||||
setActiveInput(target.dottedName)
|
||||
}}>
|
||||
<RuleValue value={value} />
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
import React, { Component } from 'react'
|
||||
import { Trans, translate } from 'react-i18next'
|
||||
import PropTypes from 'prop-types'
|
||||
import classNames from 'classnames'
|
||||
import { connect } from 'react-redux'
|
||||
import { Field, change, formValueSelector } from 'redux-form'
|
||||
import { Field, change } from 'redux-form'
|
||||
import { stepAction } from '../../actions'
|
||||
import { capitalise0 } from '../../utils'
|
||||
import { path } from 'ramda'
|
||||
import Explicable from 'Components/conversation/Explicable'
|
||||
import IgnoreStepButton from './IgnoreStepButton'
|
||||
import { findRuleByDottedName } from 'Engine/rules'
|
||||
|
||||
export let buildValidationFunction = valueType => {
|
||||
let validator = valueType ? valueType.validator : {},
|
||||
{ pre = v => v, test = v => true, error } = validator
|
||||
{ pre = v => v, test = () => true, error } = validator
|
||||
return v => v != undefined && (test(pre(v)) ? undefined : error)
|
||||
}
|
||||
/*
|
||||
|
@ -39,10 +37,8 @@ export var FormDecorator = formType => RenderField =>
|
|||
dispatch(change('conversation', field, value))
|
||||
})
|
||||
)
|
||||
@translate()
|
||||
class extends Component {
|
||||
static contextTypes = {
|
||||
i18n: PropTypes.object.isRequired
|
||||
}
|
||||
state = {
|
||||
helpVisible: false
|
||||
}
|
||||
|
@ -62,17 +58,16 @@ export var FormDecorator = formType => RenderField =>
|
|||
|
||||
renderUnfolded() {
|
||||
let {
|
||||
setFormValue,
|
||||
stepAction,
|
||||
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,
|
||||
themeColours
|
||||
} = this.props,
|
||||
{ i18n } = this.context
|
||||
setFormValue,
|
||||
stepAction,
|
||||
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,
|
||||
themeColours
|
||||
} = this.props
|
||||
|
||||
/* There won't be any answer zone here, widen the question zone */
|
||||
let wideQuestion = formType == 'rhetorical-question' && !possibleChoice
|
||||
|
@ -144,21 +139,19 @@ export var FormDecorator = formType => RenderField =>
|
|||
dottedName,
|
||||
fieldName,
|
||||
fieldTitle,
|
||||
flatRules
|
||||
} = this.props,
|
||||
{ i18n } = this.context
|
||||
flatRules,
|
||||
t
|
||||
} = this.props
|
||||
|
||||
let answer = situationGate(fieldName),
|
||||
rule = findRuleByDottedName(flatRules, dottedName + ' . ' + answer),
|
||||
translatedAnswer = (rule && rule.title) || i18n.t(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 className="answer">{translatedAnswer}</span>
|
||||
</span>
|
||||
<button
|
||||
className="edit"
|
||||
|
@ -170,7 +163,6 @@ export var FormDecorator = formType => RenderField =>
|
|||
<Trans>Modifier</Trans>
|
||||
</span>
|
||||
</button>
|
||||
{}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React, { Component } from 'react'
|
||||
import { translate } from 'react-i18next'
|
||||
import PropTypes from 'prop-types'
|
||||
import { FormDecorator } from './FormDecorator'
|
||||
import classnames from 'classnames'
|
||||
import SendButton from './SendButton'
|
||||
|
@ -9,9 +8,6 @@ import InputSuggestions from './InputSuggestions'
|
|||
@FormDecorator('input')
|
||||
@translate()
|
||||
export default class Input extends Component {
|
||||
static contextTypes = {
|
||||
i18n: PropTypes.object.isRequired
|
||||
}
|
||||
render() {
|
||||
let {
|
||||
input,
|
||||
|
@ -19,13 +15,13 @@ export default class Input extends Component {
|
|||
submit,
|
||||
valueType,
|
||||
meta: { dirty, error, active },
|
||||
t,
|
||||
themeColours
|
||||
} = this.props,
|
||||
answerSuffix = valueType.suffix,
|
||||
suffixed = answerSuffix != null,
|
||||
inputError = dirty && error,
|
||||
submitDisabled = !dirty || inputError,
|
||||
{ i18n } = this.context
|
||||
submitDisabled = !dirty || inputError
|
||||
|
||||
return (
|
||||
<span>
|
||||
|
@ -39,7 +35,7 @@ export default class Input extends Component {
|
|||
className={classnames({ suffixed })}
|
||||
id={'step-' + dottedName}
|
||||
inputMode="numeric"
|
||||
placeholder={i18n.t('votre réponse')}
|
||||
placeholder={t('votre réponse')}
|
||||
style={
|
||||
!active
|
||||
? { border: '2px dashed #ddd' }
|
||||
|
|
|
@ -3,24 +3,20 @@ import './InputSuggestions.css'
|
|||
import withColours from '../withColours'
|
||||
import { toPairs } from 'ramda'
|
||||
import { translate } from 'react-i18next'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
@withColours
|
||||
@translate()
|
||||
export default class extends Component {
|
||||
static contextTypes = {
|
||||
i18n: PropTypes.object.isRequired
|
||||
}
|
||||
export default class InputSuggestions extends Component {
|
||||
state = { suggestion: null }
|
||||
render() {
|
||||
let {
|
||||
suggestions,
|
||||
onSecondClick,
|
||||
onFirstClick,
|
||||
colouredBackground,
|
||||
colours
|
||||
} = this.props,
|
||||
{ i18n } = this.context
|
||||
suggestions,
|
||||
onSecondClick,
|
||||
onFirstClick,
|
||||
colouredBackground,
|
||||
colours,
|
||||
t
|
||||
} = this.props
|
||||
|
||||
if (!suggestions) return null
|
||||
return (
|
||||
|
@ -41,7 +37,7 @@ export default class extends Component {
|
|||
? colours.textColour
|
||||
: colours.textColourOnWhite
|
||||
}}>
|
||||
<span title={i18n.t('cliquez pour insérer cette suggestion')}>
|
||||
<span title={t('cliquez pour insérer cette suggestion')}>
|
||||
{text}
|
||||
</span>
|
||||
</li>
|
||||
|
|
|
@ -26,7 +26,10 @@ let getOptions = input =>
|
|||
@FormDecorator('select')
|
||||
export default class Select extends Component {
|
||||
render() {
|
||||
let { input: { onChange }, submit, suggestions } = this.props,
|
||||
let {
|
||||
input: { onChange },
|
||||
submit
|
||||
} = this.props,
|
||||
submitOnChange = option => {
|
||||
onChange(option.code)
|
||||
submit()
|
||||
|
|
|
@ -6,30 +6,33 @@ import { AttachDictionary } from '../AttachDictionary'
|
|||
import knownMecanisms from 'Engine/known-mecanisms.yaml'
|
||||
import { makeJsx } from 'Engine/evaluation'
|
||||
import './Algorithm.css'
|
||||
import { humanFigure } from '../../utils'
|
||||
import { head } from 'ramda'
|
||||
import { analyse } from 'Engine/traverse'
|
||||
import { exampleSituationGateWithDefaults } from './Examples'
|
||||
import PropTypes from 'prop-types'
|
||||
import withLanguage from '../withLanguage'
|
||||
|
||||
let RuleWithoutFormula = () => (
|
||||
<p>
|
||||
<Trans i18nKey="input">
|
||||
Cette règle n'a pas de formule de calcul pour l'instant. Sa valeur doit donc
|
||||
être renseignée directement.
|
||||
Cette règle n’a pas de formule de calcul pour l’instant. Sa valeur doit
|
||||
donc être renseignée directement.
|
||||
</Trans>
|
||||
</p>
|
||||
)
|
||||
|
||||
@AttachDictionary(knownMecanisms)
|
||||
@translate()
|
||||
@withLanguage
|
||||
export default class Algorithm extends React.Component {
|
||||
static contextTypes = {
|
||||
i18n: PropTypes.object.isRequired
|
||||
}
|
||||
render() {
|
||||
let { rule: displayedRule, showValues, currentExample, rules } = this.props,
|
||||
{ i18n } = this.context,
|
||||
let {
|
||||
rule: displayedRule,
|
||||
showValues,
|
||||
currentExample,
|
||||
t,
|
||||
rules,
|
||||
language
|
||||
} = this.props,
|
||||
ruleWithoutFormula =
|
||||
!displayedRule['formule'] ||
|
||||
path(['formule', 'explanation', 'une possibilité'], displayedRule)
|
||||
|
@ -52,7 +55,9 @@ export default class Algorithm extends React.Component {
|
|||
)
|
||||
applicabilityMecanisms.length > 0 && (
|
||||
<section id="declenchement">
|
||||
<h2><Trans>Déclenchement</Trans></h2>
|
||||
<h2>
|
||||
<Trans>Déclenchement</Trans>
|
||||
</h2>
|
||||
<ul>
|
||||
{applicabilityMecanisms.map(v => (
|
||||
<li key={v.name}>{makeJsx(v)}</li>
|
||||
|
@ -65,7 +70,11 @@ export default class Algorithm extends React.Component {
|
|||
<h2>
|
||||
<Trans>Calcul</Trans>
|
||||
{!ruleWithoutFormula && (
|
||||
<small><Trans i18nKey="understand">Cliquez sur chaque chaque valeur pour comprendre</Trans></small>
|
||||
<small>
|
||||
<Trans i18nKey="understand">
|
||||
Cliquez sur chaque chaque valeur pour comprendre
|
||||
</Trans>
|
||||
</small>
|
||||
)}
|
||||
</h2>
|
||||
{ruleWithoutFormula ? (
|
||||
|
@ -76,14 +85,16 @@ export default class Algorithm extends React.Component {
|
|||
</section>
|
||||
<section
|
||||
id="ruleValue"
|
||||
style={{ visibility: showValues ? 'visible' : 'hidden' }}
|
||||
>
|
||||
style={{ visibility: showValues ? 'visible' : 'hidden' }}>
|
||||
<i className="fa fa-calculator" aria-hidden="true" />{' '}
|
||||
{rule.nodeValue == 0
|
||||
? i18n.t('Règle non applicable')
|
||||
? t('Règle non applicable')
|
||||
: rule.nodeValue == null
|
||||
? i18n.t('Situation incomplète')
|
||||
: humanFigure(2)(rule.nodeValue) + ' €'}
|
||||
? t('Situation incomplète')
|
||||
: Intl.NumberFormat(language, {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(rule.nodeValue)}
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
import React from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import React, { Component } from 'react'
|
||||
import withLanguage from '../withLanguage'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { encodeRuleName } from 'Engine/rules'
|
||||
import classNames from 'classnames'
|
||||
import { humanFigure } from '../../utils'
|
||||
|
||||
import './RuleValueVignette.css'
|
||||
import ReactCSSTransitionGroup from 'react-addons-css-transition-group'
|
||||
|
||||
export default ({ name, type, title, nodeValue: ruleValue }) => (
|
||||
let RuleValueVignette = ({ name, title, nodeValue: ruleValue }) => (
|
||||
<span key={name} className="RuleValueVignette">
|
||||
<Link to={'/règle/' + encodeRuleName(name)}>
|
||||
<div className="rule-box">
|
||||
|
@ -19,20 +17,37 @@ export default ({ name, type, title, nodeValue: ruleValue }) => (
|
|||
</span>
|
||||
)
|
||||
|
||||
export let RuleValue = ({ value }) =>
|
||||
do {
|
||||
@withLanguage
|
||||
export class RuleValue extends Component {
|
||||
render() {
|
||||
let { value, language } = this.props
|
||||
let unsatisfied = value == null,
|
||||
irrelevant = value == 0
|
||||
let [className, text] = irrelevant
|
||||
? ['irrelevant', '0']
|
||||
: unsatisfied ? ['unsatisfied', ''] : ['figure', humanFigure(0)(value)]
|
||||
;<ReactCSSTransitionGroup
|
||||
transitionName="flash"
|
||||
transitionEnterTimeout={100}
|
||||
transitionLeaveTimeout={100}>
|
||||
<span key={text} className="Rule-value">
|
||||
{' '}
|
||||
<span className={className}>{text}</span>
|
||||
</span>
|
||||
</ReactCSSTransitionGroup>
|
||||
: unsatisfied
|
||||
? ['unsatisfied', '']
|
||||
: [
|
||||
'figure',
|
||||
Intl.NumberFormat(language, {
|
||||
style: 'currency',
|
||||
currency: 'EUR',
|
||||
maximumFractionDigits: 0,
|
||||
minimumFractionDigits: 0
|
||||
}).format(value)
|
||||
]
|
||||
return (
|
||||
<ReactCSSTransitionGroup
|
||||
transitionName="flash"
|
||||
transitionEnterTimeout={100}
|
||||
transitionLeaveTimeout={100}>
|
||||
<span key={text} className="Rule-value">
|
||||
{' '}
|
||||
<span className={className}>{text}</span>
|
||||
</span>
|
||||
</ReactCSSTransitionGroup>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default RuleValueVignette
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
export default function withLanguage(WrappedComponent) {
|
||||
return class WithLanguage extends Component {
|
||||
static contextTypes = {
|
||||
i18n: PropTypes.object.isRequired
|
||||
}
|
||||
static displayName = `withLanguage(${Component.displayName ||
|
||||
Component.name})`
|
||||
render() {
|
||||
return (
|
||||
<WrappedComponent
|
||||
{...this.props}
|
||||
language={this.context.i18n.language + ''}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,9 +6,3 @@ export let getIframeOption = optionName => {
|
|||
hasOption = url.includes(optionName + '=')
|
||||
return hasOption && url.split(optionName + '=')[1].split('&')[0]
|
||||
}
|
||||
|
||||
export let fmt =
|
||||
'Intl' in window ? new Intl.NumberFormat('fr-FR').format : v => v
|
||||
|
||||
export let humanFigure = decimalDigits => value =>
|
||||
fmt(value.toFixed(decimalDigits))
|
||||
|
|
|
@ -52,7 +52,7 @@ module.exports = {
|
|||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules|dist|test/,
|
||||
exclude: /node_modules|dist/,
|
||||
loader: 'babel-loader'
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
var webpack = require('webpack'),
|
||||
path = require('path'),
|
||||
HardSourceWebpackPlugin = require('hard-source-webpack-plugin'),
|
||||
common = require('./webpack.common.js')
|
||||
|
||||
module.exports = {
|
||||
|
|
304
yarn.lock
304
yarn.lock
|
@ -663,6 +663,16 @@
|
|||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd"
|
||||
|
||||
"@sinonjs/formatio@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "http://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz#84db7e9eb5531df18a8c5e0bfb6e449e55e654b2"
|
||||
dependencies:
|
||||
samsam "1.3.0"
|
||||
|
||||
"@types/node@*":
|
||||
version "10.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.0.3.tgz#1f89840c7aac2406cc43a2ecad98fc02a8e130e4"
|
||||
|
||||
JSONStream@^1.3.2:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.2.tgz#c102371b6ec3a7cf3b847ca00c20bb0fce4c6dea"
|
||||
|
@ -1898,6 +1908,10 @@ bonjour@^3.5.0:
|
|||
multicast-dns "^6.0.1"
|
||||
multicast-dns-service-types "^1.1.0"
|
||||
|
||||
boolbase@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
||||
|
||||
boom@4.x.x:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31"
|
||||
|
@ -2228,6 +2242,17 @@ check-error@^1.0.1:
|
|||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
|
||||
|
||||
cheerio@^1.0.0-rc.2:
|
||||
version "1.0.0-rc.2"
|
||||
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db"
|
||||
dependencies:
|
||||
css-select "~1.2.0"
|
||||
dom-serializer "~0.1.0"
|
||||
entities "~1.1.1"
|
||||
htmlparser2 "^3.9.1"
|
||||
lodash "^4.15.0"
|
||||
parse5 "^3.0.1"
|
||||
|
||||
chokidar@^1.6.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
|
||||
|
@ -2767,6 +2792,15 @@ css-loader@^0.28.11:
|
|||
postcss-value-parser "^3.3.0"
|
||||
source-list-map "^2.0.0"
|
||||
|
||||
css-select@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
|
||||
dependencies:
|
||||
boolbase "~1.0.0"
|
||||
css-what "2.1"
|
||||
domutils "1.5.1"
|
||||
nth-check "~1.0.1"
|
||||
|
||||
css-selector-tokenizer@^0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz#e6988474ae8c953477bf5e7efecfceccd9cf4c86"
|
||||
|
@ -2775,6 +2809,10 @@ css-selector-tokenizer@^0.7.0:
|
|||
fastparse "^1.1.1"
|
||||
regexpu-core "^1.0.0"
|
||||
|
||||
css-what@2.1:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd"
|
||||
|
||||
cssesc@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4"
|
||||
|
@ -3080,7 +3118,7 @@ dezalgo@^1.0.0, dezalgo@~1.0.3:
|
|||
asap "^2.0.0"
|
||||
wrappy "1"
|
||||
|
||||
diff@3.5.0, diff@^3.3.1, diff@^3.5.0:
|
||||
diff@3.5.0, diff@^3.1.0, diff@^3.3.1, diff@^3.5.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
|
||||
|
||||
|
@ -3130,6 +3168,13 @@ doctrine@^2.0.2, doctrine@^2.1.0:
|
|||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.3.1.tgz#fc1a4e15ffdf60ddde03a480a9c0fece821dd4a6"
|
||||
|
||||
dom-serializer@0, dom-serializer@~0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
|
||||
dependencies:
|
||||
domelementtype "~1.1.1"
|
||||
entities "~1.1.1"
|
||||
|
||||
dom-walk@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
|
||||
|
@ -3138,12 +3183,40 @@ domain-browser@^1.1.1:
|
|||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
|
||||
|
||||
domelementtype@1, domelementtype@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2"
|
||||
|
||||
domelementtype@~1.1.1:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
|
||||
|
||||
domexception@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90"
|
||||
dependencies:
|
||||
webidl-conversions "^4.0.2"
|
||||
|
||||
domhandler@^2.3.0:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.1.tgz#892e47000a99be55bbf3774ffea0561d8879c259"
|
||||
dependencies:
|
||||
domelementtype "1"
|
||||
|
||||
domutils@1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
|
||||
dependencies:
|
||||
dom-serializer "0"
|
||||
domelementtype "1"
|
||||
|
||||
domutils@^1.5.1:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
|
||||
dependencies:
|
||||
dom-serializer "0"
|
||||
domelementtype "1"
|
||||
|
||||
dot-prop@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177"
|
||||
|
@ -3169,8 +3242,8 @@ duplexer@~0.1.1:
|
|||
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
|
||||
|
||||
duplexify@^3.4.2, duplexify@^3.5.3:
|
||||
version "3.5.4"
|
||||
resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.4.tgz#4bb46c1796eabebeec4ca9a2e66b808cb7a3d8b4"
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.0.tgz#592903f5d80b38d037220541264d69a198fb3410"
|
||||
dependencies:
|
||||
end-of-stream "^1.0.0"
|
||||
inherits "^2.0.1"
|
||||
|
@ -3247,10 +3320,55 @@ enhanced-resolve@^4.0.0:
|
|||
memory-fs "^0.4.0"
|
||||
tapable "^1.0.0"
|
||||
|
||||
entities@^1.1.1, entities@~1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
|
||||
|
||||
envinfo@^4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-4.4.2.tgz#472c49f3a8b9bca73962641ce7cb692bf623cd1c"
|
||||
|
||||
enzyme-adapter-react-16@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.1.1.tgz#a8f4278b47e082fbca14f5bfb1ee50ee650717b4"
|
||||
dependencies:
|
||||
enzyme-adapter-utils "^1.3.0"
|
||||
lodash "^4.17.4"
|
||||
object.assign "^4.0.4"
|
||||
object.values "^1.0.4"
|
||||
prop-types "^15.6.0"
|
||||
react-reconciler "^0.7.0"
|
||||
react-test-renderer "^16.0.0-0"
|
||||
|
||||
enzyme-adapter-utils@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.3.0.tgz#d6c85756826c257a8544d362cc7a67e97ea698c7"
|
||||
dependencies:
|
||||
lodash "^4.17.4"
|
||||
object.assign "^4.0.4"
|
||||
prop-types "^15.6.0"
|
||||
|
||||
enzyme@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.3.0.tgz#0971abd167f2d4bf3f5bd508229e1c4b6dc50479"
|
||||
dependencies:
|
||||
cheerio "^1.0.0-rc.2"
|
||||
function.prototype.name "^1.0.3"
|
||||
has "^1.0.1"
|
||||
is-boolean-object "^1.0.0"
|
||||
is-callable "^1.1.3"
|
||||
is-number-object "^1.0.3"
|
||||
is-string "^1.0.4"
|
||||
is-subset "^0.1.1"
|
||||
lodash "^4.17.4"
|
||||
object-inspect "^1.5.0"
|
||||
object-is "^1.0.1"
|
||||
object.assign "^4.1.0"
|
||||
object.entries "^1.0.4"
|
||||
object.values "^1.0.4"
|
||||
raf "^3.4.0"
|
||||
rst-selector-parser "^2.2.3"
|
||||
|
||||
err-code@^1.0.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960"
|
||||
|
@ -3274,7 +3392,7 @@ error@^7.0.2:
|
|||
string-template "~0.2.1"
|
||||
xtend "~4.0.0"
|
||||
|
||||
es-abstract@^1.7.0:
|
||||
es-abstract@^1.6.1, es-abstract@^1.7.0:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.11.0.tgz#cce87d518f0496893b1a30cd8461835535480681"
|
||||
dependencies:
|
||||
|
@ -3950,10 +4068,18 @@ fstream@^1.0.0, fstream@^1.0.2:
|
|||
mkdirp ">=0.5 0"
|
||||
rimraf "2"
|
||||
|
||||
function-bind@^1.0.2, function-bind@^1.1.1:
|
||||
function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||
|
||||
function.prototype.name@^1.0.3:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.0.tgz#8bd763cc0af860a859cc5d49384d74b932cd2327"
|
||||
dependencies:
|
||||
define-properties "^1.1.2"
|
||||
function-bind "^1.1.1"
|
||||
is-callable "^1.1.3"
|
||||
|
||||
functional-red-black-tree@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
|
||||
|
@ -4473,6 +4599,17 @@ html-parse-stringify2@2.0.1:
|
|||
dependencies:
|
||||
void-elements "^2.0.1"
|
||||
|
||||
htmlparser2@^3.9.1:
|
||||
version "3.9.2"
|
||||
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338"
|
||||
dependencies:
|
||||
domelementtype "^1.3.0"
|
||||
domhandler "^2.3.0"
|
||||
domutils "^1.5.1"
|
||||
entities "^1.1.1"
|
||||
inherits "^2.0.1"
|
||||
readable-stream "^2.0.2"
|
||||
|
||||
http-auth@3.1.x:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/http-auth/-/http-auth-3.1.3.tgz#945cfadd66521eaf8f7c84913d377d7b15f24e31"
|
||||
|
@ -4719,6 +4856,14 @@ interpret@^1.0.0, interpret@^1.0.1, interpret@^1.0.4:
|
|||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
|
||||
|
||||
intl-locales-supported@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/intl-locales-supported/-/intl-locales-supported-1.0.0.tgz#9a9d94dbf104a87818881952dcb782053f0aeefa"
|
||||
|
||||
intl@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/intl/-/intl-1.2.5.tgz#82244a2190c4e419f8371f5aa34daa3420e2abde"
|
||||
|
||||
into-stream@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6"
|
||||
|
@ -4770,6 +4915,10 @@ is-binary-path@^1.0.0:
|
|||
dependencies:
|
||||
binary-extensions "^1.0.0"
|
||||
|
||||
is-boolean-object@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93"
|
||||
|
||||
is-buffer@^1.1.5:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
||||
|
@ -4905,6 +5054,10 @@ is-npm@^1.0.0:
|
|||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4"
|
||||
|
||||
is-number-object@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.3.tgz#f265ab89a9f445034ef6aff15a8f00b00f551799"
|
||||
|
||||
is-number@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
|
||||
|
@ -5007,6 +5160,14 @@ is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0:
|
|||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
|
||||
is-string@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.4.tgz#cc3a9b69857d621e963725a24caeec873b826e64"
|
||||
|
||||
is-subset@^0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6"
|
||||
|
||||
is-svg@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9"
|
||||
|
@ -5253,6 +5414,10 @@ jsx-ast-utils@^2.0.1:
|
|||
dependencies:
|
||||
array-includes "^3.0.3"
|
||||
|
||||
just-extend@^1.1.27:
|
||||
version "1.1.27"
|
||||
resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-1.1.27.tgz#ec6e79410ff914e472652abfa0e603c03d60e905"
|
||||
|
||||
keyv@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373"
|
||||
|
@ -5507,10 +5672,18 @@ lodash.debounce@^4.0.4:
|
|||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
||||
|
||||
lodash.flattendeep@^4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
|
||||
|
||||
lodash.flow@^3.3.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a"
|
||||
|
||||
lodash.get@^4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
|
||||
|
||||
lodash.memoize@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
||||
|
@ -5590,6 +5763,10 @@ loglevelnext@^1.0.1:
|
|||
es6-symbol "^3.1.1"
|
||||
object.assign "^4.1.0"
|
||||
|
||||
lolex@^2.2.0, lolex@^2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.3.2.tgz#85f9450425103bf9e7a60668ea25dc43274ca807"
|
||||
|
||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.0, loose-envify@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
|
||||
|
@ -6053,7 +6230,7 @@ nearley-loader@^2.0.0:
|
|||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/nearley-loader/-/nearley-loader-2.0.0.tgz#8d75fd2ab3ca9f6153ae099b2bf18f8d5605d203"
|
||||
|
||||
nearley@^2.13.0:
|
||||
nearley@^2.13.0, nearley@^2.7.10:
|
||||
version "2.13.0"
|
||||
resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.13.0.tgz#6e7b0f4e68bfc3e74c99eaef2eda39e513143439"
|
||||
dependencies:
|
||||
|
@ -6086,6 +6263,16 @@ nice-try@^1.0.4:
|
|||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4"
|
||||
|
||||
nise@^1.2.0:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/nise/-/nise-1.3.3.tgz#c17a850066a8a1dfeb37f921da02441afc4a82ba"
|
||||
dependencies:
|
||||
"@sinonjs/formatio" "^2.0.0"
|
||||
just-extend "^1.1.27"
|
||||
lolex "^2.3.2"
|
||||
path-to-regexp "^1.7.0"
|
||||
text-encoding "^0.6.4"
|
||||
|
||||
no-case@^2.2.0:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac"
|
||||
|
@ -6458,6 +6645,12 @@ npm@^5.7.1:
|
|||
gauge "~2.7.3"
|
||||
set-blocking "~2.0.0"
|
||||
|
||||
nth-check@~1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4"
|
||||
dependencies:
|
||||
boolbase "~1.0.0"
|
||||
|
||||
nu-stream@^3.3.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/nu-stream/-/nu-stream-3.3.1.tgz#d9ab5037bfd00c86e76bbe28686727063b91b3af"
|
||||
|
@ -6490,6 +6683,14 @@ object-copy@^0.1.0:
|
|||
define-property "^0.2.5"
|
||||
kind-of "^3.0.3"
|
||||
|
||||
object-inspect@^1.5.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b"
|
||||
|
||||
object-is@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.1.tgz#0aa60ec9989a0b3ed795cf4d06f62cf1ad6539b6"
|
||||
|
||||
object-keys@^1.0.11, object-keys@^1.0.8:
|
||||
version "1.0.11"
|
||||
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d"
|
||||
|
@ -6509,6 +6710,15 @@ object.assign@^4.0.4, object.assign@^4.1.0:
|
|||
has-symbols "^1.0.0"
|
||||
object-keys "^1.0.11"
|
||||
|
||||
object.entries@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.0.4.tgz#1bf9a4dd2288f5b33f3a993d257661f05d161a5f"
|
||||
dependencies:
|
||||
define-properties "^1.1.2"
|
||||
es-abstract "^1.6.1"
|
||||
function-bind "^1.1.0"
|
||||
has "^1.0.1"
|
||||
|
||||
object.omit@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa"
|
||||
|
@ -6522,6 +6732,15 @@ object.pick@^1.3.0:
|
|||
dependencies:
|
||||
isobject "^3.0.1"
|
||||
|
||||
object.values@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.0.4.tgz#e524da09b4f66ff05df457546ec72ac99f13069a"
|
||||
dependencies:
|
||||
define-properties "^1.1.2"
|
||||
es-abstract "^1.6.1"
|
||||
function-bind "^1.1.0"
|
||||
has "^1.0.1"
|
||||
|
||||
obuf@^1.0.0, obuf@^1.1.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e"
|
||||
|
@ -6781,6 +7000,12 @@ parse5@4.0.0:
|
|||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
|
||||
|
||||
parse5@^3.0.1:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c"
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
parseurl@~1.3.1, parseurl@~1.3.2:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3"
|
||||
|
@ -7360,10 +7585,14 @@ qrcode-terminal@~0.11.0:
|
|||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz#ffc6c28a2fc0bfb47052b47e23f4f446a5fbdb9e"
|
||||
|
||||
qs@6.5.1, qs@~6.5.1:
|
||||
qs@6.5.1:
|
||||
version "6.5.1"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
|
||||
|
||||
qs@~6.5.1:
|
||||
version "6.5.2"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
|
||||
|
||||
query-string@^4.1.0:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb"
|
||||
|
@ -7399,6 +7628,12 @@ qw@~1.0.1:
|
|||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/qw/-/qw-1.0.1.tgz#efbfdc740f9ad054304426acb183412cc8b996d4"
|
||||
|
||||
raf@^3.4.0:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.0.tgz#a28876881b4bc2ca9117d4138163ddb80f781575"
|
||||
dependencies:
|
||||
performance-now "^2.1.0"
|
||||
|
||||
railroad-diagrams@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e"
|
||||
|
@ -7551,6 +7786,10 @@ react-input-autosize@^2.1.2:
|
|||
dependencies:
|
||||
prop-types "^15.5.8"
|
||||
|
||||
react-is@^16.3.2:
|
||||
version "16.3.2"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.3.2.tgz#f4d3d0e2f5fbb6ac46450641eb2e25bf05d36b22"
|
||||
|
||||
react-json-tree@^0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/react-json-tree/-/react-json-tree-0.11.0.tgz#f5b17e83329a9c76ae38be5c04fda3a7fd684a35"
|
||||
|
@ -7567,6 +7806,15 @@ react-pure-render@^1.0.2:
|
|||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-pure-render/-/react-pure-render-1.0.2.tgz#9d8a928c7f2c37513c2d064e57b3e3c356e9fabb"
|
||||
|
||||
react-reconciler@^0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.7.0.tgz#9614894103e5f138deeeb5eabaf3ee80eb1d026d"
|
||||
dependencies:
|
||||
fbjs "^0.8.16"
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.0"
|
||||
|
||||
react-redux@^5.0.7:
|
||||
version "5.0.7"
|
||||
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8"
|
||||
|
@ -7629,6 +7877,15 @@ react-side-effect@^1.1.0:
|
|||
exenv "^1.2.1"
|
||||
shallowequal "^1.0.1"
|
||||
|
||||
react-test-renderer@^16.0.0-0:
|
||||
version "16.3.2"
|
||||
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.3.2.tgz#3d1ed74fda8db42521fdf03328e933312214749a"
|
||||
dependencies:
|
||||
fbjs "^0.8.16"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.0"
|
||||
react-is "^16.3.2"
|
||||
|
||||
react-transition-group@^1.2.0:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.2.1.tgz#e11f72b257f921b213229a774df46612346c7ca6"
|
||||
|
@ -8239,6 +8496,13 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
|
|||
hash-base "^3.0.0"
|
||||
inherits "^2.0.1"
|
||||
|
||||
rst-selector-parser@^2.2.3:
|
||||
version "2.2.3"
|
||||
resolved "https://registry.yarnpkg.com/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz#81b230ea2fcc6066c89e3472de794285d9b03d91"
|
||||
dependencies:
|
||||
lodash.flattendeep "^4.4.0"
|
||||
nearley "^2.7.10"
|
||||
|
||||
run-async@^2.0.0, run-async@^2.2.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
|
||||
|
@ -8289,6 +8553,10 @@ safer-buffer@^2.1.0:
|
|||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
|
||||
samsam@1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50"
|
||||
|
||||
sanctuary-type-classes@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/sanctuary-type-classes/-/sanctuary-type-classes-3.0.0.tgz#e4cf422abceb8c78b6f625d84d61fdb5c6d44116"
|
||||
|
@ -8463,6 +8731,22 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
|
|||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
||||
|
||||
sinon-chai@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-3.0.0.tgz#d5cbd70fa71031edd96b528e0eed4038fcc99f29"
|
||||
|
||||
sinon@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/sinon/-/sinon-4.5.0.tgz#427ae312a337d3c516804ce2754e8c0d5028cb04"
|
||||
dependencies:
|
||||
"@sinonjs/formatio" "^2.0.0"
|
||||
diff "^3.1.0"
|
||||
lodash.get "^4.4.2"
|
||||
lolex "^2.2.0"
|
||||
nise "^1.2.0"
|
||||
supports-color "^5.1.0"
|
||||
type-detect "^4.0.5"
|
||||
|
||||
slash@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
|
||||
|
@ -8962,6 +9246,10 @@ term-size@^1.2.0:
|
|||
dependencies:
|
||||
execa "^0.7.0"
|
||||
|
||||
text-encoding@^0.6.4:
|
||||
version "0.6.4"
|
||||
resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19"
|
||||
|
||||
text-table@^0.2.0, text-table@~0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
|
@ -9083,7 +9371,7 @@ type-check@~0.3.2:
|
|||
dependencies:
|
||||
prelude-ls "~1.1.2"
|
||||
|
||||
type-detect@^4.0.0:
|
||||
type-detect@^4.0.0, type-detect@^4.0.5:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
|
||||
|
||||
|
|
Loading…
Reference in New Issue