From a85ec43f30ed2b9c72baddd68704ad482a724fee Mon Sep 17 00:00:00 2001 From: Sean Sundberg Date: Sat, 23 Sep 2023 07:00:32 -0500 Subject: [PATCH] Add file upload to Data Extraction page closes #52 Signed-off-by: Sean Sundberg --- src/services/file-upload/file-upload.api.ts | 4 +- src/services/file-upload/file-upload.rest.ts | 5 ++- src/views/DataExtraction/DataExtraction.tsx | 37 ++++++++++++++++++- .../KYCCaseReview/KYCCaseReview.tsx | 10 ++++- .../KYCCaseDetail/util/event-handler.util.ts | 14 +++---- 5 files changed, 54 insertions(+), 16 deletions(-) diff --git a/src/services/file-upload/file-upload.api.ts b/src/services/file-upload/file-upload.api.ts index 784d99c..c17183a 100644 --- a/src/services/file-upload/file-upload.api.ts +++ b/src/services/file-upload/file-upload.api.ts @@ -1,5 +1,7 @@ import {DocumentModel} from "../../models"; +export type FileUploadContext = 'data-extraction' | 'kyc-case'; + export abstract class FileUploadApi { - abstract uploadFile(caseId: string, name: string, file: File): Promise; + abstract uploadFile(caseId: string, name: string, file: File, context?: FileUploadContext): Promise; } diff --git a/src/services/file-upload/file-upload.rest.ts b/src/services/file-upload/file-upload.rest.ts index fcc2c5b..c6d78ab 100644 --- a/src/services/file-upload/file-upload.rest.ts +++ b/src/services/file-upload/file-upload.rest.ts @@ -1,15 +1,16 @@ import axios from "axios"; -import {FileUploadApi} from "./file-upload.api"; +import {FileUploadApi, FileUploadContext} from "./file-upload.api"; import {DocumentModel} from "../../models"; export class FileUploadRest implements FileUploadApi { - uploadFile(caseId: string, name: string, file: File): Promise { + uploadFile(caseId: string, name: string, file: File, context: FileUploadContext = 'kyc-case'): Promise { const url = '/api/document/upload' const form = new FormData(); form.append('name', name); form.append('parentId', caseId); + form.append('context', context); form.append('file', file); return axios diff --git a/src/views/DataExtraction/DataExtraction.tsx b/src/views/DataExtraction/DataExtraction.tsx index 46f7636..a31f515 100644 --- a/src/views/DataExtraction/DataExtraction.tsx +++ b/src/views/DataExtraction/DataExtraction.tsx @@ -2,7 +2,17 @@ // @ts-ignore import React, {ChangeEvent, FormEvent, useState} from 'react'; import {useAtomValue, useSetAtom} from "jotai"; -import {Button, Checkbox, DataTableHeader, Form, FormGroup, Loading, TextInput} from "@carbon/react"; +import { + Button, + Checkbox, Column, + DataTableHeader, + FileUploader, + Form, + FormGroup, + Grid, + Loading, + TextInput +} from "@carbon/react"; import './DataExtraction.scss'; import { @@ -14,6 +24,7 @@ import {DataExtractionApi, dataExtractionApi} from "../../services"; import {DataTable, Stack} from "../../components"; import {DataExtractionQuestionModel} from "../../models"; import {Loadable} from "jotai/vanilla/utils/loadable"; +import {handleFileUploaderChange} from "../KYC/KYCCaseDetail/util"; export interface DataExtractionProps { } @@ -37,6 +48,7 @@ const createEmptyDataExtractionValues = (questionLoadable: Loadable = () => { const questionLoadable = useAtomValue(dataExtractionQuestionAtomLoadable) const [dataExtraction, setDataExtraction] = useState(createEmptyDataExtractionValues(questionLoadable)) + const [fileStatus, setFileStatus] = useState<'edit' | 'complete' | 'uploading'>('edit') const setResults = useSetAtom(dataExtractionResultsAtom) const service: DataExtractionApi = dataExtractionApi() @@ -116,7 +128,9 @@ export const DataExtraction: React.FunctionComponent = () = onChange={handleCustomer} required={true} /> - + + + {questions.map(question => { return ( = () = />) })} + + + + {}, setFileStatus, 'data-extraction')} + name="" /> + + +
diff --git a/src/views/KYC/KYCCaseDetail/KYCCaseReview/KYCCaseReview.tsx b/src/views/KYC/KYCCaseDetail/KYCCaseReview/KYCCaseReview.tsx index 0ccd195..c12a8a7 100644 --- a/src/views/KYC/KYCCaseDetail/KYCCaseReview/KYCCaseReview.tsx +++ b/src/views/KYC/KYCCaseDetail/KYCCaseReview/KYCCaseReview.tsx @@ -7,7 +7,7 @@ import {default as setValue} from "set-value"; import './KYCCaseReview.scss'; import {CountrySelect, DocumentList, EntityTypeSelect, IndustryTypeSelect, Stack} from "../../../../components"; -import {createEmptyReviewCase, FormOptionModel, KycCaseModel, ReviewCaseModel} from "../../../../models"; +import {createEmptyReviewCase, DocumentModel, FormOptionModel, KycCaseModel, ReviewCaseModel} from "../../../../models"; import {KycCaseManagementApi, kycCaseManagementApi} from "../../../../services"; import {handleFileUploaderChange} from "../util"; import {leftOuter} from "../../../../utils"; @@ -69,6 +69,12 @@ export const KYCCaseReview: React.FunctionComponent = (props } } + const handleDocuments = (newDocuments: DocumentModel[]) => { + const documents = updatedCase.documents.concat(newDocuments) + + setUpdatedCase(Object.assign({}, updatedCase, {documents})) + } + return (
@@ -139,7 +145,7 @@ export const KYCCaseReview: React.FunctionComponent = (props multiple={true} disabled={false} iconDescription="Delete file" - onChange={handleFileUploaderChange(props.currentCase.id, updatedCase, setUpdatedCase, setFileStatus)} + onChange={handleFileUploaderChange(props.currentCase.id, handleDocuments, setFileStatus, 'data-extraction')} name="" />
diff --git a/src/views/KYC/KYCCaseDetail/util/event-handler.util.ts b/src/views/KYC/KYCCaseDetail/util/event-handler.util.ts index 13fce95..8416432 100644 --- a/src/views/KYC/KYCCaseDetail/util/event-handler.util.ts +++ b/src/views/KYC/KYCCaseDetail/util/event-handler.util.ts @@ -1,8 +1,8 @@ -import {DocumentedCase, DocumentModel} from "../../../../models"; -import {fileUploadApi, FileUploadApi} from "../../../../services"; +import {DocumentModel} from "../../../../models"; +import {fileUploadApi, FileUploadApi, FileUploadContext} from "../../../../services"; import {fileListUtil} from "../../../../utils"; -export const handleFileUploaderChange = (caseId: string, updatedCase: T, setUpdatedCase, setFileStatus) => { +export const handleFileUploaderChange = (id: string, handleNewDocuments: (newDocuments: DocumentModel[]) => void, setFileStatus: (status: unknown) => void, context: FileUploadContext = 'kyc-case') => { const fileUploadService: FileUploadApi = fileUploadApi(); return (event: {target: {files: FileList, filenameStatus: string}}) => { @@ -14,17 +14,13 @@ export const handleFileUploaderChange = (caseId: stri setFileStatus('uploading') // TODO handle document remove - Promise.all(files.map(f => fileUploadService.uploadFile(caseId, f.name, f))) + Promise.all(files.map(f => fileUploadService.uploadFile(id, f.name, f, context))) .then((result: DocumentModel[]) => { setFileStatus('complete'); return result.filter(doc => !!doc); }) - .then((newDocuments: DocumentModel[]) => { - const documents = updatedCase.documents.concat(newDocuments) - - setUpdatedCase(Object.assign({}, updatedCase, {documents})) - }) + .then(handleNewDocuments) .catch(() => setFileStatus('error')) } }