From 0a8b671d2bf96124015f6044ad20c844b6e1bdd7 Mon Sep 17 00:00:00 2001 From: Ilya Beda Date: Tue, 19 Nov 2024 13:28:53 +1100 Subject: [PATCH] Refactor uploading --- .../widgets/UploadFileControl/index.tsx | 60 +++++-------------- src/services/file-upload.ts | 44 ++++++++------ 2 files changed, 40 insertions(+), 64 deletions(-) diff --git a/src/components/BaseQuestionnaireResponseForm/widgets/UploadFileControl/index.tsx b/src/components/BaseQuestionnaireResponseForm/widgets/UploadFileControl/index.tsx index 0db59017..15a53f5b 100644 --- a/src/components/BaseQuestionnaireResponseForm/widgets/UploadFileControl/index.tsx +++ b/src/components/BaseQuestionnaireResponseForm/widgets/UploadFileControl/index.tsx @@ -1,5 +1,6 @@ import { InboxOutlined } from '@ant-design/icons'; -import { Form, Upload, message } from 'antd'; +import { formatError } from 'aidbox-react'; +import { Form, Upload, message, notification } from 'antd'; import type { UploadFile } from 'antd'; import { Attachment } from 'fhir/r4b'; import { useRef, useState } from 'react'; @@ -8,7 +9,7 @@ import { QuestionItemProps } from 'sdc-qrf'; import { isSuccess } from '@beda.software/remote-data'; import { - generateDownloadUrl, + /* generateDownloadUrl, */ generateUploadUrl, uploadFileWithXHR, CustomUploadRequestOption, @@ -20,32 +21,11 @@ const { Dragger } = Upload; type UploadFileProps = QuestionItemProps; -async function fetchUploadUrl(fileName: string) { - const response = await generateUploadUrl(fileName); - if (isSuccess(response) && response.data?.put_presigned_url) { - return { - uploadUrl: response.data.put_presigned_url, - filename: response.data.filename, - }; - } else { - throw new Error('file upload failed.'); - } -} - -async function fetchDownloadUrl(filename: string) { - const response = await generateDownloadUrl(filename); - if (isSuccess(response) && response.data?.get_presigned_url) { - return response.data.get_presigned_url; - } else { - throw new Error('url download failed'); - } -} - export function UploadFileControl({ parentPath, questionItem }: UploadFileProps) { const { linkId, helpText, repeats } = questionItem; const fieldName = [...parentPath, linkId]; const { formItem, value, onChange } = useFieldController(fieldName, questionItem); - const ref = useRef>({}); + /* const ref = useRef>({}); */ const uid = useRef>({}); const initialFileList: Array = (value ?? []).map((v: { value: { Attachment: Attachment } }) => { @@ -53,8 +33,8 @@ export function UploadFileControl({ parentPath, questionItem }: UploadFileProps) const file: UploadFile = { uid: url, name: url, - url: ref.current[url], - thumbUrl: ref.current[url], + /* url: ref.current[url], */ + /* thumbUrl: ref.current[url], */ }; return file; }); @@ -64,26 +44,14 @@ export function UploadFileControl({ parentPath, questionItem }: UploadFileProps) const multiple = repeats; const customRequest = async (options: CustomUploadRequestOption) => { - const { file, onSuccess, onError, onProgress } = options; - try { - const { uploadUrl, filename } = await fetchUploadUrl((file as any).name); - uid.current[(file as any).uid] = filename; - - uploadFileWithXHR( - { - file, - onProgress, - onError, - onSuccess: async (body: any, xhr?: XMLHttpRequest | undefined) => { - const downloadUrl = await fetchDownloadUrl(filename); - ref.current[filename] = downloadUrl; - onSuccess && onSuccess(body, xhr); - }, - }, - uploadUrl, - ); - } catch (error) { - message.error(`${(file as any).name} file upload failed.`); + const file: UploadFile = options.file as any; + const response = await generateUploadUrl(file.name); + if (isSuccess(response)) { + const { filename, uploadUrl } = response.data; + uid.current[file.uid] = filename; + uploadFileWithXHR(options, uploadUrl); + } else { + notification.error(formatError(response.error)); } }; const onUploaderChange = (info: { fileList: UploadFile[]; file: UploadFile }) => { diff --git a/src/services/file-upload.ts b/src/services/file-upload.ts index 174ee752..23041fc0 100644 --- a/src/services/file-upload.ts +++ b/src/services/file-upload.ts @@ -1,7 +1,9 @@ -import { service } from 'aidbox-react/lib/services/service'; import type { UploadRequestOption } from 'rc-upload/lib/interface'; +import { service } from 'aidbox-react/lib/services/service'; + import config from '@beda.software/emr-config'; +import { mapSuccess } from '@beda.software/remote-data'; interface UploadUrlResponse { filename: string; @@ -13,28 +15,34 @@ interface DownloadUrlResponse { } export async function generateUploadUrl(filename: string) { - return await service({ - baseURL: config.baseURL, - url: '/$generate-upload-url', - method: 'POST', - data: { - filename, - }, - }); + return mapSuccess( + await service({ + baseURL: config.baseURL, + url: '/$generate-upload-url', + method: 'POST', + data: { + filename, + }, + }), + (data) => ({ filename: data.filename, uploadUrl: data.put_presigned_url }), + ); } export async function generateDownloadUrl(key: string) { - return await service({ - baseURL: config.baseURL, - url: '/$generate-download-url', - method: 'POST', - data: { - key, - }, - }); + return mapSuccess( + await service({ + baseURL: config.baseURL, + url: '/$generate-download-url', + method: 'POST', + data: { + key, + }, + }), + ({ get_presigned_url }) => ({ downloadUrl: get_presigned_url }), + ); } -export type CustomUploadRequestOption = Pick; +export type CustomUploadRequestOption = Pick; export function uploadFileWithXHR(options: CustomUploadRequestOption, uploadUrl: string) { const { file, onProgress, onError, onSuccess } = options;