-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add uploads field to logbook prior notification form
- Loading branch information
1 parent
9aee6bb
commit a25bd9e
Showing
9 changed files
with
208 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { sha256 } from '@utils/sha256' | ||
import { getOIDCConfig } from 'auth/getOIDCConfig' | ||
import { getOIDCUser } from 'auth/getOIDCUser' | ||
import { useCallback, useEffect, useState } from 'react' | ||
|
||
const { IS_OIDC_ENABLED } = getOIDCConfig() | ||
|
||
/** | ||
* Hook to get API request headers required for OIDC authentication. | ||
* | ||
* If the returned headers are `undefined`, | ||
* it means that you need to wait for the headers to be updated before making your request. | ||
* This is because the headers are updated asynchronously (`await sha256(nextToken)`). | ||
*/ | ||
export function useAuthRequestHeaders(): Record<string, string> | undefined { | ||
const [headers, setHeaders] = useState<Record<string, string> | undefined>(undefined) | ||
|
||
const user = getOIDCUser() | ||
const token = user?.access_token | ||
|
||
const updateHeaders = useCallback(async (nextToken: string | undefined) => { | ||
if (!IS_OIDC_ENABLED) { | ||
setHeaders({}) | ||
|
||
return | ||
} | ||
if (!nextToken) { | ||
setHeaders(undefined) | ||
|
||
return | ||
} | ||
|
||
const nextHeaders = { | ||
authorization: `Bearer ${nextToken}`, | ||
...(crypto?.subtle ? { 'x-correlation-id': await sha256(nextToken) } : {}) | ||
} | ||
|
||
setHeaders(nextHeaders) | ||
}, []) | ||
|
||
useEffect(() => { | ||
updateHeaders(token) | ||
}, [token, updateHeaders]) | ||
|
||
return headers | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
115 changes: 115 additions & 0 deletions
115
frontend/src/features/PriorNotification/components/shared/UploadFiles.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import { monitorfishApiKy } from '@api/api' | ||
import { RtkCacheTagType } from '@api/constants' | ||
import { | ||
priorNotificationApi, | ||
useGetPriorNotificationUploadsQuery | ||
} from '@features/PriorNotification/priorNotificationApi' | ||
import { useMainAppDispatch } from '@hooks/useMainAppDispatch' | ||
import { useKey } from '@mtes-mct/monitor-ui' | ||
import { assertNotNullish } from '@utils/assertNotNullish' | ||
import { downloadFile } from '@utils/downloadFile' | ||
import { useAuthRequestHeaders } from 'auth/hooks/useAuthRequestHeaders' | ||
import { useCallback, useMemo } from 'react' | ||
import { Uploader } from 'rsuite' | ||
import styled from 'styled-components' | ||
|
||
import type { FileType } from 'rsuite/esm/Uploader' | ||
|
||
type UploadFilesProps = Readonly<{ | ||
isManualPriorNotification: boolean | ||
reportId: string | ||
}> | ||
export function UploadFiles({ isManualPriorNotification, reportId }: UploadFilesProps) { | ||
const dispatch = useMainAppDispatch() | ||
const headers = useAuthRequestHeaders() | ||
|
||
const action = `/bff/v1/prior_notifications/${reportId}/uploads?isManualPriorNotification=${isManualPriorNotification}` | ||
const { data: uploads } = useGetPriorNotificationUploadsQuery(reportId) | ||
|
||
const key = useKey([uploads]) | ||
const uploadAsFileTypes: FileType[] | undefined = useMemo( | ||
() => | ||
uploads | ||
? uploads.map(upload => ({ | ||
fileKey: upload.id, | ||
mimeType: upload.mimeType, | ||
name: upload.fileName | ||
})) | ||
: undefined, | ||
[uploads] | ||
) | ||
|
||
const download = useCallback( | ||
async (fileType: FileType) => { | ||
assertNotNullish(fileType.fileKey) | ||
assertNotNullish(fileType.name) | ||
|
||
const url = `/bff/v1/prior_notifications/${reportId}/uploads/${fileType.fileKey}` | ||
const response = await monitorfishApiKy.get(url) | ||
const blob = await response.blob() | ||
|
||
downloadFile(fileType.name, (fileType as any).mimeType, blob) | ||
}, | ||
[reportId] | ||
) | ||
|
||
const refetch = useCallback(() => { | ||
dispatch(priorNotificationApi.util.invalidateTags([RtkCacheTagType.PriorNotificationDocuments])) | ||
}, [dispatch]) | ||
|
||
const remove = useCallback( | ||
async (file: FileType) => { | ||
await dispatch( | ||
priorNotificationApi.endpoints.deletePriorNotificationUpload.initiate({ | ||
priorNotificationUploadId: file.fileKey, | ||
reportId | ||
}) | ||
).unwrap() | ||
}, | ||
[dispatch, reportId] | ||
) | ||
|
||
if (!headers || !uploadAsFileTypes) { | ||
return <></> | ||
} | ||
|
||
return ( | ||
<Wrapper> | ||
<Uploader | ||
key={key} | ||
action={action} | ||
defaultFileList={uploadAsFileTypes} | ||
draggable | ||
headers={headers} | ||
onPreview={download} | ||
onRemove={remove} | ||
onSuccess={refetch} | ||
> | ||
<File>Glissez ou déposez des fichier à ajouter au préavis.</File> | ||
</Uploader> | ||
</Wrapper> | ||
) | ||
} | ||
|
||
const Wrapper = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
gap: 8px; | ||
margin-bottom: 8px; | ||
> .rs-uploader { | ||
> .rs-uploader-file-items { | ||
> .rs-uploader-file-item { | ||
> .rs-uploader-file-item-panel { | ||
cursor: pointer; | ||
} | ||
} | ||
} | ||
} | ||
` | ||
|
||
const File = styled.div` | ||
font-style: italic; | ||
color: ${p => p.theme.color.slateGray}; | ||
padding: 24px 90px; | ||
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export function downloadFile(fileName: string, mimeType: string, blob: Blob) { | ||
const link = document.createElement('a') | ||
link.href = URL.createObjectURL(new Blob([blob], { type: mimeType })) | ||
link.download = fileName | ||
|
||
link.click() | ||
} |