From 3e11337b3b4c36df20d5565d60d05995b0314363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Thu, 8 Nov 2018 13:30:39 +0100 Subject: [PATCH] Allow sorting in the file picker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- core/css/styles.scss | 41 +++++++++++++++++++++++++ core/js/oc-dialogs.js | 56 +++++++++++++++++++++++++++++----- core/templates/filepicker.html | 42 +++++++++++++++++++------ 3 files changed, 121 insertions(+), 18 deletions(-) diff --git a/core/css/styles.scss b/core/css/styles.scss index 9b7da39369..62d2bb45c9 100644 --- a/core/css/styles.scss +++ b/core/css/styles.scss @@ -773,6 +773,47 @@ code { margin-bottom: 50px; } .filelist { + thead { + tr { + border-bottom: 1px solid var(--color-border); + background-color: var(--color-main-background); + th { + width: auto; + border: none; + } + } + } + th .columntitle { + display: block; + padding: 15px; + height: 50px; + box-sizing: border-box; + -moz-box-sizing: border-box; + vertical-align: middle; + } + th .columntitle.name { + padding-left: 5px; + margin-left: 50px; + } + + th .sort-indicator { + width: 10px; + height: 8px; + margin-left: 5px; + display: inline-block; + vertical-align: text-bottom; + opacity: .3; + } + .sort-indicator.hidden, + th:hover .sort-indicator.hidden, + th:focus .sort-indicator.hidden { + visibility: hidden; + } + th:hover .sort-indicator.hidden, + th:focus .sort-indicator.hidden { + visibility: visible; + } + td { padding: 14px; border-bottom: 1px solid var(--color-border); diff --git a/core/js/oc-dialogs.js b/core/js/oc-dialogs.js index dee74502a6..e46dd9a57e 100644 --- a/core/js/oc-dialogs.js +++ b/core/js/oc-dialogs.js @@ -192,6 +192,9 @@ var OCdialogs = { */ filepicker:function(title, callback, multiselect, mimetypeFilter, modal, type) { var self = this; + + this.filepicker.sortField = 'name'; + this.filepicker.sortOrder = 'asc'; // avoid opening the picker twice if (this.filepicker.loading) { return; @@ -252,6 +255,7 @@ var OCdialogs = { } self.$filePicker.ready(function() { + self.$fileListHeader = self.$filePicker.find('.filelist thead tr'); self.$filelist = self.$filePicker.find('.filelist tbody'); self.$dirTree = self.$filePicker.find('.dirtree'); self.$dirTree.on('click', 'div:not(:last-child)', self, function (event) { @@ -260,6 +264,12 @@ var OCdialogs = { self.$filelist.on('click', 'tr', function(event) { self._handlePickerClick(event, $(this), type); }); + self.$fileListHeader.on('click', 'a', function(event) { + var dir = self.$filePicker.data('path'); + self.filepicker.sortField = $(event.currentTarget).data('sort'); + self.filepicker.sortOrder = self.filepicker.sortOrder === 'asc' ? 'desc' : 'asc'; + self._fillFilePicker(dir); + }); self._fillFilePicker(''); }); @@ -824,7 +834,7 @@ var OCdialogs = { var self = this; $.get(OC.filePath('core', 'templates', 'filepicker.html'), function(tmpl) { self.$filePickerTemplate = $(tmpl); - self.$listTmpl = self.$filePickerTemplate.find('.filelist tr:first-child').detach(); + self.$listTmpl = self.$filePickerTemplate.find('.filelist tbody tr:first-child').detach(); defer.resolve(self.$filePickerTemplate); }) .fail(function(jqXHR, textStatus, errorThrown) { @@ -892,20 +902,50 @@ var OCdialogs = { if (typeof(filter) === "string") { filter = [filter]; } + self.$fileListHeader.find('.sort-indicator').addClass('hidden').removeClass('icon-triangle-n').removeClass('icon-triangle-s'); + self.$fileListHeader.find('[data-sort=' + self.filepicker.sortField + '] .sort-indicator').removeClass('hidden'); + if (self.filepicker.sortOrder === 'asc') { + self.$fileListHeader.find('[data-sort=' + self.filepicker.sortField + '] .sort-indicator').addClass('icon-triangle-s'); + } else { + self.$fileListHeader.find('[data-sort=' + self.filepicker.sortField + '] .sort-indicator').addClass('icon-triangle-n'); + } self.filepicker.filesClient.getFolderContents(dir).then(function(status, files) { if (filter && filter.length > 0 && filter.indexOf('*') === -1) { files = files.filter(function (file) { return file.type === 'dir' || filter.indexOf(file.mimetype) !== -1; }); } - files = files.sort(function(a, b) { - if (a.type === 'dir' && b.type !== 'dir') { - return -1; - } else if(a.type !== 'dir' && b.type === 'dir') { - return 1; - } else { - return a.name.localeCompare(b.name, undefined, {numeric: true}); + + var Comparators = { + name: function(fileInfo1, fileInfo2) { + if (fileInfo1.type === 'dir' && fileInfo2.type !== 'dir') { + return -1; + } + if (fileInfo1.type !== 'dir' && fileInfo2.type === 'dir') { + return 1; + } + return OC.Util.naturalSortCompare(fileInfo1.name, fileInfo2.name); + }, + size: function(fileInfo1, fileInfo2) { + return fileInfo1.size - fileInfo2.size; + }, + mtime: function(fileInfo1, fileInfo2) { + return fileInfo1.mtime - fileInfo2.mtime; } + }; + var comparator = Comparators[self.filepicker.sortField] || Comparators.name; + files = files.sort(function(file1, file2) { + var isFavorite = function(fileInfo) { + return fileInfo.tags && fileInfo.tags.indexOf(OC.TAG_FAVORITE) >= 0; + }; + + if (isFavorite(file1) && !isFavorite(file2)) { + return -1; + } else if (!isFavorite(file1) && isFavorite(file2)) { + return 1; + } + + return self.filepicker.sortOrder === 'asc' ? comparator(file1, file2) : -comparator(file1, file2); }); self._fillSlug(); diff --git a/core/templates/filepicker.html b/core/templates/filepicker.html index 4c66dfc707..090e6bce77 100644 --- a/core/templates/filepicker.html +++ b/core/templates/filepicker.html @@ -8,17 +8,39 @@

{emptytext}

+ + + + + + + - - - - - + + + + +
+ + + + Size + + + + Modified + +
{filename} - - {size} - {date}
{filename} + + {size} + {date}