18169: Removed cancel disable when uploading
[arvados-workbench2.git] / src / common / webdav.ts
index 27e1f22de5be8c642072d7ae42b80f9189fe524b..93ec21cb724f26d2ede4cf9be4b211defaf85b9c 100644 (file)
@@ -2,6 +2,8 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
+import { customEncodeURI } from "./url";
+
 export class WebDAV {
 
     defaults: WebDAVDefaults = {
@@ -25,21 +27,41 @@ export class WebDAV {
         this.request({
             ...config, url,
             method: 'PUT',
-            data,
+            data
         })
 
+    upload = (url: string, files: File[], config: WebDAVRequestConfig = {}) => {
+        return Promise.all(
+            files.map(file => this.request({
+                ...config, url,
+                method: 'PUT',
+                data: file
+            }))
+        );
+    }
+
     copy = (url: string, destination: string, config: WebDAVRequestConfig = {}) =>
         this.request({
             ...config, url,
             method: 'COPY',
-            headers: { ...config.headers, Destination: this.defaults.baseURL + destination }
+            headers: {
+                ...config.headers,
+                Destination: this.defaults.baseURL
+                    ? this.defaults.baseURL.replace(/\/+$/, '') + '/' + destination.replace(/^\/+/, '')
+                    : destination
+            }
         })
 
     move = (url: string, destination: string, config: WebDAVRequestConfig = {}) =>
         this.request({
             ...config, url,
             method: 'MOVE',
-            headers: { ...config.headers, Destination: this.defaults.baseURL + destination }
+            headers: {
+                ...config.headers,
+                Destination: this.defaults.baseURL
+                    ? this.defaults.baseURL.replace(/\/+$/, '') + '/' + destination.replace(/^\/+/, '')
+                    : destination
+            }
         })
 
     delete = (url: string, config: WebDAVRequestConfig = {}) =>
@@ -51,24 +73,53 @@ export class WebDAV {
     private request = (config: RequestConfig) => {
         return new Promise<XMLHttpRequest>((resolve, reject) => {
             const r = this.createRequest();
-            r.open(config.method, this.defaults.baseURL + config.url);
+            this.defaults.baseURL = this.defaults.baseURL.replace(/\/+$/, '');
+            r.open(config.method,
+                `${this.defaults.baseURL
+                    ? this.defaults.baseURL+'/'
+                    : ''}${customEncodeURI(config.url)}`);
 
             const headers = { ...this.defaults.headers, ...config.headers };
             Object
                 .keys(headers)
                 .forEach(key => r.setRequestHeader(key, headers[key]));
 
+            if (!(window as any).cancelTokens) {
+                Object.assign(window, { cancelTokens: {} });
+            }
+
+            (window as any).cancelTokens[config.url] = () => { 
+                resolve(r);
+                r.abort();
+            }
+
             if (config.onUploadProgress) {
                 r.upload.addEventListener('progress', config.onUploadProgress);
             }
 
-            r.addEventListener('load', () => resolve(r));
-            r.addEventListener('error', () => reject(r));
+            // This event gets triggered on *any* server response
+            r.addEventListener('load', () => {
+                if (r.status >= 400) {
+                    return reject(r);
+                } else {
+                    return resolve(r);
+                }
+            });
+
+            // This event gets triggered on network errors
+            r.addEventListener('error', () => {
+                return reject(r);
+            });
+
+            r.upload.addEventListener('error', () => {
+                return reject(r);
+            });
 
             r.send(config.data);
         });
     }
 }
+
 export interface WebDAVRequestConfig {
     headers?: {
         [key: string]: string;
@@ -87,4 +138,4 @@ interface RequestConfig {
     headers?: { [key: string]: string };
     data?: any;
     onUploadProgress?: (event: ProgressEvent) => void;
-}
+}
\ No newline at end of file