Skip to content

Commit

Permalink
add deposit proof
Browse files Browse the repository at this point in the history
  • Loading branch information
ddecrulle committed Apr 9, 2024
1 parent 5474b52 commit bb35413
Show file tree
Hide file tree
Showing 14 changed files with 110 additions and 47 deletions.
19 changes: 18 additions & 1 deletion openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -850,7 +850,24 @@
],
"responses": {
"200": {
"description": "OK"
"description": "OK",
"content": {
"application/pdf": {
"schema": {
"type": "string",
"format": "binary"
}
}
},
"headers": {
"Content-Disposition": {
"description": "The filename of the returned PDF",
"schema": {
"type": "string",
"example": "attachment; filename=\"deposit_proof.pdf\""
}
}
}
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions orval.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ export default defineConfig({
path: './src/api/axiosInstance.ts',
name: 'stromaeInstance',
},
operations: {
generateDepositProof: {
mutator: {
path: './src/api/axiosInstance.ts',
name: 'depositProofInstance',
},
},
},
},
},
hooks: {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "stromae-dsfr",
"private": true,
"version": "0.0.19",
"version": "0.0.20",
"type": "module",
"scripts": {
"prepare": "vite-envs update-types",
Expand Down
16 changes: 11 additions & 5 deletions src/api/06-survey-units.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import type {
UpdateDataBody,
} from '../model/api'
import { stromaeInstance } from './axiosInstance'
import { depositProofInstance } from './axiosInstance'

type SecondParameter<T extends (...args: any) => any> = Parameters<T>[1]

Expand Down Expand Up @@ -1443,11 +1444,16 @@ export const useGetInterviewerSurveyUnits = <
*/
export const generateDepositProof = (
id: string,
options?: SecondParameter<typeof stromaeInstance>,
options?: SecondParameter<typeof depositProofInstance>,
signal?: AbortSignal
) => {
return stromaeInstance<void>(
{ url: `/api/survey-unit/${id}/deposit-proof`, method: 'GET', signal },
return depositProofInstance<Blob>(
{
url: `/api/survey-unit/${id}/deposit-proof`,
method: 'GET',
responseType: 'blob',
signal,
},
options
)
}
Expand All @@ -1469,7 +1475,7 @@ export const getGenerateDepositProofQueryOptions = <
TData
>
>
request?: SecondParameter<typeof stromaeInstance>
request?: SecondParameter<typeof depositProofInstance>
}
) => {
const { query: queryOptions, request: requestOptions } = options ?? {}
Expand Down Expand Up @@ -1513,7 +1519,7 @@ export const useGenerateDepositProof = <
TData
>
>
request?: SecondParameter<typeof stromaeInstance>
request?: SecondParameter<typeof depositProofInstance>
}
): UseQueryResult<TData, TError> & { queryKey: QueryKey } => {
const queryOptions = getGenerateDepositProofQueryOptions(id, options)
Expand Down
17 changes: 13 additions & 4 deletions src/api/axiosInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ const onRequest = async (config: any) => ({
'Content-Type': 'application/json;charset=utf-8',
Accept: 'application/json;charset=utf-8',
...(await (async () => {
// TODO : Remove this when oidc is in place
return undefined
const accessToken = await getAccessToken()

if (!accessToken) {
Expand All @@ -41,9 +39,20 @@ axiosInstance.interceptors.request.use(onRequest)
export const stromaeInstance = <T>(
config: AxiosRequestConfig,
options?: AxiosRequestConfig
): Promise<T> => {
return axiosInstance({
) => {
return axiosInstance<T>({
...config,
...options,
}).then(({ data }) => data)
}

//DepositProofInstance
export const depositProofInstance = <T>(
config: AxiosRequestConfig,
options?: AxiosRequestConfig
) => {
return axiosInstance<T>({
...config,
...options,
})
}
3 changes: 1 addition & 2 deletions src/components/Orchestrator/CustomPages/ValidationModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ export type Props = {
open?: () => Promise<void>
}>
}
export function ValidationModal({actionsRef}: Props) {

export function ValidationModal({ actionsRef }: Props) {
const id = useId()

const [modal] = useState(() =>
Expand Down
4 changes: 2 additions & 2 deletions src/components/Orchestrator/CustomPages/WelcomeModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ export function WelcomeModal(props: { goBack: () => void }) {
},
{
doClosesModal: true,
children: "Reprendre la où j'en étais",
children: "Reprendre où j'en étais",
onClick: goBack,
},
]}
concealingBackdrop={true}
>
Vous avez déjà commencé à renseigner le questionnaire. Souhaitez-vous
reprendre la vous en étiez ou revenir à la première page ?
reprendre là où vous en étiez ou revenir à la première page ?
</modal.Component>
)
}
8 changes: 7 additions & 1 deletion src/components/Orchestrator/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export function Navigation(
handlePreviousClick: () => void
handleNextClick: () => void
handleDownloadData: () => void
handleDepositProofClick: () => Promise<void>
mode: OrchestratorProps['mode']
}>
) {
Expand All @@ -20,6 +21,7 @@ export function Navigation(
handleNextClick,
handlePreviousClick,
handleDownloadData,
handleDepositProofClick,
mode,
children,
} = props
Expand Down Expand Up @@ -63,7 +65,11 @@ export function Navigation(
priority="primary"
title={"Passer à l'étape suivante"}
id="continue-button"
onClick={handleNextClick}
onClick={
currentPage === 'endPage'
? handleDepositProofClick
: handleNextClick
}
>
{nextLabel}
</Button>
Expand Down
33 changes: 18 additions & 15 deletions src/components/Orchestrator/Orchestrator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { downloadAsJson } from 'utils/downloadAsJson'
import { useNavigate } from '@tanstack/react-router'
import { Welcome } from './CustomPages/Welcome'
import { Navigation } from './Navigation'
import { useEffect, useState } from 'react'
import { useState } from 'react'
import { Validation } from './CustomPages/Validation'
import { useStromaeNavigation } from './useStromaeNavigation'
import { EndPage } from './CustomPages/EndPage'
Expand Down Expand Up @@ -46,14 +46,13 @@ export namespace OrchestratorProps {
onSuccess?: () => void
}) => void
updateStateData: (params: { stateData: StateData }) => void
getDepositProof: () => Promise<void>
}
}

export function Orchestrator(props: OrchestratorProps) {
const { source, surveyUnitData, getReferentiel, mode } = props

const navigate = useNavigate()

const initialCurrentPage = surveyUnitData?.stateData?.currentPage

const {
Expand Down Expand Up @@ -120,6 +119,7 @@ export function Orchestrator(props: OrchestratorProps) {
goToLunaticPage,
initialCurrentPage,
openValidationModal: () => validationModalActionsRef.current.open(),
mode,
})

const getCurrentStateData = (): StateData => {
Expand All @@ -128,9 +128,6 @@ export function Orchestrator(props: OrchestratorProps) {
return { date: Date.now(), currentPage, state: 'VALIDATED' }
case 'lunaticPage':
return { date: Date.now(), currentPage: pageTag, state: 'INIT' }
case 'downloadPage':
//downloadPage is not really a page, this is only use internally to manage state
return { date: Date.now(), currentPage: 'endPage', state: 'VALIDATED' }
case 'validationPage':
case 'welcomePage':
default:
Expand All @@ -150,15 +147,6 @@ export function Orchestrator(props: OrchestratorProps) {
})
})

const isDownloadPage = currentPage === 'downloadPage'

// When reaching the download page, start downloading the page
useEffect(() => {
if (!isDownloadPage || mode !== 'visualize') return
downloadAsJsonRef.current()
navigate({ to: '/visualize' })
}, [isDownloadPage, downloadAsJsonRef, navigate, mode])

// Persist data when page change in "collect" mode
useUpdateEffect(() => {
if (mode !== 'collect') return
Expand All @@ -173,6 +161,20 @@ export function Orchestrator(props: OrchestratorProps) {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentPage, pageTag])

const navigate = useNavigate()

const handleDepositProofClick = async () => {
switch (mode) {
case 'visualize': {
downloadAsJsonRef.current()
navigate({ to: '/visualize' })
break
}
case 'collect': {
return props.getDepositProof()
}
}
}
return (
<div className={fr.cx('fr-container--fluid', 'fr-mt-1w', 'fr-mb-7w')}>
<Provider>
Expand All @@ -183,6 +185,7 @@ export function Orchestrator(props: OrchestratorProps) {
handleDownloadData={downloadAsJsonRef.current}
currentPage={currentPage}
mode={mode}
handleDepositProofClick={handleDepositProofClick}
>
<div className={fr.cx('fr-mb-4v')}>
{currentPage === 'welcomePage' && (
Expand Down
9 changes: 2 additions & 7 deletions src/components/Orchestrator/useStromaeNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type Params = {
goPrevLunatic: LunaticGoPreviousPage
openValidationModal: () => Promise<void>
goToLunaticPage: LunaticGoToPage
mode: 'visualize' | 'collect'
}

export function useStromaeNavigation({
Expand All @@ -27,9 +28,7 @@ export function useStromaeNavigation({
openValidationModal,
}: Params) {
const [currentPage, setCurrentPage] = useState<InternalPageType>(() =>
['endPage', 'downloadPage'].includes(initialCurrentPage) //downloadPage should not be saved into state but to be sure i handle case
? 'endPage'
: 'welcomePage'
initialCurrentPage === 'endPage' ? 'endPage' : 'welcomePage'
)

const goNext = () => {
Expand All @@ -44,8 +43,6 @@ export function useStromaeNavigation({
case 'lunaticPage':
return isLastPage ? setCurrentPage('validationPage') : goNextLunatic()
case 'endPage':
return setCurrentPage('downloadPage')
case 'downloadPage':
return
}
assert<Equals<typeof currentPage, never>>(false)
Expand All @@ -56,7 +53,6 @@ export function useStromaeNavigation({
return setCurrentPage('lunaticPage')
case 'lunaticPage':
return isFirstPage ? setCurrentPage('welcomePage') : goPrevLunatic()
case 'downloadPage':
case 'endPage':
case 'welcomePage':
return
Expand All @@ -73,7 +69,6 @@ export function useStromaeNavigation({
) => {
switch (params.page) {
case 'validationPage':
case 'downloadPage':
case 'endPage':
case 'welcomePage':
setCurrentPage(params.page)
Expand Down
6 changes: 1 addition & 5 deletions src/model/Page.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import type { useLunatic } from '@inseefr/lunatic'

export type StromaePage =
| 'welcomePage'
| 'validationPage'
| 'endPage'
| 'downloadPage'
export type StromaePage = 'welcomePage' | 'validationPage' | 'endPage'

export type PageType = StromaePage | ReturnType<typeof useLunatic>['pageTag']

Expand Down
29 changes: 28 additions & 1 deletion src/pages/Collect/CollectPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import type {
LunaticGetReferentiel,
Nomenclature,
} from 'components/Orchestrator/utils/lunaticType'
import { useSetStateData, useUpdateCollectedData } from 'api/06-survey-units'
import {
getGenerateDepositProofQueryOptions,
useSetStateData,
useUpdateCollectedData,
} from 'api/06-survey-units'
import type { LunaticData } from '@inseefr/lunatic'
import type { StateData } from 'model/StateData'
import { useDocumentTitle } from 'hooks/useDocumentTitle'
Expand Down Expand Up @@ -45,6 +49,28 @@ export function CollectPage() {
const updateStateData = (params: { stateData: StateData }) =>
mutationUpdateStateData.mutate({ id: surveyUnitId, data: params.stateData })

const getDepositProof = () =>
queryClient
.ensureQueryData(getGenerateDepositProofQueryOptions(surveyUnitId))
.then((response) => {
const fileName =
(response.headers['content-disposition'].match(
/filename="(.+?)"/
)[1] as string) ?? 'document.pdf' //content-disposition is present in OpenAPI spec but not well inferred by type

const url = URL.createObjectURL(response.data)
const link = document.createElement('a')
link.href = url
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
URL.revokeObjectURL(url)
})
.catch((error) => {
console.error('Error downloading PDF:', error)
})

return (
<Orchestrator
mode="collect"
Expand All @@ -53,6 +79,7 @@ export function CollectPage() {
getReferentiel={getReferentiel}
updateCollectedData={updateCollectedData}
updateStateData={updateStateData}
getDepositProof={getDepositProof}
/>
)
}
2 changes: 0 additions & 2 deletions src/pages/Collect/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ export const collectRoute = createRoute({
params: { questionnaireId, surveyUnitId },
context: { queryClient },
}) => {


const sourcePr = queryClient
.ensureQueryData(getGetQuestionnaireDataQueryOptions(questionnaireId))
.then((e) => e.value as unknown as LunaticSource) // We'd like to use zod, but the files are heavy.
Expand Down
1 change: 0 additions & 1 deletion src/parser/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ export const stromaePageSchema = z.enum([
'welcomePage',
'validationPage',
'endPage',
'downloadPage',
])

assert<Equals<z.infer<typeof stromaePageSchema>, StromaePage>>()
Expand Down

0 comments on commit bb35413

Please sign in to comment.