18169: Fixed upload cancelation on a single file
[arvados-workbench2.git] / src / store / file-uploader / file-uploader-reducer.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { UploadFile, fileUploaderActions, FileUploaderAction } from "./file-uploader-actions";
6 import { uniqBy } from 'lodash';
7
8 export type UploaderState = UploadFile[];
9
10 const initialState: UploaderState = [];
11
12 export const fileUploaderReducer = (state: UploaderState = initialState, action: FileUploaderAction) => {
13     return fileUploaderActions.match(action, {
14         SET_UPLOAD_FILES: files => files.map((f, idx) => ({
15             id: idx,
16             file: f,
17             prevLoaded: 0,
18             loaded: 0,
19             total: 0,
20             startTime: 0,
21             prevTime: 0,
22             currentTime: 0
23         })),
24         UPDATE_UPLOAD_FILES: files => {
25             const updateFiles = files.map((f, idx) => ({
26                 id: state.length + idx,
27                 file: f,
28                 prevLoaded: 0,
29                 loaded: 0,
30                 total: 0,
31                 startTime: 0,
32                 prevTime: 0,
33                 currentTime: 0
34             }));
35             const updatedState = state.concat(updateFiles);
36             const uniqUpdatedState = uniqBy(updatedState, 'file.name');
37
38             return uniqUpdatedState;
39         },
40         DELETE_UPLOAD_FILE: file => {
41             const idToDelete: number = file.id;
42             const updatedState = state.filter(file => file.id !== idToDelete);
43
44             return updatedState;
45         },
46         CANCEL_FILES_UPLOAD: () => {
47             state.forEach((file) => {
48                 let interval = setInterval(() => {
49                     const key = Object.keys((window as any).cancelTokens).find(key => key.indexOf(file.file.name) > -1);
50     
51                     if (key) {
52                         clearInterval(interval);
53                         (window as any).cancelTokens[key]();
54                         delete (window as any).cancelTokens[key];
55                     }
56                 }, 100);
57             });
58
59             return [];
60         },
61         START_UPLOAD: () => {
62             const startTime = Date.now();
63             return state.map(f => ({ ...f, startTime, prevTime: startTime }));
64         },
65         SET_UPLOAD_PROGRESS: ({ fileId, loaded, total, currentTime }) =>
66             state.map(f => f.id === fileId ? {
67                 ...f,
68                 prevLoaded: f.loaded,
69                 loaded,
70                 total,
71                 prevTime: f.currentTime,
72                 currentTime
73             } : f),
74         CLEAR_UPLOAD: () => [],
75         default: () => state
76     });
77 };