diff --git a/src/molecules/FileProgress/CompactFileProgress.tsx b/src/molecules/FileProgress/CompactFileProgress.tsx index cafbaa9e6..d5dfa9a6b 100644 --- a/src/molecules/FileProgress/CompactFileProgress.tsx +++ b/src/molecules/FileProgress/CompactFileProgress.tsx @@ -33,6 +33,7 @@ const CompactFileProgress: FC = ({ showCompleteState, fullErrorText, handleOnClick, + isDeleting, }) => { const [src, setSrc] = useState(''); @@ -71,7 +72,7 @@ const CompactFileProgress: FC = ({ ); } - if (showCompleteState) { + if (showCompleteState && !isDeleting) { return ( {' @@ -82,7 +83,9 @@ const CompactFileProgress: FC = ({ = ({ ); }, [ - file.name, - showCompleteState, isError, + showCompleteState, + isDeleting, progressPercent, shortErrorText, src, + file.name, ]); return ( @@ -109,16 +113,18 @@ const CompactFileProgress: FC = ({ Loading... )} - - - + {!isDeleting && ( + + + + )} ); }; diff --git a/src/molecules/FileProgress/FileProgress.stories.tsx b/src/molecules/FileProgress/FileProgress.stories.tsx index d4a645935..edd9e699d 100644 --- a/src/molecules/FileProgress/FileProgress.stories.tsx +++ b/src/molecules/FileProgress/FileProgress.stories.tsx @@ -31,7 +31,7 @@ const meta: Meta = { }, args: { compact: false, - file: new File([], 'test'), + file: new File([], 'Image.png'), progressPercent: 1, isDone: false, customLoadingText: undefined, @@ -40,7 +40,8 @@ const meta: Meta = { fullErrorText: undefined, onCancel: () => null, onRetry: () => null, - onDelete: () => null, + onDelete: () => + new Promise((resolve) => setTimeout(() => resolve(), 2000)), }, }; diff --git a/src/molecules/FileProgress/FileProgress.test.tsx b/src/molecules/FileProgress/FileProgress.test.tsx index 3af56ac54..bfed2b075 100644 --- a/src/molecules/FileProgress/FileProgress.test.tsx +++ b/src/molecules/FileProgress/FileProgress.test.tsx @@ -6,6 +6,7 @@ import { refresh, } from '@equinor/eds-icons'; import { faker } from '@faker-js/faker'; +import { waitFor } from '@testing-library/react'; import { CompactFileProgressBaseProps, @@ -23,7 +24,9 @@ function fakeProps(): return { file: file, - onDelete: () => null, + onDelete: vi.fn( + () => new Promise((resolve) => setTimeout(() => resolve(), 400)) + ), }; } @@ -160,6 +163,20 @@ test('Renders regular error state with default error text', () => { expect(errorText).toBeInTheDocument(); }); +test('Clicking delete shows a progress bar and callsOnDelete', async () => { + const { file, onDelete } = fakeProps(); + + render(); + + const user = userEvent.setup(); + + await user.click(screen.getByRole('button')); + + expect(screen.getByRole('progressbar')).toBeInTheDocument(); + + await waitFor(() => expect(onDelete).toHaveBeenCalledTimes(1)); +}); + test('Renders compact loading state with progress bar', () => { const { file, onDelete } = fakeProps(); diff --git a/src/molecules/FileProgress/FileProgress.tsx b/src/molecules/FileProgress/FileProgress.tsx index 0675ce8cc..28b2a6436 100644 --- a/src/molecules/FileProgress/FileProgress.tsx +++ b/src/molecules/FileProgress/FileProgress.tsx @@ -1,11 +1,11 @@ -import { FC, useMemo } from 'react'; +import { FC, useMemo, useState } from 'react'; import { FileWithPath } from 'react-dropzone'; import CompactFileProgress from 'src/molecules/FileProgress/CompactFileProgress'; import RegularFileProgress from 'src/molecules/FileProgress/RegularFileProgress'; interface FileProgressBaseProps { - onDelete: () => void; + onDelete: () => Promise; file: FileWithPath | File; isDone?: boolean; progressPercent?: number; @@ -30,6 +30,7 @@ export interface CompactFileProgressBaseProps extends FileProgressBaseProps { export interface FileProgressPropsExtension { showCompleteState: boolean; handleOnClick: () => void; + isDeleting: boolean; } /** @@ -38,16 +39,19 @@ export interface FileProgressPropsExtension { export const FileProgress: FC< RegularFileProgressBaseProps | CompactFileProgressBaseProps > = (props) => { + const [isDeleting, setIsDeleting] = useState(false); const showCompleteState = useMemo(() => { if (props.isError ?? props.isDone === undefined) return true; return props.isDone; }, [props.isError, props.isDone]); - const handleOnClick = () => { + const handleOnClick = async () => { if (!showCompleteState && props.onCancel) { props.onCancel(); } else { - props.onDelete(); + setIsDeleting(true); + await props.onDelete(); + setIsDeleting(false); } }; @@ -55,6 +59,7 @@ export const FileProgress: FC< return ( @@ -64,6 +69,7 @@ export const FileProgress: FC< return ( diff --git a/src/molecules/FileProgress/RegularFileProgress.tsx b/src/molecules/FileProgress/RegularFileProgress.tsx index c8afed5dd..e2675a09d 100644 --- a/src/molecules/FileProgress/RegularFileProgress.tsx +++ b/src/molecules/FileProgress/RegularFileProgress.tsx @@ -1,6 +1,11 @@ import { FC, useMemo } from 'react'; -import { Button, Icon, Typography } from '@equinor/eds-core-react'; +import { + Button, + CircularProgress, + Icon, + Typography, +} from '@equinor/eds-core-react'; import { close_circle_outlined, delete_to_trash, @@ -9,7 +14,7 @@ import { } from '@equinor/eds-icons'; import { colors } from 'src/atoms/style'; -import { formatBytes } from 'src/atoms/utils'; +import { formatDataSize } from 'src/atoms/utils'; import { FileProgressPropsExtension, RegularFileProgressBaseProps, @@ -36,11 +41,16 @@ const RegularFileProgress: FC = ({ fullErrorText, showCompleteState, handleOnClick, + isDeleting, }) => { const fileSizeProgress = useMemo(() => { if (!file?.size || !progressPercent) return 1; const progressInSize = (file.size / 100) * progressPercent; - return formatBytes(progressInSize, 1); + return formatDataSize({ + inputFormat: 'B', + size: progressInSize, + decimals: 1, + }); }, [file?.size, progressPercent]); const detailsText = useMemo(() => { @@ -73,15 +83,21 @@ const RegularFileProgress: FC = ({ {file.name}
- + {isDeleting ? ( + + ) : ( + + )} {isError && onRetry && (