Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / applications / drive / src / app / components / TransferManager / TransferItem.tsx
blob2e6e6087212bc4b6321160072d381e286a5359b7
1 import * as React from 'react';
3 import { FileIcon, FileNameDisplay, Loader } from '@proton/components';
4 import humanSize, { shortHumanSize } from '@proton/shared/lib/helpers/humanSize';
5 import clsx from '@proton/utils/clsx';
7 import {
8     getProgressBarStatus,
9     isTransferCanceled,
10     isTransferDone,
11     isTransferInitializing,
12     isTransferPaused,
13     isTransferPending,
14     isTransferProgress,
15     isTransferSkipped,
16 } from '../../utils/transfer';
17 import ProgressBar from './ProgressBar';
18 import TransferControls from './TransferControls';
19 import TransferStateIndicator from './TransferStateIndicator';
20 import type { TransferProps } from './interfaces';
21 import { TransferType } from './transfer';
23 type Props<T extends TransferType> = React.HTMLAttributes<HTMLDivElement> &
24     TransferProps<T> & {
25         stats: {
26             progress: number;
27             speed: number;
28         };
29     };
31 const Transfer = <T extends TransferType>({ stats, transfer, type, className, ...rest }: Props<T>) => {
32     const isInitializing = isTransferInitializing(transfer);
33     const isNameUnresolved = isInitializing || isTransferPending(transfer);
34     const isProgress = isTransferProgress(transfer);
35     const isPaused = isTransferPaused(transfer);
36     const isCanceled = isTransferCanceled(transfer);
37     const isSkipped = isTransferSkipped(transfer);
38     const isDone = isTransferDone(transfer);
40     const fileSize = transfer.meta.size;
41     const progressLimit = fileSize || 1;
42     const percentageDone = isDone ? 100 : !fileSize ? 0 : Math.floor(100 * (stats.progress / fileSize));
44     const progress = isDone ? progressLimit : stats.progress;
45     const speed = humanSize({ bytes: stats.speed });
47     const isUploadingFolder = type === TransferType.Upload && transfer.meta.mimeType === 'Folder';
49     return (
50         <div
51             className={clsx([
52                 'transfers-manager-list-item p-4',
53                 (isCanceled || isSkipped) && 'transfers-manager-list-item--canceled',
54                 className,
55             ])}
56             data-testid="transfer-item-row"
57             {...rest}
58         >
59             <div className="transfers-manager-list-item-name flex flex-nowrap items-center text-ellipsis">
60                 <span className="transfers-manager-list-item-icon flex shrink-0 mr-2">
61                     {isInitializing ? <Loader size="small" /> : <FileIcon mimeType={transfer.meta.mimeType} />}
62                 </span>
63                 <span className={clsx(['flex', isNameUnresolved && 'color-weak'])} data-testid="transfer-item-name">
64                     <FileNameDisplay text={transfer.meta.filename} />
65                 </span>
66             </div>
68             {!isUploadingFolder && (
69                 <div className="transfers-manager-list-item-size text-right text-ellipsis" title={`${percentageDone}%`}>
70                     {(isProgress || isPaused) && progress > 0 && (
71                         <span className="hidden lg:inline">{shortHumanSize(progress)} / </span>
72                     )}
73                     {fileSize !== undefined
74                         ? shortHumanSize(fileSize)
75                         : isProgress && <Loader className="inline" size="small" />}
76                 </div>
77             )}
79             <div className="transfers-manager-list-item-status flex flex-nowrap items-center justify-end text-ellipsis">
80                 <TransferStateIndicator transfer={transfer} type={type} speed={speed} />
81             </div>
83             <TransferControls transfer={transfer} type={type} />
85             <ProgressBar
86                 status={getProgressBarStatus(transfer.state)}
87                 aria-describedby={transfer.id}
88                 value={isCanceled ? 0 : progress}
89                 max={progressLimit}
90             />
91         </div>
92     );
95 export default Transfer;