diff --git a/src/components/ComponentsRenderer/ComponentsRenderer.tsx b/src/components/ComponentsRenderer/ComponentsRenderer.tsx index ea545410..c9a2d3cc 100644 --- a/src/components/ComponentsRenderer/ComponentsRenderer.tsx +++ b/src/components/ComponentsRenderer/ComponentsRenderer.tsx @@ -2,14 +2,22 @@ import * as lunatic from '@inseefr/lunatic'; import { OrchestratedElement } from '../../typeStromae/type'; import { LunaticComponentContainer } from '../formulaire/LunaticComponentContainer'; import { LunaticComponents } from '@inseefr/lunatic'; -import type { ReactNode } from 'react'; +import { type ReactNode } from 'react'; type Props = { only?: string[]; except?: string[]; // Key that trigger a new autofocus on the first field focusKey?: string; -} & Pick; +} & Pick< + OrchestratedElement, + | 'currentErrors' + | 'disabled' + | 'getComponents' + | 'goToPage' + | 'goPreviousPage' + | 'goNextPage' +>; export function ComponentsRenderer(props: Props) { const { @@ -27,18 +35,20 @@ export function ComponentsRenderer(props: Props) { ) ?? []; return ( - ({ - ...rest, - errors: currentErrors, - disabled, - })} - wrapper={({ children, id }: { children: ReactNode; id: string }) => ( - - )} - /> + <> + ({ + ...rest, + errors: currentErrors, + disabled, + })} + wrapper={({ children, id }: { children: ReactNode; id: string }) => ( + + )} + /> + ); } diff --git a/src/components/ConfirmationModal/ConfirmationModal.tsx b/src/components/ConfirmationModal/ConfirmationModal.tsx new file mode 100644 index 00000000..e663ed5d --- /dev/null +++ b/src/components/ConfirmationModal/ConfirmationModal.tsx @@ -0,0 +1,76 @@ +import { ReactNode, useCallback, useContext, useState } from 'react'; +import { makeStyles } from '@codegouvfr/react-dsfr/tss'; +import { GoToPage } from '../../typeLunatic/type-source'; +import { + ModalDsfr, + ModalDsfrContent, + ModalDsfrFooter, +} from '../ContinueOrRestart/ModalDsfr'; +import { fr } from '@codegouvfr/react-dsfr'; +import { useLunaticContext } from '../orchestrator/UseLunatic'; + +const useStyles = makeStyles()({ + root: { + '+ .lunatic-component-with-dsfr': { + marginBottom: '2rem', + }, + }, +}); + +type ConfirmationType = { + goToPage?: GoToPage; + description: ReactNode; + label: ReactNode; +}; + +export function ConfirmationModal(props: ConfirmationType) { + const { classes, cx } = useStyles(); + + const [display, setDisplay] = useState(true); + const { goToPage, goNextPage } = useContext(useLunaticContext); + const onClose = useCallback(() => { + setDisplay(false); + goToPage?.({ page: '17' }); + }, [goToPage]); + + const confirm = useCallback(() => { + goNextPage?.(); + }, [goNextPage]); + + if (!display) { + return null; + } + return ( +
+ + +

{props.label}

+ {props.description} +
+ +
    +
  • + +
  • +
  • + +
  • +
+
+
+
+ ); +} diff --git a/src/components/ContinueOrRestart/ModalContinueOrRestart.tsx b/src/components/ContinueOrRestart/ModalContinueOrRestart.tsx index 4fa258a6..80d3a9a0 100644 --- a/src/components/ContinueOrRestart/ModalContinueOrRestart.tsx +++ b/src/components/ContinueOrRestart/ModalContinueOrRestart.tsx @@ -1,5 +1,5 @@ import { useRef } from 'react'; -import { ModalDsfr } from './ModalDsfr'; +import { ModalDsfr, ModalDsfrContent, ModalDsfrFooter } from './ModalDsfr'; import { fr } from '@codegouvfr/react-dsfr/fr'; export function ModalContinueOrRestart(props: { @@ -15,30 +15,36 @@ export function ModalContinueOrRestart(props: { close={props.onClose} last={last.current as HTMLElement} > -

Bienvenue

-

- Vous avez déjà commencé à renseigner le questionnaire. Souhaitez-vous - reprendre là où vous en étiez ou revenir à la première page ? -

-
    -
  • - -
  • -
  • - -
  • -
+ +

+ Bienvenue +

+

+ Vous avez déjà commencé à renseigner le questionnaire. Souhaitez-vous + reprendre là où vous en étiez ou revenir à la première page ? +

+
+ +
    +
  • + +
  • +
  • + +
  • +
+
); } diff --git a/src/components/ContinueOrRestart/ModalDsfr.tsx b/src/components/ContinueOrRestart/ModalDsfr.tsx index 40877637..7e23128e 100644 --- a/src/components/ContinueOrRestart/ModalDsfr.tsx +++ b/src/components/ContinueOrRestart/ModalDsfr.tsx @@ -8,6 +8,14 @@ type ModalDsfrProps = { last?: HTMLElement; }; +export function ModalDsfrContent(props: PropsWithChildren) { + return
{props.children}
; +} + +export function ModalDsfrFooter(props: PropsWithChildren) { + return
{props.children}
; +} + export function ModalDsfr(props: PropsWithChildren) { const first = useRef(null); const { children, id, close, last } = props; @@ -26,7 +34,13 @@ export function ModalDsfr(props: PropsWithChildren) { ); return ( - diff --git a/src/components/formulaire/Formulaire.tsx b/src/components/formulaire/Formulaire.tsx index 7150dbbc..d707fe29 100644 --- a/src/components/formulaire/Formulaire.tsx +++ b/src/components/formulaire/Formulaire.tsx @@ -11,6 +11,8 @@ type Props = Pick< | 'waiting' | 'pageTag' | 'isLastPage' + | 'goNextPage' + | 'goToPage' >; const useStyles = makeStyles()({ @@ -87,6 +89,8 @@ const useStyles = makeStyles()({ export function Formulaire(props: Props) { const { getComponents, + goToPage, + goNextPage, currentErrors, disabled = false, waiting, @@ -102,9 +106,11 @@ export function Formulaire(props: Props) { ); diff --git a/src/components/modals/Modals.tsx b/src/components/modals/Modals.tsx deleted file mode 100644 index d9d13db0..00000000 --- a/src/components/modals/Modals.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import {OrchestratedElement} from '../../typeStromae/type'; -import {ComponentsRenderer} from '../ComponentsRenderer'; -import { makeStyles } from "@codegouvfr/react-dsfr/tss"; - -type Props = Pick - -const useStyles = makeStyles()({ - root: { - "+ .lunatic-component-with-dsfr": { - "marginBottom": "2rem" - } - } -}); - -export function Modals(props: Props) { - const { getComponents, currentErrors, disabled = false, ...rest } = props; - const { classes, cx } = useStyles(); - - return ( -
- -
- ); -} diff --git a/src/components/modals/index.ts b/src/components/modals/index.ts deleted file mode 100644 index 411803d6..00000000 --- a/src/components/modals/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Modals } from './Modals'; \ No newline at end of file diff --git a/src/components/orchestrator/UseLunatic.tsx b/src/components/orchestrator/UseLunatic.tsx index 78addfc7..92e5da09 100644 --- a/src/components/orchestrator/UseLunatic.tsx +++ b/src/components/orchestrator/UseLunatic.tsx @@ -1,6 +1,7 @@ import { useLunatic } from '@inseefr/lunatic'; import * as custom from '@inseefr/lunatic-dsfr'; import { + createContext, PropsWithChildren, useCallback, useEffect, @@ -20,6 +21,17 @@ import { OrchestratorProps } from './Orchestrator'; import { useQuestionnaireTitle } from './useQuestionnaireTitle'; import { useRedirectIfAlreadyValidated } from './useRedirectIfAlreadyValidated'; import { useSaving } from './useSaving'; +import { ConfirmationModal as Modal } from '../ConfirmationModal/ConfirmationModal'; + +const CUSTOM = { ...custom, Modal }; + +// +export type UseLunaticContext = ReturnType; +const useLunaticContextInitial: UseLunaticContext = { + goToPage: () => null, + goNextPage: () => null, +}; +export const useLunaticContext = createContext(useLunaticContextInitial); export function createPersonalizationMap( personalization: Array @@ -77,7 +89,7 @@ export function UseLunatic(props: PropsWithChildren) { useEffect(() => { setArgs({ getReferentiel, - custom, + custom: CUSTOM, preferences, features, savingType, @@ -152,28 +164,30 @@ export function UseLunatic(props: PropsWithChildren) { } return ( - - compileControls={compileControls} - getComponents={getComponents} - goPreviousPage={handleGoBack} - goNextPage={handleGoNext} - isFirstPage={isFirstPage} - isLastPage={isLastPage} - goToPage={goToPage} - getData={getData} - pageTag={pageTag} - disabled={disabled} - pageFromAPI={pageFromAPI} - personalization={personalizationMap} - initialCollectStatus={initialCollectStatus} - refreshControls={refreshControls} - setRefreshControls={setRefreshControls} - waiting={waiting} - savingFailure={failure} - currentChange={currentChange} - > - {children} - + + + compileControls={compileControls} + getComponents={getComponents} + goPreviousPage={handleGoBack} + goNextPage={handleGoNext} + isFirstPage={isFirstPage} + isLastPage={isLastPage} + goToPage={goToPage} + getData={getData} + pageTag={pageTag} + disabled={disabled} + pageFromAPI={pageFromAPI} + personalization={personalizationMap} + initialCollectStatus={initialCollectStatus} + refreshControls={refreshControls} + setRefreshControls={setRefreshControls} + waiting={waiting} + savingFailure={failure} + currentChange={currentChange} + > + {children} + + ); } diff --git a/src/pages/questionnaire/Questionnaire.tsx b/src/pages/questionnaire/Questionnaire.tsx index 68fd78ac..64f8b72b 100644 --- a/src/pages/questionnaire/Questionnaire.tsx +++ b/src/pages/questionnaire/Questionnaire.tsx @@ -9,7 +9,6 @@ import { Grid } from '../../components/Grid/Grid'; import { Formulaire } from '../../components/formulaire'; import { Layout } from '../../components/layout'; import { LoadFromApi } from '../../components/loadSourceData/LoadFromApi'; -import { Modals } from '../../components/modals'; import { Continuer } from '../../components/navigation/Continuer'; import { Precedent } from '../../components/navigation/Precedent'; import { Orchestrator } from '../../components/orchestrator'; @@ -42,7 +41,6 @@ export function Questionnaire(props: QuestionnaireProps) { - diff --git a/src/pages/questionnaireReadOnly/QuestionnaireReadOnly.tsx b/src/pages/questionnaireReadOnly/QuestionnaireReadOnly.tsx index f787f813..98aa59af 100644 --- a/src/pages/questionnaireReadOnly/QuestionnaireReadOnly.tsx +++ b/src/pages/questionnaireReadOnly/QuestionnaireReadOnly.tsx @@ -4,7 +4,6 @@ import { Grid } from '../../components/Grid/Grid'; import { Formulaire } from '../../components/formulaire'; import { Layout } from '../../components/layout'; import { LoadFromApi } from '../../components/loadSourceData/LoadFromApi'; -import { Modals } from '../../components/modals'; import { Continuer } from '../../components/navigation/Continuer'; import { Precedent } from '../../components/navigation/Precedent'; import { OrchestratorReadOnly } from '../../components/orchestrator'; @@ -30,7 +29,6 @@ export function QuestionnaireReadOnly() { - diff --git a/src/pages/visualize/VisualizeResources.tsx b/src/pages/visualize/VisualizeResources.tsx index 75a644fa..217f7dc1 100644 --- a/src/pages/visualize/VisualizeResources.tsx +++ b/src/pages/visualize/VisualizeResources.tsx @@ -7,7 +7,6 @@ import { Grid } from '../../components/Grid/Grid'; import { Formulaire } from '../../components/formulaire'; import { Layout } from '../../components/layout/Layout'; import { LoadFromUrl } from '../../components/loadSourceData/LoadFromUrl'; -import { Modals } from '../../components/modals'; import { Continuer } from '../../components/navigation/Continuer'; import { Precedent } from '../../components/navigation/Precedent'; import { @@ -43,7 +42,6 @@ export function VisualizeResources(props: VisualizeResourcesProps) { - diff --git a/src/typeLunatic/type-source.ts b/src/typeLunatic/type-source.ts index 974cf2ce..a59bdc82 100644 --- a/src/typeLunatic/type-source.ts +++ b/src/typeLunatic/type-source.ts @@ -84,6 +84,13 @@ export type Hierarchy = { subSequence: SequenceDescription; }; +export type GoToPage = (page: { page: string; iteration?: number }) => void; + +// type GetComponentProps = () => { +// errors: Record | undefined; +// disabled: boolean; +// }; + export type ComponentTypeBase = { label: LabelType; declarations?: DeclarationType[]; @@ -97,6 +104,7 @@ export type ComponentTypeBase = { mandatory?: boolean; page: string; title?: string; + executeExpression: (expression: string) => ReactNode; }; export type ComponentType = | (ComponentTypeBase & ComponentSequenceType)