commit
a204b57498
|
@ -38,9 +38,9 @@
|
|||
"react-addons-css-transition-group": "^15.6.2",
|
||||
"react-color": "^2.14.0",
|
||||
"react-dom": "npm:@hot-loader/react-dom",
|
||||
"react-easy-emoji": "^1.2.0",
|
||||
"react-easy-emoji": "^1.4.0",
|
||||
"react-fuzzy-highlighter": "^0.3.1",
|
||||
"react-helmet": "6.0.0-beta",
|
||||
"react-helmet": "^6.0.0",
|
||||
"react-i18next": "^11.0.0",
|
||||
"react-loading-skeleton": "^2.0.1",
|
||||
"react-markdown": "^4.1.0",
|
||||
|
|
|
@ -8,17 +8,17 @@ import { useTranslation } from 'react-i18next'
|
|||
|
||||
const ANIMATION_SPRING = config.gentle
|
||||
|
||||
let ChartItemBar = ({ styles, color, numberToPlot, unit }) => {
|
||||
type ChartItemBarProps = {
|
||||
numberToPlot: number
|
||||
unit?: string
|
||||
style: React.CSSProperties
|
||||
}
|
||||
|
||||
function ChartItemBar({ style, numberToPlot, unit }: ChartItemBarProps) {
|
||||
const language = useTranslation().i18n.language
|
||||
return (
|
||||
<div className="distribution-chart__bar-container">
|
||||
<animated.div
|
||||
className="distribution-chart__bar"
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
flex: styles.flex
|
||||
}}
|
||||
/>
|
||||
<animated.div className="distribution-chart__bar" style={style} />
|
||||
<div
|
||||
css={`
|
||||
font-weight: bold;
|
||||
|
@ -31,11 +31,14 @@ let ChartItemBar = ({ styles, color, numberToPlot, unit }) => {
|
|||
</div>
|
||||
)
|
||||
}
|
||||
let BranchIcône = ({ icône }) => (
|
||||
<div className="distribution-chart__legend">
|
||||
<span className="distribution-chart__icon">{emoji(icône)}</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
function BranchIcon({ icon }: { icon: string }) {
|
||||
return (
|
||||
<div className="distribution-chart__legend">
|
||||
<span className="distribution-chart__icon">{emoji(icon)}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
type BarChartBranchProps = {
|
||||
value: number
|
||||
|
@ -73,7 +76,7 @@ export default function BarChartBranch({
|
|||
className="distribution-chart__item"
|
||||
style={{ opacity: styles.opacity }}
|
||||
>
|
||||
{icon && <BranchIcône icône={icon} />}
|
||||
{icon && <BranchIcon icon={icon} />}
|
||||
<div className="distribution-chart__item-content">
|
||||
<p className="distribution-chart__counterparts">
|
||||
<span className="distribution-chart__branche-name">{title}</span>
|
||||
|
@ -81,12 +84,12 @@ export default function BarChartBranch({
|
|||
{description && <small>{description}</small>}
|
||||
</p>
|
||||
<ChartItemBar
|
||||
{...{
|
||||
styles,
|
||||
color,
|
||||
numberToPlot,
|
||||
unit
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
flex: styles.flex
|
||||
}}
|
||||
numberToPlot={numberToPlot}
|
||||
unit={unit}
|
||||
/>
|
||||
</div>
|
||||
</animated.div>
|
||||
|
|
|
@ -3,13 +3,14 @@ import { any, identity, path } from 'ramda'
|
|||
import React from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import './Algorithm.css'
|
||||
import { EvaluatedRule, ParsedRule } from 'Rules'
|
||||
|
||||
let Conditions = ({
|
||||
'rendu non applicable': disabledBy,
|
||||
parentDependencies,
|
||||
'applicable si': applicable,
|
||||
'non applicable si': notApplicable
|
||||
}) => {
|
||||
}: EvaluatedRule) => {
|
||||
let listElements = [
|
||||
...parentDependencies.map(
|
||||
parentDependency =>
|
||||
|
@ -21,7 +22,7 @@ let Conditions = ({
|
|||
)
|
||||
),
|
||||
...disabledBy?.explanation?.isDisabledBy?.map(
|
||||
(dependency, i) =>
|
||||
(dependency: EvaluatedRule, i: number) =>
|
||||
dependency?.nodeValue === true && (
|
||||
<ShowIfDisabled dependency={dependency} key={`dependency ${i}`} />
|
||||
)
|
||||
|
@ -40,7 +41,7 @@ let Conditions = ({
|
|||
) : null
|
||||
}
|
||||
|
||||
function ShowIfDisabled({ dependency }) {
|
||||
function ShowIfDisabled({ dependency }: { dependency: EvaluatedRule }) {
|
||||
return (
|
||||
<li>
|
||||
<span css="background: yellow">
|
||||
|
@ -51,7 +52,7 @@ function ShowIfDisabled({ dependency }) {
|
|||
)
|
||||
}
|
||||
|
||||
export default function Algorithm({ rule }) {
|
||||
export default function Algorithm({ rule }: { rule: EvaluatedRule }) {
|
||||
let formula =
|
||||
rule.formule ||
|
||||
(rule.category === 'variable' && rule.explanation.formule),
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { ParsedRule } from 'Engine/types'
|
||||
import yaml from 'yaml'
|
||||
import React from 'react'
|
||||
import rules from 'Rules'
|
||||
import rules, { ParsedRule } from 'Rules'
|
||||
import PublicodeHighlighter from '../ui/PublicodeHighlighter'
|
||||
|
||||
type RuleSourceProps = Pick<ParsedRule, 'dottedName'>
|
||||
|
|
|
@ -7,6 +7,7 @@ import { DottedName } from 'Rules'
|
|||
import './PaySlip.css'
|
||||
import { Line, SalaireBrutSection, SalaireNetSection } from './PaySlipSections'
|
||||
import RuleLink from './RuleLink'
|
||||
import { ParsedRules, ParsedRule } from 'Rules'
|
||||
|
||||
export const SECTION_ORDER = [
|
||||
'protection sociale . santé',
|
||||
|
@ -21,9 +22,9 @@ export const SECTION_ORDER = [
|
|||
|
||||
type Section = typeof SECTION_ORDER[number]
|
||||
|
||||
function getSection(rule): Section {
|
||||
function getSection(rule: ParsedRule): Section {
|
||||
const section = ('protection sociale . ' +
|
||||
(rule.cotisation?.branche ?? rule.taxe?.branche)) as Section
|
||||
rule.cotisation?.branche) as Section
|
||||
if (SECTION_ORDER.includes(section)) {
|
||||
return section
|
||||
}
|
||||
|
@ -31,7 +32,7 @@ function getSection(rule): Section {
|
|||
}
|
||||
|
||||
export function getCotisationsBySection(
|
||||
parsedRules
|
||||
parsedRules: ParsedRules
|
||||
): Array<[Section, DottedName[]]> {
|
||||
const cotisations = [
|
||||
...parsedRules['contrat salarié . cotisations . patronales'].formule
|
||||
|
@ -41,7 +42,7 @@ export function getCotisationsBySection(
|
|||
]
|
||||
.map(cotisation => cotisation.dottedName)
|
||||
.filter(Boolean)
|
||||
.reduce((acc, cotisation) => {
|
||||
.reduce((acc, cotisation: DottedName) => {
|
||||
const sectionName = getSection(parsedRules[cotisation])
|
||||
return {
|
||||
...acc,
|
||||
|
@ -154,12 +155,12 @@ function Cotisation({ dottedName }: { dottedName: DottedName }) {
|
|||
const partSalariale = useEvaluation(
|
||||
'contrat salarié . cotisations . salariales'
|
||||
)?.formule.explanation.explanation.find(
|
||||
cotisation => cotisation.dottedName === dottedName
|
||||
(cotisation: ParsedRule) => cotisation.dottedName === dottedName
|
||||
)
|
||||
const partPatronale = useEvaluation(
|
||||
'contrat salarié . cotisations . patronales'
|
||||
)?.formule.explanation.explanation.find(
|
||||
cotisation => cotisation.dottedName === dottedName
|
||||
(cotisation: ParsedRule) => cotisation.dottedName === dottedName
|
||||
)
|
||||
if (!partPatronale?.nodeValue && !partSalariale?.nodeValue) {
|
||||
return null
|
||||
|
|
|
@ -36,7 +36,7 @@ export default function SearchBar({
|
|||
const { i18n } = useTranslation()
|
||||
const history = useHistory()
|
||||
const useDefaultValues = useContext(UseDefaultValuesContext)
|
||||
const handleKeyDown = e => {
|
||||
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (e.key === 'Enter' && results.length > 0) {
|
||||
finallyCallback && finallyCallback()
|
||||
history.push({
|
||||
|
@ -257,7 +257,7 @@ export default function SearchBar({
|
|||
`}
|
||||
value={input}
|
||||
placeholder={i18n.t('Entrez des mots clefs ici')}
|
||||
onKeyDown={e => handleKeyDown(e)}
|
||||
onKeyDown={handleKeyDown}
|
||||
onChange={e => {
|
||||
let input = e.target.value
|
||||
setInput(input)
|
||||
|
|
|
@ -6,15 +6,19 @@ import SeeAnswersButton from 'Components/conversation/SeeAnswersButton'
|
|||
import PageFeedback from 'Components/Feedback/PageFeedback'
|
||||
import SearchButton from 'Components/SearchButton'
|
||||
import TargetSelection from 'Components/TargetSelection'
|
||||
import React from 'react'
|
||||
import React, { useEffect } from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
import { firstStepCompletedSelector } from 'Selectors/simulationSelectors'
|
||||
import { useSimulationProgress } from 'Components/utils/useNextQuestion'
|
||||
import * as Animate from 'Ui/animate'
|
||||
import Progress from 'Ui/Progress'
|
||||
import { setSimulationConfig } from 'Actions/actions'
|
||||
import { useLocation } from 'react-router'
|
||||
import { SimulationConfig } from 'Reducers/rootReducer'
|
||||
|
||||
type SimulationProps = {
|
||||
config: SimulationConfig
|
||||
explanations?: React.ReactNode
|
||||
results?: React.ReactNode
|
||||
customEndMessages?: ConversationProps['customEndMessages']
|
||||
|
@ -22,11 +26,17 @@ type SimulationProps = {
|
|||
}
|
||||
|
||||
export default function Simulation({
|
||||
config,
|
||||
explanations,
|
||||
results,
|
||||
customEndMessages,
|
||||
showPeriodSwitch
|
||||
}: SimulationProps) {
|
||||
const dispatch = useDispatch()
|
||||
const location = useLocation<{ fromGérer?: boolean }>()
|
||||
useEffect(() => {
|
||||
dispatch(setSimulationConfig(config, location.state?.fromGérer))
|
||||
}, [config])
|
||||
const firstStepCompleted = useSelector(firstStepCompletedSelector)
|
||||
const progress = useSimulationProgress()
|
||||
return (
|
||||
|
|
|
@ -10,15 +10,15 @@ import {
|
|||
} from 'Components/utils/EngineContext'
|
||||
import { SitePathsContext } from 'Components/utils/SitePathsContext'
|
||||
import { formatCurrency, formatValue } from 'Engine/format'
|
||||
import { EvaluatedRule } from 'Engine/types'
|
||||
import { EvaluatedRule, EvaluatedNode } from 'Engine/types'
|
||||
import { isNil } from 'ramda'
|
||||
import React, { useCallback, useContext, useEffect, useState } from 'react'
|
||||
import emoji from 'react-easy-emoji'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { Link, useLocation } from 'react-router-dom'
|
||||
import { RootState } from 'Reducers/rootReducer'
|
||||
import { DottedName } from 'Rules'
|
||||
import { RootState, SimulationConfig } from 'Reducers/rootReducer'
|
||||
import { DottedName, ParsedRule } from 'Rules'
|
||||
import {
|
||||
situationSelector,
|
||||
targetUnitSelector
|
||||
|
@ -29,7 +29,6 @@ import CurrencyInput from './CurrencyInput/CurrencyInput'
|
|||
import './TargetSelection.css'
|
||||
|
||||
export default function TargetSelection({ showPeriodSwitch = true }) {
|
||||
const [initialRender, setInitialRender] = useState(true)
|
||||
const objectifs = useSelector(
|
||||
(state: RootState) => state.simulation?.config.objectifs || []
|
||||
)
|
||||
|
@ -40,7 +39,7 @@ export default function TargetSelection({ showPeriodSwitch = true }) {
|
|||
{((typeof objectifs[0] === 'string'
|
||||
? [{ objectifs }]
|
||||
: objectifs) as any).map(
|
||||
({ icône, objectifs: targets, nom }, index) => (
|
||||
({ icône, objectifs: targets, nom }, index: number) => (
|
||||
<React.Fragment key={nom || '0'}>
|
||||
<div style={{ display: 'flex', alignItems: 'end' }}>
|
||||
<div style={{ flex: 1 }}>
|
||||
|
@ -151,7 +150,7 @@ const Target = ({ dottedName }: TargetProps) => {
|
|||
)
|
||||
}
|
||||
|
||||
let Header = ({ target }) => {
|
||||
let Header = ({ target }: { target: ParsedRule }) => {
|
||||
const sitePaths = useContext(SitePathsContext)
|
||||
const { t } = useTranslation()
|
||||
const { pathname } = useLocation()
|
||||
|
|
|
@ -154,7 +154,12 @@ function HeadingWithAnchorLink({
|
|||
)
|
||||
}
|
||||
|
||||
function Heading({ level, children, ...otherProps }) {
|
||||
type HeadingProps = {
|
||||
level: number
|
||||
children: React.ReactNode
|
||||
} & React.ComponentProps<'h1'>
|
||||
|
||||
function Heading({ level, children, ...otherProps }: HeadingProps) {
|
||||
return React.createElement(`h${level}`, otherProps, children)
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ import {
|
|||
sortWith,
|
||||
takeWhile,
|
||||
toPairs,
|
||||
values,
|
||||
zipWith
|
||||
} from 'ramda'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
@ -71,7 +70,7 @@ const similarity = (rule1: string = '', rule2: string = '') =>
|
|||
export function getNextQuestions(
|
||||
missingVariables: MissingVariables,
|
||||
questionConfig: SimulationConfig['questions'] = {},
|
||||
answeredQuestions = [],
|
||||
answeredQuestions: Array<DottedName> = [],
|
||||
situation: Simulation['situation'] = {}
|
||||
): Array<DottedName> {
|
||||
const {
|
||||
|
|
|
@ -7,7 +7,7 @@ import CurrencyInput from 'Components/CurrencyInput/CurrencyInput'
|
|||
import PercentageField from 'Components/PercentageField'
|
||||
import ToggleSwitch from 'Components/ui/ToggleSwitch'
|
||||
import { EngineContext } from 'Components/utils/EngineContext'
|
||||
import { ParsedRules } from 'Engine/types'
|
||||
import { ParsedRules, ParsedRule } from 'Engine/types'
|
||||
import React, { useContext } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { DottedName } from 'Rules'
|
||||
|
@ -130,10 +130,14 @@ export default function RuleInput({
|
|||
return <Input {...commonProps} unit={unit} />
|
||||
}
|
||||
|
||||
let getVariant = rule => rule?.formule?.explanation['possibilités']
|
||||
let getVariant = (rule: ParsedRule) =>
|
||||
rule?.formule?.explanation['possibilités']
|
||||
|
||||
export let buildVariantTree = (allRules, path) => {
|
||||
let rec = path => {
|
||||
export let buildVariantTree = <Name extends string>(
|
||||
allRules: ParsedRules<Name>,
|
||||
path: Name
|
||||
) => {
|
||||
let rec = (path: Name) => {
|
||||
let node = allRules[path]
|
||||
if (!node) throw new Error(`La règle ${path} est introuvable`)
|
||||
let variant = getVariant(node)
|
||||
|
@ -144,7 +148,7 @@ export let buildVariantTree = (allRules, path) => {
|
|||
!!variant
|
||||
? {
|
||||
canGiveUp,
|
||||
children: variants.map(v => rec(path + ' . ' + v))
|
||||
children: variants.map((v: string) => rec(`${path} . ${v}` as Name))
|
||||
}
|
||||
: null
|
||||
)
|
||||
|
|
|
@ -23,8 +23,10 @@ import {
|
|||
} from './temporal'
|
||||
import { ParsedRule, ParsedRules } from './types'
|
||||
|
||||
export let makeJsx = (node: EvaluatedNode): JSX.Element =>
|
||||
typeof node.jsx == 'function' ? node.jsx(node) : <></>
|
||||
export let makeJsx = (node: EvaluatedNode): JSX.Element => {
|
||||
const Component = node.jsx
|
||||
return <Component {...node} />
|
||||
}
|
||||
|
||||
export let collectNodeMissing = node => node.missingVariables || {}
|
||||
|
||||
|
@ -119,7 +121,7 @@ export const evaluateArrayWithFilter = (evaluationFilter, reducer, start) => (
|
|||
})
|
||||
}
|
||||
|
||||
export let defaultNode = nodeValue => ({
|
||||
export let defaultNode = (nodeValue: EvaluatedNode['nodeValue']) => ({
|
||||
nodeValue,
|
||||
// eslint-disable-next-line
|
||||
jsx: ({ nodeValue }: EvaluatedNode) => (
|
||||
|
@ -211,7 +213,6 @@ type DefaultValues<Names extends string> = { [name in Names]: any } | {}
|
|||
export function collectDefaults<Names extends string>(
|
||||
parsedRules: ParsedRules<Names>
|
||||
): DefaultValues<Names> {
|
||||
const cache = { _meta: { contextRule: [] as string[] } }
|
||||
return (Object.values(parsedRules) as Array<ParsedRule<Names>>).reduce(
|
||||
(acc, parsedRule) => {
|
||||
if (parsedRule?.['par défaut'] == null) {
|
||||
|
|
|
@ -84,7 +84,7 @@ export default class Engine<Names extends string> {
|
|||
)
|
||||
|
||||
if (Object.keys(result.defaultValue?.missingVariable ?? {}).length) {
|
||||
throw new evaluationError(
|
||||
throw evaluationError(
|
||||
context,
|
||||
"Impossible d'évaluer l'expression car celle ci fait appel à des variables manquantes"
|
||||
)
|
||||
|
|
|
@ -3,10 +3,7 @@ import React from 'react'
|
|||
import { makeJsx } from '../evaluation'
|
||||
import { Node } from './common'
|
||||
|
||||
export default function Allègement({
|
||||
nodeValue,
|
||||
explanations: rawExplanation
|
||||
}) {
|
||||
export default function Allègement({ nodeValue, explanation: rawExplanation }) {
|
||||
// Don't display attributes with default values
|
||||
let explanation = map(k => (k && !k.isDefault ? k : null), rawExplanation)
|
||||
return (
|
||||
|
|
|
@ -316,10 +316,7 @@ export let mecanismSum = (recurse, k, v) => {
|
|||
|
||||
return {
|
||||
evaluate,
|
||||
// eslint-disable-next-line
|
||||
jsx: ({ nodeValue, explanation, unit }: EvaluatedRule) => (
|
||||
<Somme nodeValue={nodeValue} explanation={explanation} unit={unit} />
|
||||
),
|
||||
jsx: Somme,
|
||||
explanation,
|
||||
category: 'mecanism',
|
||||
name: 'somme',
|
||||
|
|
|
@ -2,7 +2,7 @@ import { dropLast, last, pipe, propEq, range, take } from 'ramda'
|
|||
import { coerceArray } from '../utils'
|
||||
import { EvaluatedRule, Rule, Rules } from './types'
|
||||
|
||||
export const splitName = str => str.split(' . ')
|
||||
export const splitName = (str: string) => str.split(' . ')
|
||||
export const joinName = strs => strs.join(' . ')
|
||||
export const parentName = pipe(
|
||||
splitName,
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
import { assoc, mapObjIndexed } from 'ramda'
|
||||
import { Rule, Rules } from './types'
|
||||
|
||||
type Translation = Record<string, string>
|
||||
type translateAttribute = (
|
||||
prop: string,
|
||||
rule: Rule,
|
||||
translation: Translation,
|
||||
lang: string
|
||||
) => Rule
|
||||
|
||||
/* Traduction */
|
||||
const translateContrôle = (prop, rule, translation, lang) =>
|
||||
const translateContrôle: translateAttribute = (prop, rule, translation, lang) =>
|
||||
assoc(
|
||||
'contrôles',
|
||||
rule.contrôles.map((control, i) => ({
|
||||
rule.contrôles!.map((control, i) => ({
|
||||
...control,
|
||||
message: translation[`${prop}.${i}.${lang}`]?.replace(
|
||||
/^\[automatic\] /,
|
||||
|
@ -15,10 +23,15 @@ const translateContrôle = (prop, rule, translation, lang) =>
|
|||
rule
|
||||
)
|
||||
|
||||
const translateSuggestion = (prop, rule, translation, lang) =>
|
||||
const translateSuggestion: translateAttribute = (
|
||||
prop,
|
||||
rule,
|
||||
translation,
|
||||
lang
|
||||
) =>
|
||||
assoc(
|
||||
'suggestions',
|
||||
Object.entries(rule.suggestions).reduce(
|
||||
Object.entries(rule.suggestions!).reduce(
|
||||
(acc, [name, value]) => ({
|
||||
...acc,
|
||||
[translation[`${prop}.${name}.${lang}`]?.replace(
|
||||
|
@ -41,9 +54,9 @@ export const attributesToTranslate = [
|
|||
'note'
|
||||
]
|
||||
|
||||
const translateProp = (lang: string, translation: Object) => (
|
||||
const translateProp = (lang: string, translation: Translation) => (
|
||||
rule: Rule,
|
||||
prop
|
||||
prop: string
|
||||
) => {
|
||||
if (prop === 'contrôles' && rule?.contrôles) {
|
||||
return translateContrôle(prop, rule, translation, lang)
|
||||
|
@ -58,7 +71,7 @@ const translateProp = (lang: string, translation: Object) => (
|
|||
|
||||
function translateRule<Names extends string>(
|
||||
lang: string,
|
||||
translations: { [Name in Names]: Object },
|
||||
translations: { [Name in Names]: Translation },
|
||||
name: Names,
|
||||
rule: Rule
|
||||
): Rule {
|
||||
|
@ -74,7 +87,7 @@ function translateRule<Names extends string>(
|
|||
|
||||
export default function translateRules<Names extends string>(
|
||||
lang: string,
|
||||
translations: { [Name in Names]: Object },
|
||||
translations: { [Name in Names]: Translation },
|
||||
rules: Rules<Names>
|
||||
): Rules<Names> {
|
||||
const translatedRules = mapObjIndexed(
|
||||
|
|
|
@ -48,6 +48,15 @@ export type ParsedRule<Name extends string = string> = Rule & {
|
|||
category?: string
|
||||
rulePropType?: string
|
||||
jsx?: Function
|
||||
cotisation?: Partial<{
|
||||
'dû par': string
|
||||
branche: string
|
||||
destinataire: string
|
||||
responsable: string
|
||||
}>
|
||||
taxe?: {
|
||||
'dû par': string
|
||||
}
|
||||
}
|
||||
|
||||
export type ParsedRules<Names extends string = string> = {
|
||||
|
@ -67,7 +76,7 @@ export type EvaluatedNode<
|
|||
nodeValue: Evaluation<T>
|
||||
explanation?: Object
|
||||
isDefault?: boolean
|
||||
jsx?: (node: EvaluatedNode) => JSX.Element
|
||||
jsx: React.FunctionComponent<EvaluatedNode>
|
||||
missingVariables: Partial<Record<Names, number>>
|
||||
} & (T extends number
|
||||
? {
|
||||
|
@ -87,4 +96,7 @@ export type EvaluatedRule<
|
|||
EvaluatedNode<Names, Type> & {
|
||||
isApplicable: boolean
|
||||
explanation: Explanation
|
||||
'rendu non applicable': EvaluatedRule<Names, {}, Type>
|
||||
'applicable si': EvaluatedNode<Names, Type>
|
||||
'non applicable si': EvaluatedNode<Names, Type>
|
||||
}
|
||||
|
|
|
@ -227,6 +227,11 @@ artiste-auteur . revenus . BNC . micro-bnc:
|
|||
résumé.fr: Avec abattement forfaitaire fiscal de 34 % au titre des frais professionnels
|
||||
titre.en: Would you like to opt-in for the micro-BNC regime?
|
||||
titre.fr: Souhaitez-vous opter pour le régime micro-BNC ?
|
||||
artiste-auteur . revenus . BNC . micro-bnc . contrôle micro-bnc:
|
||||
description.en: "[automatic] Your income does not allow you to opt for the micro-BNC plan."
|
||||
description.fr: Vos revenus ne vous permettent pas d'opter pour le régime micro-BNC.
|
||||
titre.en: "[automatic] micro-bnc control"
|
||||
titre.fr: contrôle micro-bnc
|
||||
artiste-auteur . revenus . BNC . recettes:
|
||||
résumé.en: The amount of your gross revenue excluding VAT
|
||||
résumé.fr: Le montant de vos recettes brutes hors TVA
|
||||
|
|
|
@ -66,6 +66,7 @@ export type SimulationConfig = {
|
|||
objectifs:
|
||||
| Array<DottedName>
|
||||
| Array<{ icône: string; nom: string; objectifs: Array<DottedName> }>
|
||||
'objectifs cachés': Array<DottedName>
|
||||
situation: Simulation['situation']
|
||||
bloquant?: Array<DottedName>
|
||||
questions?: Partial<Record<QuestionsKind, Array<DottedName>>>
|
||||
|
@ -140,7 +141,7 @@ function simulation(
|
|||
case 'UPDATE_SITUATION':
|
||||
const targets = without(
|
||||
['entreprise . charges'],
|
||||
objectifsSelector({ simulation: state })
|
||||
objectifsSelector({ simulation: state } as RootState)
|
||||
)
|
||||
const situation = state.situation
|
||||
const { fieldName: dottedName, value } = action
|
||||
|
|
|
@ -20,14 +20,18 @@ artiste-auteur . revenus . BNC:
|
|||
- sinon: frais réels
|
||||
|
||||
artiste-auteur . revenus . BNC . micro-bnc:
|
||||
applicable si:
|
||||
toutes ces conditions:
|
||||
- recettes > 0
|
||||
- recettes < 72500 €/an
|
||||
non applicable si: contrôle micro-bnc
|
||||
par défaut: oui
|
||||
titre: Souhaitez-vous opter pour le régime micro-BNC ?
|
||||
résumé: Avec abattement forfaitaire fiscal de 34 % au titre des frais professionnels
|
||||
|
||||
artiste-auteur . revenus . BNC . micro-bnc . contrôle micro-bnc:
|
||||
description: Vos revenus ne vous permettent pas d'opter pour le régime micro-BNC.
|
||||
formule:
|
||||
toutes ces conditions:
|
||||
- recettes != 0
|
||||
- recettes > 72500 €/an
|
||||
|
||||
artiste-auteur . revenus . BNC . recettes:
|
||||
titre: Revenu en BNC
|
||||
par défaut: 0 €/an
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
// future.
|
||||
import {
|
||||
EvaluatedRule as GenericEvaluatedRule,
|
||||
ParsedRule as GenericParsedRule,
|
||||
ParsedRules as GenericParsedRules,
|
||||
Rules as GenericRules
|
||||
} from 'Engine/types'
|
||||
import artisteAuteur from './artiste-auteur.yaml'
|
||||
|
@ -25,6 +27,8 @@ import situationPersonnelle from './situation-personnelle.yaml'
|
|||
|
||||
export type DottedName = keyof typeof jsonRules
|
||||
export type Rules = GenericRules<DottedName>
|
||||
export type ParsedRules = GenericParsedRules<DottedName>
|
||||
export type ParsedRule = GenericParsedRule<DottedName>
|
||||
export type EvaluatedRule = GenericEvaluatedRule<DottedName>
|
||||
export type Situation = Partial<Record<DottedName, string>>
|
||||
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import { DottedName } from './../rules/index'
|
||||
import { createSelector } from 'reselect'
|
||||
import { RootState, SimulationConfig } from 'Reducers/rootReducer'
|
||||
|
||||
export const configSelector = (state: RootState): Partial<SimulationConfig> =>
|
||||
state.simulation?.config ?? {}
|
||||
|
||||
export const configSelector = state => state.simulation?.config ?? {}
|
||||
export const objectifsSelector = createSelector([configSelector], config => {
|
||||
const primaryObjectifs = ((config.objectifs ?? []) as any)
|
||||
const primaryObjectifs = (config.objectifs ?? ([] as any))
|
||||
.map((obj: DottedName | { objectifs: Array<DottedName> }) =>
|
||||
typeof obj === 'string' ? [obj] : obj.objectifs
|
||||
)
|
||||
|
@ -12,10 +15,13 @@ export const objectifsSelector = createSelector([configSelector], config => {
|
|||
const objectifs = [...primaryObjectifs, ...(config['objectifs cachés'] ?? [])]
|
||||
return objectifs
|
||||
})
|
||||
|
||||
const emptySituation = {}
|
||||
export const situationSelector = state =>
|
||||
|
||||
export const situationSelector = (state: RootState) =>
|
||||
state.simulation?.situation ?? emptySituation
|
||||
export const configSituationSelector = state =>
|
||||
|
||||
export const configSituationSelector = (state: RootState) =>
|
||||
configSelector(state).situation ?? emptySituation
|
||||
|
||||
export const firstStepCompletedSelector = createSelector(
|
||||
|
@ -30,11 +36,11 @@ export const firstStepCompletedSelector = createSelector(
|
|||
}
|
||||
)
|
||||
|
||||
export const targetUnitSelector = state =>
|
||||
export const targetUnitSelector = (state: RootState) =>
|
||||
state.simulation?.targetUnit ?? '€/mois'
|
||||
|
||||
export const currentQuestionSelector = state =>
|
||||
export const currentQuestionSelector = (state: RootState) =>
|
||||
state.simulation?.unfoldedStep ?? null
|
||||
|
||||
export const answeredQuestionsSelector = state =>
|
||||
export const answeredQuestionsSelector = (state: RootState) =>
|
||||
state.simulation?.foldedSteps ?? []
|
||||
|
|
|
@ -25,9 +25,9 @@ const ressources = {
|
|||
}
|
||||
|
||||
export default function Budget() {
|
||||
const [selectedYear, setSelectedYear] = useState('2020')
|
||||
const years = ['2019', '2020']
|
||||
const years = ['2019', '2020'] as const
|
||||
const quarters = ['T1', 'T2', 'T3', 'T4']
|
||||
const [selectedYear, setSelectedYear] = useState<typeof years[number]>('2020')
|
||||
const categories = uniq(
|
||||
quarters
|
||||
.map(q => Object.keys(budget[2020][q] ?? {}))
|
||||
|
@ -44,7 +44,9 @@ export default function Budget() {
|
|||
{emoji('📅')} Année{' '}
|
||||
<select
|
||||
value={selectedYear}
|
||||
onChange={event => setSelectedYear(event.target.value)}
|
||||
onChange={event =>
|
||||
setSelectedYear(event.target.value as typeof years[number])
|
||||
}
|
||||
>
|
||||
{years.map(year => (
|
||||
<option key={year}>{year}</option>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { setSimulationConfig } from 'Actions/actions'
|
||||
import RuleLink from 'Components/RuleLink'
|
||||
import Simulation from 'Components/Simulation'
|
||||
import chomagePartielConfig from 'Components/simulationConfigs/chômage-partiel.yaml'
|
||||
|
@ -12,8 +11,6 @@ import { EvaluatedRule } from 'Engine/types'
|
|||
import React, { useContext, useEffect, useState } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import { useLocation } from 'react-router'
|
||||
import { DottedName } from 'Rules'
|
||||
import styled from 'styled-components'
|
||||
import Animate from 'Ui/animate'
|
||||
|
@ -26,14 +23,7 @@ declare global {
|
|||
}
|
||||
|
||||
export default function ChômagePartiel() {
|
||||
const dispatch = useDispatch()
|
||||
const location = useLocation<{ fromGérer?: boolean }>()
|
||||
const inIframe = useContext(IsEmbeddedContext)
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
setSimulationConfig(chomagePartielConfig, location.state?.fromGérer)
|
||||
)
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
if (inIframe || !productionMode) {
|
||||
return
|
||||
|
@ -100,6 +90,7 @@ export default function ChômagePartiel() {
|
|||
</ul>
|
||||
</Warning>
|
||||
<Simulation
|
||||
config={chomagePartielConfig}
|
||||
results={<ExplanationSection />}
|
||||
customEndMessages={
|
||||
<span className="ui__ notice">Voir les résultats au-dessus</span>
|
||||
|
|
|
@ -50,7 +50,7 @@ export default function ArtisteAuteur() {
|
|||
<SimpleField dottedName="artiste-auteur . revenus . traitements et salaires" />
|
||||
<SimpleField dottedName="artiste-auteur . revenus . BNC . recettes" />
|
||||
<SimpleField dottedName="artiste-auteur . revenus . BNC . micro-bnc" />
|
||||
<WarningRegimeSpecial />
|
||||
<Warning dottedName="artiste-auteur . revenus . BNC . micro-bnc . contrôle micro-bnc" />
|
||||
<SimpleField dottedName="artiste-auteur . revenus . BNC . frais réels" />
|
||||
<SimpleField dottedName="artiste-auteur . cotisations . option surcotisation" />
|
||||
</InitialRenderContext.Provider>
|
||||
|
@ -103,18 +103,16 @@ function SimpleField({ dottedName }: SimpleFieldProps) {
|
|||
)
|
||||
}
|
||||
|
||||
function WarningRegimeSpecial() {
|
||||
const situation = useSelector(situationSelector)
|
||||
const recettes = situation['artiste-auteur . revenus . BNC . recettes']
|
||||
const showWarning = recettes !== 0 && recettes >= 70000
|
||||
if (!showWarning) {
|
||||
type WarningProps = {
|
||||
dottedName: DottedName
|
||||
}
|
||||
|
||||
function Warning({ dottedName }: WarningProps) {
|
||||
const warning = useEvaluation(dottedName)
|
||||
if (!warning.nodeValue) {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<li>
|
||||
Vos revenus ne vous permettent pas d'opter pour le régime micro-BNC.
|
||||
</li>
|
||||
)
|
||||
return <li>{warning.description}</li>
|
||||
}
|
||||
|
||||
const ResultBlock = styled.div`
|
||||
|
@ -168,11 +166,7 @@ const branches = [
|
|||
icon: '👵'
|
||||
},
|
||||
{
|
||||
dottedName: 'artiste-auteur . cotisations . CSG-CRDS . CSG',
|
||||
icon: '🏛'
|
||||
},
|
||||
{
|
||||
dottedName: 'artiste-auteur . cotisations . CSG-CRDS . CRDS',
|
||||
dottedName: 'artiste-auteur . cotisations . CSG-CRDS',
|
||||
icon: '🏛'
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,22 +1,13 @@
|
|||
import { setSimulationConfig } from 'Actions/actions'
|
||||
import SalaryExplanation from 'Components/SalaryExplanation'
|
||||
import Warning from 'Components/SimulateurWarning'
|
||||
import Simulation from 'Components/Simulation'
|
||||
import assimiléConfig from 'Components/simulationConfigs/assimilé.yaml'
|
||||
import { IsEmbeddedContext } from 'Components/utils/embeddedContext'
|
||||
import React, { useContext, useEffect } from 'react'
|
||||
import React, { useContext } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import { useLocation } from 'react-router'
|
||||
|
||||
export default function AssimiléSalarié() {
|
||||
const dispatch = useDispatch()
|
||||
const location = useLocation<{ fromGérer?: boolean }>()
|
||||
useEffect(() => {
|
||||
dispatch(setSimulationConfig(assimiléConfig, location.state?.fromGérer))
|
||||
}, [])
|
||||
|
||||
const { t } = useTranslation()
|
||||
const inIframe = useContext(IsEmbeddedContext)
|
||||
|
||||
|
@ -45,7 +36,10 @@ export default function AssimiléSalarié() {
|
|||
</h1>
|
||||
)}
|
||||
<Warning simulateur="assimilé-salarié" />
|
||||
<Simulation explanations={<SalaryExplanation />} />
|
||||
<Simulation
|
||||
config={assimiléConfig}
|
||||
explanations={<SalaryExplanation />}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { setSimulationConfig } from 'Actions/actions'
|
||||
import Warning from 'Components/SimulateurWarning'
|
||||
import Simulation from 'Components/Simulation'
|
||||
import autoEntrepreneurConfig from 'Components/simulationConfigs/auto-entrepreneur.yaml'
|
||||
|
@ -6,22 +5,14 @@ import StackedBarChart from 'Components/StackedBarChart'
|
|||
import { ThemeColorsContext } from 'Components/utils/colors'
|
||||
import { IsEmbeddedContext } from 'Components/utils/embeddedContext'
|
||||
import { EngineContext } from 'Components/utils/EngineContext'
|
||||
import { default as React, useContext, useEffect } from 'react'
|
||||
import { default as React, useContext } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { useLocation } from 'react-router'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { targetUnitSelector } from 'Selectors/simulationSelectors'
|
||||
|
||||
export default function AutoEntrepreneur() {
|
||||
const dispatch = useDispatch()
|
||||
const location = useLocation<{ fromGérer?: boolean }>()
|
||||
const inIframe = useContext(IsEmbeddedContext)
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
setSimulationConfig(autoEntrepreneurConfig, location.state?.fromGérer)
|
||||
)
|
||||
}, [])
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
|
@ -49,7 +40,10 @@ export default function AutoEntrepreneur() {
|
|||
</h1>
|
||||
)}
|
||||
<Warning simulateur="auto-entrepreneur" />
|
||||
<Simulation explanations={<ExplanationSection />} />
|
||||
<Simulation
|
||||
config={autoEntrepreneurConfig}
|
||||
explanations={<ExplanationSection />}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { setSimulationConfig } from 'Actions/actions'
|
||||
import Warning from 'Components/SimulateurWarning'
|
||||
import Simulation from 'Components/Simulation'
|
||||
import indépendantConfig from 'Components/simulationConfigs/indépendant.yaml'
|
||||
|
@ -6,18 +5,11 @@ import StackedBarChart from 'Components/StackedBarChart'
|
|||
import { ThemeColorsContext } from 'Components/utils/colors'
|
||||
import { IsEmbeddedContext } from 'Components/utils/embeddedContext'
|
||||
import { EngineContext } from 'Components/utils/EngineContext'
|
||||
import { default as React, useContext, useEffect } from 'react'
|
||||
import { default as React, useContext } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import { useLocation } from 'react-router'
|
||||
|
||||
export default function Indépendant() {
|
||||
const dispatch = useDispatch()
|
||||
const location = useLocation<{ fromGérer?: boolean }>()
|
||||
useEffect(() => {
|
||||
dispatch(setSimulationConfig(indépendantConfig, location.state?.fromGérer))
|
||||
}, [])
|
||||
const { t } = useTranslation()
|
||||
const inIframe = useContext(IsEmbeddedContext)
|
||||
|
||||
|
@ -46,7 +38,10 @@ export default function Indépendant() {
|
|||
</h1>
|
||||
)}
|
||||
<Warning simulateur="indépendant" />
|
||||
<Simulation explanations={<ExplanationSection />} />
|
||||
<Simulation
|
||||
config={indépendantConfig}
|
||||
explanations={<ExplanationSection />}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { setSimulationConfig } from 'Actions/actions'
|
||||
import Banner from 'Components/Banner'
|
||||
import PreviousSimulationBanner from 'Components/PreviousSimulationBanner'
|
||||
import SalaryExplanation from 'Components/SalaryExplanation'
|
||||
|
@ -8,11 +7,10 @@ import { IsEmbeddedContext } from 'Components/utils/embeddedContext'
|
|||
import { SitePathsContext } from 'Components/utils/SitePathsContext'
|
||||
import urlIllustrationNetBrutEn from 'Images/illustration-net-brut-en.png'
|
||||
import urlIllustrationNetBrut from 'Images/illustration-net-brut.png'
|
||||
import { default as React, useContext, useEffect } from 'react'
|
||||
import { default as React, useContext } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import { Link, useLocation } from 'react-router-dom'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
export default function Salarié() {
|
||||
const { t } = useTranslation()
|
||||
|
@ -134,15 +132,11 @@ function SeoExplanations() {
|
|||
}
|
||||
|
||||
export let SalarySimulation = () => {
|
||||
const dispatch = useDispatch()
|
||||
const location = useLocation<{ fromGérer?: boolean }>()
|
||||
const sitePaths = useContext(SitePathsContext)
|
||||
useEffect(() => {
|
||||
dispatch(setSimulationConfig(salariéConfig, location.state?.fromGérer))
|
||||
}, [])
|
||||
return (
|
||||
<>
|
||||
<Simulation
|
||||
config={salariéConfig}
|
||||
explanations={<SalaryExplanation />}
|
||||
customEndMessages={
|
||||
<>
|
||||
|
|
|
@ -123,7 +123,7 @@ export const Results = ({ targets, onClickShare, rules }: ResultsProps) => {
|
|||
// console.warn
|
||||
const warnings: string[] = []
|
||||
const originalWarn = console.warn
|
||||
console.warn = warning => warnings.push(warning)
|
||||
console.warn = (warning: string) => warnings.push(warning)
|
||||
const evaluation = engine.evaluate(currentTarget)
|
||||
console.warn = originalWarn
|
||||
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
declare module 'react-easy-emoji' {
|
||||
function emoji(input: string): string
|
||||
|
||||
export default emoji
|
||||
}
|
38
yarn.lock
38
yarn.lock
|
@ -9338,7 +9338,7 @@ prop-types-exact@^1.2.0:
|
|||
object.assign "^4.1.0"
|
||||
reflect.ownkeys "^0.2.0"
|
||||
|
||||
prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
version "15.7.2"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||
|
@ -9642,15 +9642,15 @@ react-color@^2.14.0:
|
|||
prop-types "^15.6.2"
|
||||
scheduler "^0.19.0"
|
||||
|
||||
react-easy-emoji@^1.2.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/react-easy-emoji/-/react-easy-emoji-1.3.0.tgz#c68ac1512985c08429928ab19d83824c272379c2"
|
||||
integrity sha512-OBv+Yue3ubZ+Qe2DMNZAXReluJFy7eG1fFNG2+AfzIYN7dhFCFynpt+mX93QuOa15GJR6u5LzwnrnTWsDSIxrg==
|
||||
react-easy-emoji@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/react-easy-emoji/-/react-easy-emoji-1.4.0.tgz#dfcbb743bf8439af265aa25a1e72998c6d2225ff"
|
||||
integrity sha512-TcufijpuWKgYgzbySEBukNef+y0HI/4PAJ4gc9vb1CF7Q4CcAS2ZV8VMZk0ObtKKwJJfVgAHVt86nXWOed8QXg==
|
||||
dependencies:
|
||||
lodash.assign "^4.0.8"
|
||||
string-replace-to-array "^1.0.1"
|
||||
|
||||
react-fast-compare@^2.0.2:
|
||||
react-fast-compare@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
|
||||
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
|
||||
|
@ -9664,15 +9664,15 @@ react-fuzzy-highlighter@^0.3.1:
|
|||
set-value "^3.0.1"
|
||||
strind "^0.3.0"
|
||||
|
||||
react-helmet@6.0.0-beta:
|
||||
version "6.0.0-beta"
|
||||
resolved "https://registry.yarnpkg.com/react-helmet/-/react-helmet-6.0.0-beta.tgz#1f2ac04521951486e4fce3296d0c88aae8cabd5c"
|
||||
integrity sha512-GnNWsokebTe7fe8MH2I/a2dl4THYWhthLBoMaQSRYqW5XbPo881WAJGi+lqRBjyOFryW6zpQluEkBy70zh+h9w==
|
||||
react-helmet@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-helmet/-/react-helmet-6.0.0.tgz#fcb93ebaca3ba562a686eb2f1f9d46093d83b5f8"
|
||||
integrity sha512-My6S4sa0uHN/IuVUn0HFmasW5xj9clTkB9qmMngscVycQ5vVG51Qp44BEvLJ4lixupTwDlU9qX1/sCrMN4AEPg==
|
||||
dependencies:
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.5.4"
|
||||
react-fast-compare "^2.0.2"
|
||||
react-side-effect "^1.1.0"
|
||||
prop-types "^15.7.2"
|
||||
react-fast-compare "^2.0.4"
|
||||
react-side-effect "^2.1.0"
|
||||
|
||||
react-hot-loader@^4.12.15:
|
||||
version "4.12.20"
|
||||
|
@ -9800,12 +9800,10 @@ react-router@5.1.2, react-router@^5.1.1:
|
|||
tiny-invariant "^1.0.2"
|
||||
tiny-warning "^1.0.0"
|
||||
|
||||
react-side-effect@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-1.2.0.tgz#0e940c78faba0c73b9b0eba9cd3dda8dfb7e7dae"
|
||||
integrity sha512-v1ht1aHg5k/thv56DRcjw+WtojuuDHFUgGfc+bFHOWsF4ZK6C2V57DO0Or0GPsg6+LSTE0M6Ry/gfzhzSwbc5w==
|
||||
dependencies:
|
||||
shallowequal "^1.0.1"
|
||||
react-side-effect@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-2.1.0.tgz#1ce4a8b4445168c487ed24dab886421f74d380d3"
|
||||
integrity sha512-IgmcegOSi5SNX+2Snh1vqmF0Vg/CbkycU9XZbOHJlZ6kMzTmi3yc254oB1WCkgA7OQtIAoLmcSFuHTc/tlcqXg==
|
||||
|
||||
react-smooth@^1.0.5:
|
||||
version "1.0.5"
|
||||
|
@ -10678,7 +10676,7 @@ sha.js@^2.4.0, sha.js@^2.4.8:
|
|||
inherits "^2.0.1"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
shallowequal@^1.0.1, shallowequal@^1.1.0:
|
||||
shallowequal@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
|
||||
integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
|
||||
|
|
Loading…
Reference in New Issue