Autofix new eslint rules

pull/2070/head
Jérémy Rialland 2022-03-28 14:57:11 +02:00 committed by Jérémy Rialland
parent 058702462e
commit d0c4e69a8a
155 changed files with 351 additions and 27 deletions

View File

@ -6,4 +6,5 @@ import { Names } from './dist/names'
export type DottedName = Names
declare let rules: Record<Names, Rule>
export default rules

View File

@ -6,4 +6,5 @@ import { Names } from './dist/names'
export type DottedName = Names
declare let rules: Record<Names, Rule>
export default rules

View File

@ -25,7 +25,9 @@ const falsy = <T>(value: T | false): value is T => Boolean(value)
const formatRulesToAlgolia = (rules: ParsedRules<string>) =>
Object.entries(rules)
.map(([n, rule]) => {
if (!rule) return false
if (!rule) {
return false
}
const path = n.split(' . ')
const {
title,

View File

@ -85,6 +85,7 @@ export function createTracker(siteId?: string, doNotTrack = false) {
super.dispatch()
}
}
return Tag
}
@ -116,6 +117,7 @@ export class Log implements ATTracker {
},
getVisitorMode() {
console.debug('ATTracker::privacy.getVisitorMode')
return { name: 'exempt' }
},
}

View File

@ -14,6 +14,7 @@ export function toAtString(string: string): string {
string = string.replace(/[\307\347]/g, 'c')
string = string.replace(/[\321\361]/g, 'n')
string = string.replace(/[^\w]/gi, '_')
return string
}
@ -31,6 +32,7 @@ let chapters: {
chapter2?: string
chapter3?: string
} = {}
export function TrackChapter(props: {
chapter1?: Chapter1
chapter2?: string
@ -38,14 +40,17 @@ export function TrackChapter(props: {
}) {
if (props.chapter1) {
chapters = { chapter2: '', chapter3: '', ...props }
return null
}
if (props.chapter2) {
chapters = { ...chapters, chapter3: '', ...props }
return null
}
chapters = { ...chapters, ...props }
return null
}
@ -73,5 +78,6 @@ export function TrackPage(props: {
propsFormatted.chapter2,
propsFormatted.chapter3,
])
return null
}

View File

@ -70,6 +70,7 @@ export default function Root({
// eslint-disable-next-line react-hooks/exhaustive-deps
[rules]
)
return (
<StrictMode>
<Provider
@ -105,6 +106,7 @@ const Router = () => {
}),
[configSituation, simulatorSituation, companySituation]
)
return (
<SituationProvider situation={situation}>
<Switch>
@ -130,6 +132,7 @@ const App = () => {
const { t } = useTranslation()
const sitePaths = useContext(SitePathsContext)
const isEmbedded = useIsEmbedded()
return (
<StyledLayout isEmbeded={isEmbedded}>
{!isEmbedded && <Header />}

View File

@ -28,6 +28,7 @@ export const useDispatchAndGoToNextQuestion = () => {
history.push(nextQuestion)
}
}, [dispatched])
return (action: Action) => {
dispatch(action)
setDispatched(true)
@ -76,6 +77,7 @@ export const resetCompanyStatusChoice = (
export const useSetEntreprise = () => {
const dispatch = useDispatch()
return (entreprise: FabriqueSocialEntreprise) => {
if (entreprise === null) {
return

View File

@ -37,6 +37,7 @@ export async function searchCommunes(
return null
}
const json = (await response.json()) as Array<ApiCommuneJson>
return json
.flatMap(({ codesPostaux, ...commune }) =>
codesPostaux
@ -68,6 +69,7 @@ export async function fetchCommuneDetails(
if (taux === null) {
return null
}
return {
...commune,
'taux du versement transport': taux,

View File

@ -64,5 +64,6 @@ async function searchFullText(
}
const json: FabriqueSocialSearchPayload = await response.json()
return json.entreprises
}

View File

@ -14,6 +14,7 @@ export async function fetchCompanyDetails(siren: string) {
return null
}
const json = await response.json()
return json.unite_legale
}
@ -24,6 +25,7 @@ export async function searchDenominationOrSiren(value: string) {
if (isSIREN(value)) {
return [{ siren: value }]
}
return searchFullText(value)
}

View File

@ -34,6 +34,7 @@ export default function Banner({
const hiddenState = useSelector(firstStepCompletedSelector)
const hidden = hiddenProp || (hideAfterFirstStep && hiddenState)
return !hidden ? (
<FadeIn className={className}>
<Container>

View File

@ -37,6 +37,7 @@ function ChartItemBar({
},
flex: display ? percentage : 0,
})
return (
<div className="distribution-chart__bar-container">
{disableAnimation ? (

View File

@ -53,6 +53,7 @@ export default function Value<Names extends string>({
</RuleLink>
)
}
return <span {...props}>{value}</span>
}
@ -61,6 +62,7 @@ type ConditionProps = {
defaultIfNotYetDefined?: boolean
children: React.ReactNode
}
export function Condition({
expression,
defaultIfNotYetDefined = false,
@ -82,6 +84,7 @@ export function Condition({
if (!boolValue) {
return null
}
return <>{children}</>
}
@ -96,6 +99,7 @@ export function WhenApplicable({
if (engine.evaluate(dottedName).nodeValue == null) {
return null
}
return <>{children}</>
}
export function WhenNotApplicable({
@ -109,6 +113,7 @@ export function WhenNotApplicable({
if (engine.evaluate(dottedName).nodeValue !== null) {
return null
}
return <>{children}</>
}
@ -123,6 +128,7 @@ export function WhenAlreadyDefined({
if (isNotYetDefined(engine.evaluate(dottedName).nodeValue)) {
return null
}
return <>{children}</>
}
@ -137,5 +143,6 @@ export function WhenNotAlreadyDefined({
if (!isNotYetDefined(engine.evaluate(dottedName).nodeValue)) {
return null
}
return <>{children}</>
}

View File

@ -34,6 +34,7 @@ const askFeedback = (url: string) => {
if (!previousFeedbackDate) {
return true
}
return (
new Date(previousFeedbackDate) <
new Date(new Date().setMonth(new Date().getMonth() - 4))

View File

@ -6,6 +6,7 @@ import { Trans, useTranslation } from 'react-i18next'
export default function LegalNotice() {
const { t } = useTranslation()
return (
<PopoverWithTrigger
trigger={(buttonProps) => (

View File

@ -37,6 +37,7 @@ function getSection(rule: RuleNode): Section {
if (SECTION_ORDER.includes(section)) {
return section
}
return 'protection sociale . autres'
}
@ -75,11 +76,13 @@ export function getCotisationsBySection(
)
.reduce((acc, cotisation: DottedName) => {
const sectionName = getSection(parsedRules[cotisation])
return {
...acc,
[sectionName]: (acc[sectionName] ?? new Set()).add(cotisation),
}
}, {} as Record<Section, Set<DottedName>>)
return Object.entries(cotisations)
.map(([section, dottedNames]) => [section, [...dottedNames.values()]])
.sort(
@ -132,6 +135,7 @@ export default function PaySlip() {
</H4>
{cotisationsBySection.map(([sectionDottedName, cotisations]) => {
const section = parsedRules[sectionDottedName]
return (
<Fragment key={section.dottedName}>
<H5 className="payslip__cotisationTitle">
@ -231,6 +235,7 @@ function Cotisation({ dottedName }: { dottedName: DottedName }) {
if (!partPatronale.nodeValue && !partSalariale.nodeValue) {
return null
}
return (
<>
<RuleLink dottedName={dottedName} />

View File

@ -30,6 +30,7 @@ export const SalaireBrutSection = () => {
export const SalaireNetSection = () => {
const { t } = useTranslation()
return (
<div className="payslip__salarySection">
<H4 className="payslip__salaryTitle">
@ -89,8 +90,9 @@ export function Line({
// ⚠️ isNotApplicable is a bad func only here to help with further refactoring:
isNotApplicable(evaluatedNode.nodeValue) ||
evaluatedNode.nodeValue === 0
)
) {
return null
}
return (
<Condition expression={`${rule} > 0`}>

View File

@ -19,6 +19,7 @@ export default function PeriodSwitch() {
unit: '€/an',
},
]
return (
<div>
<ToggleGroup

View File

@ -15,6 +15,7 @@ export default function RuleLink(
) {
const sitePaths = useContext(SitePathsContext)
const engine = useContext(EngineContext)
return (
<EngineRuleLink
{...props}

View File

@ -20,6 +20,7 @@ export function ShareSimulationPopup({ url }: { url: string }) {
useEffect(() => {
const handler = setTimeout(() => setLinkCopied(false), 5000)
return () => {
clearTimeout(handler)
}

View File

@ -34,6 +34,7 @@ export function useUrl() {
: import.meta.env.VITE_EN_BASE_URL
searchParams.set('utm_source', 'sharing')
return siteUrl + path + '?' + searchParams.toString()
}

View File

@ -13,6 +13,7 @@ const QuestionsContainer = styled.div`
`0 0 ${theme.box.borderRadius} ${theme.box.borderRadius}`};
background: ${({ theme }) => {
const colorPalette = theme.colors.bases.primary
return `linear-gradient(60deg, ${colorPalette[200]} 0%, ${colorPalette[100]} 100%);`
}};
`

View File

@ -77,6 +77,7 @@ export function SimulationGoal({
) {
return null
}
return (
<Appear unless={!appear || initialRender}>
<StyledGoal>

View File

@ -68,6 +68,7 @@ const StyledSimulationGoals = styled.div<
const colorPalette = publique
? theme.colors.publics[publique]
: theme.colors.bases.primary
return css`linear-gradient(60deg, ${colorPalette[800]} 0%, ${colorPalette[600]} 100%);`
}};

View File

@ -52,6 +52,7 @@ export default function Simulation({
const existingCompany = !!useSelector(companySituationSelector)[
'entreprise . SIREN'
]
return (
<>
{!firstStepCompleted && <TrackPage name="accueil" />}

View File

@ -65,6 +65,7 @@ type Precision = 1 | 0.1 | 0.01
function integerAndDecimalParts(value: number) {
const integer = Math.floor(value)
const decimal = value - integer
return { integer, decimal }
}
@ -104,6 +105,7 @@ export function roundedPercentages(
precision: Precision
) {
const logScale = Math.log10(precision)
return simpleRoundedPer(values, logScale).map(
(int) => int / Math.pow(10, -logScale)
)
@ -128,6 +130,7 @@ export function StackedBarChart({
})
const styles = useSpring({ opacity: displayChart ? 1 : 0 })
return !useContext(DisableAnimationContext) ? (
<animated.div ref={intersectionRef} style={styles}>
<InnerStackedBarChart data={data} precision={precision} />
@ -147,6 +150,7 @@ function InnerStackedBarChart({ data, precision }: InnerStackedBarChartProps) {
...data,
percentage: percentages[index],
}))
return (
<>
<BarStack className="print-background-force">
@ -190,6 +194,7 @@ export default function StackedRulesChart({
}: StackedRulesChartProps) {
const engine = useEngine()
const targetUnit = useSelector(targetUnitSelector)
return (
<StackedBarChart
precision={precision}

View File

@ -74,6 +74,7 @@ function highlightLabelToJSX(highlightLabel: string) {
)
}
result.push(highlightLabel.slice(parsedLength))
return result
}

View File

@ -177,6 +177,7 @@ function AnswerElement(
setEditing(false)
}
window.addEventListener('click', onClickOutside)
return () => window.removeEventListener('click', onClickOutside)
}, [])
const situation = useSelector(situationSelector)

View File

@ -53,6 +53,7 @@ export function MultipleAnswerInput({
// seront stockées ainsi dans le state :
// [parent object path]: dotted fieldName relative to parent
const { handleChange, defaultValue, currentSelection } = useSelection(props)
return (
<RadioGroup onChange={handleChange} value={currentSelection ?? undefined}>
<RadioChoice

View File

@ -14,8 +14,11 @@ export default function DateInput({
value,
}: InputProps) {
const dateValue = useMemo(() => {
if (!value || typeof value !== 'string') return undefined
if (!value || typeof value !== 'string') {
return undefined
}
const [day, month, year] = value.split('/')
return `${year}-${month}-${day}`
}, [value])
// const [currentValue, setCurrentValue] = useState(dateValue)
@ -38,6 +41,7 @@ export default function DateInput({
},
[onChange]
)
return (
<div className="step input">
<div>

View File

@ -14,10 +14,14 @@ export function ExplicableRule({
const engine = useContext(EngineContext)
// Rien à expliquer ici, ce n'est pas une règle
if (dottedName == null) return null
if (dottedName == null) {
return null
}
const rule = engine.getRule(dottedName)
if (rule.rawNode.description == null) return null
if (rule.rawNode.description == null) {
return null
}
//TODO montrer les variables de type 'une possibilité'

View File

@ -24,6 +24,7 @@ export default function InputSuggestions({
if (!suggestions || !Object.keys(suggestions).length) {
return null
}
return (
<StyledInputSuggestion className={className}>
{toPairs(suggestions).map(([text, value]: [string, ASTNode]) => {
@ -32,8 +33,11 @@ export default function InputSuggestions({
key={text}
onPress={() => {
onFirstClick(value)
if (suggestion !== value) setSuggestion(value)
else onSecondClick && onSecondClick(value)
if (suggestion !== value) {
setSuggestion(value)
} else {
onSecondClick && onSecondClick(value)
}
}}
title={t('cliquez pour insérer cette suggestion')}
>

View File

@ -52,6 +52,7 @@ export default function NumberInput({
...formatOptions,
}
const debouncedOnChange = useCallback(debounce(1000, onChange), [])
return (
<StyledNumberInput>
<NumberField
@ -118,6 +119,7 @@ function getSerializedUnit(
) ?? ''
)
}
return (
Intl.NumberFormat(locale, {
unit: formatUnit,
@ -161,6 +163,7 @@ function getFormatUnit(unit: Unit): Intl.NumberFormatOptions['unit'] | null {
if (denominator) {
formatUnit += `-per-${UNIT_MAP[denominator as keyof typeof UNIT_MAP]}`
}
return formatUnit
}

View File

@ -101,20 +101,24 @@ export default function RuleInput({
/>
)
}
if (rule.rawNode.API && rule.rawNode.API === 'commune')
if (rule.rawNode.API && rule.rawNode.API === 'commune') {
return <SelectCommune {...commonProps} />
if (rule.rawNode.API && rule.rawNode.API.startsWith('pays détachement'))
}
if (rule.rawNode.API && rule.rawNode.API.startsWith('pays détachement')) {
return (
<SelectPaysDétachement
{...commonProps}
plusFrance={rule.rawNode.API.endsWith('plus France')}
/>
)
if (rule.rawNode.API)
}
if (rule.rawNode.API) {
throw new Error("Les seules API implémentées sont 'commune'")
}
if (rule.dottedName == 'contrat salarié . ATMP . taux collectif ATMP')
if (rule.dottedName == 'contrat salarié . ATMP . taux collectif ATMP') {
return <SelectAtmp {...commonProps} />
}
if (rule.rawNode.type === 'date') {
return <DateInput {...commonProps} />
@ -162,11 +166,14 @@ export const buildVariantTree = <Name extends string>(
path: Name
): Choice => {
const node = engine.getRule(path)
if (!node) throw new Error(`La règle ${path} est introuvable`)
if (!node) {
throw new Error(`La règle ${path} est introuvable`)
}
const variant = getVariant(node)
const canGiveUp =
variant &&
(!variant['choix obligatoire'] || variant['choix obligatoire'] === 'non')
return Object.assign(
node,
variant

View File

@ -13,6 +13,7 @@ export default function TextInput({
autoFocus,
}: InputProps & { value: Evaluation<string> }) {
const debouncedOnChange = useCallback(debounce(1000, onChange), [])
return (
<TextField
autoFocus={autoFocus}

View File

@ -15,6 +15,7 @@ import {
function formatCommune(value: SearchCommune) {
return value && `${value.nom} (${value.codePostal})`
}
export default function Select({
onChange,
value,
@ -86,6 +87,7 @@ export default function Select({
setName(value)
if (value.length < 2) {
setSearchResults(null)
return
}
setLoadingState(true)
@ -143,6 +145,7 @@ export default function Select({
<OptionList role="listbox" aria-expanded="true" id="liste-commune">
{searchResults.map((result, i) => {
const nom = formatCommune(result)
return (
<Option
as="li"

View File

@ -65,6 +65,7 @@ export default function SelectPaysDétachement({
const valueId = value
? statesWithID.find((s) => s.name === value)?.id
: undefined
return (
<Select
name="country"

View File

@ -51,6 +51,7 @@ const STATES = [
'Uruguay',
'Autre',
]
export default function SelectPaysDétachement({
value,
onChange,
@ -66,6 +67,7 @@ export default function SelectPaysDétachement({
const valueId = value
? statesWithID.find((s) => s.name === value)?.id
: undefined
return (
<Select
name="country"

View File

@ -1,4 +1,5 @@
import ContactImage from '@/images/contact.png'
const Contact = () => (
<div className="centeredMessage">
<p>

View File

@ -14,6 +14,7 @@ export default function Header() {
const {
i18n: { language },
} = useTranslation()
return (
<Container>
<StyledHeader>

View File

@ -37,6 +37,7 @@ export default function NewsBanner() {
if (!showBanner) {
return null
}
return (
<Banner className="print-hidden" onClick={() => setShowBanner(false)}>
<InnerBanner>

View File

@ -91,6 +91,7 @@ const InfiniteHits = styled.div`
const Hits = connectInfiniteHits(({ hits, hasMore, refineNext }) => {
const { t } = useTranslation()
return (
<InfiniteHits>
<HitList>

View File

@ -5,6 +5,7 @@ import { connectSearchBox } from 'react-instantsearch-dom'
export const SearchBox = connectSearchBox(
({ currentRefinement, isSearchStalled, refine }) => {
const { t } = useTranslation()
return (
<form noValidate action="" role="search">
<SearchField

View File

@ -7,6 +7,7 @@ import { RulesInfiniteHits } from './RulesInfiniteHits'
import { SearchBox } from './SearchBox'
import { SearchRoot } from './SearchRoot'
import { SimulatorHits } from './SimulatorHits'
const ALGOLIA_APP_ID = import.meta.env.VITE_ALGOLIA_APP_ID || ''
const ALGOLIA_SEARCH_KEY = import.meta.env.VITE_ALGOLIA_SEARCH_KEY || ''
const ALGOLIA_INDEX_PREFIX = import.meta.env.VITE_ALGOLIA_INDEX_PREFIX || ''

View File

@ -54,6 +54,7 @@ export const SimulatorHits = connectHits<
AlgoliaSimulatorHit
>(({ hits }: SimulatorHitsProps) => {
const sitePaths = useContext(SitePathsContext)
return (
<>
{hits.length > 0 && (

View File

@ -13,6 +13,7 @@ export default function CotisationsForfaitaires() {
const rule = useEngine().getRule(
'dirigeant . indépendant . cotisations et contributions . début activité'
)
return (
<FromBottom>
<Message>

View File

@ -10,6 +10,7 @@ export default function CotisationsRégularisation() {
const rule = useEngine().getRule(
'dirigeant . indépendant . cotisations et contributions . régularisation'
)
return (
<FromBottom>
<div>

View File

@ -170,6 +170,7 @@ function DroitsRetraite() {
) {
return null
}
return (
<Trans i18nKey="pages.simulateurs.indépendant.retraite-droits-acquis">
<H3 as="h2">Retraite : droits acquis sur l'année</H3>

View File

@ -23,6 +23,7 @@ import { Message } from '@/design-system'
export default function InstitutionsPartenaires() {
const unit = useSelector(targetUnitSelector)
return (
<section>
<FromBottom>
@ -97,6 +98,7 @@ export function CotisationsUrssaf({
extraNotice,
}: CotisationsUrssafProps) {
const unit = useSelector(targetUnitSelector)
return (
<InstitutionLine>
<InstitutionLogo
@ -121,6 +123,7 @@ export function CotisationsUrssaf({
export function ImpôtsDGFIP() {
const unit = useSelector(targetUnitSelector)
return (
<Condition expression="impôt . montant > 0">
<InstitutionLine>
@ -169,6 +172,7 @@ function CaisseRetraite() {
const dottedName =
`dirigeant . indépendant . PL . ${caisse}` as DottedName
const { description, références } = engine.getRule(dottedName).rawNode
return (
<Condition expression={dottedName} key={caisse}>
<InstitutionLine>
@ -205,6 +209,7 @@ export function InstitutionsPartenairesArtisteAuteur() {
const { description: descriptionIRCEC } = useEngine().getRule(
'artiste-auteur . cotisations . IRCEC'
).rawNode
return (
<section>
<H3>Vos cotisations</H3>

View File

@ -11,6 +11,7 @@ type AnimatedTargetValueProps = {
const formatDifference = (difference: number, language: string) => {
const prefix = difference > 0 ? '+' : ''
return prefix + formatValue(difference, { displayedUnit: '€', language })
}
@ -45,6 +46,7 @@ export default function AnimatedTargetValue({
if (!difference || Math.abs(difference) < 1) {
return null
}
return (
<div
className="print-hidden"

View File

@ -96,6 +96,7 @@ const StyledLink = styled(Link)`
margin-left: ${({ theme }) => theme.spacings.xs};
white-space: nowrap;
`
export type ChecklistProps = {
children: React.ReactNode
onItemCheck?: (name: string, isChecked: boolean) => void
@ -114,6 +115,7 @@ export function Checklist({
if (!React.isValidElement(child)) {
throw new Error('Invalid child passed to Checklist')
}
return React.cloneElement(child, {
onChange: (isSelected: boolean) =>
onItemCheck?.(child.props.name, isSelected),

View File

@ -36,6 +36,7 @@ export function FromBottom({
return <>{children}</>
}
const childrenArray = React.Children.toArray(children)
return (
<>
{trail.map((style, i) => (
@ -70,6 +71,7 @@ export function FromTop({
return <>{children}</>
}
const childrenArray = React.Children.toArray(children)
return (
<>
{trail.map((style, i) => (
@ -102,6 +104,7 @@ export const FadeIn = ({
if (useContext(DisableAnimationContext)) {
return <>{children}</>
}
return <animated.div style={style}>{children}</animated.div>
}

View File

@ -11,5 +11,6 @@ export default function BrowserOnly({
if (import.meta.env.SSR) {
return null
}
return <Appear>{children}</Appear>
}

View File

@ -15,6 +15,7 @@ const useIsPrintContext = () => {
// `addEventListener` isn't supported by old versions of Safari and throws a
// fatal error. See #1790 and https://stackoverflow.com/a/56466334
matchMediaPrint.addEventListener?.('change', matchListener)
return () => {
matchMediaPrint.removeEventListener?.('change', matchListener)
}
@ -27,6 +28,7 @@ const useIsPrintContext = () => {
setPrintContext(true)
})
}
return () => {
window.onbeforeprint = null
}
@ -41,6 +43,7 @@ export function DisableAnimationOnPrintProvider({
children: React.ReactNode
}) {
const isPrintContext = useIsPrintContext()
return (
<DisableAnimationContext.Provider value={isPrintContext}>
{children}

View File

@ -3,9 +3,11 @@ import { useEffect } from 'react'
export default function DisableScroll() {
useEffect(() => {
document.documentElement.style.overflow = 'hidden'
return () => {
document.documentElement.style.overflow = ''
}
}, [])
return null
}

View File

@ -1,5 +1,6 @@
import emojiFn from 'react-easy-emoji'
import { useTranslation } from 'react-i18next'
type PropType = {
emoji: string | undefined
alt?: string
@ -20,6 +21,7 @@ export default function Emoji({ emoji, alt, title }: PropType) {
if (!emoji) {
return null
}
return emojiFn(
emoji,
import.meta.env.MODE === 'production'

View File

@ -11,9 +11,11 @@ const engineOptions = {
const key = unitsTranslations
.find(([, trans]) => trans === unit)?.[0]
.replace(/_plural$/, '')
return key || unit
},
}
export function engineFactory(rules: Rules, options = {}) {
return new Engine(rules, { ...engineOptions, ...options })
}
@ -31,12 +33,14 @@ type SituationProviderProps = {
Record<DottedName, string | number | Record<string, unknown>>
>
}
export function SituationProvider({
children,
situation,
}: SituationProviderProps) {
const engine = useContext(EngineContext)
engine.setSituation(situation)
return (
<EngineContext.Provider value={engine}>{children}</EngineContext.Provider>
)

View File

@ -30,6 +30,7 @@ export default function Meta({
ogTitle: ogTitle ? t(`${page}.ogTitle`, ogTitle) || ogTitle : title,
ogImage: ogImage ? t(`${page}.ogImage`, ogImage) || ogImage : null,
}
return (
<Helmet htmlAttributes={{ lang: i18n.language }}>
<title>{meta.title}</title>

View File

@ -31,6 +31,7 @@ export function ScrollToTop({
window.scroll(0, 0)
}
}, [])
return <div ref={ref} />
}

View File

@ -32,6 +32,7 @@ export function IsEmbeddedProvider({
isEmbeded?: boolean
}) {
const state = useState(isEmbeded)
return (
<IsEmbeddedContext.Provider value={state}>
{children}

View File

@ -18,5 +18,6 @@ export function useDebounce<T>(value: T, delay: number) {
},
[value, delay] // Only re-call effect if value or delay changes
)
return debouncedValue
}

View File

@ -194,6 +194,7 @@ export function HeadingWithAnchorLink({
) : (
children
)
return (
<Heading
id={headingId}

View File

@ -13,6 +13,7 @@ export const getInitialState = <T extends Storage>(key: string): T | null => {
} catch (e) {
// eslint-disable-next-line no-console
console.warn(e)
return null
}
}
@ -36,5 +37,6 @@ export const usePersistingState = <T extends Storage>(
const initialState = persistedState != null ? persistedState : defaultState
const [state, setState] = useState<T>(initialState)
useSafeLocaleStorage(key, state)
return [state, setState] as const
}

View File

@ -15,6 +15,7 @@ export default function ({
useEffect(() => {
if (typeof IntersectionObserver === 'undefined') {
setWasOnScreen(true) // No effect for old browsers
return
}
@ -38,6 +39,7 @@ export default function ({
if (node) {
observer.observe(node)
}
return () => {
node && unobserve && observer.unobserve(node)
}

View File

@ -14,6 +14,7 @@ export function WatchInitialRender(props: { children: ReactNode }) {
useEffect(() => {
setInitialRender(false)
}, [])
return (
<InitialRenderContext.Provider value={initialRender}>
{props.children}

View File

@ -35,6 +35,7 @@ import {
import { EngineContext } from './EngineContext'
type MissingVariables = Partial<Record<DottedName, number>>
export function getNextSteps(
missingVariables: Array<MissingVariables>
): Array<DottedName> {
@ -65,6 +66,7 @@ export function getNextSteps(
),
pairs = toPairs<number>(missingByCompound),
sortedPairs = sortWith([descend(byCount), descend(byScore) as any], pairs)
return map(head, sortedPairs) as any
}
@ -108,12 +110,14 @@ export function getNextQuestions(
.replace(/'/g, '')
.trim() as DottedName)
: lastStep
return sortBy((question) => {
const indexList =
whitelist.findIndex((name) => question.startsWith(name)) + 1
const indexNotPriority =
notPriority.findIndex((name) => question.startsWith(name)) + 1
const differenceCoeff = questionDifference(question, lastStepWithAnswer)
return indexList + indexNotPriority + differenceCoeff
}, nextSteps)
}
@ -138,6 +142,7 @@ export const useNextQuestions = function (): Array<DottedName> {
if (currentQuestion && currentQuestion !== next[0]) {
next = [currentQuestion, ...next.filter((val) => val !== currentQuestion)]
}
return next.filter(
(question) => engine.evaluate(question).nodeValue !== null
)

View File

@ -57,6 +57,7 @@ export function createSearchParams(
? init
: Object.keys(init).reduce((memo, key) => {
const value = init[key]
return memo.concat(
Array.isArray(value) ? value.map((v) => [key, v]) : [[key, value]]
)

View File

@ -66,6 +66,7 @@ export default function useSearchParamsSimulationSharing() {
setUrlSituationIsExtracted(true)
}
return
}, [
currentUrl,
@ -92,6 +93,7 @@ export const useParamsFromSituation = (situation: Situation) => {
() => getRulesParamNames(engine.getParsedRules()),
[engine]
)
return getSearchParamsFromSituation(engine, situation, dottedNameParamName)
}
@ -100,6 +102,7 @@ const objectifsOfConfig = (config: Partial<SimulationConfig>) =>
if (typeof objectifOrSection === 'string') {
return [objectifOrSection]
}
return objectifOrSection.objectifs
})
@ -140,11 +143,13 @@ export function getSearchParamsFromSituation(
([dottedName, value]) => {
const paramName = dottedNameParamNameMapping[dottedName]
const serializedValue = serializeEvaluation(engine.evaluate(value))
if (typeof serializedValue !== 'undefined')
if (typeof serializedValue !== 'undefined') {
searchParams.set(paramName, serializedValue)
}
}
)
searchParams.sort()
return searchParams
}

View File

@ -26,6 +26,7 @@ const useIFrameOffset = () => {
}
void getIframeOffset().then(setOffset)
}, [])
return offsetTop
}

View File

@ -58,9 +58,15 @@ export const StyledButton = styled.button<StyledButtonProps>`
font-weight: 500;
padding: ${({ size }) => {
if (size === 'XL') return '1.25rem 2rem'
if (size === 'MD') return '0.875rem 2rem'
if (size === 'XS') return '0.5rem 2rem'
if (size === 'XL') {
return '1.25rem 2rem'
}
if (size === 'MD') {
return '0.875rem 2rem'
}
if (size === 'XS') {
return '0.5rem 2rem'
}
}};
@media (max-width: ${({ theme }) => theme.breakpointsWidth.sm}) {
width: 100%;

View File

@ -81,6 +81,7 @@ export function getTitleProps(children: React.ReactNode, as: keyof ReactHTML) {
as = children.type as keyof ReactHTML
children = children.props.children ?? null
}
return { as, children }
}

View File

@ -24,6 +24,7 @@ export default function Checkbox(
const state = useToggleState(props)
const ref = useRef<HTMLInputElement | null>(null)
const { inputProps } = useCheckbox(props, state, ref)
return (
<CheckboxContainer>
<input type="checkbox" className="sr-only" ref={ref} {...inputProps} />

View File

@ -31,6 +31,7 @@ type NumberFieldProps = Omit<AriaNumberFieldProps, 'placeholder'> & {
placeholder?: number
onChange?: (n?: number) => void
}
export default function NumberField(props: NumberFieldProps) {
const { locale } = useLocale()
const step = !props.step
@ -82,6 +83,7 @@ export default function NumberField(props: NumberFieldProps) {
const length = ref.current.value.length * 2
ref.current.setSelectionRange(0, length * 2)
}, [])
return (
<StyledNumberFieldContainer>
<StyledInputContainer
@ -289,6 +291,7 @@ function useSimpleNumberFieldState(
if (!inputValue || defaultInputValue === inputValue) {
updateInputValue(undefined)
updateNumberValue(undefined)
return
}
@ -302,6 +305,7 @@ function useSimpleNumberFieldState(
const parsedValue = numberParser.parse(inputValue)
if (isNaN(parsedValue)) {
updateInputValue(numberValue)
return
}
updateNumberValue(parsedValue)
@ -313,6 +317,7 @@ function useSimpleNumberFieldState(
inputValue.match(/^[^\d]*0([0]+|[\d\s,.]+)[^\d]*$/)
) {
setInputValue(inputValue)
return
}

View File

@ -16,6 +16,7 @@ export function Radio(props: AriaRadioProps) {
}
const ref = useRef(null)
const { inputProps } = useRadio(props, state, ref)
return (
<label>
<InputRadio {...inputProps} className="sr-only" ref={ref} />

View File

@ -130,6 +130,7 @@ function Option({ item, state }: OptionProps) {
export function Label({ children }: { children: ReactNode }) {
const { labelProps } = useContext(OptionContext)
return <div {...labelProps}>{children}</div>
}
@ -140,5 +141,6 @@ const StyledDescription = styled.div`
export function Description({ children }: { children: ReactNode }) {
const { descriptionProps } = useContext(OptionContext)
return <StyledDescription {...descriptionProps}>{children}</StyledDescription>
}

View File

@ -74,6 +74,7 @@ const Value = styled.span`
const StyledIcon = styled(CarretDown)`
margin: 0 4px;
`
export const Wrapper = styled.div<{
hasError: boolean
hasLabel: boolean
@ -196,6 +197,7 @@ export function Select<T extends Record<string, unknown>>(
const { buttonProps } = useButton(triggerProps, ref)
const { focusProps, isFocusVisible } = useFocusRing()
return (
<Wrapper isOpen={state.isOpen} hasError={false} hasLabel={false}>
<HiddenSelect

View File

@ -50,6 +50,7 @@ type ContainerProps = {
darkMode?: boolean
backgroundColor?: (theme: DefaultTheme) => string
}
export default function Container({
backgroundColor,
darkMode = false,

View File

@ -14,6 +14,7 @@ type MessageProps = {
type?: MessageType
light?: boolean
}
export function Message({
type = 'primary',
icon = false,
@ -24,6 +25,7 @@ export function Message({
if (typeof children !== 'object') {
children = <Body>{children}</Body>
}
return (
<ThemeProvider theme={(theme) => ({ ...theme, darkMode: false })}>
<StyledMessage type={type} border={border} light={light}>
@ -78,6 +80,7 @@ const StyledMessage = styled.div<
type === 'secondary' || type === 'primary'
? theme.colors.bases[type]
: theme.colors.extended[type]
return css`
padding: ${theme.spacings.xs} ${theme.spacings.lg};
background-color: ${light ? 'rgba(255,255,255,0.75)' : colorSpace[100]};

View File

@ -9,6 +9,7 @@ const baseHeading = css`
? theme.colors.extended.grey[100]
: theme.colors.bases.primary[700]};
`
export const HeadingUnderline = css`
::after {
height: 1.25rem;
@ -86,10 +87,21 @@ export const H6 = styled.h6`
`
export const fromLevel = (level: number) => {
if (level === 1) return H1
if (level === 2) return H2
if (level === 3) return H3
if (level === 4) return H4
if (level === 5) return H5
if (level === 1) {
return H1
}
if (level === 2) {
return H2
}
if (level === 3) {
return H3
}
if (level === 4) {
return H4
}
if (level === 5) {
return H5
}
return H6
}

View File

@ -47,6 +47,7 @@ export const Link = React.forwardRef<
GenericButtonOrLinkProps & { children: React.ReactNode }
>(function Link(ariaButtonProps, forwardedRef) {
const buttonOrLinkProps = useButtonOrLink(ariaButtonProps, forwardedRef)
return <StyledLink {...buttonOrLinkProps} />
})
@ -137,6 +138,7 @@ export function useButtonOrLink(
as: elementType,
ref,
}
return buttonOrLinkProps
}

View File

@ -28,5 +28,6 @@ export function hexToHSL(hex: string): [number, number, number] {
}
h /= 6
}
return [h * 360, s * 100, l * 100].map(Math.round) as [number, number, number]
}

View File

@ -18,5 +18,6 @@ export function useDebounce<T>(value: T, delay: number) {
},
[value, delay] // Only re-call effect if value or delay changes
)
return debouncedValue
}

View File

@ -48,6 +48,7 @@ const translateProp =
}
let propTrans = translation[prop + '.' + lang]
propTrans = propTrans?.replace(/^\[automatic\] /, '')
return propTrans ? assoc(prop, propTrans, rule) : rule
}
@ -61,6 +62,7 @@ function translateRule<Names extends string>(
if (!ruleTrans) {
return rule
}
return attributesToTranslate.reduce(
translateProp(lang, ruleTrans),
rule ?? {}

View File

@ -42,6 +42,7 @@ export default function Budget() {
)
const { language } = useTranslation().i18n
return (
<>
<TrackPage chapter1="informations" name="budget" />
@ -96,6 +97,7 @@ export default function Budget() {
<td>{label}</td>
{quarters.map((q) => {
const value = budget[selectedYear]?.[q]?.[label]
return (
<td key={q}>
{value
@ -130,6 +132,7 @@ export default function Budget() {
const value = sum(
Object.values(budget[selectedYear]?.[q] ?? {})
)
return (
<td key={q}>
{value
@ -161,6 +164,7 @@ export default function Budget() {
const value = Math.round(
sum(Object.values(budget[selectedYear]?.[q] ?? {})) * 1.2
)
return (
<td key={q}>
{value

View File

@ -591,7 +591,9 @@ const StatutsExample = ({ statut }: StatutsExampleProps) => {
EURL: 'https://bpifrance-creation.fr/file/109070/download?token=Ul-rT6Z0',
}
if (!(statut in links)) return null
if (!(statut in links)) {
return null
}
return (
<Link href={links[statut as keyof typeof links]}>
@ -605,6 +607,7 @@ const StatutsExample = ({ statut }: StatutsExampleProps) => {
export const FAQAutoEntrepreneurArticle = () => {
const { t } = useTranslation()
return (
<Article
title={

View File

@ -8,6 +8,7 @@ import { TrackPage } from '../../../ATInternetTracking'
export default function Autoentrepreneur() {
const { t } = useTranslation()
return (
<>
<TrackPage name="auto-entrepreneur_ou_independant" />

View File

@ -7,6 +7,7 @@ import { TrackPage } from '../../../ATInternetTracking'
export default function DefineDirectorStatus() {
const { t } = useTranslation()
return (
<>
<TrackPage name="independant_ou_assimile-salarie" />

View File

@ -14,6 +14,7 @@ import { TrackPage } from '../../../ATInternetTracking'
export default function MinorityDirector() {
const { t } = useTranslation()
const dispatch = useDispatchAndGoToNextQuestion()
return (
<>
<TrackPage name="majoritaire_ou_minoritaire" />

View File

@ -13,6 +13,7 @@ import { TrackPage } from '../../../ATInternetTracking'
export default function NumberOfAssociates() {
const dispatch = useDispatchAndGoToNextQuestion()
const { t } = useTranslation()
return (
<>
<TrackPage name="seul_ou_plusieurs" />

View File

@ -21,6 +21,7 @@ type StatutButtonProps = {
const StatutButton = ({ statut }: StatutButtonProps) => {
const sitePaths = useContext(SitePathsContext)
const { t } = useTranslation()
return (
<Button to={sitePaths.créer[statut]} light size="XS">
<>
@ -90,6 +91,7 @@ const StatutTitle = ({ statut, language }: StatutTitleProps) =>
export default function SetMainStatus() {
const { t, i18n } = useTranslation()
const possibleStatus = useSelector(possibleStatusSelector)
return (
<>
<TrackPage chapter2="statut" name="liste" />

View File

@ -72,6 +72,7 @@ export default function PreviousAnswers() {
if (Object.values(legalStatus).length < 1) {
return null
}
return (
<PreviousAnswersList>
{Object.entries(legalStatus).map(

View File

@ -14,6 +14,7 @@ import { TrackPage } from '../../../ATInternetTracking'
export default function SoleProprietorship() {
const dispatch = useDispatchAndGoToNextQuestion()
const { t } = useTranslation()
return (
<>
<TrackPage name="societe_ou_entreprise_individuelle" />

View File

@ -51,6 +51,7 @@ export default function Créer() {
const sitePaths = useContext(SitePathsContext)
const location = useLocation()
useResetFollowingAnswers()
return (
<>
<Link to={sitePaths.créer.index}>

View File

@ -24,6 +24,7 @@ export default function Créer() {
(state: RootState) =>
!!Object.keys(state.choixStatutJuridique.companyLegalStatus).length
)
return (
<FromBottom>
<TrackPage name="accueil" />

View File

@ -1,5 +1,6 @@
import { Trans } from 'react-i18next'
import { LegalStatus } from '@/selectors/companyStatusSelectors'
type Props = {
statut: LegalStatus
}

View File

@ -12,6 +12,7 @@ import Home from './Home'
export default function CreateMyCompany() {
const sitePaths = useContext(SitePathsContext)
const location = useLocation()
return (
<>
<ScrollToTop key={location.pathname} />

View File

@ -2,6 +2,7 @@ import { Button } from '@/design-system/buttons'
import { H2 } from '@/design-system/typography/heading'
import { lazy, Suspense, useEffect, useMemo, useRef, useState } from 'react'
import useSimulatorsData from '../Simulateurs/metadata'
const LazyColorPicker = lazy(() => import('./ColorPicker'))
export default function IntegrationTest() {
@ -31,6 +32,7 @@ export default function IntegrationTest() {
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [version])
return (
<>
<H2>Quel module ?</H2>

View File

@ -5,6 +5,7 @@ import { generateSiteMap } from '../../sitePaths'
export default function SiteMap() {
const sitePaths = useContext(SitePathsContext)
return (
<>
<H1>Sitemap</H1>

View File

@ -90,6 +90,7 @@ function BackToSimulation() {
if (!url) {
return null
}
return (
<>
<Spacing lg />
@ -120,6 +121,7 @@ function DocumentationLanding() {
function DocumentationRulesList() {
const ruleEntries = Object.keys(rules) as DottedName[]
return (
<>
<H1>Liste des règles</H1>
@ -166,6 +168,7 @@ export function References({ references }: ReferencesProps) {
<StyledReferences>
{Object.entries(references).map(([name, link]) => {
const domain = cleanDomain(link)
return (
<li key={name}>
<span className="imageWrapper">

View File

@ -17,6 +17,7 @@ type SubSectionProp = {
dottedName: DottedName
hideTitle?: boolean
}
export function SubSection({
dottedName: sectionDottedName,
hideTitle = false,
@ -38,6 +39,7 @@ export function SubSection({
dottedName,
rawNode: { question },
} = engine.getRule(nextStep)
return !!question && dottedName.startsWith(sectionDottedName)
})
@ -56,6 +58,7 @@ type SimpleFieldProps = {
question?: RuleNode['rawNode']['question']
showSuggestions?: boolean
}
export function SimpleField({
dottedName,
question,
@ -77,6 +80,7 @@ export function SimpleField({
if (evaluation.nodeValue === null) {
return null
}
return (
<div>
<FromTop>

Some files were not shown because too many files have changed in this diff Show More