Skip to content

Commit

Permalink
add controls
Browse files Browse the repository at this point in the history
  • Loading branch information
ddecrulle committed Mar 14, 2024
1 parent 2170f70 commit 9bbc115
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/components/Orchestrator/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import ButtonsGroup from '@codegouvfr/react-dsfr/ButtonsGroup'
import { Grid } from 'components/Grid'
import { useMemo, type PropsWithChildren } from 'react'
import { useStyles } from 'tss-react'
import type { PageType } from './type'
import type { PageType } from './utils/type'

export function Navigation(
props: PropsWithChildren<{
Expand Down
40 changes: 39 additions & 1 deletion src/components/Orchestrator/Orchestrator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
useLunatic,
LunaticComponents,
type LunaticSource,
type LunaticError,
} from '@inseefr/lunatic'
import { slotComponents } from '@inseefr/lunatic-dsfr'
import { fr } from '@codegouvfr/react-dsfr'
Expand All @@ -17,6 +18,7 @@ import { ValidationModal } from './CustomPages/ValidationModal'
import { assert } from 'tsafe/assert'
import type { SurveyUnitData } from 'model/SurveyUnitData'
import type { StateData } from 'model/StateData'
import { isBlockingError, isSameErrors } from './utils/controls'

export function Orchestrator(props: {
source: LunaticSource
Expand All @@ -31,6 +33,7 @@ export function Orchestrator(props: {
const {
getComponents,
Provider,
compileControls,
goPreviousPage: goPrevLunatic,
goNextPage: goNextLunatic,
getData,
Expand All @@ -44,12 +47,43 @@ export function Orchestrator(props: {
autoSuggesterLoading: true,
})

const [activeErrors, setActiveErrors] = useState<
Record<string, LunaticError[]> | undefined
>(undefined)

const [validationModalActions] = useState<{
open?: () => Promise<void>
}>({})

const goNextHandlingControls = () => {
const { currentErrors } = compileControls()

//No errors, we goNext
if (!currentErrors) {
setActiveErrors(undefined)
goNextLunatic()
return
}

//An error is blocking, we stay on the page
if (isBlockingError(currentErrors)) {
//compileControls returns isCritical but I prefer define my own rules of blocking error in the orchestrator
setActiveErrors(currentErrors)
return
}

// activeErrors and currentErrors are the same and no blocking error, we go next
if (isSameErrors(currentErrors, activeErrors)) {
setActiveErrors(undefined)
goNextLunatic()
return
}

setActiveErrors(currentErrors)
}

const { currentPage, goNext, goToPage, goPrevious } = useStromaeNavigation({
goNextLunatic,
goNextLunatic: goNextHandlingControls,
goPrevLunatic,
isFirstPage,
isLastPage,
Expand Down Expand Up @@ -114,8 +148,12 @@ export function Orchestrator(props: {
)}
{currentPage === 'lunaticPage' && (
<LunaticComponents
autoFocusKey={pageTag}
components={getComponents()}
slots={slotComponents}
componentProps={() => ({
errors: activeErrors,
})}
/>
)}
{currentPage === 'validationPage' && <Validation />}
Expand Down
6 changes: 3 additions & 3 deletions src/components/Orchestrator/useStromaeNavigation.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useState } from 'react'
import type { PageType } from './type'
import type { PageType } from './utils/type'
import { assert, type Equals } from 'tsafe/assert'
import type { useLunatic } from '@inseefr/lunatic'

Expand All @@ -9,8 +9,8 @@ type Params = {
isLastPage: boolean
initialCurrentPage: string | undefined
//initialCurrentPage: PageType
goNextLunatic: () => void
goPrevLunatic: () => void
goNextLunatic: ReturnType<typeof useLunatic>['goNextPage']
goPrevLunatic: ReturnType<typeof useLunatic>['goPreviousPage']
openValidationModal: () => Promise<void>
goToLunaticPage: LunaticGoToPage
}
Expand Down
34 changes: 34 additions & 0 deletions src/components/Orchestrator/utils/controls.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { LunaticError } from '@inseefr/lunatic'
import { areArraysEqual } from 'utils/compareArray'

export function isBlockingError(errors: Record<string, LunaticError[]>) {
return Object.values(errors).some((errorArray) =>
errorArray.some(
(error) =>
error.typeOfControl === 'FORMAT' || error.criticality === 'ERROR'
)
)
}

export function isSameErrors(
currentErrors: Record<string, LunaticError[]>,
errors: Record<string, LunaticError[]> | undefined
) {
if (!errors) {
//currentErrors can not be undefined (currentErrors is undefined when no error)
return false
}

// extract errors Id in an arrays to compare them easily
const extractErrorsIds = (rawErrors: Record<string, LunaticError[]>) => {
return Object.values(rawErrors).reduce(
(acc, val) => acc.concat(val.map((error) => error.id)),
[] as string[]
)
}

const currentErrorsIds = extractErrorsIds(currentErrors)
const errorsIds = extractErrorsIds(errors)

return areArraysEqual(currentErrorsIds, errorsIds)
}
File renamed without changes.
12 changes: 12 additions & 0 deletions src/utils/compareArray.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//Remove symbol because not needed in equality comparison
type PrimitiveArray = (string | number | boolean | null | undefined | bigint)[]

export const areArraysEqual = (
arrayA: PrimitiveArray,
arrayB: PrimitiveArray
) => {
return (
arrayA.length === arrayB.length &&
arrayA.every((element, index) => element === arrayB[index])
)
}

0 comments on commit 9bbc115

Please sign in to comment.