From 688f6162daeec724c537f9c283092f45b29b05f2 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Thu, 3 Apr 2014 20:57:06 +0200 Subject: Add sorting to files list, trashbin and public files --- apps/files/js/filelist.js | 139 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 120 insertions(+), 19 deletions(-) (limited to 'apps/files/js') diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 40ec898635e..1c24ca45996 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -11,6 +11,9 @@ /* global OC, t, n, FileList, FileActions, Files, FileSummary, BreadCrumb */ /* global dragOptions, folderDropOptions */ window.FileList = { + SORT_INDICATOR_ASC_CLASS: 'icon-triangle-s', + SORT_INDICATOR_DESC_CLASS: 'icon-triangle-n', + appName: t('files', 'Files'), isEmpty: true, useUndo:true, @@ -45,18 +48,19 @@ window.FileList = { _selectionSummary: null, /** - * Compare two file info objects, sorting by - * folders first, then by name. + * Sort attribute */ - _fileInfoCompare: function(fileInfo1, fileInfo2) { - if (fileInfo1.type === 'dir' && fileInfo2.type !== 'dir') { - return -1; - } - if (fileInfo1.type !== 'dir' && fileInfo2.type === 'dir') { - return 1; - } - return fileInfo1.name.localeCompare(fileInfo2.name); - }, + _sort: 'name', + + /** + * Sort direction: 'asc' or 'desc' + */ + _sortDirection: 'asc', + + /** + * Sort comparator function for the current sort + */ + _sortComparator: null, /** * Initialize the file list and its components @@ -76,6 +80,10 @@ window.FileList = { this.fileSummary = this._createSummary(); + this._sort = 'name'; + this._sortDirection = 'asc'; + this._sortComparator = this.Comparators.name; + this.breadcrumb = new BreadCrumb({ onClick: this._onClickBreadCrumb, onDrop: _.bind(this._onDropOnBreadCrumb, this), @@ -86,6 +94,8 @@ window.FileList = { $('#controls').prepend(this.breadcrumb.$el); + this.$el.find('thead th .columntitle').click(_.bind(this._onClickHeader, this)); + $(window).resize(function() { // TODO: debounce this ? var width = $(this).width(); @@ -236,6 +246,27 @@ window.FileList = { return false; }, + /** + * Event handler when clicking on a table header + */ + _onClickHeader: function(e) { + var $target = $(e.target); + var sort; + if (!$target.is('a')) { + $target = $target.closest('a'); + } + sort = $target.attr('data-sort'); + if (sort) { + if (this._sort === sort) { + this.setSort(sort, (this._sortDirection === 'desc')?'asc':'desc'); + } + else { + this.setSort(sort, 'asc'); + } + this.reload(); + } + }, + /** * Event handler when clicking on a bread crumb */ @@ -722,6 +753,27 @@ window.FileList = { } this.breadcrumb.setDirectory(this.getCurrentDirectory()); }, + /** + * Sets the current sorting and refreshes the list + * + * @param sort sort attribute name + * @param direction sort direction, one of "asc" or "desc" + */ + setSort: function(sort, direction) { + var comparator = this.Comparators[sort] || this.Comparators.name; + this._sort = sort; + this._sortDirection = (direction === 'desc')?'desc':'asc'; + this._sortComparator = comparator; + if (direction === 'desc') { + this._sortComparator = function(fileInfo1, fileInfo2) { + return -comparator(fileInfo1, fileInfo2); + }; + } + this.$el.find('thead th .sort-indicator') + .removeClass(this.SORT_INDICATOR_ASC_CLASS + ' ' + this.SORT_INDICATOR_DESC_CLASS); + this.$el.find('thead th.column-' + sort + ' .sort-indicator') + .addClass(direction === 'desc' ? this.SORT_INDICATOR_DESC_CLASS : this.SORT_INDICATOR_ASC_CLASS); + }, /** * @brief Reloads the file list using ajax call */ @@ -733,7 +785,9 @@ window.FileList = { FileList._reloadCall = $.ajax({ url: Files.getAjaxUrl('list'), data: { - dir : $('#dir').val() + dir: $('#dir').val(), + sort: FileList._sort, + sortdirection: FileList._sortDirection }, error: function(result) { FileList.reloadCallback(result); @@ -859,7 +913,7 @@ window.FileList = { */ _findInsertionIndex: function(fileData) { var index = 0; - while (index < this.files.length && this._fileInfoCompare(fileData, this.files[index]) > 0) { + while (index < this.files.length && this._sortComparator(fileData, this.files[index]) > 0) { index++; } return index; @@ -1218,15 +1272,15 @@ window.FileList = { updateSelectionSummary: function() { var summary = this._selectionSummary.summary; if (summary.totalFiles === 0 && summary.totalDirs === 0) { - $('#headerName span.name').text(t('files','Name')); - $('#headerSize').text(t('files','Size')); - $('#modified').text(t('files','Modified')); + $('#headerName a.name>span:first').text(t('files','Name')); + $('#headerSize a>span:first').text(t('files','Size')); + $('#modified a>span:first').text(t('files','Modified')); $('table').removeClass('multiselect'); $('.selectedActions').addClass('hidden'); } else { $('.selectedActions').removeClass('hidden'); - $('#headerSize').text(OC.Util.humanFileSize(summary.totalSize)); + $('#headerSize a>span:first').text(OC.Util.humanFileSize(summary.totalSize)); var selection = ''; if (summary.totalDirs > 0) { selection += n('files', '%n folder', '%n folders', summary.totalDirs); @@ -1237,8 +1291,8 @@ window.FileList = { if (summary.totalFiles > 0) { selection += n('files', '%n file', '%n files', summary.totalFiles); } - $('#headerName span.name').text(selection); - $('#modified').text(''); + $('#headerName a.name>span:first').text(selection); + $('#modified a>span:first').text(''); $('table').addClass('multiselect'); } }, @@ -1529,6 +1583,7 @@ $(document).ready(function() { targetDir = parseCurrentDirFromUrl(); } if (targetDir) { + FileList.setSort('name', 'asc'); FileList.changeDirectory(targetDir, false); } }; @@ -1542,3 +1597,49 @@ $(document).ready(function() { }, 0); }); +/** + * Sort comparators. + */ +FileList.Comparators = { + /** + * Compares two file infos by name, making directories appear + * first. + * + * @param fileInfo1 file info + * @param fileInfo2 file info + * @return -1 if the first file must appear before the second one, + * 0 if they are identify, 1 otherwise. + */ + name: function(fileInfo1, fileInfo2) { + if (fileInfo1.type === 'dir' && fileInfo2.type !== 'dir') { + return -1; + } + if (fileInfo1.type !== 'dir' && fileInfo2.type === 'dir') { + return 1; + } + return fileInfo1.name.localeCompare(fileInfo2.name); + }, + /** + * Compares two file infos by size. + * + * @param fileInfo1 file info + * @param fileInfo2 file info + * @return -1 if the first file must appear before the second one, + * 0 if they are identify, 1 otherwise. + */ + size: function(fileInfo1, fileInfo2) { + return fileInfo1.size - fileInfo2.size; + }, + /** + * Compares two file infos by timestamp. + * + * @param fileInfo1 file info + * @param fileInfo2 file info + * @return -1 if the first file must appear before the second one, + * 0 if they are identify, 1 otherwise. + */ + mtime: function(fileInfo1, fileInfo2) { + return fileInfo1.mtime - fileInfo2.mtime; + } +}; + -- cgit v1.2.3