Merge pull request #8041 from owncloud/files-sortcolumns
File list sorting by clicking on column headers
This commit is contained in:
commit
9a9665f361
|
@ -17,8 +17,11 @@ $baseUrl = OCP\Util::linkTo('files', 'index.php') . '?dir=';
|
||||||
|
|
||||||
$permissions = $dirInfo->getPermissions();
|
$permissions = $dirInfo->getPermissions();
|
||||||
|
|
||||||
|
$sortAttribute = isset( $_GET['sort'] ) ? $_GET['sort'] : 'name';
|
||||||
|
$sortDirection = isset( $_GET['sortdirection'] ) ? ($_GET['sortdirection'] === 'desc') : false;
|
||||||
|
|
||||||
// make filelist
|
// make filelist
|
||||||
$files = \OCA\Files\Helper::getFiles($dir);
|
$files = \OCA\Files\Helper::getFiles($dir, $sortAttribute, $sortDirection);
|
||||||
|
|
||||||
$data['directory'] = $dir;
|
$data['directory'] = $dir;
|
||||||
$data['files'] = \OCA\Files\Helper::formatFileInfos($files);
|
$data['files'] = \OCA\Files\Helper::formatFileInfos($files);
|
||||||
|
|
|
@ -116,10 +116,29 @@ tr:hover span.extension {
|
||||||
|
|
||||||
table tr.mouseOver td { background-color:#eee; }
|
table tr.mouseOver td { background-color:#eee; }
|
||||||
table th { height:24px; padding:0 8px; color:#999; }
|
table th { height:24px; padding:0 8px; color:#999; }
|
||||||
table th .name {
|
table th .columntitle {
|
||||||
position: absolute;
|
display: inline-block;
|
||||||
left: 55px;
|
padding: 15px;
|
||||||
top: 15px;
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
table th .columntitle.name {
|
||||||
|
padding-left: 5px;
|
||||||
|
margin-left: 50px;
|
||||||
|
max-width: 300px;
|
||||||
|
}
|
||||||
|
/* hover effect on sortable column */
|
||||||
|
table th a.columntitle:hover {
|
||||||
|
background-color: #F0F0F0;
|
||||||
|
}
|
||||||
|
table th .sort-indicator {
|
||||||
|
width: 10px;
|
||||||
|
height: 8px;
|
||||||
|
margin-left: 10px;
|
||||||
|
display: inline-block;
|
||||||
}
|
}
|
||||||
table th, table td { border-bottom:1px solid #ddd; text-align:left; font-weight:normal; }
|
table th, table td { border-bottom:1px solid #ddd; text-align:left; font-weight:normal; }
|
||||||
table td {
|
table td {
|
||||||
|
@ -139,8 +158,11 @@ table th#headerName {
|
||||||
}
|
}
|
||||||
table th#headerSize, table td.filesize {
|
table th#headerSize, table td.filesize {
|
||||||
min-width: 48px;
|
min-width: 48px;
|
||||||
padding: 0 16px;
|
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
table table td.filesize {
|
||||||
|
padding: 0 16px;
|
||||||
}
|
}
|
||||||
table th#headerDate, table td.date {
|
table th#headerDate, table td.date {
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
|
@ -197,10 +219,6 @@ table td.filename input.filename {
|
||||||
table td.filename a, table td.login, table td.logout, table td.download, table td.upload, table td.create, table td.delete { padding:3px 8px 8px 3px; }
|
table td.filename a, table td.login, table td.logout, table td.download, table td.upload, table td.create, table td.delete { padding:3px 8px 8px 3px; }
|
||||||
table td.filename .nametext, .uploadtext, .modified { float:left; padding:14px 0; }
|
table td.filename .nametext, .uploadtext, .modified { float:left; padding:14px 0; }
|
||||||
|
|
||||||
#modified {
|
|
||||||
position: absolute;
|
|
||||||
top: 15px;
|
|
||||||
}
|
|
||||||
.modified {
|
.modified {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
/* global OC, t, n, FileList, FileActions, Files, FileSummary, BreadCrumb */
|
/* global OC, t, n, FileList, FileActions, Files, FileSummary, BreadCrumb */
|
||||||
/* global dragOptions, folderDropOptions */
|
/* global dragOptions, folderDropOptions */
|
||||||
window.FileList = {
|
window.FileList = {
|
||||||
|
SORT_INDICATOR_ASC_CLASS: 'icon-triangle-s',
|
||||||
|
SORT_INDICATOR_DESC_CLASS: 'icon-triangle-n',
|
||||||
|
|
||||||
appName: t('files', 'Files'),
|
appName: t('files', 'Files'),
|
||||||
isEmpty: true,
|
isEmpty: true,
|
||||||
useUndo:true,
|
useUndo:true,
|
||||||
|
@ -45,18 +48,19 @@ window.FileList = {
|
||||||
_selectionSummary: null,
|
_selectionSummary: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare two file info objects, sorting by
|
* Sort attribute
|
||||||
* folders first, then by name.
|
|
||||||
*/
|
*/
|
||||||
_fileInfoCompare: function(fileInfo1, fileInfo2) {
|
_sort: 'name',
|
||||||
if (fileInfo1.type === 'dir' && fileInfo2.type !== 'dir') {
|
|
||||||
return -1;
|
/**
|
||||||
}
|
* Sort direction: 'asc' or 'desc'
|
||||||
if (fileInfo1.type !== 'dir' && fileInfo2.type === 'dir') {
|
*/
|
||||||
return 1;
|
_sortDirection: 'asc',
|
||||||
}
|
|
||||||
return fileInfo1.name.localeCompare(fileInfo2.name);
|
/**
|
||||||
},
|
* Sort comparator function for the current sort
|
||||||
|
*/
|
||||||
|
_sortComparator: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the file list and its components
|
* Initialize the file list and its components
|
||||||
|
@ -76,6 +80,8 @@ window.FileList = {
|
||||||
|
|
||||||
this.fileSummary = this._createSummary();
|
this.fileSummary = this._createSummary();
|
||||||
|
|
||||||
|
this.setSort('name', 'asc');
|
||||||
|
|
||||||
this.breadcrumb = new BreadCrumb({
|
this.breadcrumb = new BreadCrumb({
|
||||||
onClick: this._onClickBreadCrumb,
|
onClick: this._onClickBreadCrumb,
|
||||||
onDrop: _.bind(this._onDropOnBreadCrumb, this),
|
onDrop: _.bind(this._onDropOnBreadCrumb, this),
|
||||||
|
@ -86,6 +92,8 @@ window.FileList = {
|
||||||
|
|
||||||
$('#controls').prepend(this.breadcrumb.$el);
|
$('#controls').prepend(this.breadcrumb.$el);
|
||||||
|
|
||||||
|
this.$el.find('thead th .columntitle').click(_.bind(this._onClickHeader, this));
|
||||||
|
|
||||||
$(window).resize(function() {
|
$(window).resize(function() {
|
||||||
// TODO: debounce this ?
|
// TODO: debounce this ?
|
||||||
var width = $(this).width();
|
var width = $(this).width();
|
||||||
|
@ -236,6 +244,27 @@ window.FileList = {
|
||||||
return false;
|
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
|
* Event handler when clicking on a bread crumb
|
||||||
*/
|
*/
|
||||||
|
@ -685,8 +714,6 @@ window.FileList = {
|
||||||
previousDir: currentDir
|
previousDir: currentDir
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
this._selectedFiles = {};
|
|
||||||
this._selectionSummary.clear();
|
|
||||||
this.reload();
|
this.reload();
|
||||||
},
|
},
|
||||||
linkTo: function(dir) {
|
linkTo: function(dir) {
|
||||||
|
@ -722,10 +749,34 @@ window.FileList = {
|
||||||
}
|
}
|
||||||
this.breadcrumb.setDirectory(this.getCurrentDirectory());
|
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
|
* @brief Reloads the file list using ajax call
|
||||||
*/
|
*/
|
||||||
reload: function() {
|
reload: function() {
|
||||||
|
this._selectedFiles = {};
|
||||||
|
this._selectionSummary.clear();
|
||||||
|
this.$el.find('#select_all').prop('checked', false);
|
||||||
FileList.showMask();
|
FileList.showMask();
|
||||||
if (FileList._reloadCall) {
|
if (FileList._reloadCall) {
|
||||||
FileList._reloadCall.abort();
|
FileList._reloadCall.abort();
|
||||||
|
@ -733,7 +784,9 @@ window.FileList = {
|
||||||
FileList._reloadCall = $.ajax({
|
FileList._reloadCall = $.ajax({
|
||||||
url: Files.getAjaxUrl('list'),
|
url: Files.getAjaxUrl('list'),
|
||||||
data: {
|
data: {
|
||||||
dir : $('#dir').val()
|
dir: $('#dir').val(),
|
||||||
|
sort: FileList._sort,
|
||||||
|
sortdirection: FileList._sortDirection
|
||||||
},
|
},
|
||||||
error: function(result) {
|
error: function(result) {
|
||||||
FileList.reloadCallback(result);
|
FileList.reloadCallback(result);
|
||||||
|
@ -859,7 +912,7 @@ window.FileList = {
|
||||||
*/
|
*/
|
||||||
_findInsertionIndex: function(fileData) {
|
_findInsertionIndex: function(fileData) {
|
||||||
var index = 0;
|
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++;
|
index++;
|
||||||
}
|
}
|
||||||
return index;
|
return index;
|
||||||
|
@ -1221,15 +1274,15 @@ window.FileList = {
|
||||||
updateSelectionSummary: function() {
|
updateSelectionSummary: function() {
|
||||||
var summary = this._selectionSummary.summary;
|
var summary = this._selectionSummary.summary;
|
||||||
if (summary.totalFiles === 0 && summary.totalDirs === 0) {
|
if (summary.totalFiles === 0 && summary.totalDirs === 0) {
|
||||||
$('#headerName span.name').text(t('files','Name'));
|
$('#headerName a.name>span:first').text(t('files','Name'));
|
||||||
$('#headerSize').text(t('files','Size'));
|
$('#headerSize a>span:first').text(t('files','Size'));
|
||||||
$('#modified').text(t('files','Modified'));
|
$('#modified a>span:first').text(t('files','Modified'));
|
||||||
$('table').removeClass('multiselect');
|
$('table').removeClass('multiselect');
|
||||||
$('.selectedActions').addClass('hidden');
|
$('.selectedActions').addClass('hidden');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$('.selectedActions').removeClass('hidden');
|
$('.selectedActions').removeClass('hidden');
|
||||||
$('#headerSize').text(OC.Util.humanFileSize(summary.totalSize));
|
$('#headerSize a>span:first').text(OC.Util.humanFileSize(summary.totalSize));
|
||||||
var selection = '';
|
var selection = '';
|
||||||
if (summary.totalDirs > 0) {
|
if (summary.totalDirs > 0) {
|
||||||
selection += n('files', '%n folder', '%n folders', summary.totalDirs);
|
selection += n('files', '%n folder', '%n folders', summary.totalDirs);
|
||||||
|
@ -1240,8 +1293,8 @@ window.FileList = {
|
||||||
if (summary.totalFiles > 0) {
|
if (summary.totalFiles > 0) {
|
||||||
selection += n('files', '%n file', '%n files', summary.totalFiles);
|
selection += n('files', '%n file', '%n files', summary.totalFiles);
|
||||||
}
|
}
|
||||||
$('#headerName span.name').text(selection);
|
$('#headerName a.name>span:first').text(selection);
|
||||||
$('#modified').text('');
|
$('#modified a>span:first').text('');
|
||||||
$('table').addClass('multiselect');
|
$('table').addClass('multiselect');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1545,3 +1598,49 @@ $(document).ready(function() {
|
||||||
}, 0);
|
}, 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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,16 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or
|
||||||
|
* later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace OCA\Files;
|
namespace OCA\Files;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class for manipulating file information
|
||||||
|
*/
|
||||||
class Helper
|
class Helper
|
||||||
{
|
{
|
||||||
public static function buildFileStorageStatistics($dir) {
|
public static function buildFileStorageStatistics($dir) {
|
||||||
|
@ -9,12 +18,12 @@ class Helper
|
||||||
$storageInfo = \OC_Helper::getStorageInfo($dir);
|
$storageInfo = \OC_Helper::getStorageInfo($dir);
|
||||||
|
|
||||||
$l = new \OC_L10N('files');
|
$l = new \OC_L10N('files');
|
||||||
$maxUploadFilesize = \OCP\Util::maxUploadFilesize($dir, $storageInfo['free']);
|
$maxUploadFileSize = \OCP\Util::maxUploadFilesize($dir, $storageInfo['free']);
|
||||||
$maxHumanFilesize = \OCP\Util::humanFileSize($maxUploadFilesize);
|
$maxHumanFileSize = \OCP\Util::humanFileSize($maxUploadFileSize);
|
||||||
$maxHumanFilesize = $l->t('Upload (max. %s)', array($maxHumanFilesize));
|
$maxHumanFileSize = $l->t('Upload (max. %s)', array($maxHumanFileSize));
|
||||||
|
|
||||||
return array('uploadMaxFilesize' => $maxUploadFilesize,
|
return array('uploadMaxFilesize' => $maxUploadFileSize,
|
||||||
'maxHumanFilesize' => $maxHumanFilesize,
|
'maxHumanFilesize' => $maxHumanFileSize,
|
||||||
'freeSpace' => $storageInfo['free'],
|
'freeSpace' => $storageInfo['free'],
|
||||||
'usedSpacePercent' => (int)$storageInfo['relative']);
|
'usedSpacePercent' => (int)$storageInfo['relative']);
|
||||||
}
|
}
|
||||||
|
@ -27,7 +36,6 @@ class Helper
|
||||||
*/
|
*/
|
||||||
public static function determineIcon($file) {
|
public static function determineIcon($file) {
|
||||||
if($file['type'] === 'dir') {
|
if($file['type'] === 'dir') {
|
||||||
$dir = $file['directory'];
|
|
||||||
$icon = \OC_Helper::mimetypeIcon('dir');
|
$icon = \OC_Helper::mimetypeIcon('dir');
|
||||||
$absPath = $file->getPath();
|
$absPath = $file->getPath();
|
||||||
$mount = \OC\Files\Filesystem::getMountManager()->find($absPath);
|
$mount = \OC\Files\Filesystem::getMountManager()->find($absPath);
|
||||||
|
@ -57,7 +65,7 @@ class Helper
|
||||||
* @param \OCP\Files\FileInfo $b file
|
* @param \OCP\Files\FileInfo $b file
|
||||||
* @return int -1 if $a must come before $b, 1 otherwise
|
* @return int -1 if $a must come before $b, 1 otherwise
|
||||||
*/
|
*/
|
||||||
public static function fileCmp($a, $b) {
|
public static function compareFileNames($a, $b) {
|
||||||
$aType = $a->getType();
|
$aType = $a->getType();
|
||||||
$bType = $b->getType();
|
$bType = $b->getType();
|
||||||
if ($aType === 'dir' and $bType !== 'dir') {
|
if ($aType === 'dir' and $bType !== 'dir') {
|
||||||
|
@ -69,6 +77,32 @@ class Helper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comparator function to sort files by date
|
||||||
|
*
|
||||||
|
* @param \OCP\Files\FileInfo $a file
|
||||||
|
* @param \OCP\Files\FileInfo $b file
|
||||||
|
* @return int -1 if $a must come before $b, 1 otherwise
|
||||||
|
*/
|
||||||
|
public static function compareTimestamp($a, $b) {
|
||||||
|
$aTime = $a->getMTime();
|
||||||
|
$bTime = $b->getMTime();
|
||||||
|
return $aTime - $bTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comparator function to sort files by size
|
||||||
|
*
|
||||||
|
* @param \OCP\Files\FileInfo $a file
|
||||||
|
* @param \OCP\Files\FileInfo $b file
|
||||||
|
* @return int -1 if $a must come before $b, 1 otherwise
|
||||||
|
*/
|
||||||
|
public static function compareSize($a, $b) {
|
||||||
|
$aSize = $a->getSize();
|
||||||
|
$bSize = $b->getSize();
|
||||||
|
return $aSize - $bSize;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats the file info to be returned as JSON to the client.
|
* Formats the file info to be returned as JSON to the client.
|
||||||
*
|
*
|
||||||
|
@ -120,12 +154,35 @@ class Helper
|
||||||
* returns it as a sorted array of FileInfo.
|
* returns it as a sorted array of FileInfo.
|
||||||
*
|
*
|
||||||
* @param string $dir path to the directory
|
* @param string $dir path to the directory
|
||||||
|
* @param string $sortAttribute attribute to sort on
|
||||||
|
* @param bool $sortDescending true for descending sort, false otherwise
|
||||||
* @return \OCP\Files\FileInfo[] files
|
* @return \OCP\Files\FileInfo[] files
|
||||||
*/
|
*/
|
||||||
public static function getFiles($dir) {
|
public static function getFiles($dir, $sortAttribute = 'name', $sortDescending = false) {
|
||||||
$content = \OC\Files\Filesystem::getDirectoryContent($dir);
|
$content = \OC\Files\Filesystem::getDirectoryContent($dir);
|
||||||
|
|
||||||
usort($content, array('\OCA\Files\Helper', 'fileCmp'));
|
return self::sortFiles($content, $sortAttribute, $sortDescending);
|
||||||
return $content;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort the given file info array
|
||||||
|
*
|
||||||
|
* @param \OCP\Files\FileInfo[] files to sort
|
||||||
|
* @param string $sortAttribute attribute to sort on
|
||||||
|
* @param bool $sortDescending true for descending sort, false otherwise
|
||||||
|
* @return \OCP\Files\FileInfo[] sorted files
|
||||||
|
*/
|
||||||
|
public static function sortFiles($files, $sortAttribute = 'name', $sortDescending = false) {
|
||||||
|
$sortFunc = 'compareFileNames';
|
||||||
|
if ($sortAttribute === 'mtime') {
|
||||||
|
$sortFunc = 'compareTimestamp';
|
||||||
|
} else if ($sortAttribute === 'size') {
|
||||||
|
$sortFunc = 'compareSize';
|
||||||
|
}
|
||||||
|
usort($files, array('\OCA\Files\Helper', $sortFunc));
|
||||||
|
if ($sortDescending) {
|
||||||
|
$files = array_reverse($files);
|
||||||
|
}
|
||||||
|
return $files;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
<?php /** @var $l OC_L10N */ ?>
|
||||||
<div id="controls">
|
<div id="controls">
|
||||||
<div class="actions creatable hidden">
|
<div class="actions creatable hidden">
|
||||||
<?php if(!isset($_['dirToken'])):?>
|
<?php if(!isset($_['dirToken'])):?>
|
||||||
|
@ -60,11 +61,11 @@
|
||||||
<table id="filestable" data-allow-public-upload="<?php p($_['publicUploadEnabled'])?>" data-preview-x="36" data-preview-y="36">
|
<table id="filestable" data-allow-public-upload="<?php p($_['publicUploadEnabled'])?>" data-preview-x="36" data-preview-y="36">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="hidden" id='headerName'>
|
<th id='headerName' class="hidden column-name">
|
||||||
<div id="headerName-container">
|
<div id="headerName-container">
|
||||||
<input type="checkbox" id="select_all" />
|
<input type="checkbox" id="select_all" />
|
||||||
<label for="select_all"></label>
|
<label for="select_all"></label>
|
||||||
<span class="name"><?php p($l->t( 'Name' )); ?></span>
|
<a class="name sort columntitle" data-sort="name"><span><?php p($l->t( 'Name' )); ?></span><span class="sort-indicator"></span></a>
|
||||||
<span id="selectedActionsList" class="selectedActions">
|
<span id="selectedActionsList" class="selectedActions">
|
||||||
<?php if($_['allowZipDownload']) : ?>
|
<?php if($_['allowZipDownload']) : ?>
|
||||||
<a href="" class="download">
|
<a href="" class="download">
|
||||||
|
@ -76,9 +77,11 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="hidden" id="headerSize"><?php p($l->t('Size')); ?></th>
|
<th id="headerSize" class="hidden column-size">
|
||||||
<th class="hidden" id="headerDate">
|
<a class="size sort columntitle" data-sort="size"><span><?php p($l->t('Size')); ?></span><span class="sort-indicator"></span></a>
|
||||||
<span id="modified"><?php p($l->t( 'Modified' )); ?></span>
|
</th>
|
||||||
|
<th id="headerDate" class="hidden column-mtime">
|
||||||
|
<a id="modified" class="columntitle" data-sort="mtime"><span><?php p($l->t( 'Modified' )); ?></span><span class="sort-indicator"></span></a>
|
||||||
<?php if ($_['permissions'] & OCP\PERMISSION_DELETE): ?>
|
<?php if ($_['permissions'] & OCP\PERMISSION_DELETE): ?>
|
||||||
<span class="selectedActions"><a href="" class="delete-selected">
|
<span class="selectedActions"><a href="" class="delete-selected">
|
||||||
<?php p($l->t('Delete'))?>
|
<?php p($l->t('Delete'))?>
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or
|
||||||
|
* later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../lib/helper.php';
|
||||||
|
|
||||||
|
use OCA\Files;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Test_Files_Helper
|
||||||
|
*/
|
||||||
|
class Test_Files_Helper extends \PHPUnit_Framework_TestCase {
|
||||||
|
|
||||||
|
private function makeFileInfo($name, $size, $mtime, $isDir = false) {
|
||||||
|
return new \OC\Files\FileInfo(
|
||||||
|
'/',
|
||||||
|
null,
|
||||||
|
'/',
|
||||||
|
array(
|
||||||
|
'name' => $name,
|
||||||
|
'size' => $size,
|
||||||
|
'mtime' => $mtime,
|
||||||
|
'type' => $isDir ? 'dir' : 'file',
|
||||||
|
'mimetype' => $isDir ? 'httpd/unix-directory' : 'application/octet-stream'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a file list for testing
|
||||||
|
*/
|
||||||
|
private function getTestFileList() {
|
||||||
|
return array(
|
||||||
|
self::makeFileInfo('a.txt', 4, 1000),
|
||||||
|
self::makeFileInfo('q.txt', 5, 150),
|
||||||
|
self::makeFileInfo('subdir2', 87, 128, true),
|
||||||
|
self::makeFileInfo('b.txt', 166, 800),
|
||||||
|
self::makeFileInfo('o.txt', 12, 100),
|
||||||
|
self::makeFileInfo('subdir', 88, 125, true),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortDataProvider() {
|
||||||
|
return array(
|
||||||
|
array(
|
||||||
|
'name',
|
||||||
|
false,
|
||||||
|
array('subdir', 'subdir2', 'a.txt', 'b.txt', 'o.txt', 'q.txt'),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'name',
|
||||||
|
true,
|
||||||
|
array('q.txt', 'o.txt', 'b.txt', 'a.txt', 'subdir2', 'subdir'),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'size',
|
||||||
|
false,
|
||||||
|
array('a.txt', 'q.txt', 'o.txt', 'subdir2', 'subdir', 'b.txt'),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'size',
|
||||||
|
true,
|
||||||
|
array('b.txt', 'subdir', 'subdir2', 'o.txt', 'q.txt', 'a.txt'),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'mtime',
|
||||||
|
false,
|
||||||
|
array('o.txt', 'subdir', 'subdir2', 'q.txt', 'b.txt', 'a.txt'),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'mtime',
|
||||||
|
true,
|
||||||
|
array('a.txt', 'b.txt', 'q.txt', 'subdir2', 'subdir', 'o.txt'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider sortDataProvider
|
||||||
|
*/
|
||||||
|
public function testSortByName($sort, $sortDescending, $expectedOrder) {
|
||||||
|
$files = self::getTestFileList();
|
||||||
|
$files = \OCA\Files\Helper::sortFiles($files, $sort, $sortDescending);
|
||||||
|
$fileNames = array();
|
||||||
|
foreach ($files as $fileInfo) {
|
||||||
|
$fileNames[] = $fileInfo->getName();
|
||||||
|
}
|
||||||
|
$this->assertEquals(
|
||||||
|
$expectedOrder,
|
||||||
|
$fileNames
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -77,13 +77,17 @@ describe('FileList tests', function() {
|
||||||
// dummy table
|
// dummy table
|
||||||
// TODO: at some point this will be rendered by the FileList class itself!
|
// TODO: at some point this will be rendered by the FileList class itself!
|
||||||
'<table id="filestable">' +
|
'<table id="filestable">' +
|
||||||
'<thead><tr><th id="headerName" class="hidden">' +
|
'<thead><tr>' +
|
||||||
|
'<th id="headerName" class="hidden column-name">' +
|
||||||
'<input type="checkbox" id="select_all">' +
|
'<input type="checkbox" id="select_all">' +
|
||||||
'<span class="name">Name</span>' +
|
'<a class="name columntitle" data-sort="name"><span>Name</span><span class="sort-indicator"></span></a>' +
|
||||||
'<span class="selectedActions hidden">' +
|
'<span class="selectedActions hidden">' +
|
||||||
'<a href class="download">Download</a>' +
|
'<a href class="download">Download</a>' +
|
||||||
'<a href class="delete-selected">Delete</a></span>' +
|
'<a href class="delete-selected">Delete</a></span>' +
|
||||||
'</th></tr></thead>' +
|
'</th>' +
|
||||||
|
'<th class="hidden column-size"><a class="columntitle" data-sort="size"><span class="sort-indicator"></span></a></th>' +
|
||||||
|
'<th class="hidden column-mtime"><a class="columntitle" data-sort="mtime"><span class="sort-indicator"></span></a></th>' +
|
||||||
|
'</tr></thead>' +
|
||||||
'<tbody id="fileList"></tbody>' +
|
'<tbody id="fileList"></tbody>' +
|
||||||
'<tfoot></tfoot>' +
|
'<tfoot></tfoot>' +
|
||||||
'</table>' +
|
'</table>' +
|
||||||
|
@ -940,7 +944,7 @@ describe('FileList tests', function() {
|
||||||
expect(fakeServer.requests.length).toEqual(1);
|
expect(fakeServer.requests.length).toEqual(1);
|
||||||
var url = fakeServer.requests[0].url;
|
var url = fakeServer.requests[0].url;
|
||||||
var query = url.substr(url.indexOf('?') + 1);
|
var query = url.substr(url.indexOf('?') + 1);
|
||||||
expect(OC.parseQueryString(query)).toEqual({'dir': '/subdir'});
|
expect(OC.parseQueryString(query)).toEqual({'dir': '/subdir', sort: 'name', sortdirection: 'asc'});
|
||||||
fakeServer.respond();
|
fakeServer.respond();
|
||||||
expect($('#fileList tr').length).toEqual(4);
|
expect($('#fileList tr').length).toEqual(4);
|
||||||
expect(FileList.findFileEl('One.txt').length).toEqual(1);
|
expect(FileList.findFileEl('One.txt').length).toEqual(1);
|
||||||
|
@ -951,7 +955,7 @@ describe('FileList tests', function() {
|
||||||
expect(fakeServer.requests.length).toEqual(1);
|
expect(fakeServer.requests.length).toEqual(1);
|
||||||
var url = fakeServer.requests[0].url;
|
var url = fakeServer.requests[0].url;
|
||||||
var query = url.substr(url.indexOf('?') + 1);
|
var query = url.substr(url.indexOf('?') + 1);
|
||||||
expect(OC.parseQueryString(query)).toEqual({'dir': '/anothersubdir'});
|
expect(OC.parseQueryString(query)).toEqual({'dir': '/anothersubdir', sort: 'name', sortdirection: 'asc'});
|
||||||
fakeServer.respond();
|
fakeServer.respond();
|
||||||
});
|
});
|
||||||
it('switches to root dir when current directory does not exist', function() {
|
it('switches to root dir when current directory does not exist', function() {
|
||||||
|
@ -1260,7 +1264,7 @@ describe('FileList tests', function() {
|
||||||
expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(42);
|
expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(42);
|
||||||
});
|
});
|
||||||
it('Selecting files updates selection summary', function() {
|
it('Selecting files updates selection summary', function() {
|
||||||
var $summary = $('#headerName span.name');
|
var $summary = $('#headerName a.name>span:first');
|
||||||
expect($summary.text()).toEqual('Name');
|
expect($summary.text()).toEqual('Name');
|
||||||
FileList.findFileEl('One.txt').find('input:checkbox').click();
|
FileList.findFileEl('One.txt').find('input:checkbox').click();
|
||||||
FileList.findFileEl('Three.pdf').find('input:checkbox').click();
|
FileList.findFileEl('Three.pdf').find('input:checkbox').click();
|
||||||
|
@ -1268,7 +1272,7 @@ describe('FileList tests', function() {
|
||||||
expect($summary.text()).toEqual('1 folder & 2 files');
|
expect($summary.text()).toEqual('1 folder & 2 files');
|
||||||
});
|
});
|
||||||
it('Unselecting files hides selection summary', function() {
|
it('Unselecting files hides selection summary', function() {
|
||||||
var $summary = $('#headerName span.name');
|
var $summary = $('#headerName a.name>span:first');
|
||||||
FileList.findFileEl('One.txt').find('input:checkbox').click().click();
|
FileList.findFileEl('One.txt').find('input:checkbox').click().click();
|
||||||
expect($summary.text()).toEqual('Name');
|
expect($summary.text()).toEqual('Name');
|
||||||
});
|
});
|
||||||
|
@ -1431,5 +1435,150 @@ describe('FileList tests', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it('resets the file selection on reload', function() {
|
||||||
|
FileList.$el.find('#select_all').click();
|
||||||
|
FileList.reload();
|
||||||
|
expect(FileList.$el.find('#select_all').prop('checked')).toEqual(false);
|
||||||
|
expect(FileList.getSelectedFiles()).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('Sorting files', function() {
|
||||||
|
it('Sorts by name by default', function() {
|
||||||
|
FileList.reload();
|
||||||
|
expect(fakeServer.requests.length).toEqual(1);
|
||||||
|
var url = fakeServer.requests[0].url;
|
||||||
|
var query = OC.parseQueryString(url.substr(url.indexOf('?') + 1));
|
||||||
|
expect(query.sort).toEqual('name');
|
||||||
|
expect(query.sortdirection).toEqual('asc');
|
||||||
|
});
|
||||||
|
it('Reloads file list with a different sort when clicking on column header of unsorted column', function() {
|
||||||
|
FileList.$el.find('.column-size .columntitle').click();
|
||||||
|
expect(fakeServer.requests.length).toEqual(1);
|
||||||
|
var url = fakeServer.requests[0].url;
|
||||||
|
var query = OC.parseQueryString(url.substr(url.indexOf('?') + 1));
|
||||||
|
expect(query.sort).toEqual('size');
|
||||||
|
expect(query.sortdirection).toEqual('asc');
|
||||||
|
});
|
||||||
|
it('Toggles sort direction when clicking on already sorted column', function() {
|
||||||
|
FileList.$el.find('.column-name .columntitle').click();
|
||||||
|
expect(fakeServer.requests.length).toEqual(1);
|
||||||
|
var url = fakeServer.requests[0].url;
|
||||||
|
var query = OC.parseQueryString(url.substr(url.indexOf('?') + 1));
|
||||||
|
expect(query.sort).toEqual('name');
|
||||||
|
expect(query.sortdirection).toEqual('desc');
|
||||||
|
});
|
||||||
|
it('Toggles the sort indicator when clicking on a column header', function() {
|
||||||
|
var ASC_CLASS = FileList.SORT_INDICATOR_ASC_CLASS;
|
||||||
|
var DESC_CLASS = FileList.SORT_INDICATOR_DESC_CLASS;
|
||||||
|
FileList.$el.find('.column-size .columntitle').click();
|
||||||
|
// moves triangle to size column
|
||||||
|
expect(
|
||||||
|
FileList.$el.find('.column-name .sort-indicator').hasClass(ASC_CLASS + ' ' + DESC_CLASS)
|
||||||
|
).toEqual(false);
|
||||||
|
expect(
|
||||||
|
FileList.$el.find('.column-size .sort-indicator').hasClass(ASC_CLASS)
|
||||||
|
).toEqual(true);
|
||||||
|
|
||||||
|
// click again on size column, reverses direction
|
||||||
|
FileList.$el.find('.column-size .columntitle').click();
|
||||||
|
expect(
|
||||||
|
FileList.$el.find('.column-size .sort-indicator').hasClass(DESC_CLASS)
|
||||||
|
).toEqual(true);
|
||||||
|
|
||||||
|
// click again on size column, reverses direction
|
||||||
|
FileList.$el.find('.column-size .columntitle').click();
|
||||||
|
expect(
|
||||||
|
FileList.$el.find('.column-size .sort-indicator').hasClass(ASC_CLASS)
|
||||||
|
).toEqual(true);
|
||||||
|
|
||||||
|
// click on mtime column, moves indicator there
|
||||||
|
FileList.$el.find('.column-mtime .columntitle').click();
|
||||||
|
expect(
|
||||||
|
FileList.$el.find('.column-size .sort-indicator').hasClass(ASC_CLASS + ' ' + DESC_CLASS)
|
||||||
|
).toEqual(false);
|
||||||
|
expect(
|
||||||
|
FileList.$el.find('.column-mtime .sort-indicator').hasClass(ASC_CLASS)
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
it('Uses correct sort comparator when inserting files', function() {
|
||||||
|
testFiles.sort(FileList.Comparators.size);
|
||||||
|
// this will make it reload the testFiles with the correct sorting
|
||||||
|
FileList.$el.find('.column-size .columntitle').click();
|
||||||
|
expect(fakeServer.requests.length).toEqual(1);
|
||||||
|
fakeServer.requests[0].respond(
|
||||||
|
200,
|
||||||
|
{ 'Content-Type': 'application/json' },
|
||||||
|
JSON.stringify({
|
||||||
|
status: 'success',
|
||||||
|
data: {
|
||||||
|
files: testFiles,
|
||||||
|
permissions: 31
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
var newFileData = {
|
||||||
|
id: 999,
|
||||||
|
type: 'file',
|
||||||
|
name: 'new file.txt',
|
||||||
|
mimetype: 'text/plain',
|
||||||
|
size: 40001,
|
||||||
|
etag: '999'
|
||||||
|
};
|
||||||
|
FileList.add(newFileData);
|
||||||
|
expect(FileList.files.length).toEqual(5);
|
||||||
|
expect(FileList.$fileList.find('tr').length).toEqual(5);
|
||||||
|
expect(FileList.findFileEl('One.txt').index()).toEqual(0);
|
||||||
|
expect(FileList.findFileEl('somedir').index()).toEqual(1);
|
||||||
|
expect(FileList.findFileEl('Two.jpg').index()).toEqual(2);
|
||||||
|
expect(FileList.findFileEl('new file.txt').index()).toEqual(3);
|
||||||
|
expect(FileList.findFileEl('Three.pdf').index()).toEqual(4);
|
||||||
|
});
|
||||||
|
it('Uses correct reversed sort comparator when inserting files', function() {
|
||||||
|
testFiles.sort(FileList.Comparators.size);
|
||||||
|
testFiles.reverse();
|
||||||
|
// this will make it reload the testFiles with the correct sorting
|
||||||
|
FileList.$el.find('.column-size .columntitle').click();
|
||||||
|
expect(fakeServer.requests.length).toEqual(1);
|
||||||
|
fakeServer.requests[0].respond(
|
||||||
|
200,
|
||||||
|
{ 'Content-Type': 'application/json' },
|
||||||
|
JSON.stringify({
|
||||||
|
status: 'success',
|
||||||
|
data: {
|
||||||
|
files: testFiles,
|
||||||
|
permissions: 31
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
// reverse sort
|
||||||
|
FileList.$el.find('.column-size .columntitle').click();
|
||||||
|
fakeServer.requests[1].respond(
|
||||||
|
200,
|
||||||
|
{ 'Content-Type': 'application/json' },
|
||||||
|
JSON.stringify({
|
||||||
|
status: 'success',
|
||||||
|
data: {
|
||||||
|
files: testFiles,
|
||||||
|
permissions: 31
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
var newFileData = {
|
||||||
|
id: 999,
|
||||||
|
type: 'file',
|
||||||
|
name: 'new file.txt',
|
||||||
|
mimetype: 'text/plain',
|
||||||
|
size: 40001,
|
||||||
|
etag: '999'
|
||||||
|
};
|
||||||
|
FileList.add(newFileData);
|
||||||
|
expect(FileList.files.length).toEqual(5);
|
||||||
|
expect(FileList.$fileList.find('tr').length).toEqual(5);
|
||||||
|
expect(FileList.findFileEl('One.txt').index()).toEqual(4);
|
||||||
|
expect(FileList.findFileEl('somedir').index()).toEqual(3);
|
||||||
|
expect(FileList.findFileEl('Two.jpg').index()).toEqual(2);
|
||||||
|
expect(FileList.findFileEl('new file.txt').index()).toEqual(1);
|
||||||
|
expect(FileList.findFileEl('Three.pdf').index()).toEqual(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -20,11 +20,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// only need filesystem apps
|
|
||||||
$RUNTIME_APPTYPES=array('filesystem');
|
|
||||||
|
|
||||||
// Init owncloud
|
|
||||||
|
|
||||||
if(!\OC_App::isEnabled('files_sharing')){
|
if(!\OC_App::isEnabled('files_sharing')){
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
@ -47,6 +42,9 @@ if (isset($_GET['dir'])) {
|
||||||
$relativePath = $_GET['dir'];
|
$relativePath = $_GET['dir'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$sortAttribute = isset( $_GET['sort'] ) ? $_GET['sort'] : 'name';
|
||||||
|
$sortDirection = isset( $_GET['sortdirection'] ) ? ($_GET['sortdirection'] === 'desc') : false;
|
||||||
|
|
||||||
$data = \OCA\Files_Sharing\Helper::setupFromToken($token, $relativePath, $password);
|
$data = \OCA\Files_Sharing\Helper::setupFromToken($token, $relativePath, $password);
|
||||||
|
|
||||||
$linkItem = $data['linkItem'];
|
$linkItem = $data['linkItem'];
|
||||||
|
@ -64,7 +62,7 @@ $data = array();
|
||||||
$baseUrl = OCP\Util::linkTo('files_sharing', 'index.php') . '?t=' . urlencode($token) . '&dir=';
|
$baseUrl = OCP\Util::linkTo('files_sharing', 'index.php') . '?t=' . urlencode($token) . '&dir=';
|
||||||
|
|
||||||
// make filelist
|
// make filelist
|
||||||
$files = \OCA\Files\Helper::getFiles($dir);
|
$files = \OCA\Files\Helper::getFiles($dir, $sortAttribute, $sortDirection);
|
||||||
|
|
||||||
$formattedFiles = array();
|
$formattedFiles = array();
|
||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
|
|
|
@ -4,11 +4,13 @@ OCP\JSON::checkLoggedIn();
|
||||||
|
|
||||||
// Load the files
|
// Load the files
|
||||||
$dir = isset( $_GET['dir'] ) ? $_GET['dir'] : '';
|
$dir = isset( $_GET['dir'] ) ? $_GET['dir'] : '';
|
||||||
|
$sortAttribute = isset( $_GET['sort'] ) ? $_GET['sort'] : 'name';
|
||||||
|
$sortDirection = isset( $_GET['sortdirection'] ) ? ($_GET['sortdirection'] === 'desc') : false;
|
||||||
$data = array();
|
$data = array();
|
||||||
|
|
||||||
// make filelist
|
// make filelist
|
||||||
try {
|
try {
|
||||||
$files = \OCA\Files_Trashbin\Helper::getTrashFiles($dir);
|
$files = \OCA\Files_Trashbin\Helper::getTrashFiles($dir, $sortAttribute, $sortDirection);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
header("HTTP/1.0 404 Not Found");
|
header("HTTP/1.0 404 Not Found");
|
||||||
exit();
|
exit();
|
||||||
|
|
|
@ -80,6 +80,7 @@
|
||||||
FileList.initialize = function() {
|
FileList.initialize = function() {
|
||||||
var result = oldInit.apply(this, arguments);
|
var result = oldInit.apply(this, arguments);
|
||||||
$('.undelete').click('click', FileList._onClickRestoreSelected);
|
$('.undelete').click('click', FileList._onClickRestoreSelected);
|
||||||
|
this.setSort('mtime', 'desc');
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,14 @@ class Helper
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Retrieves the contents of a trash bin directory.
|
* Retrieves the contents of a trash bin directory.
|
||||||
|
*
|
||||||
* @param string $dir path to the directory inside the trashbin
|
* @param string $dir path to the directory inside the trashbin
|
||||||
* or empty to retrieve the root of the trashbin
|
* or empty to retrieve the root of the trashbin
|
||||||
|
* @param string $sortAttribute attribute to sort on or empty to disable sorting
|
||||||
|
* @param bool $sortDescending true for descending sort, false otherwise
|
||||||
* @return \OCP\Files\FileInfo[]
|
* @return \OCP\Files\FileInfo[]
|
||||||
*/
|
*/
|
||||||
public static function getTrashFiles($dir){
|
public static function getTrashFiles($dir, $sortAttribute = '', $sortDescending = false){
|
||||||
$result = array();
|
$result = array();
|
||||||
$timestamp = null;
|
$timestamp = null;
|
||||||
$user = \OCP\User::getUser();
|
$user = \OCP\User::getUser();
|
||||||
|
@ -57,8 +60,9 @@ class Helper
|
||||||
closedir($dirContent);
|
closedir($dirContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
usort($result, array('\OCA\Files\Helper', 'fileCmp'));
|
if ($sortAttribute !== '') {
|
||||||
|
return \OCA\Files\Helper::sortFiles($result, $sortAttribute, $sortDescending);
|
||||||
|
}
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
<?php /** @var $l OC_L10N */ ?>
|
||||||
<div id="controls">
|
<div id="controls">
|
||||||
<div id="file_action_panel"></div>
|
<div id="file_action_panel"></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,19 +6,19 @@
|
||||||
|
|
||||||
<div id="emptycontent" class="hidden"><?php p($l->t('Nothing in here. Your trash bin is empty!'))?></div>
|
<div id="emptycontent" class="hidden"><?php p($l->t('Nothing in here. Your trash bin is empty!'))?></div>
|
||||||
|
|
||||||
<input type="hidden" id="permissions" value="0"></input>
|
<input type="hidden" id="permissions" value="0">
|
||||||
<input type="hidden" id="disableSharing" data-status="<?php p($_['disableSharing']); ?>"></input>
|
<input type="hidden" id="disableSharing" data-status="<?php p($_['disableSharing']); ?>">
|
||||||
<input type="hidden" name="dir" value="<?php p($_['dir']) ?>" id="dir">
|
<input type="hidden" name="dir" value="<?php p($_['dir']) ?>" id="dir">
|
||||||
|
|
||||||
<table id="filestable">
|
<table id="filestable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th id='headerName'>
|
<th id='headerName' class="hidden column-name">
|
||||||
<div id="headerName-container">
|
<div id="headerName-container">
|
||||||
<input type="checkbox" id="select_all" />
|
<input type="checkbox" id="select_all" />
|
||||||
<label for="select_all"></label>
|
<label for="select_all"></label>
|
||||||
<span class='name'><?php p($l->t( 'Name' )); ?></span>
|
<a class="name sort columntitle" data-sort="name"><span><?php p($l->t( 'Name' )); ?></span><span class="sort-indicator"></span></a>
|
||||||
<span class='selectedActions'>
|
<span id="selectedActionsList" class='selectedActions'>
|
||||||
<a href="" class="undelete">
|
<a href="" class="undelete">
|
||||||
<img class="svg" alt="<?php p($l->t( 'Restore' )); ?>"
|
<img class="svg" alt="<?php p($l->t( 'Restore' )); ?>"
|
||||||
src="<?php print_unescaped(OCP\image_path("core", "actions/history.svg")); ?>" />
|
src="<?php print_unescaped(OCP\image_path("core", "actions/history.svg")); ?>" />
|
||||||
|
@ -26,8 +27,8 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th id="headerDate">
|
<th id="headerDate" class="hidden column-mtime">
|
||||||
<span id="modified"><?php p($l->t( 'Deleted' )); ?></span>
|
<a id="modified" class="columntitle" data-sort="mtime"><span><?php p($l->t( 'Deleted' )); ?></span><span class="sort-indicator"></span></a>
|
||||||
<span class="selectedActions">
|
<span class="selectedActions">
|
||||||
<a href="" class="delete-selected">
|
<a href="" class="delete-selected">
|
||||||
<?php p($l->t('Delete'))?>
|
<?php p($l->t('Delete'))?>
|
||||||
|
|
Loading…
Reference in New Issue