Skip to content

Commit

Permalink
add save on logout
Browse files Browse the repository at this point in the history
  • Loading branch information
ddecrulle committed May 30, 2024
1 parent ea5db45 commit 17a55fa
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 8 deletions.
16 changes: 15 additions & 1 deletion src/components/Orchestrator/Orchestrator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { useRefSync } from 'hooks/useRefSync'
import { isSequencePage } from './utils/sequence'
import { scrollToFirstError } from './utils/scrollToFirstError'
import { isObjectEmpty } from 'utils/isObjectEmpty'
import { useAddPreLogoutAction } from 'utils/prelogout'

export type OrchestratorProps = OrchestratorProps.Common &
(OrchestratorProps.Visualize | OrchestratorProps.Collect)
Expand Down Expand Up @@ -158,13 +159,26 @@ export function Orchestrator(props: OrchestratorProps) {
})
})

useAddPreLogoutAction(() => {
if (mode !== 'collect') return

const { updateDataAndStateData } = props

const data = getChangedData()

updateDataAndStateData({
stateData: getCurrentStateData(),
data: isObjectEmpty(data.COLLECTED ?? {}) ? undefined : data.COLLECTED,
onSuccess: resetChangedData,
})
})
// Persist data and stateData when page change in "collect" mode
useUpdateEffect(() => {
if (mode !== 'collect') return
const { updateDataAndStateData } = props

const data = getChangedData()

updateDataAndStateData({
stateData: getCurrentStateData(),
data: isObjectEmpty(data.COLLECTED ?? {}) ? undefined : data.COLLECTED,
Expand Down
19 changes: 19 additions & 0 deletions src/hooks/useEvent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useRef, useState } from "react";

/**
* https://stackoverflow.com/questions/65890278/why-cant-usecallback-always-return-the-same-ref
* https://github.com/reactjs/rfcs/blob/useevent/text/0000-useevent.md
**/
export function useEvent<T extends ((...args: any[]) => unknown) | undefined | null>(
callback: NonNullable<T>
): T {
const callbackRef = useRef<typeof callback>(null as any);

callbackRef.current = callback;

return useState(
() =>
(...args: Parameters<Exclude<T, undefined | null>>) =>
callbackRef.current(...args)
)[0] as T;
}
9 changes: 4 additions & 5 deletions src/hooks/useUpdateEffect.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { useEffect, useRef } from 'react'

function useFirstMountState(): boolean {
const isFirst = useRef(true)

if (isFirst.current) {
isFirst.current = false
const isFirstRef = useRef(true)

if (isFirstRef.current) {
isFirstRef.current = false
return true
}

return isFirst.current
return isFirstRef.current
}

export const useUpdateEffect: typeof useEffect = (effect, deps) => {
Expand Down
7 changes: 5 additions & 2 deletions src/router/Layout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import logoInsee from 'assets/logo-insee.png'
import { headerFooterDisplayItem } from '@codegouvfr/react-dsfr/Display'
import { Badge } from '@codegouvfr/react-dsfr/Badge'
import { useLogoutUrl } from 'hooks/useLogoutUrl'
import { executePreLogoutActions } from 'utils/prelogout'

export function Header() {
const { isUserLoggedIn, logout } = useOidc()
Expand Down Expand Up @@ -38,11 +39,13 @@ export function Header() {
{
iconId: 'ri-account-box-line',
buttonProps: {
onClick: () =>
onClick: async () => {
await executePreLogoutActions()
logout({
redirectTo: 'specific url',
url: logoutUrl,
}),
})
},
},
text: 'Se déconnecter',
} as const,
Expand Down
20 changes: 20 additions & 0 deletions src/utils/prelogout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useEvent } from 'hooks/useEvent'
import { useEffect } from 'react'

const actions = new Set<() => Promise<void> | void>()

export async function executePreLogoutActions() {
for (const action of actions) {
await action()
}
}

export function useAddPreLogoutAction(
action: () => Promise<void> | void
): void {
const stableAction = useEvent(action)
useEffect(() => {
actions.add(stableAction)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
}

0 comments on commit 17a55fa

Please sign in to comment.