Merge branch 'master' of github.com:betagouv/mon-entreprise
commit
36b194f8f1
|
@ -1,3 +1,7 @@
|
|||
## 0.3.0
|
||||
|
||||
Ajoute la règle `code` contenant le code de l'exonération covid applicable à transmettre à l'administration fiscale
|
||||
|
||||
## 0.2.0
|
||||
|
||||
Change complètement l'organisation des règles publicodes pour être au plus proche de l'implémentation
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Modèle social français en publicodes
|
||||
# Covid : exonération de cotisation sociale pour les indépendants
|
||||
|
||||
Ce paquet contient les règles [publicodes](https://publi.codes) utilisées sur https://mon-entreprise.urssaf.fr pour le calcul de l'exonération covid 2021.
|
||||
|
||||
|
@ -18,15 +18,19 @@ const engine = new Engine(rules)
|
|||
engine.setSituation({
|
||||
"lieu d'exercice": "'métropole'",
|
||||
"début d'activité": "'mai 2021'",
|
||||
secteur: "'S1'",
|
||||
secteur: "'S1bis'",
|
||||
|
||||
'mois . avril 2021': 'LFSS 600',
|
||||
'mois . mai 2021': 'non',
|
||||
'mois . juin 2021': 'LFSS 600',
|
||||
'mois . décembre 2021': 'LFSS 300',
|
||||
'mois . mai 2021': "'LFSS 600'",
|
||||
'mois . juin 2021': "'LFR1'",
|
||||
'mois . juillet 2021': "'LFSS 600'",
|
||||
'mois . août 2021': 'non',
|
||||
'mois . décembre 2021': "'LFSS 300'",
|
||||
'mois . janvier 2022': "'LFSS 600'",
|
||||
'mois . février 2022': "'LFSS 300'",
|
||||
})
|
||||
|
||||
console.log(formatValue(engine.evaluate('montant total')))
|
||||
console.log(formatValue(engine.evaluate('montant total'))) // "3000 €"
|
||||
console.log(engine.evaluate('code').nodeValue) // "S1B;O;3;1;O;1"
|
||||
```
|
||||
|
||||
👉 **[Voir l'exemple complet](https://codesandbox.io/s/covidform-rxweh?file=/src/index.js)**
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "exoneration-covid",
|
||||
"version": "0.2.0",
|
||||
"version": "0.3.0",
|
||||
"description": "Les règles publicodes pour le calcul de l'exonération de cotisations covid (année 2021)",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./index.d.ts",
|
||||
|
@ -17,10 +17,10 @@
|
|||
"type": "module",
|
||||
"devDependencies": {
|
||||
"js-yaml": "^4.1.0",
|
||||
"publicodes": "^1.0.0-beta.30"
|
||||
"publicodes": "^1.0.0-beta.31"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"publicodes": "^1.0.0-beta.30"
|
||||
"publicodes": "^1.0.0-beta.31"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node ../scripts/build-rules.js",
|
||||
|
|
|
@ -369,6 +369,7 @@ exonération S2 . mois éligibles:
|
|||
arrondi: oui
|
||||
unité: mois
|
||||
- 1 mois
|
||||
|
||||
exonération S2 . mois éligibles . premier mois:
|
||||
variations:
|
||||
- si: début d'activité . date < 01/2021
|
||||
|
@ -390,3 +391,53 @@ montant total:
|
|||
- LFR1
|
||||
- LFSS 300
|
||||
- exonération S2
|
||||
|
||||
code:
|
||||
texte: '{{ secteur }};{{ LFSS }};{{ LFR1 }}'
|
||||
|
||||
# Applicabilité ajoutée pour éviter un code mal formatté en cas de variable non définie
|
||||
# Cf https://github.com/betagouv/publicodes/issues/172
|
||||
applicable si:
|
||||
toutes ces conditions:
|
||||
- secteur
|
||||
- LFSS
|
||||
- LFR1
|
||||
|
||||
code . secteur:
|
||||
variations:
|
||||
- si: secteur . S1bis
|
||||
alors: "'S1B'"
|
||||
- sinon: secteur
|
||||
|
||||
code . LFSS:
|
||||
variations:
|
||||
- si: secteur . S2
|
||||
alors:
|
||||
texte: O;{{ mois S2 }}
|
||||
- si: LFSS 300 + LFSS 600 = 0€
|
||||
alors: "'N'"
|
||||
- si: LFSS 300 = 0€
|
||||
alors:
|
||||
texte: O;{{ mois 600 }}
|
||||
- sinon: # LFSS 300 et 600
|
||||
texte: O;{{ mois 600 }};{{ mois 300}}
|
||||
|
||||
code . LFSS . mois S2:
|
||||
valeur: exonération S2 . mois éligibles
|
||||
unité: ''
|
||||
code . LFSS . mois 300:
|
||||
valeur: LFSS 300 . mois éligibles
|
||||
unité: ''
|
||||
code . LFSS . mois 600:
|
||||
valeur: LFSS 600 . mois éligibles
|
||||
unité: ''
|
||||
|
||||
code . LFR1:
|
||||
variations:
|
||||
- si: LFR1 = 0€
|
||||
alors: "'N'"
|
||||
- sinon:
|
||||
texte: O;{{ mois }}
|
||||
code . LFR1 . mois:
|
||||
valeur: LFR1 . mois éligibles
|
||||
unité: ''
|
||||
|
|
|
@ -91,7 +91,6 @@ dirigeant . assimilé salarié:
|
|||
rend non applicable:
|
||||
- contrat salarié . convention collective
|
||||
- contrat salarié . activité partielle
|
||||
- contrat salarié . déduction forfaitaire spécifique
|
||||
- contrat salarié . rémunération . primes
|
||||
- contrat salarié . rémunération . primes . fin d'année
|
||||
- contrat salarié . rémunération . primes . activité
|
||||
|
@ -1295,17 +1294,17 @@ dirigeant . indépendant . cotisations et contributions . exonérations . pensio
|
|||
acronyme: PI
|
||||
question: Êtes-vous titulaire d’une pension d’invalidité à titre de travailleur indépendant ?
|
||||
description: |-
|
||||
Si vous êtes titulaire d’une **pension d’invalidité** versée par un régime des travailleurs non-salariés
|
||||
non agricoles, vous bénécifiez d’une **exonération totale des cotisations de retraite complémentaire et
|
||||
Si vous êtes titulaire d’une **pension d’invalidité** versée par un régime des travailleurs non-salariés
|
||||
non agricoles, vous bénécifiez d’une **exonération totale des cotisations de retraite complémentaire et
|
||||
des cotisations maladie**.
|
||||
|
||||
Pour que vous puissiez **continuer à accumuler des points de retraite complémentaire** comme les autres travailleurs,
|
||||
Pour que vous puissiez **continuer à accumuler des points de retraite complémentaire** comme les autres travailleurs,
|
||||
il vous est attribué des **"points gratuits"**.
|
||||
|
||||
Dans le cas général, le nombre de points reçu correspond à la **moyenne mensuelle des points cotisés
|
||||
pendant la période d'activité indépendante** avant versement de la pension.
|
||||
Dans le cas général, le nombre de points reçu correspond à la **moyenne mensuelle des points cotisés
|
||||
pendant la période d'activité indépendante** avant versement de la pension.
|
||||
|
||||
> Par exemple, si vous avez cotisé pendant 6 ans et 11 mois pour un total de 588 points, le nombre de points gratuits reçu chaque mois sera de :
|
||||
> Par exemple, si vous avez cotisé pendant 6 ans et 11 mois pour un total de 588 points, le nombre de points gratuits reçu chaque mois sera de :
|
||||
|
||||
> `588 / (6 * 12 + 11) = 7,08`
|
||||
type: notification
|
||||
|
|
|
@ -19,7 +19,7 @@ VITE_FR_BASE_URL="http://localhost:3000/mon-entreprise"
|
|||
VITE_EN_BASE_URL="http://localhost:3000/infrance"
|
||||
|
||||
# Variables optionnelles
|
||||
VITE_COMPANY_SEARCH_HOST=https://search-recherche-entreprises.fabrique.social.gouv.fr
|
||||
VITE_COMPANY_SEARCH_HOST=https://api.recherche-entreprises.fabrique.social.gouv.fr
|
||||
|
||||
# https://github.com/reduxjs/redux-devtools/blob/main/extension/docs/Features/Trace.md
|
||||
VITE_REDUX_TRACE=true
|
||||
|
|
|
@ -30,7 +30,7 @@ describe(`Navigation to income simulator using company name (${
|
|||
let pendingRequests = new Set()
|
||||
let responses = {}
|
||||
const hostnamesToRecord = [
|
||||
'search-recherche-entreprises.fabrique.social.gouv.fr',
|
||||
'api.recherche-entreprises.fabrique.social.gouv.fr',
|
||||
'geo.api.gouv.fr',
|
||||
]
|
||||
beforeEach(function () {
|
||||
|
|
|
@ -19,7 +19,7 @@ describe('Landing page', function () {
|
|||
let pendingRequests = new Set()
|
||||
let responses = {}
|
||||
const hostnamesToRecord = [
|
||||
'search-recherche-entreprises.fabrique.social.gouv.fr',
|
||||
'api.recherche-entreprises.fabrique.social.gouv.fr',
|
||||
'geo.api.gouv.fr',
|
||||
]
|
||||
cy.clearLocalStorage() // Try to avoid flaky tests
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[[headers]]
|
||||
for = "/*"
|
||||
[headers.values]
|
||||
Content-Security-Policy = "default-src 'self' mon-entreprise.fr; style-src 'self' 'unsafe-inline' mon-entreprise.zammad.com; connect-src 'self' *.sentry.io raw.githubusercontent.com *.xiti.com mon-entreprise.zammad.com search-recherche-entreprises.fabrique.social.gouv.fr geo.api.gouv.fr *.algolianet.com; form-action 'self' *.sibforms.com *.sentry.io mon-entreprise.zammad.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.xiti.com stonly.com code.jquery.com mon-entreprise.zammad.com polyfill.io; img-src 'self' data: *.xiti.com user-images.githubusercontent.com; frame-src 'self' https://www.youtube-nocookie.com https://codesandbox.io"
|
||||
Content-Security-Policy = "default-src 'self' mon-entreprise.fr; style-src 'self' 'unsafe-inline' mon-entreprise.zammad.com; connect-src 'self' *.sentry.io raw.githubusercontent.com *.xiti.com mon-entreprise.zammad.com api.recherche-entreprises.fabrique.social.gouv.fr geo.api.gouv.fr *.algolianet.com; form-action 'self' *.sibforms.com *.sentry.io mon-entreprise.zammad.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.xiti.com stonly.com code.jquery.com mon-entreprise.zammad.com polyfill.io; img-src 'self' data: *.xiti.com user-images.githubusercontent.com; frame-src 'self' https://www.youtube-nocookie.com https://codesandbox.io"
|
||||
|
||||
## Twemoji proxy for client privacy #1219
|
||||
[[redirects]]
|
||||
|
|
|
@ -73,8 +73,8 @@
|
|||
"fuse.js": "^6.4.6",
|
||||
"markdown-to-jsx": "^7.1.5",
|
||||
"modele-social": "^0.6.0",
|
||||
"publicodes": "^1.0.0-beta.30",
|
||||
"publicodes-react": "^1.0.0-beta.30",
|
||||
"publicodes": "^1.0.0-beta.31",
|
||||
"publicodes-react": "^1.0.0-beta.31",
|
||||
"ramda": "^0.27.0",
|
||||
"react": "^17.0.0",
|
||||
"react-color": "^2.14.0",
|
||||
|
|
|
@ -4,14 +4,12 @@ import fs from 'fs'
|
|||
import path from 'path'
|
||||
import { filter, flatten, map, partition, pipe } from 'ramda'
|
||||
import { compose } from 'redux'
|
||||
import { fileURLToPath } from 'url'
|
||||
import { createDataDir, writeInDataDir } from './utils.js'
|
||||
|
||||
const matomoSiteVisitsHistory = JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(
|
||||
import.meta.url.replace('file:', ''),
|
||||
'../matomoVisitHistory.json'
|
||||
)
|
||||
path.join(fileURLToPath(import.meta.url), '..', 'matomoVisitHistory.json')
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -278,7 +276,9 @@ async function main() {
|
|||
// have a static ressource accessible without authentification.
|
||||
writeInDataDir('stats.json', {
|
||||
visitesJours: [],
|
||||
visitesMois: [],
|
||||
visitesMois: {
|
||||
pages: [],
|
||||
},
|
||||
satisfaction: [],
|
||||
retoursUtilisateurs: {
|
||||
open: [],
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
import { existsSync, mkdirSync, writeFileSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
const dataDir = new URL('../source/data/', import.meta.url).pathname
|
||||
const dataDir = join(
|
||||
fileURLToPath(import.meta.url),
|
||||
'..',
|
||||
'..',
|
||||
'source',
|
||||
'data'
|
||||
)
|
||||
|
||||
export function createDataDir() {
|
||||
if (!existsSync(dataDir)) {
|
||||
|
|
|
@ -47,7 +47,7 @@ type FabriqueSocialSearchPayload = {
|
|||
|
||||
const COMPANY_SEARCH_HOST =
|
||||
import.meta.env.VITE_COMPANY_SEARCH_HOST ||
|
||||
'https://search-recherche-entreprises.fabrique.social.gouv.fr'
|
||||
'https://api.recherche-entreprises.fabrique.social.gouv.fr'
|
||||
|
||||
const makeSearchUrl = (query: string, limit: number) =>
|
||||
`${COMPANY_SEARCH_HOST}/api/v1/search?query=${query}&open=true&convention=false&employer=false&ranked=false&limit=${limit}`
|
||||
|
|
|
@ -9,7 +9,6 @@ export default function PeriodSwitch() {
|
|||
|
||||
const currentUnit = useSelector(targetUnitSelector)
|
||||
const { t } = useTranslation()
|
||||
|
||||
const periods = [
|
||||
{
|
||||
label: t('Mensuel'),
|
||||
|
@ -23,7 +22,7 @@ export default function PeriodSwitch() {
|
|||
return (
|
||||
<div>
|
||||
<ToggleGroup
|
||||
defaultValue={currentUnit}
|
||||
value={currentUnit}
|
||||
onChange={(unit: string) => dispatch(updateUnit(unit))}
|
||||
>
|
||||
{periods.map(({ label, unit }) => (
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
/* eslint-disable @typescript-eslint/no-use-before-define */
|
||||
import type { AriaListBoxOptions } from '@react-aria/listbox'
|
||||
import { useListBox, useOption } from '@react-aria/listbox'
|
||||
import { useListBox, useOption, AriaListBoxOptions } from '@react-aria/listbox'
|
||||
import type { ListState } from '@react-stately/list'
|
||||
import type { Node } from '@react-types/shared'
|
||||
import * as React from 'react'
|
||||
import {
|
||||
RefObject,
|
||||
useRef,
|
||||
HTMLAttributes,
|
||||
createContext,
|
||||
ReactNode,
|
||||
useContext,
|
||||
} from 'react'
|
||||
import styled, { css } from 'styled-components'
|
||||
|
||||
interface ListBoxProps extends AriaListBoxOptions<unknown> {
|
||||
listBoxRef?: React.RefObject<HTMLUListElement>
|
||||
listBoxRef?: RefObject<HTMLUListElement>
|
||||
state: ListState<unknown>
|
||||
}
|
||||
|
||||
|
@ -67,7 +72,7 @@ const ItemContent = styled.div`
|
|||
`
|
||||
|
||||
export function ListBox(props: ListBoxProps) {
|
||||
const ref = React.useRef<HTMLUListElement>(null)
|
||||
const ref = useRef<HTMLUListElement>(null)
|
||||
const { listBoxRef = ref, state } = props
|
||||
const { listBoxProps } = useListBox(props, state, listBoxRef)
|
||||
|
||||
|
@ -81,17 +86,17 @@ export function ListBox(props: ListBoxProps) {
|
|||
}
|
||||
|
||||
interface OptionContextValue {
|
||||
labelProps: React.HTMLAttributes<HTMLElement>
|
||||
descriptionProps: React.HTMLAttributes<HTMLElement>
|
||||
labelProps: HTMLAttributes<HTMLElement>
|
||||
descriptionProps: HTMLAttributes<HTMLElement>
|
||||
}
|
||||
|
||||
const OptionContext = React.createContext<OptionContextValue>({
|
||||
const OptionContext = createContext<OptionContextValue>({
|
||||
labelProps: {},
|
||||
descriptionProps: {},
|
||||
})
|
||||
|
||||
function Option({ item, state }: OptionProps) {
|
||||
const ref = React.useRef<HTMLLIElement>(null)
|
||||
const ref = useRef<HTMLLIElement>(null)
|
||||
const { optionProps, labelProps, descriptionProps, isSelected, isFocused } =
|
||||
useOption(
|
||||
{
|
||||
|
@ -123,8 +128,8 @@ function Option({ item, state }: OptionProps) {
|
|||
// described by the description, which makes for better announcements
|
||||
// for screen reader users.
|
||||
|
||||
export function Label({ children }: { children: React.ReactNode }) {
|
||||
const { labelProps } = React.useContext(OptionContext)
|
||||
export function Label({ children }: { children: ReactNode }) {
|
||||
const { labelProps } = useContext(OptionContext)
|
||||
return <div {...labelProps}>{children}</div>
|
||||
}
|
||||
|
||||
|
@ -133,7 +138,7 @@ const StyledDescription = styled.div`
|
|||
font-size: 12px;
|
||||
`
|
||||
|
||||
export function Description({ children }: { children: React.ReactNode }) {
|
||||
const { descriptionProps } = React.useContext(OptionContext)
|
||||
export function Description({ children }: { children: ReactNode }) {
|
||||
const { descriptionProps } = useContext(OptionContext)
|
||||
return <StyledDescription {...descriptionProps}>{children}</StyledDescription>
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { FocusScope } from '@react-aria/focus'
|
||||
import { DismissButton, useOverlay } from '@react-aria/overlays'
|
||||
import * as React from 'react'
|
||||
import { RefObject, ReactNode, useRef } from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
interface PopoverProps {
|
||||
popoverRef?: React.RefObject<HTMLDivElement>
|
||||
children: React.ReactNode
|
||||
popoverRef?: RefObject<HTMLDivElement>
|
||||
children: ReactNode
|
||||
isOpen?: boolean
|
||||
onClose?: () => void
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ const Wrapper = styled.div`
|
|||
`
|
||||
|
||||
export function Popover(props: PopoverProps) {
|
||||
const ref = React.useRef<HTMLDivElement>(null)
|
||||
const ref = useRef<HTMLDivElement>(null)
|
||||
const { popoverRef = ref, isOpen, onClose, children } = props
|
||||
|
||||
// Handle events that should cause the popup to close,
|
||||
|
|
|
@ -5,7 +5,7 @@ import { mergeProps } from '@react-aria/utils'
|
|||
import { useSelectState } from '@react-stately/select'
|
||||
import type { AriaSelectProps } from '@react-types/select'
|
||||
import { CarretDown } from 'DesignSystem/icons/carret-down'
|
||||
import * as React from 'react'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled, { css } from 'styled-components'
|
||||
import { ListBox } from './ListBox'
|
||||
|
@ -175,16 +175,17 @@ export function Select<T extends Record<string, unknown>>(
|
|||
// Create state based on the incoming props
|
||||
const state = useSelectState(props)
|
||||
|
||||
React.useEffect(() => {
|
||||
useEffect(() => {
|
||||
if (props.value && props.value !== state.selectedKey) {
|
||||
state.setSelectedKey(props.value)
|
||||
}
|
||||
// On ne veut pas d'update bidirectionnel, c'est pourquoi state n'est pas dans
|
||||
// les dépendances
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [props.value])
|
||||
|
||||
// Get props for child elements from useSelect
|
||||
const ref = React.useRef(null)
|
||||
const ref = useRef<HTMLButtonElement>(null)
|
||||
const { labelProps, triggerProps, valueProps, menuProps } = useSelect(
|
||||
props,
|
||||
state,
|
||||
|
|
|
@ -5854,47 +5854,47 @@ dirigeant . indépendant . cotisations et contributions . exonérations . pensio
|
|||
description.en: >-
|
||||
[automatic] If you are the holder of a **disability pension** paid by a
|
||||
non-agricultural non-salaried worker scheme, you benefit from a **total
|
||||
exemption from supplementary pension and
|
||||
exemption from supplementary pension and
|
||||
|
||||
non-agricultural non-salaried workers, you are entitled to a **total exemption from supplementary pension contributions and
|
||||
non-agricultural non-salaried workers, you are entitled to a **total exemption from supplementary pension contributions and
|
||||
|
||||
health insurance contributions**.
|
||||
|
||||
|
||||
So that you can **continue to accumulate complementary pension points** like other workers,
|
||||
So that you can **continue to accumulate complementary pension points** like other workers,
|
||||
|
||||
you are allocated **"free points "**.
|
||||
|
||||
|
||||
In the general case, the number of points received corresponds to the **average monthly points contributed during the period of
|
||||
In the general case, the number of points received corresponds to the **average monthly points contributed during the period of
|
||||
|
||||
during the period of self-employment** before the pension is paid.
|
||||
during the period of self-employment** before the pension is paid.
|
||||
|
||||
|
||||
> For example, if you have contributed for 6 years and 11 months for a total of 588 points, the number of free points received each month will be :
|
||||
> For example, if you have contributed for 6 years and 11 months for a total of 588 points, the number of free points received each month will be :
|
||||
|
||||
|
||||
> `588 / (6 * 12 + 11) = 7,08`
|
||||
description.fr: >-
|
||||
Si vous êtes titulaire d’une **pension d’invalidité** versée par un régime
|
||||
des travailleurs non-salariés
|
||||
des travailleurs non-salariés
|
||||
|
||||
non agricoles, vous bénécifiez d’une **exonération totale des cotisations de retraite complémentaire et
|
||||
non agricoles, vous bénécifiez d’une **exonération totale des cotisations de retraite complémentaire et
|
||||
|
||||
des cotisations maladie**.
|
||||
|
||||
|
||||
Pour que vous puissiez **continuer à accumuler des points de retraite complémentaire** comme les autres travailleurs,
|
||||
Pour que vous puissiez **continuer à accumuler des points de retraite complémentaire** comme les autres travailleurs,
|
||||
|
||||
il vous est attribué des **"points gratuits"**.
|
||||
|
||||
|
||||
Dans le cas général, le nombre de points reçu correspond à la **moyenne mensuelle des points cotisés
|
||||
Dans le cas général, le nombre de points reçu correspond à la **moyenne mensuelle des points cotisés
|
||||
|
||||
pendant la période d'activité indépendante** avant versement de la pension.
|
||||
pendant la période d'activité indépendante** avant versement de la pension.
|
||||
|
||||
|
||||
> Par exemple, si vous avez cotisé pendant 6 ans et 11 mois pour un total de 588 points, le nombre de points gratuits reçu chaque mois sera de :
|
||||
> Par exemple, si vous avez cotisé pendant 6 ans et 11 mois pour un total de 588 points, le nombre de points gratuits reçu chaque mois sera de :
|
||||
|
||||
|
||||
> `588 / (6 * 12 + 11) = 7,08`
|
||||
|
|
|
@ -14,7 +14,7 @@ import { Li, Ul } from 'DesignSystem/typography/list'
|
|||
import { Body } from 'DesignSystem/typography/paragraphs'
|
||||
import rules, { DottedName } from 'modele-social'
|
||||
import { getDocumentationSiteMap, RulePage } from 'publicodes-react'
|
||||
import { useContext, useMemo } from 'react'
|
||||
import { ComponentType, useContext, useMemo } from 'react'
|
||||
import { Helmet } from 'react-helmet-async'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
@ -69,10 +69,10 @@ export default function MonEntrepriseRulePage() {
|
|||
documentationPath={documentationPath}
|
||||
renderers={{
|
||||
Head: Helmet,
|
||||
Link: Link as React.ComponentType<{
|
||||
Link: Link as ComponentType<{
|
||||
to: string
|
||||
}>,
|
||||
Text: Markdown as any,
|
||||
Text: Markdown,
|
||||
References,
|
||||
}}
|
||||
/>
|
||||
|
@ -147,9 +147,13 @@ const referencesImages = {
|
|||
'bpifrance-creation.fr': '/références-images/bpi-création.png',
|
||||
}
|
||||
|
||||
type ReferencesProps = React.ComponentProps<
|
||||
NonNullable<React.ComponentProps<typeof RulePage>['renderers']['References']>
|
||||
>
|
||||
type ReferencesProps = {
|
||||
references: React.ComponentProps<
|
||||
NonNullable<
|
||||
React.ComponentProps<typeof RulePage>['renderers']['References']
|
||||
>
|
||||
>['references']
|
||||
}
|
||||
|
||||
export function References({ references }: ReferencesProps) {
|
||||
const cleanDomain = (link: string) =>
|
||||
|
@ -217,10 +221,31 @@ const StyledReferences = styled.ul`
|
|||
}
|
||||
`
|
||||
|
||||
type OverrideComponentType = {
|
||||
componentStyle: {
|
||||
rules: Array<
|
||||
| ((
|
||||
props: Record<string, unknown>
|
||||
) =>
|
||||
| string
|
||||
| false
|
||||
| null
|
||||
| undefined
|
||||
| OverrideComponentType['componentStyle']['rules'])
|
||||
| string
|
||||
>
|
||||
}
|
||||
}
|
||||
|
||||
// HACKKKKY THING. DO NOT DO THIS AT HOME
|
||||
function componentCSS(rules: any, props: any) {
|
||||
function componentCSS(Compo: unknown, props: Record<never, never>): string {
|
||||
const rules =
|
||||
'componentStyle' in (Compo as OverrideComponentType)
|
||||
? (Compo as OverrideComponentType).componentStyle.rules
|
||||
: (Compo as string[])
|
||||
|
||||
return rules
|
||||
.map((x: any) => {
|
||||
.map((x) => {
|
||||
if (typeof x !== 'function') {
|
||||
return x
|
||||
}
|
||||
|
@ -234,39 +259,40 @@ function componentCSS(rules: any, props: any) {
|
|||
if (Array.isArray(result)) {
|
||||
return componentCSS(result, props)
|
||||
}
|
||||
console.error('Should not happen', result)
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Should not happen', result, typeof result)
|
||||
})
|
||||
.join('')
|
||||
}
|
||||
|
||||
const StyledDocumentation = styled.div`
|
||||
h1 {
|
||||
${(props) => componentCSS((H1.componentStyle as any).rules, props)}
|
||||
${(props) => componentCSS(H1, props)}
|
||||
margin-top: 1rem;
|
||||
}
|
||||
h2 {
|
||||
${(props) => componentCSS((H2.componentStyle as any).rules, props)}
|
||||
${(props) => componentCSS(H2, props)}
|
||||
}
|
||||
h3 {
|
||||
${(props) => componentCSS((H3.componentStyle as any).rules, props)}
|
||||
${(props) => componentCSS(H3, props)}
|
||||
}
|
||||
h4 {
|
||||
${(props) => componentCSS((H4.componentStyle as any).rules, props)}
|
||||
${(props) => componentCSS(H4, props)}
|
||||
}
|
||||
h5 {
|
||||
${(props) => componentCSS((H5.componentStyle as any).rules, props)}
|
||||
${(props) => componentCSS(H5, props)}
|
||||
}
|
||||
p {
|
||||
${(props) => componentCSS((Body.componentStyle as any).rules, props)}
|
||||
${(props) => componentCSS(Body, props)}
|
||||
}
|
||||
Ul {
|
||||
${(props) => componentCSS((Ul.componentStyle as any).rules, props)}
|
||||
${(props) => componentCSS(Ul, props)}
|
||||
}
|
||||
Li {
|
||||
${(props) => componentCSS((Li.componentStyle as any).rules, props)}
|
||||
${(props) => componentCSS(Li, props)}
|
||||
}
|
||||
a {
|
||||
${(props) => componentCSS((StyledLink.componentStyle as any).rules, props)}
|
||||
${(props) => componentCSS(StyledLink, props)}
|
||||
}
|
||||
button {
|
||||
font-size: 1rem;
|
||||
|
|
|
@ -32,7 +32,7 @@ export default function PageData(props: SimulatorData[keyof SimulatorData]) {
|
|||
|
||||
const année = useContext(EngineContext).evaluate('année')
|
||||
.nodeValue as Evaluation<number>
|
||||
const year = année != null && année != 2022 ? ' - ' + année : ''
|
||||
const year = typeof année === 'number' && année != 2022 ? ` - ${année}` : ''
|
||||
|
||||
const inIframe = useIsEmbedded()
|
||||
const fromGérer = !!useLocation<{ fromGérer?: boolean }>().state?.fromGérer
|
||||
|
@ -68,7 +68,7 @@ export default function PageData(props: SimulatorData[keyof SimulatorData]) {
|
|||
return (
|
||||
<CurrentSimulatorDataProvider value={props}>
|
||||
<TrackChapter {...trackInfo} />
|
||||
{meta && <Meta page={`simulateur.${title}`} {...meta} />}
|
||||
{meta && <Meta page={`simulateur.${title ?? ''}`} {...meta} />}
|
||||
{title && !inIframe && (
|
||||
<>
|
||||
<H1>
|
||||
|
|
|
@ -28,4 +28,7 @@ questions:
|
|||
unité par défaut: €/an
|
||||
situation:
|
||||
dirigeant: "'assimilé salarié'"
|
||||
contrat salarié . activité partielle: non #TODO : en attendant que la transitivité du remplacement soit implémentée
|
||||
|
||||
#TODO : en attendant que la transitivité du remplacement soit implémentée (https://github.com/betagouv/publicodes/issues/55)
|
||||
contrat salarié . activité partielle: non
|
||||
contrat salarié . déduction forfaitaire spécifique: non
|
||||
|
|
|
@ -43,15 +43,17 @@ function IntegrationCustomizer() {
|
|||
|
||||
const defaultModuleFromUrl =
|
||||
new URLSearchParams(search ?? '').get('module') ?? ''
|
||||
|
||||
const [currentModule, setCurrentModule] = useState(
|
||||
simulators[defaultModuleFromUrl] ? defaultModuleFromUrl : 'salarié'
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
history.replace({ search: `?module=${currentModule}` })
|
||||
}, [currentModule])
|
||||
console.log(currentModule, simulators[currentModule])
|
||||
}, [currentModule, history])
|
||||
|
||||
const [color, setColor] = useState<string | undefined>()
|
||||
|
||||
return (
|
||||
<>
|
||||
<H2>
|
||||
|
@ -65,7 +67,7 @@ function IntegrationCustomizer() {
|
|||
</H3>
|
||||
<Select
|
||||
label="Assistant ou simulateur"
|
||||
onSelectionChange={setCurrentModule as any}
|
||||
onSelectionChange={(val) => setCurrentModule(String(val))}
|
||||
selectedKey={currentModule}
|
||||
>
|
||||
{Object.entries(simulators).map(([module, s]) => (
|
||||
|
@ -114,7 +116,7 @@ function IntegrationCustomizer() {
|
|||
<MemoryRouter
|
||||
key={currentModule}
|
||||
initialEntries={[
|
||||
`/iframes/${simulators[currentModule].iframePath}`,
|
||||
`/iframes/${simulators[currentModule].iframePath ?? ''}`,
|
||||
]}
|
||||
>
|
||||
<ThemeColorsProvider
|
||||
|
@ -140,6 +142,7 @@ function IntegrationCustomizer() {
|
|||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const PrevisualisationContainer = styled(Grid)`
|
||||
background-color: white;
|
||||
border: 1px solid ${({ theme }) => theme.colors.extended.grey[300]};
|
||||
|
|
38
yarn.lock
38
yarn.lock
|
@ -3640,20 +3640,6 @@ flush-write-stream@^1.0.2:
|
|||
inherits "^2.0.3"
|
||||
readable-stream "^2.3.6"
|
||||
|
||||
focus-trap-react@^8.8.2:
|
||||
version "8.9.1"
|
||||
resolved "https://registry.yarnpkg.com/focus-trap-react/-/focus-trap-react-8.9.1.tgz#5f2b3bce6a7c4de6485fd6f4c5e8c0cbaa6e9ad3"
|
||||
integrity sha512-QGVw4ch1ZfT2IcCL1ehBgrwnFuPA0nP7hXcrZzC8SThbktt/jiXCWQSKhA2WL0nVbxTiZ7YpIu/foTekp+dcqA==
|
||||
dependencies:
|
||||
focus-trap "^6.7.2"
|
||||
|
||||
focus-trap@^6.7.2:
|
||||
version "6.7.2"
|
||||
resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-6.7.2.tgz#02e63b12f4d4b3d00bfac4309cfd223e9b4ed44e"
|
||||
integrity sha512-mRVv9QPCXITaDreu+pNXiPk1Rpn0WQtGvGrDo3Z/s2kdwtzFw/WOPfbLkdxWWvcahoInm9eRztuQOr1RNyQGrw==
|
||||
dependencies:
|
||||
tabbable "^5.2.1"
|
||||
|
||||
foreach@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
|
||||
|
@ -5137,14 +5123,12 @@ psl@^1.1.28:
|
|||
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
|
||||
integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
|
||||
|
||||
publicodes-react@^1.0.0-beta.30:
|
||||
version "1.0.0-beta.30"
|
||||
resolved "https://registry.yarnpkg.com/publicodes-react/-/publicodes-react-1.0.0-beta.30.tgz#ff1b815c69da4f5f6616f425535f109aae169005"
|
||||
integrity sha512-8WtZLUVx7NPTSpD2ikmpUwkA9rLZ4oMNANijN9lUqka8rjIQUStYQely4whk4QwAlkUeTgtzoATAws5Qe46CDg==
|
||||
publicodes-react@^1.0.0-beta.31:
|
||||
version "1.0.0-beta.31"
|
||||
resolved "https://registry.yarnpkg.com/publicodes-react/-/publicodes-react-1.0.0-beta.31.tgz#96929254097ffa9fa837c517776a8c223fb3e09f"
|
||||
integrity sha512-k/3dHxGupQTjI3B5w0+dVOxOs1nfJTGdXWCzKiZaRv3M+Fd/bgLz8zKOWgqiAQMKdeItz36FUPKelWvxL5dOwA==
|
||||
dependencies:
|
||||
focus-trap-react "^8.8.2"
|
||||
styled-components "^5.1.0"
|
||||
yaml "^1.9.2"
|
||||
|
||||
publicodes@^1.0.0-beta.30:
|
||||
version "1.0.0-beta.30"
|
||||
|
@ -5155,6 +5139,15 @@ publicodes@^1.0.0-beta.30:
|
|||
nearley "^2.19.2"
|
||||
yaml "^1.9.2"
|
||||
|
||||
publicodes@^1.0.0-beta.31:
|
||||
version "1.0.0-beta.31"
|
||||
resolved "https://registry.yarnpkg.com/publicodes/-/publicodes-1.0.0-beta.31.tgz#580e7c466fc21ccd27428ea13a3874eff9551db6"
|
||||
integrity sha512-Bhy/BKy4eP3u/ms0K2x0uH9CYDpjiA/utgagr65A9PpL7lToiMACRrLXJLkwh+xHXy9f/32OD92FZoTB026TCA==
|
||||
dependencies:
|
||||
moo "^0.5.1"
|
||||
nearley "^2.19.2"
|
||||
yaml "^1.9.2"
|
||||
|
||||
pump@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909"
|
||||
|
@ -6107,11 +6100,6 @@ systemjs@^6.11.0:
|
|||
resolved "https://registry.yarnpkg.com/systemjs/-/systemjs-6.12.1.tgz#47cdd23a6ec9f1b01cf5b5f70562c8550da229d3"
|
||||
integrity sha512-hqTN6kW+pN6/qro6G9OZ7ceDQOcYno020zBQKpZQLsJhYTDMCMNfXi/Y8duF5iW+4WWZr42ry0MMkcRGpbwG2A==
|
||||
|
||||
tabbable@^5.2.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-5.2.1.tgz#e3fda7367ddbb172dcda9f871c0fdb36d1c4cd9c"
|
||||
integrity sha512-40pEZ2mhjaZzK0BnI+QGNjJO8UYx9pP5v7BGe17SORTO0OEuuaAwQTkAp8whcZvqon44wKFOikD+Al11K3JICQ==
|
||||
|
||||
text-table@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
|
|
Loading…
Reference in New Issue