Ajout du bouton de partage

pull/2092/head
Jérémy Rialland 2022-04-06 11:03:36 +02:00 committed by Johan Girod
parent 3eaf981dfb
commit 5e1c1a2aa3
4 changed files with 90 additions and 71 deletions

View File

@ -1,29 +1,31 @@
import { Grid } from '@mui/material'
import Emoji from '@/components/utils/Emoji'
import { PopoverWithTrigger } from '@/design-system'
import { Button } from '@/design-system/buttons'
import { Spacing } from '@/design-system/layout'
import { PopoverWithTrigger } from '@/design-system'
import { CurrentSimulatorDataContext } from '../../pages/Simulateurs/metadata'
import { useContext } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
import { RootState } from '@/reducers/rootReducer'
import {
companySituationSelector,
situationSelector,
} from '@/selectors/simulationSelectors'
import { Grid } from '@mui/material'
import { useContext } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
import styled from 'styled-components'
import { TrackingContext } from '../../ATInternetTracking'
import { CurrentSimulatorDataContext } from '../../pages/Simulateurs/metadata'
import { PlacesDesEntreprisesButton } from '../PlaceDesEntreprises'
import { useParamsFromSituation } from '../utils/useSearchParamsSimulationSharing'
import { ShareSimulationPopup } from './ShareSimulationPopup'
import { PlacesDesEntreprisesButton } from '../PlaceDesEntreprises'
export function useUrl() {
const language = useTranslation().i18n.language
const situation = {
...useSelector(situationSelector),
...useSelector(companySituationSelector),
...useSelector((state: RootState) => state.DRISituation),
}
delete situation['entreprise . SIREN']
const searchParams = useParamsFromSituation(situation)
const currentSimulatorData = useContext(CurrentSimulatorDataContext)
@ -42,7 +44,15 @@ const ButtonLabel = styled.span`
margin-left: 1rem;
`
export default function ShareOrSaveSimulationBanner() {
export default function ShareOrSaveSimulationBanner({
share,
print,
placeDesEntreprises,
}: {
share?: boolean
print?: boolean
placeDesEntreprises?: boolean
}) {
const { t } = useTranslation()
const tracker = useContext(TrackingContext)
const shareAPIAvailable = !!window?.navigator?.share
@ -69,42 +79,45 @@ export default function ShareOrSaveSimulationBanner() {
spacing={4}
justifyContent="center"
>
<Grid item xs={12} sm="auto">
<PopoverWithTrigger
title={t('shareSimulation.modal.title', 'Votre lien de partage')}
trigger={(buttonProps) => (
<Button
{...buttonProps}
light
size="XS"
onPress={(e) => {
tracker.events.send('click.action', {
click_chapter1: 'feature:partage',
click: 'démarré',
})
startSharing().catch(
// eslint-disable-next-line no-console
(err) => console.error(err)
)
{share && (
<Grid item xs={12} sm="auto">
<PopoverWithTrigger
title={t('shareSimulation.modal.title', 'Votre lien de partage')}
trigger={(buttonProps) => (
<Button
{...buttonProps}
light
size="XS"
onPress={(e) => {
tracker.events.send('click.action', {
click_chapter1: 'feature:partage',
click: 'démarré',
})
tracker.dispatch()
startSharing().catch(
// eslint-disable-next-line no-console
(err) => console.error(err)
)
buttonProps?.onPress?.(e)
}}
>
<Emoji emoji="🔗" />
<ButtonLabel>
<Trans i18nKey="shareSimulation.banner">
Générer un lien de partage
</Trans>
</ButtonLabel>
</Button>
)}
small
>
<ShareSimulationPopup url={url} />
</PopoverWithTrigger>
</Grid>
buttonProps?.onPress?.(e)
}}
>
<Emoji emoji="🔗" />
<ButtonLabel>
<Trans i18nKey="shareSimulation.banner">
Générer un lien de partage
</Trans>
</ButtonLabel>
</Button>
)}
small
>
<ShareSimulationPopup url={url} />
</PopoverWithTrigger>
</Grid>
)}
{typeof window.print === 'function' && (
{print && typeof window.print === 'function' && (
<Grid item xs={12} sm="auto">
<Button light size="XS" onPress={() => window.print()}>
<Emoji emoji="🖨" />
@ -117,9 +130,11 @@ export default function ShareOrSaveSimulationBanner() {
</Grid>
)}
<Grid item xs={12} sm="auto">
<PlacesDesEntreprisesButton pathname="/aide-entreprise/rh-mon-entreprise-urssaf-fr/theme/recrutement-formation#section-breadcrumbs" />
</Grid>
{placeDesEntreprises && (
<Grid item xs={12} sm="auto">
<PlacesDesEntreprisesButton pathname="/aide-entreprise/rh-mon-entreprise-urssaf-fr/theme/recrutement-formation#section-breadcrumbs" />
</Grid>
)}
</Grid>
</>
)

View File

@ -97,7 +97,7 @@ export default function Simulation({
)}
{firstStepCompleted && !hideDetails && (
<>
<ShareOrSaveSimulationBanner />
<ShareOrSaveSimulationBanner share print placeDesEntreprises />
<Spacing lg />
</>
)}

View File

@ -7,11 +7,7 @@ import { useEngine } from '@/components/utils/EngineContext'
import { configSelector } from '@/selectors/simulationSelectors'
import Engine, { ParsedRules, serializeEvaluation } from 'publicodes'
import { DottedName } from 'modele-social'
import {
updateSituation,
setActiveTarget,
batchUpdateSituation,
} from '@/actions/actions'
import { setActiveTarget, batchUpdateSituation } from '@/actions/actions'
import { isEmpty } from 'ramda'
type Objectifs = (string | { objectifs: string[] })[]
@ -139,15 +135,17 @@ export function getSearchParamsFromSituation(
): URLSearchParams {
const searchParams = new URLSearchParams()
const dottedNameParamNameMapping = Object.fromEntries(dottedNameParamName)
;(Object.entries(situation) as [DottedName, any][]).forEach(
([dottedName, value]) => {
const paramName = dottedNameParamNameMapping[dottedName]
const serializedValue = serializeEvaluation(engine.evaluate(value))
if (typeof serializedValue !== 'undefined') {
searchParams.set(paramName, serializedValue)
}
Object.entries(situation).forEach(([dottedName, value]) => {
const paramName = dottedNameParamNameMapping[dottedName]
const serializedValue = serializeEvaluation(engine.evaluate(value))
if (typeof serializedValue !== 'undefined') {
searchParams.set(paramName, serializedValue)
} else if (typeof value === 'object') {
searchParams.set(paramName, JSON.stringify(value))
}
)
})
searchParams.sort()
return searchParams
@ -157,7 +155,8 @@ export function getSituationFromSearchParams(
searchParams: URLSearchParams,
dottedNameParamName: [DottedName, ParamName][]
) {
const situation: { [key in DottedName]?: string } = {}
const situation: { [key in DottedName]?: string | Record<string, unknown> } =
{}
const paramNameDottedName = dottedNameParamName.reduce(
(dottedNameBySearchParamName, [dottedName, paramName]) => ({
@ -170,6 +169,17 @@ export function getSituationFromSearchParams(
searchParams.forEach((value, paramName) => {
if (Object.prototype.hasOwnProperty.call(paramNameDottedName, paramName)) {
situation[paramNameDottedName[paramName]] = value
if (value.startsWith('{') && value.endsWith('}')) {
try {
const parsed = JSON.parse(value) as Record<string, unknown>
situation[paramNameDottedName[paramName]] = parsed
} catch (error) {
// eslint-disable-next-line no-console
console.error(error)
}
}
}
})

View File

@ -1,12 +1,12 @@
import { DottedName } from '@/../../modele-social'
import Value, { Condition } from '@/components/EngineValue'
import ShareOrSaveSimulationBanner from '@/components/ShareSimulationBanner'
import { FromTop } from '@/components/ui/animate'
import { useEngine } from '@/components/utils/EngineContext'
import { Markdown } from '@/components/utils/markdown'
import { SitePathsContext } from '@/components/utils/SitePathsContext'
import { Message } from '@/design-system'
import Accordion from '@/design-system/accordion'
import AnswerGroup from '@/design-system/answer-group'
import { Button } from '@/design-system/buttons'
import { Container, Spacing } from '@/design-system/layout'
import { Strong } from '@/design-system/typography'
@ -312,6 +312,7 @@ function ResultSection() {
spacing={3}
alignItems="stretch"
flexWrap={'wrap-reverse'}
justifyContent="center"
>
<Grid item lg={8} xl={7}>
<Message border={false}>
@ -354,16 +355,9 @@ function ResultSection() {
)
)}
</Grid>
<Spacing lg />
<AnswerGroup justifyContent={'center'}>
<Button size="XS" light isDisabled>
Imprimer ou sauvegarder en PDF
</Button>
<Button size="XS" light isDisabled>
Obtenir un lien de partage
</Button>
</AnswerGroup>
<ShareOrSaveSimulationBanner share print />
<Spacing xl />
<Grid