✨ Permet de passer un composant pour l'affichage des références
Notre logique d'affichage des référence était assez spécifique à mon-entreprise. D'autres sont possible comme l'affichage de “cartes” https://futur.eco/documentation/transport/avion/impact On passe maintenant par un “renderer” qui permet de personnalisé le composant affiché.pull/1817/head
parent
e54bc92874
commit
e2149ff4e6
|
@ -1,13 +1,13 @@
|
|||
import { explainVariable } from 'Actions/actions'
|
||||
import Overlay from 'Components/Overlay'
|
||||
import { EngineContext } from 'Components/utils/EngineContext'
|
||||
import { Markdown } from 'Components/utils/markdown'
|
||||
import { useContext } from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { RootState } from 'Reducers/rootReducer'
|
||||
import { References } from 'publicodes-react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { References } from '../../pages/Documentation'
|
||||
import './Aide.css'
|
||||
import { EngineContext } from 'Components/utils/EngineContext'
|
||||
|
||||
export default function Aide() {
|
||||
const explained = useSelector((state: RootState) => state.explainedVariable)
|
||||
|
@ -36,7 +36,7 @@ export default function Aide() {
|
|||
<h3>
|
||||
<Trans>En savoir plus</Trans>
|
||||
</h3>
|
||||
<References refs={refs} />
|
||||
<References references={refs} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,6 @@ import Emoji from 'Components/utils/Emoji'
|
|||
import { Markdown } from 'Components/utils/markdown'
|
||||
import { DottedName } from 'modele-social'
|
||||
import { EvaluatedNode, Rule, RuleNode, serializeEvaluation } from 'publicodes'
|
||||
import { References } from 'publicodes-react'
|
||||
import {
|
||||
createContext,
|
||||
useCallback,
|
||||
|
@ -13,6 +12,7 @@ import {
|
|||
useState,
|
||||
} from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { References } from '../../pages/Documentation'
|
||||
import { Explicable } from './Explicable'
|
||||
import { binaryQuestion, InputProps } from './RuleInput'
|
||||
|
||||
|
@ -211,7 +211,7 @@ export const RadioLabel = (props: RadioLabelProps) => (
|
|||
<h3>
|
||||
<Trans>En savoir plus</Trans>
|
||||
</h3>
|
||||
<References refs={props.références} />
|
||||
<References references={props.références} />
|
||||
</>
|
||||
)}
|
||||
</Explicable>
|
||||
|
|
|
@ -2,20 +2,27 @@ import SearchRules from 'Components/search/SearchRules'
|
|||
import { FromBottom } from 'Components/ui/animate'
|
||||
import { ThemeColorsProvider } from 'Components/utils/colors'
|
||||
import { useEngine } from 'Components/utils/EngineContext'
|
||||
import Meta from 'Components/utils/Meta'
|
||||
import { ScrollToTop } from 'Components/utils/Scroll'
|
||||
import { SitePathsContext } from 'Components/utils/SitePathsContext'
|
||||
import { RulePage, getDocumentationSiteMap } from 'publicodes-react'
|
||||
import rules, { DottedName } from 'modele-social'
|
||||
import { getDocumentationSiteMap, RulePage } from 'publicodes-react'
|
||||
import { useCallback, useContext, useMemo } from 'react'
|
||||
import { Helmet } from 'react-helmet-async'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { Redirect, useHistory, useLocation, Link } from 'react-router-dom'
|
||||
import {
|
||||
Link,
|
||||
Redirect,
|
||||
Route,
|
||||
useHistory,
|
||||
useLocation,
|
||||
} from 'react-router-dom'
|
||||
import { RootState } from 'Reducers/rootReducer'
|
||||
import styled from 'styled-components'
|
||||
import { TrackPage } from '../ATInternetTracking'
|
||||
import rules, { DottedName } from 'modele-social'
|
||||
import RuleLink from '../components/RuleLink'
|
||||
import Meta from 'Components/utils/Meta'
|
||||
import { Route } from 'react-router-dom'
|
||||
import { Helmet } from 'react-helmet-async'
|
||||
import { capitalise0 } from '../utils'
|
||||
|
||||
export default function MonEntrepriseRulePage() {
|
||||
const currentSimulation = useSelector(
|
||||
|
@ -70,10 +77,10 @@ export default function MonEntrepriseRulePage() {
|
|||
rulePath={match.params.name}
|
||||
engine={engine}
|
||||
documentationPath={documentationPath}
|
||||
referenceImages={referencesImages}
|
||||
renderers={{
|
||||
Head: Helmet,
|
||||
Link,
|
||||
References,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
@ -88,7 +95,7 @@ function BackToSimulation() {
|
|||
const history = useHistory()
|
||||
const handleClick = useCallback(() => {
|
||||
url && history.push(url)
|
||||
}, [])
|
||||
}, [history, url])
|
||||
return (
|
||||
<button
|
||||
className="ui__ simple small push-left button"
|
||||
|
@ -132,15 +139,86 @@ function DocumentationRulesList() {
|
|||
}
|
||||
|
||||
const referencesImages = {
|
||||
'service-public.fr': 'images/références/marianne.png',
|
||||
'urssaf.fr': 'images/références/Urssaf.svg',
|
||||
'secu-independants.fr': 'images/références/Urssaf.svg',
|
||||
'gouv.fr': 'images/références/marianne.png',
|
||||
'agirc-arrco.fr': 'images/références/agirc-arrco.png',
|
||||
'pole-emploi.fr': 'images/références/pole-emploi.png',
|
||||
'service-public.fr': '/images/références/marianne.png',
|
||||
'legifrance.gouv.fr': '/images/références/marianne.png',
|
||||
'urssaf.fr': '/images/références/Urssaf.svg',
|
||||
'secu-independants.fr': '/images/références/Urssaf.svg',
|
||||
'gouv.fr': '/images/références/marianne.png',
|
||||
'agirc-arrco.fr': '/images/références/agirc-arrco.png',
|
||||
'pole-emploi.fr': '/images/références/pole-emploi.png',
|
||||
'ladocumentationfrançaise.fr':
|
||||
'images/références/ladocumentationfrançaise.png',
|
||||
'senat.fr': 'images/références/senat.png',
|
||||
'ameli.fr': 'images/références/ameli.png',
|
||||
'bpifrance-creation': 'images/références/bpi-création.png',
|
||||
'/images/références/ladocumentationfrançaise.png',
|
||||
'senat.fr': '/images/références/senat.png',
|
||||
'ameli.fr': '/images/références/ameli.png',
|
||||
'bpifrance-creation.fr': '/images/références/bpi-création.png',
|
||||
}
|
||||
|
||||
type ReferencesProps = React.ComponentProps<
|
||||
NonNullable<React.ComponentProps<typeof RulePage>['renderers']['References']>
|
||||
>
|
||||
|
||||
export function References({ references }: ReferencesProps) {
|
||||
const cleanDomain = (link: string) =>
|
||||
(link.includes('://') ? link.split('/')[2] : link.split('/')[0]).replace(
|
||||
'www.',
|
||||
''
|
||||
)
|
||||
|
||||
return (
|
||||
<StyledReferences>
|
||||
{Object.entries(references).map(([name, link]) => {
|
||||
const domain = cleanDomain(link)
|
||||
return (
|
||||
<li key={name}>
|
||||
<span className="imageWrapper">
|
||||
{Object.keys(referencesImages).includes(domain) && (
|
||||
<img
|
||||
src={
|
||||
referencesImages[domain as keyof typeof referencesImages]
|
||||
}
|
||||
alt={`logo de ${domain}`}
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
<a href={link} target="_blank">
|
||||
{capitalise0(name)}
|
||||
</a>
|
||||
<span className="ui__ label">{domain}</span>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</StyledReferences>
|
||||
)
|
||||
}
|
||||
|
||||
const StyledReferences = styled.ul`
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
a {
|
||||
flex: 1;
|
||||
min-width: 45%;
|
||||
text-decoration: underline;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 0.6em;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.imageWrapper {
|
||||
width: 4.5rem;
|
||||
height: 3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
img {
|
||||
max-height: 3rem;
|
||||
vertical-align: sub;
|
||||
max-width: 100%;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
`
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import Engine from 'publicodes'
|
||||
import React, { createContext } from 'react'
|
||||
import References from './rule/References'
|
||||
|
||||
export type SupportedRenderers = {
|
||||
Head?: React.ComponentType
|
||||
Link: React.ComponentType<{ to: string }>
|
||||
Head?: React.ComponentType
|
||||
References?: typeof References
|
||||
}
|
||||
|
||||
export const BasepathContext = createContext<string>('/documentation')
|
||||
export const EngineContext = createContext<Engine<string> | null>(null)
|
||||
export const ReferencesImagesContext = createContext<Record<string, string>>({})
|
||||
export const RenderersContext = createContext<Partial<SupportedRenderers>>({})
|
||||
export const RenderersContext = createContext<Partial<SupportedRenderers>>({
|
||||
References,
|
||||
})
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import { utils } from 'publicodes'
|
||||
import References from './rule/References'
|
||||
export { default as Explanation } from './Explanation'
|
||||
export { default as RulePage } from './rule/RulePage'
|
||||
export { RuleLink } from './RuleLink'
|
||||
export { References }
|
||||
|
||||
export function getDocumentationSiteMap({ engine, documentationPath }) {
|
||||
const parsedRules = engine.getParsedRules()
|
||||
|
|
|
@ -1,97 +1,32 @@
|
|||
import { toPairs } from 'ramda'
|
||||
import { capitalise0 } from 'publicodes'
|
||||
import styled from 'styled-components'
|
||||
import { useContext } from 'react'
|
||||
import { ReferencesImagesContext } from '../contexts'
|
||||
|
||||
const cleanDomain = (link: string) =>
|
||||
(link.includes('://') ? link.split('/')[2] : link.split('/')[0]).replace(
|
||||
'www.',
|
||||
''
|
||||
)
|
||||
|
||||
type RefProps = {
|
||||
name: string
|
||||
link: string
|
||||
}
|
||||
|
||||
// TODO: currently we only allow customizing the list of "references icons", but
|
||||
// this migth be limited for more advanced usages. For instance futur.eco uses a
|
||||
// different renderer for references:
|
||||
// https://futur.eco/documentation/transport/avion/impact We will probably want
|
||||
// to allow the user to provide its own components that can be inserted at
|
||||
// certains positions in the generated documentation ("hooks").
|
||||
function Ref({ name, link }: RefProps) {
|
||||
const references = useContext(ReferencesImagesContext)
|
||||
const refKey = Object.keys(references).find((r) => link.includes(r))
|
||||
const domain = cleanDomain(link)
|
||||
return (
|
||||
<li
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
key={name}
|
||||
>
|
||||
<span className="imageWrapper">
|
||||
{refKey && <img src={references[refKey]} />}
|
||||
</span>
|
||||
<a
|
||||
href={link}
|
||||
target="_blank"
|
||||
style={{
|
||||
marginRight: '1rem',
|
||||
}}
|
||||
>
|
||||
{capitalise0(name)}
|
||||
</a>
|
||||
<span className="ui__ label">{domain}</span>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
||||
type ReferencesProps = {
|
||||
refs: { [name: string]: string }
|
||||
references: Record<string, string>
|
||||
}
|
||||
|
||||
export default function References({ refs }: ReferencesProps) {
|
||||
const references = toPairs(refs)
|
||||
export default function References({ references }: ReferencesProps) {
|
||||
return (
|
||||
<StyledComponent>
|
||||
{references.map(([name, link]) => (
|
||||
<Ref key={link} name={name} link={link} />
|
||||
<ul>
|
||||
{Object.entries(references).map(([name, link]) => (
|
||||
<li
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
key={name}
|
||||
>
|
||||
<a
|
||||
href={link}
|
||||
target="_blank"
|
||||
style={{
|
||||
marginRight: '1rem',
|
||||
}}
|
||||
>
|
||||
{capitalise0(name)}
|
||||
</a>
|
||||
<span className="ui__ label">{link}</span>
|
||||
</li>
|
||||
))}
|
||||
</StyledComponent>
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
const StyledComponent = styled.ul`
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
a {
|
||||
flex: 1;
|
||||
min-width: 45%;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 0.6em;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.imageWrapper {
|
||||
width: 4.5rem;
|
||||
height: 3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
img {
|
||||
max-height: 3rem;
|
||||
vertical-align: sub;
|
||||
max-width: 100%;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
`
|
||||
|
|
|
@ -10,7 +10,6 @@ import { useContext } from 'react'
|
|||
import {
|
||||
BasepathContext,
|
||||
EngineContext,
|
||||
ReferencesImagesContext,
|
||||
RenderersContext,
|
||||
SupportedRenderers,
|
||||
} from '../contexts'
|
||||
|
@ -18,7 +17,6 @@ import Explanation from '../Explanation'
|
|||
import { Markdown } from '../Markdown'
|
||||
import { RuleLinkWithContext } from '../RuleLink'
|
||||
import RuleHeader from './Header'
|
||||
import References from './References'
|
||||
import RuleSource from './RuleSource'
|
||||
|
||||
type RulePageProps = {
|
||||
|
@ -26,7 +24,6 @@ type RulePageProps = {
|
|||
rulePath: string
|
||||
engine: Engine
|
||||
language: 'fr' | 'en'
|
||||
referenceImages?: Record<string, string>
|
||||
renderers: SupportedRenderers
|
||||
}
|
||||
|
||||
|
@ -36,7 +33,6 @@ export default function RulePage({
|
|||
engine,
|
||||
renderers,
|
||||
language,
|
||||
referenceImages = {},
|
||||
}: RulePageProps) {
|
||||
const currentEngineId = new URLSearchParams(window.location.search).get(
|
||||
'currentEngineId'
|
||||
|
@ -46,15 +42,13 @@ export default function RulePage({
|
|||
<EngineContext.Provider value={engine}>
|
||||
<BasepathContext.Provider value={documentationPath}>
|
||||
<RenderersContext.Provider value={renderers}>
|
||||
<ReferencesImagesContext.Provider value={referenceImages}>
|
||||
<Rule
|
||||
dottedName={decodeRuleName(rulePath)}
|
||||
subEngineId={
|
||||
currentEngineId ? parseInt(currentEngineId) : undefined
|
||||
}
|
||||
language={language}
|
||||
/>
|
||||
</ReferencesImagesContext.Provider>
|
||||
<Rule
|
||||
dottedName={decodeRuleName(rulePath)}
|
||||
subEngineId={
|
||||
currentEngineId ? parseInt(currentEngineId) : undefined
|
||||
}
|
||||
language={language}
|
||||
/>
|
||||
</RenderersContext.Provider>
|
||||
</BasepathContext.Provider>
|
||||
</EngineContext.Provider>
|
||||
|
@ -69,6 +63,7 @@ type RuleProps = {
|
|||
|
||||
export function Rule({ dottedName, language, subEngineId }: RuleProps) {
|
||||
const baseEngine = useContext(EngineContext)
|
||||
const { References } = useContext(RenderersContext)
|
||||
if (!baseEngine) {
|
||||
throw new Error('Engine expected')
|
||||
}
|
||||
|
@ -192,10 +187,10 @@ export function Rule({ dottedName, language, subEngineId }: RuleProps) {
|
|||
</div>
|
||||
</>
|
||||
)}
|
||||
{rule.rawNode.références && (
|
||||
{rule.rawNode.références && References && (
|
||||
<>
|
||||
<h2>Références</h2>
|
||||
<References refs={rule.rawNode.références} />
|
||||
<h3>Références</h3>
|
||||
<References references={rule.rawNode.références} />
|
||||
</>
|
||||
)}
|
||||
{/* <Examples
|
||||
|
|
Loading…
Reference in New Issue