From fa0aaf8b5f9fbe819e09bcc5f935ffe42ec0f0c7 Mon Sep 17 00:00:00 2001
From: Tamara Steinwender <tamara.steinwender@tugraz.at>
Date: Tue, 25 Aug 2020 15:23:45 +0200
Subject: [PATCH] Added 'select-all button'

---
 .../src/dbp-nextcloud-file-picker.js          | 103 +++++++++++++-----
 packages/file-handling/src/file-source.js     |   4 +-
 .../src/i18n/de/translation.json              |   6 +-
 .../src/i18n/en/translation.json              |   6 +-
 4 files changed, 86 insertions(+), 33 deletions(-)

diff --git a/packages/file-handling/src/dbp-nextcloud-file-picker.js b/packages/file-handling/src/dbp-nextcloud-file-picker.js
index 9287b600..6b3a8fd6 100644
--- a/packages/file-handling/src/dbp-nextcloud-file-picker.js
+++ b/packages/file-handling/src/dbp-nextcloud-file-picker.js
@@ -47,6 +47,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
         this.activeDirectoryACL = '';
         this.forAll = false;
         this.uploadCount = 0;
+        this.selectAllButton = true;
     }
 
     static get scopedElements() {
@@ -78,6 +79,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
             uploadFileDirectory: { type: String, attribute: false },
             activeDirectoryRights: { type: String, attribute: false },
             activeDirectoryACL: { type: String, attribute: false },
+            selectAllButton: { type: Boolean, attribute: false },
         };
     }
 
@@ -114,7 +116,6 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                 placeholder:i18n.t('nextcloud-file-picker.no-data'),
                 resizableColumns:false,
                 columns: [
-
                     {title: "", field: "type", align:"center", headerSort:false, width:50, responsive:1, formatter: (cell, formatterParams, onRendered) => {
                             const icon_tag =  that.constructor.getScopedTagName("dbp-icon");
                             let icon = `<${icon_tag} name="empty-file" class="nextcloud-picker-icon"></${icon_tag}>`;
@@ -161,10 +162,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
 
                 ],
                 rowFormatter: (row) => {
-                    //row - row component
-
-                    var data = row.getData();
-                    if(!checkFileType(data, this.allowedMimeTypes)){
+                    let data = row.getData();
+                    if(!this.checkFileType(data, this.allowedMimeTypes)){
                         row.getElement().classList.add("no-select");
                         row.getElement().classList.remove("tabulator-selectable");
                     }
@@ -199,6 +198,12 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                                     this.directoryClicked(e, data);
                                     break;
                                 case "file":
+                                    if (this.tabulatorTable.getSelectedRows().length === this.tabulatorTable.getRows().filter(row => row.getData().type != 'directory' && this.checkFileType(row.getData(), this.allowedMimeTypes)).length) {
+                                        this.selectAllButton = false;
+                                    }
+                                    else {
+                                        this.selectAllButton = true;
+                                    }
                                     break;
                             }
                         }
@@ -208,6 +213,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                     }
                 },
                 rowDblClick: (e, row) => {
+                    // comment this in for double click directory change
                    /* if (this.directoriesOnly) {
                         const data = row.getData();
                         this.directoryClicked(e, data);
@@ -225,24 +231,9 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
             {
                 this.tabulatorTable.options.selectableRangeMode = "click";
             }*/
-            function checkFileType(data, filterParams) {
-                // check if file is allowed
-                if (typeof data.mime === 'undefined') {
-                    return true;
-                }
-                const [fileMainType, fileSubType] = data.mime.split('/');
-                const mimeTypes = filterParams.split(',');
-                let deny = true;
 
-                mimeTypes.forEach((str) => {
-                    const [mainType, subType] = str.split('/');
-                    deny = deny && ((mainType !== '*' && mainType !== fileMainType) || (subType !== '*' && subType !== fileSubType));
-                });
-
-                return !deny;
-            }
             if (typeof this.allowedMimeTypes !== 'undefined' && !this.directoriesOnly) {
-                this.tabulatorTable.setFilter(checkFileType, this.allowedMimeTypes);
+                this.tabulatorTable.setFilter(this.checkFileType, this.allowedMimeTypes);
             }
             if (typeof this.directoriesOnly !== 'undefined' && this.directoriesOnly)
             {
@@ -254,9 +245,29 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
         });
     }
 
+    /**
+     * check mime type of row
+     *
+     * @param row.getDatat(), mimetypes
+     */
+    checkFileType(data, filterParams) {
+        if (typeof data.mime === 'undefined') {
+            return true;
+        }
+        const [fileMainType, fileSubType] = data.mime.split('/');
+        const mimeTypes = filterParams.split(',');
+        let deny = true;
+
+        mimeTypes.forEach((str) => {
+            const [mainType, subType] = str.split('/');
+            deny = deny && ((mainType !== '*' && mainType !== fileMainType) || (subType !== '*' && subType !== fileSubType));
+        });
+
+        return !deny;
+    }
+
     openFilePicker() {
-        if (this.webDavClient === null)
-        {
+        if (this.webDavClient === null) {
             this.loading = true;
             this.statusText = i18n.t('nextcloud-file-picker.auth-progress');
             const authUrl = this.authUrl + "?target-origin=" + encodeURIComponent(window.location.href);
@@ -264,7 +275,6 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                 "width=400,height=400,menubar=no,scrollbars=no,status=no,titlebar=no,toolbar=no");
         }
         else {
-
             this.loadDirectory(this.directoryPath, this.webDavClient);
 
         }
@@ -303,15 +313,14 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
      * @param path
      */
     loadDirectory(path) {
-        console.log("loaaadddding");
+        this.selectAllButton = true;
         this.loading = true;
         this.statusText = i18n.t('nextcloud-file-picker.loadpath-nextcloud-file-picker', {name: this.nextcloudName});
         this.lastDirectoryPath = this.directoryPath;
         this.directoryPath = path;
 
         // see https://github.com/perry-mitchell/webdav-client#getdirectorycontents
-        if (this.webDavClient === null)
-        {
+        if (this.webDavClient === null) {
             // client is broken reload try to reset & reconnect
             this.tabulatorTable.clearData();
             this.webDavClient = null;
@@ -369,8 +378,6 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                     this.loading = false;
                     this.statusText = reloadButton;
                 }
-
-
         });
     }
 
@@ -404,8 +411,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
      * @param files
      */
     downloadFiles(files) {
-        this.tabulatorTable.deselectRow();
         files.forEach((fileData) => this.downloadFile(fileData));
+        this.tabulatorTable.deselectRow();
     }
 
     /**
@@ -847,6 +854,24 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
         }
     }
 
+    /**
+     * Select all files from tabulator table
+     *
+     */
+    selectAll() {
+        this.selectAllButton = false;
+        this.tabulatorTable.selectRow(this.tabulatorTable.getRows().filter(row => row.getData().type != 'directory' && this.checkFileType(row.getData(), this.allowedMimeTypes)));
+    }
+
+    /**
+     * Deselect files from tabulator table
+     *
+     */
+    deselectAll() {
+        this.selectAllButton = true;
+        this.tabulatorTable.getSelectedRows().forEach(row => row.deselect());
+    }
+
     /**
      * Returns the parent directory path
      *
@@ -1120,6 +1145,12 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                 align-self: end;
             }
             
+            #select-all-wrapper{
+                padding-top: 10px;
+                white-space: nowrap;
+                align-self: end;
+            }
+            
             #replace-modal-box {
                 display: flex;
                 flex-direction: column;
@@ -1391,6 +1422,18 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                                 <dbp-icon name="plus" class="nextcloud-add-folder" id="add-folder-button"></dbp-icon>
                             </button>
                         </div>
+                        <div id="select-all-wrapper" class="${classMap({hidden: this.directoriesOnly})}">
+                            <button class="button ${classMap({hidden: !this.selectAllButton})}"
+                                    title="${i18n.t('nextcloud-file-picker.select-all-title')}"
+                                    @click="${() => { this.selectAll(); }}">
+                                    ${i18n.t('nextcloud-file-picker.select-all')}
+                            </button>
+                            <button class="button ${classMap({hidden: this.selectAllButton})}"
+                                    title="${i18n.t('nextcloud-file-picker.select-nothing-title')}"
+                                    @click="${() => { this.deselectAll(); }}">
+                                    ${i18n.t('nextcloud-file-picker.select-nothing')}
+                            </button>
+                        </div>
                     </div>
                     <table id="directory-content-table" class="force-no-select"></table>
                 </div>
diff --git a/packages/file-handling/src/file-source.js b/packages/file-handling/src/file-source.js
index 21a84c19..c6d1b50d 100644
--- a/packages/file-handling/src/file-source.js
+++ b/packages/file-handling/src/file-source.js
@@ -321,12 +321,14 @@ export class FileSource extends ScopedElementsMixin(DBPLitElement) {
         console.log("openDialog");
         this.loadWebdavDirectory();
         MicroModal.show(this._('#modal-picker'), {
-            onClose: modal => { this.isDialogOpen = false; }
+            onClose: modal => { this.isDialogOpen = false;
+                this._('#nextcloud-file-picker').selectAllButton = true;}
         });
     }
 
     closeDialog() {
         console.log("closeDialog");
+        this._('#nextcloud-file-picker').selectAllButton = true;
         MicroModal.close(this._('#modal-picker'));
     }
 
diff --git a/packages/file-handling/src/i18n/de/translation.json b/packages/file-handling/src/i18n/de/translation.json
index b2d227db..d1b473c9 100644
--- a/packages/file-handling/src/i18n/de/translation.json
+++ b/packages/file-handling/src/i18n/de/translation.json
@@ -70,6 +70,10 @@
     "upload-to": "Es wird nach {{- path}} hochgeladen ...",
     "readonly": "Sie dürfen in diesem Ordner nichts hochladen.",
     "onlycreate": "Sie dürfen in diesem Ordner nur neue Dateien erstellen.",
-    "onlyedit": "Sie dürfen in diesem Ordner nur Dateien bearbeiten."
+    "onlyedit": "Sie dürfen in diesem Ordner nur Dateien bearbeiten.",
+    "select-all": "Alle auswählen",
+    "select-all-title": "Alle verfügbaren Dateien in diesem Ordner auswählen",
+    "select-nothing": "Nichts auswählen",
+    "select-nothing-title": "Alle gewählten Dateien nicht mehr selektieren"
   }
 }
diff --git a/packages/file-handling/src/i18n/en/translation.json b/packages/file-handling/src/i18n/en/translation.json
index 125e45a8..d194fb94 100644
--- a/packages/file-handling/src/i18n/en/translation.json
+++ b/packages/file-handling/src/i18n/en/translation.json
@@ -70,7 +70,11 @@
     "upload-to": "Uploading to {{path}} ...",
     "readonly": "You are not allowed to uploade files in this directory.",
     "onlycreate": "You are only allowed to create new files in this directory.",
-    "onlyedit": "You are only allowed to edit files in this directory."
+    "onlyedit": "You are only allowed to edit files in this directory.",
+    "select-all": "Select all",
+    "select-all-title": "Select all files in this folder",
+    "select-nothing": "Select none",
+    "select-nothing-title": "Select no files"
 
   }
 }
-- 
GitLab