Skip to content

Commit

Permalink
Merge pull request #815 from equinor/feat/fileprogress-ondelete-promise
Browse files Browse the repository at this point in the history
FileProgress onDelete returning promise
  • Loading branch information
mariush2 authored Oct 18, 2024
2 parents f3a3d4a + 45e4561 commit 657b03e
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 35 deletions.
34 changes: 20 additions & 14 deletions src/molecules/FileProgress/CompactFileProgress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const CompactFileProgress: FC<CompactFileProgressProps> = ({
showCompleteState,
fullErrorText,
handleOnClick,
isDeleting,
}) => {
const [src, setSrc] = useState('');

Expand Down Expand Up @@ -71,7 +72,7 @@ const CompactFileProgress: FC<CompactFileProgressProps> = ({
);
}

if (showCompleteState) {
if (showCompleteState && !isDeleting) {
return (
<ImageWrapper>
<img src={src} alt={' ' + `${file.name}`} />
Expand All @@ -82,20 +83,23 @@ const CompactFileProgress: FC<CompactFileProgressProps> = ({
<LoadingWrapper>
<CircularProgress
variant={
progressPercent === undefined ? 'indeterminate' : 'determinate'
progressPercent === undefined || isDeleting
? 'indeterminate'
: 'determinate'
}
value={progressPercent}
size={24}
/>
</LoadingWrapper>
);
}, [
file.name,
showCompleteState,
isError,
showCompleteState,
isDeleting,
progressPercent,
shortErrorText,
src,
file.name,
]);

return (
Expand All @@ -109,16 +113,18 @@ const CompactFileProgress: FC<CompactFileProgressProps> = ({
Loading...
</AdditionalText>
)}
<CloseButton
data-testid="attachment-delete-button"
onClick={handleOnClick}
>
<Icon
color={colors.text.static_icons__tertiary.rgba}
data={clear}
size={24}
/>
</CloseButton>
{!isDeleting && (
<CloseButton
data-testid="attachment-delete-button"
onClick={handleOnClick}
>
<Icon
color={colors.text.static_icons__tertiary.rgba}
data={clear}
size={24}
/>
</CloseButton>
)}
</CompactFileProgressContainer>
);
};
Expand Down
5 changes: 3 additions & 2 deletions src/molecules/FileProgress/FileProgress.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const meta: Meta<typeof FileProgress> = {
},
args: {
compact: false,
file: new File([], 'test'),
file: new File([], 'Image.png'),
progressPercent: 1,
isDone: false,
customLoadingText: undefined,
Expand All @@ -40,7 +40,8 @@ const meta: Meta<typeof FileProgress> = {
fullErrorText: undefined,
onCancel: () => null,
onRetry: () => null,
onDelete: () => null,
onDelete: () =>
new Promise<void>((resolve) => setTimeout(() => resolve(), 2000)),
},
};

Expand Down
19 changes: 18 additions & 1 deletion src/molecules/FileProgress/FileProgress.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
refresh,
} from '@equinor/eds-icons';
import { faker } from '@faker-js/faker';
import { waitFor } from '@testing-library/react';

import {
CompactFileProgressBaseProps,
Expand All @@ -23,7 +24,9 @@ function fakeProps():

return {
file: file,
onDelete: () => null,
onDelete: vi.fn(
() => new Promise<void>((resolve) => setTimeout(() => resolve(), 400))
),
};
}

Expand Down Expand Up @@ -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(<FileProgress file={file} onDelete={onDelete} isDone />);

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();

Expand Down
14 changes: 10 additions & 4 deletions src/molecules/FileProgress/FileProgress.tsx
Original file line number Diff line number Diff line change
@@ -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<void>;
file: FileWithPath | File;
isDone?: boolean;
progressPercent?: number;
Expand All @@ -30,6 +30,7 @@ export interface CompactFileProgressBaseProps extends FileProgressBaseProps {
export interface FileProgressPropsExtension {
showCompleteState: boolean;
handleOnClick: () => void;
isDeleting: boolean;
}

/**
Expand All @@ -38,23 +39,27 @@ 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);
}
};

if (props.compact) {
return (
<CompactFileProgress
{...props}
isDeleting={isDeleting}
showCompleteState={showCompleteState}
handleOnClick={handleOnClick}
/>
Expand All @@ -64,6 +69,7 @@ export const FileProgress: FC<
return (
<RegularFileProgress
{...props}
isDeleting={isDeleting}
showCompleteState={showCompleteState}
handleOnClick={handleOnClick}
/>
Expand Down
52 changes: 38 additions & 14 deletions src/molecules/FileProgress/RegularFileProgress.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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,
Expand All @@ -36,11 +41,16 @@ const RegularFileProgress: FC<RegularFileProgressProps> = ({
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(() => {
Expand Down Expand Up @@ -73,15 +83,21 @@ const RegularFileProgress: FC<RegularFileProgressProps> = ({
<FileName>
<Typography variant="caption">{file.name}</Typography>
<div>
<Button variant="ghost_icon" onClick={handleOnClick}>
<Icon
data={
showCompleteState ? delete_to_trash : close_circle_outlined
}
color={colors.text.static_icons__tertiary.rgba}
size={24}
/>
</Button>
{isDeleting ? (
<Button variant="ghost_icon">
<CircularProgress size={24} />
</Button>
) : (
<Button variant="ghost_icon" onClick={handleOnClick}>
<Icon
data={
showCompleteState ? delete_to_trash : close_circle_outlined
}
color={colors.text.static_icons__tertiary.rgba}
size={24}
/>
</Button>
)}
{isError && onRetry && (
<Button variant="ghost_icon" onClick={onRetry}>
<Icon
Expand All @@ -108,8 +124,16 @@ const RegularFileProgress: FC<RegularFileProgressProps> = ({
{file?.size && (
<Typography variant="overline">
{showCompleteState
? formatBytes(file.size, 1)
: `${fileSizeProgress} of ${formatBytes(file.size, 1)}`}
? formatDataSize({
size: file.size,
decimals: 1,
inputFormat: 'B',
})
: `${fileSizeProgress} of ${formatDataSize({
size: file.size,
decimals: 1,
inputFormat: 'B',
})}`}
</Typography>
)}
</RegularFileProgressDetails>
Expand Down

0 comments on commit 657b03e

Please sign in to comment.