From c5a4c77de365b3ec545ae0ce155ba7d7c0df900f Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Fri, 21 Jan 2022 13:30:10 -0500 Subject: [PATCH] fix(striker-ui): remove progress and update file list when file upload completes --- ...{FileUploadInfo.tsx => FileUploadForm.tsx} | 41 ++++++++++------- striker-ui/components/Files/Files.tsx | 46 ++++++++++++------- 2 files changed, 55 insertions(+), 32 deletions(-) rename striker-ui/components/Files/{FileUploadInfo.tsx => FileUploadForm.tsx} (82%) diff --git a/striker-ui/components/Files/FileUploadInfo.tsx b/striker-ui/components/Files/FileUploadForm.tsx similarity index 82% rename from striker-ui/components/Files/FileUploadInfo.tsx rename to striker-ui/components/Files/FileUploadForm.tsx index 08742919..db17ddd1 100644 --- a/striker-ui/components/Files/FileUploadInfo.tsx +++ b/striker-ui/components/Files/FileUploadForm.tsx @@ -15,7 +15,8 @@ import { ProgressBar } from '../Bars'; import { BodyText } from '../Text'; import mainAxiosInstance from '../../lib/singletons/mainAxiosInstance'; -type FileUploadInfoProps = { +type FileUploadFormProps = { + onFileUploadComplete?: () => void; openFilePickerEventEmitter?: EventEmitter; }; @@ -30,14 +31,16 @@ type InUploadFile = Pick & { progressValue: number; }; -const FILE_UPLOAD_INFO_DEFAULT_PROPS: Partial = { +const FILE_UPLOAD_FORM_DEFAULT_PROPS: Partial = { + onFileUploadComplete: undefined, openFilePickerEventEmitter: undefined, }; -const FileUploadInfo = ( +const FileUploadForm = ( { + onFileUploadComplete, openFilePickerEventEmitter, - }: FileUploadInfoProps = FILE_UPLOAD_INFO_DEFAULT_PROPS as FileUploadInfoProps, + }: FileUploadFormProps = FILE_UPLOAD_FORM_DEFAULT_PROPS as FileUploadFormProps, ): JSX.Element => { const selectFileRef = useRef(); @@ -109,20 +112,26 @@ const FileUploadInfo = ( const inUploadFile: InUploadFile = { fileName, progressValue: 0 }; inUploadFiles.push(inUploadFile); - mainAxiosInstance.post('/files', fileFormData, { - headers: { - 'Content-Type': 'multipart/form-data', - }, - onUploadProgress: ({ loaded, total }) => { - inUploadFile.progressValue = Math.round((loaded / total) * 100); - setInUploadFiles([...inUploadFiles]); + mainAxiosInstance + .post('/files', fileFormData, { + headers: { + 'Content-Type': 'multipart/form-data', + }, + onUploadProgress: ({ loaded, total }) => { + inUploadFile.progressValue = Math.round((loaded / total) * 100); + setInUploadFiles([...inUploadFiles]); + }, + }) + .then(() => { + onFileUploadComplete?.call(null); - // Should probably write a onUploadFileComplete to update the file list in the parent every time a file finishes upload. - }, - }); + inUploadFiles.splice(inUploadFiles.indexOf(inUploadFile), 1); + setInUploadFiles([...inUploadFiles]); + }); } } + // Clears "staging area" (selected files) and populates "in-progress area" (in-upload files). setSelectedFiles([]); setInUploadFiles([...inUploadFiles]); }; @@ -186,6 +195,6 @@ const FileUploadInfo = ( ); }; -FileUploadInfo.defaultProps = FILE_UPLOAD_INFO_DEFAULT_PROPS; +FileUploadForm.defaultProps = FILE_UPLOAD_FORM_DEFAULT_PROPS; -export default FileUploadInfo; +export default FileUploadForm; diff --git a/striker-ui/components/Files/Files.tsx b/striker-ui/components/Files/Files.tsx index 8bf0ed80..f298a10d 100644 --- a/striker-ui/components/Files/Files.tsx +++ b/striker-ui/components/Files/Files.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { Box, IconButton } from '@mui/material'; import { Add as AddIcon, Edit as EditIcon } from '@mui/icons-material'; import { styled } from '@mui/material/styles'; @@ -7,12 +7,12 @@ import EventEmitter from 'events'; import ICON_BUTTON_STYLE from '../../lib/consts/ICON_BUTTON_STYLE'; import { Panel } from '../Panels'; -import PeriodicFetch from '../../lib/fetchers/periodicFetch'; import Spinner from '../Spinner'; import { HeaderText } from '../Text'; import FileList from './FileList'; -import FileUploadInfo from './FileUploadInfo'; +import FileUploadForm from './FileUploadForm'; import FileEditForm from './FileEditForm'; +import fetchJSON from '../../lib/fetchers/fetchJSON'; const PREFIX = 'Files'; @@ -32,6 +32,11 @@ const StyledDiv = styled('div')(() => ({ const StyledIconButton = styled(IconButton)(ICON_BUTTON_STYLE); const Files = (): JSX.Element => { + const [rawFilesOverview, setRawFilesOverview] = useState([]); + const [ + isLoadingRawFilesOverview, + setIsLoadingRawFilesOverview, + ] = useState(false); const [isEditMode, setIsEditMode] = useState(false); const openFilePickerEventEmitter: EventEmitter = new EventEmitter(); @@ -44,10 +49,7 @@ const Files = (): JSX.Element => { setIsEditMode(!isEditMode); }; - const buildFileList = ( - rawFilesOverview: string[][] = [], - isLoadingRawFilesOverview: boolean, - ): JSX.Element => { + const buildFileList = (): JSX.Element => { let elements: JSX.Element; if (isLoadingRawFilesOverview) { elements = ; @@ -74,13 +76,22 @@ const Files = (): JSX.Element => { return elements; }; - const { - data: rawFilesOverview, - isLoading: isLoadingRawFilesOverview, - } = PeriodicFetch( - `${process.env.NEXT_PUBLIC_API_URL?.replace('/cgi-bin', '/api')}/files`, - 0, - ); + const fetchRawFilesOverview = async () => { + setIsLoadingRawFilesOverview(true); + + const data = await fetchJSON( + `${process.env.NEXT_PUBLIC_API_URL?.replace('/cgi-bin', '/api')}/files`, + ); + + setRawFilesOverview(data); + setIsLoadingRawFilesOverview(false); + }; + + useEffect(() => { + if (!isEditMode) { + fetchRawFilesOverview(); + } + }, [isEditMode]); return ( @@ -100,10 +111,13 @@ const Files = (): JSX.Element => { - { + fetchRawFilesOverview(); + }} openFilePickerEventEmitter={openFilePickerEventEmitter} /> - {buildFileList(rawFilesOverview, isLoadingRawFilesOverview)} + {buildFileList()} );