From e315bf544f4dd744fb33153466ae329ff9e9fccf Mon Sep 17 00:00:00 2001
From: Christina Toegl <toegl@tugraz.at>
Date: Tue, 15 Feb 2022 19:22:31 +0100
Subject: [PATCH] Replace inline new folder creation with modal dialog

---
 .../src/i18n/de/translation.json              |   7 +-
 .../src/i18n/en/translation.json              |   7 +-
 .../src/nextcloud-file-picker.js              | 252 ++++++++++--------
 3 files changed, 160 insertions(+), 106 deletions(-)

diff --git a/packages/file-handling/src/i18n/de/translation.json b/packages/file-handling/src/i18n/de/translation.json
index 9fb3f2a2..973ba0b8 100644
--- a/packages/file-handling/src/i18n/de/translation.json
+++ b/packages/file-handling/src/i18n/de/translation.json
@@ -85,7 +85,12 @@
         "recent-files-title": "Neueste Dateien",
         "my-recent-files-title": "Meine neuesten Dateien",
         "my-recent-files-link-text": "Meine neuesten Dateien",
-        "all-recent-files-link-text": "Alle neuesten Dateien"
+        "all-recent-files-link-text": "Alle neuesten Dateien",
+        "new-folder-dialog-title": "Neuen Ordner erstellen",
+        "new-folder-dialog-label": "Name eingeben:",
+        "new-folder-dialog-button-ok": "Ãœbernehmen",
+        "new-folder-dialog-button-cancel": "Abbrechen",
+        "new-folder-dialog-default-name": "Neuer Ordner"
     },
     "clipboard": {
         "add-files": "Dateien der Zwischenablage hinzufügen",
diff --git a/packages/file-handling/src/i18n/en/translation.json b/packages/file-handling/src/i18n/en/translation.json
index 0187b008..08885cb1 100644
--- a/packages/file-handling/src/i18n/en/translation.json
+++ b/packages/file-handling/src/i18n/en/translation.json
@@ -86,7 +86,12 @@
         "recent-files-title": "Recent Files",
         "my-recent-files-title": "My Recent Files",
         "my-recent-files-link-text": "My Recent Files",
-        "all-recent-files-link-text": "All Recent Files"
+        "all-recent-files-link-text": "All Recent Files",
+        "new-folder-dialog-title": "Create a new folder",
+        "new-folder-dialog-label": "Enter a name:",
+        "new-folder-dialog-button-ok": "Apply",
+        "new-folder-dialog-button-cancel": "Cancel",
+        "new-folder-dialog-default-name": "New folder"
     },
     "clipboard": {
         "add-files": "Add files to clipboard",
diff --git a/packages/file-handling/src/nextcloud-file-picker.js b/packages/file-handling/src/nextcloud-file-picker.js
index 018d2e12..bd6266ed 100644
--- a/packages/file-handling/src/nextcloud-file-picker.js
+++ b/packages/file-handling/src/nextcloud-file-picker.js
@@ -1881,116 +1881,63 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
         }
     }
 
+    /**
+     * Opens new folder modal
+     *
+     */
     addOpenFolderTableEntry() {
         const i18n = this._i18n;
+
+        // Avoid row animation for previously created folders
         if (this._('.addRowAnimation')) {
             this._('.addRowAnimation').classList.remove('addRowAnimation');
         }
-        this.disableRowClick = true;
-
-        const d = new Date();
-        let props = {permissions: 'RGDNVCK'};
-        var row = {
-            type: 'directory',
-            filename: '',
-            basename: '',
-            lastmod: d,
-            props: props,
-        };
 
-        const that = this;
-
-        this.tabulatorTable
-            .addRow(row, true, 1)
-            .then(() => {
-                that._('#directory-content-table')
-                    .querySelector(
-                        'div.tabulator-tableHolder > div.tabulator-table > div.tabulator-row:nth-child(1)'
-                    )
-                    .setAttribute('id', 'new-folder-row');
-                that._('#new-folder-row').classList.toggle('highlighted');
+        this.disableRowClick = true;
 
-                that._('#new-folder-row')
-                    .querySelector(
-                        'div.tabulator-cell:nth-child(1) > div > span.tabulator-responsive-collapse-toggle-open'
-                    )
-                    .classList.add('new-folder-selected');
-                that._('#new-folder-row')
-                    .querySelector(
-                        'div.tabulator-cell:nth-child(1) > div > span.tabulator-responsive-collapse-toggle-close'
-                    )
-                    .classList.add('new-folder-selected');
+        /**
+            that._('#new-folder-row-btn').addEventListener("click", event => {
+                that.addNewFolder();
+                event.stopPropagation();
+            });
 
-                // overwrite date
-                that
-                    ._('#new-folder-row')
-                    .querySelector('div.tabulator-cell:nth-child(6)').innerText = '';
-                if (
-                    that
-                        ._('#new-folder-row')
-                        .querySelector(
-                            'div.tabulator-responsive-collapse > table > tbody > tr:nth-child(1) > td:nth-child(2)'
-                        )
-                ) {
-                    that
-                        ._('#new-folder-row')
-                        .querySelector(
-                            'div.tabulator-responsive-collapse > table > tbody > tr:nth-child(1) > td:nth-child(2)'
-                        ).innerText = '';
+            that._('#new-folder-row').addEventListener('keydown', (event) => {
+                if (event.key === 'Escape') {
+                    that.deleteNewFolderEntry();
+                    event.stopPropagation();
                 }
+            });
 
-                // add input field
-                that._('#new-folder-row')
-                    .querySelector('div.tabulator-cell:nth-child(3)')
-                    .setAttribute('id', 'new-folder-cell');
-                that._('#new-folder-cell').innerHTML =
-                    '<input type="text" class="input" name="tf-new-folder" id="tf-new-folder" value="' +
-                    i18n.t('nextcloud-file-picker.new-folder-placeholder') +
-                    '" />';
-
-                let mimeElement = that._('#new-folder-row').querySelector('div.tabulator-cell[tabulator-field="mime"]');
-                if (window.getComputedStyle(mimeElement).display === "none") {
-                    that._('#tf-new-folder').classList.add('smaller');
-                }
+            document.addEventListener('keydown', this.boundCancelNewFolderHandler);
 
-                const icon_tag = that.getScopedTagName("dbp-icon");
-                let html = `<${icon_tag} name="checkmark-circle" class="new-folder-checkmark-icon"></${icon_tag}>`;
-                that._('#new-folder-row').innerHTML  += '<button class="button" title="" id="new-folder-row-btn">' + html + '</button>';
-                    
-                that._('#tf-new-folder').addEventListener('keydown', ({key}) => {
-                    if (key === 'Enter') {
-                        that.addNewFolder();
-                    }
-                });
+            that._('#new-folder-row').addEventListener('click', (event) => {
+                event.stopPropagation();
+            });
+        */
 
-                that._('#new-folder-row-btn').addEventListener("click", event => {
-                    that.addNewFolder();
-                    event.stopPropagation();
-                });
+        // Click handler should ignore first click
+        this.initateOpenNewFolder = true;
 
-                that._('#new-folder-row').addEventListener('keydown', (event) => {
-                    if (event.key === 'Escape') {
-                        that.deleteNewFolderEntry();
-                        event.stopPropagation();
-                    }
-                });
+        // give the browser a chance to paint before selecting
+        setTimeout(() => {
+            this._('#tf-new-folder-dialog').select();
+        }, 0);
 
-                document.addEventListener('keydown', this.boundCancelNewFolderHandler);
+        MicroModal.show(this._('#new-folder-modal'), {
+            disableScroll: true,
+        });
 
-                that._('#new-folder-row').addEventListener('click', (event) => {
-                    event.stopPropagation();
-                });
+        this._('#tf-new-folder-dialog').addEventListener('keydown', ({key}) => { //TODO since we do not destroy the modal it is enough to do this once
+            if (key === 'Enter') {
+                this.addNewFolder();
+            }
+        });
 
-                that.initateOpenNewFolder = true;
+        this._('#new-folder-modal-box').addEventListener('click', (event) => { //TODO same here?
+            event.stopPropagation();
+        });
 
-                // give the browser a chance to paint before selecting
-                setTimeout(() => {
-                    this._('#tf-new-folder').select();
-                }, 0);
-            })
-            .catch((error) => {
-                console.log('error', error);
-            });
+        document.addEventListener('keydown', this.boundCancelNewFolderHandler);
 
         // during folder creation it should not be possible to click something
         document.addEventListener('click', this.boundClickOutsideNewFolderHandler);
@@ -2004,27 +1951,25 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
     }
 
     deleteNewFolderEntry() {
+        const i18n = this._i18n;
+
         if (this.initateOpenNewFolder) {
             this.initateOpenNewFolder = false;
             return;
         }
 
-        this._('#new-folder-row').classList.toggle('highlighted');
-
-        var row = this.tabulatorTable.getRowFromPosition(0);
-        if (row) {
-            row.delete();
-        }
-
         this.disableRowClick = false;
+        MicroModal.close(this._('#new-folder-modal'));
+
         document.removeEventListener('click', this.boundClickOutsideNewFolderHandler);
         document.removeEventListener('keydown', this.boundCancelNewFolderHandler);
+        this._('#tf-new-folder-dialog').value = i18n.t('nextcloud-file-picker.new-folder-dialog-default-name');
     }
 
     addNewFolder() {
         const i18n = this._i18n;
-        if (this._('#tf-new-folder').value !== '') {
-            let folderName = this._('#tf-new-folder').value;
+        if (this._('#tf-new-folder-dialog').value !== '') {
+            let folderName = this._('#tf-new-folder-dialog').value;
             if (typeof this.directoryPath === 'undefined') {
                 this.directoryPath = '';
             }
@@ -3060,6 +3005,43 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                 font-size: 1.4em;
             }
 
+            #new-folder-modal-box {
+                display: flex;
+                flex-direction: column;
+                justify-content: space-between;
+                padding: 15px 20px 20px 20px;
+                max-height: 190px;
+                min-height: 190px;
+                min-width: 320px;
+                max-width: 400px;
+            }
+
+            #new-folder-modal-box header.modal-header {
+                padding: 0px;
+                display: flex;
+                justify-content: space-between;
+            }
+
+            #new-folder-modal-box footer.modal-footer .modal-footer-btn  {
+                padding: 0px;
+                display: flex;
+                justify-content: space-between;
+            }
+
+            #new-folder-modal-content {
+                display: block;
+                padding-left: 0px;
+                padding-right: 0px;
+            }
+
+            #new-folder-modal-content div .input {
+                width: 100%;
+            }
+
+            #new-folder-modal-content .nf-label {
+                padding-bottom: 1px;
+            }
+
             @media only screen and (orientation: portrait) and (max-width: 768px) {
                 .breadcrumb-arrow {
                     font-size: 1.6em;
@@ -3355,8 +3337,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                                         )}
                                     </a>
                                 </li>
-                                <li class="${classMap({hidden: !this.directoriesOnly,
-                                            inactive:
+                                <li class="${classMap({inactive:
                                                 this.isInRecent ||
                                                 this.isInFavorites ||
                                                 this.isInFilteredRecent ||
@@ -3575,6 +3556,69 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                     </div>
                 </div>
             </div>
+
+            <div class="modal micromodal-slide" id="new-folder-modal" aria-hidden="true">
+                <div class="modal-overlay" tabindex="-2" data-micromodal-close>
+                    <div
+                        class="modal-container"
+                        id="new-folder-modal-box"
+                        role="dialog"
+                        aria-modal="true"
+                        aria-labelledby="new-folder-modal-title">
+                        <header class="modal-header">
+                            <button
+                                title="${i18n.t('file-sink.modal-close')}"
+                                class="modal-close"
+                                aria-label="Close modal"
+                                @click="${() => {
+                                    this.deleteNewFolderEntry();
+                                }}">
+                                <dbp-icon
+                                    title="${i18n.t('file-sink.modal-close')}"
+                                    name="close"
+                                    class="close-icon"></dbp-icon>
+                            </button>
+                            <h3 id="new-folder-modal-title">
+                                ${i18n.t('nextcloud-file-picker.new-folder-dialog-title')}
+                            </h3>
+                        </header>
+                        <main class="modal-content" id="new-folder-modal-content">
+                            <div class="nf-label">
+                                ${i18n.t('nextcloud-file-picker.new-folder-dialog-label')}
+                            </div>
+                            <div>
+                                <input 
+                                    type="text" 
+                                    class="input" 
+                                    name="tf-new-folder-dialog" 
+                                    id="tf-new-folder-dialog" 
+                                    value="${i18n.t('nextcloud-file-picker.new-folder-dialog-default-name')}" 
+                                />
+                            </div>
+                        </main>
+                        <footer class="modal-footer">
+                            <div class="modal-footer-btn">
+                                <button
+                                    class="button"
+                                    data-micromodal-close
+                                    aria-label="Close this dialog window"
+                                    @click="${() => {
+                                        this.deleteNewFolderEntry();
+                                    }}">
+                                    ${i18n.t('nextcloud-file-picker.new-folder-dialog-button-cancel')}
+                                </button>
+                                <button
+                                    class="button select-button is-primary"
+                                    @click="${() => {
+                                        this.addNewFolder();
+                                    }}">
+                                    ${i18n.t('nextcloud-file-picker.new-folder-dialog-button-ok')}
+                                </button>
+                            </div>
+                        </footer>
+                    </div>
+                </div>
+            </div>
         `;
     }
 }
-- 
GitLab