Merge branch '14910-uploading-files-to-collection'
[arvados-workbench2.git] / src / common / webdav.ts
index 24dacbdedd6ca6f6fb39264d5803db03aec25096..a09e8fdd6de4a97aab496da4d3651446fee135f8 100644 (file)
 // SPDX-License-Identifier: AGPL-3.0
 
 export class WebDAV {
-    static create(config?: Partial<WebDAVDefaults>, createRequest?: () => XMLHttpRequest) {
-        return new WebDAV(config, createRequest);
-    }
 
     defaults: WebDAVDefaults = {
-        baseUrl: '',
+        baseURL: '',
         headers: {},
     };
 
-    propfind = (url: string, config: PropfindConfig = {}) =>
+    constructor(config?: Partial<WebDAVDefaults>, private createRequest = () => new XMLHttpRequest()) {
+        if (config) {
+            this.defaults = { ...this.defaults, ...config };
+        }
+    }
+
+    propfind = (url: string, config: WebDAVRequestConfig = {}) =>
         this.request({
             ...config, url,
             method: 'PROPFIND'
         })
 
-    put = (url: string, config: PutConfig = {}) =>
+    put = (url: string, data?: any, config: WebDAVRequestConfig = {}) =>
         this.request({
             ...config, url,
-            method: 'PUT'
+            method: 'PUT',
+            data
         })
 
-    copy = (url: string, { destination, ...config }: CopyConfig) =>
+    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 + destination }
         })
 
-    move = (url: string, { destination, ...config }: MoveConfig) =>
+    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 + destination }
         })
 
-    delete = (url: string, config: DeleteConfig = {}) =>
+    delete = (url: string, config: WebDAVRequestConfig = {}) =>
         this.request({
             ...config, url,
             method: 'DELETE'
         })
 
-    private constructor(config?: Partial<WebDAVDefaults>, private createRequest = () => new XMLHttpRequest()) {
-        if (config) {
-            this.defaults = { ...this.defaults, ...config };
-        }
-    }
-
     private request = (config: RequestConfig) => {
         return new Promise<XMLHttpRequest>((resolve, reject) => {
             const r = this.createRequest();
-            r.open(config.method, this.defaults.baseUrl + config.url);
-
+            r.open(config.method, this.defaults.baseURL + config.url);
             const headers = { ...this.defaults.headers, ...config.headers };
             Object
                 .keys(headers)
                 .forEach(key => r.setRequestHeader(key, headers[key]));
 
-            if (config.onProgress) {
-                r.addEventListener('progress', config.onProgress);
+            if (config.onUploadProgress) {
+                r.upload.addEventListener('progress', config.onUploadProgress);
             }
 
-            r.addEventListener('load', () => resolve(r));
-            r.addEventListener('error', () => reject(r));
+            r.addEventListener('load', () => {
+                if (r.status === 404) {
+                    return reject(r);
+                } else {
+                    return resolve(r);
+                }
+            });
+
+            r.addEventListener('error', () => {
+                return reject(r);
+            });
+
+            r.upload.addEventListener('error', () => {
+                return reject(r);
+            });
 
             r.send(config.data);
         });
-
     }
 }
 
-export interface PropfindConfig extends BaseConfig { }
-
-export interface PutConfig extends BaseConfig {
-    data?: any;
-}
-
-export interface CopyConfig extends BaseConfig {
-    destination: string;
-}
-
-export interface MoveConfig extends BaseConfig {
-    destination: string;
-}
-
-export interface DeleteConfig extends BaseConfig { }
-
-interface BaseConfig {
+export interface WebDAVRequestConfig {
     headers?: {
         [key: string]: string;
     };
+    onUploadProgress?: (event: ProgressEvent) => void;
 }
 
 interface WebDAVDefaults {
-    baseUrl: string;
+    baseURL: string;
     headers: { [key: string]: string };
 }
 
@@ -105,5 +109,5 @@ interface RequestConfig {
     url: string;
     headers?: { [key: string]: string };
     data?: any;
-    onProgress?: (event: ProgressEvent) => void;
-}
+    onUploadProgress?: (event: ProgressEvent) => void;
+}
\ No newline at end of file