aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files')
-rw-r--r--apps/files/appinfo/application.php3
-rw-r--r--apps/files/appinfo/routes.php6
-rw-r--r--apps/files/controller/apicontroller.php32
-rw-r--r--apps/files/controller/viewcontroller.php13
-rw-r--r--apps/files/js/app.js6
-rw-r--r--apps/files/js/filelist.js22
-rw-r--r--apps/files/templates/index.php2
-rw-r--r--apps/files/tests/controller/ViewControllerTest.php22
-rw-r--r--apps/files/tests/controller/apicontrollertest.php55
-rw-r--r--apps/files/tests/js/filelistSpec.js16
10 files changed, 161 insertions, 16 deletions
diff --git a/apps/files/appinfo/application.php b/apps/files/appinfo/application.php
index 593e0533c80..2d2decf6288 100644
--- a/apps/files/appinfo/application.php
+++ b/apps/files/appinfo/application.php
@@ -43,7 +43,8 @@ class Application extends App {
$server->getUserSession(),
$c->query('TagService'),
$server->getPreviewManager(),
- $server->getShareManager()
+ $server->getShareManager(),
+ $server->getConfig()
);
});
diff --git a/apps/files/appinfo/routes.php b/apps/files/appinfo/routes.php
index 731c671b60a..6ad938101a2 100644
--- a/apps/files/appinfo/routes.php
+++ b/apps/files/appinfo/routes.php
@@ -1,6 +1,7 @@
<?php
/**
* @author Bart Visscher <bartv@thisnet.nl>
+ * @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Lukas Reschke <lukas@owncloud.com>
* @author Roeland Jago Douma <rullzer@owncloud.com>
* @author Tobias Kaminsky <tobias@kaminsky.me>
@@ -48,6 +49,11 @@ $application->registerRoutes(
'verb' => 'GET',
'requirements' => array('tagName' => '.+'),
),
+ array(
+ 'name' => 'API#updateFileSorting',
+ 'url' => '/api/v1/sorting',
+ 'verb' => 'POST'
+ ),
[
'name' => 'view#index',
'url' => '/',
diff --git a/apps/files/controller/apicontroller.php b/apps/files/controller/apicontroller.php
index ad286284386..43d426476fe 100644
--- a/apps/files/controller/apicontroller.php
+++ b/apps/files/controller/apicontroller.php
@@ -1,6 +1,7 @@
<?php
/**
* @author Joas Schilling <nickvergessen@owncloud.com>
+ * @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Lukas Reschke <lukas@owncloud.com>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Roeland Jago Douma <rullzer@owncloud.com>
@@ -29,13 +30,14 @@ namespace OCA\Files\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Controller;
+use OCP\IConfig;
use OCP\IRequest;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\DataDisplayResponse;
+use OCP\AppFramework\Http\Response;
use OCA\Files\Service\TagService;
use OCP\IPreview;
use OCP\Share\IManager;
-use OCP\Files\FileInfo;
use OCP\Files\Node;
use OCP\IUserSession;
@@ -53,6 +55,8 @@ class ApiController extends Controller {
private $previewManager;
/** IUserSession */
private $userSession;
+ /** IConfig */
+ private $config;
/**
* @param string $appName
@@ -65,12 +69,14 @@ class ApiController extends Controller {
IUserSession $userSession,
TagService $tagService,
IPreview $previewManager,
- IManager $shareManager) {
+ IManager $shareManager,
+ IConfig $config) {
parent::__construct($appName, $request);
$this->userSession = $userSession;
$this->tagService = $tagService;
$this->previewManager = $previewManager;
$this->shareManager = $shareManager;
+ $this->config = $config;
}
/**
@@ -196,4 +202,26 @@ class ApiController extends Controller {
return $shareTypes;
}
+ /**
+ * Change the default sort mode
+ *
+ * @NoAdminRequired
+ *
+ * @param string $mode
+ * @param string $direction
+ * @return Response
+ */
+ public function updateFileSorting($mode, $direction) {
+ $allowedMode = ['name', 'size', 'mtime'];
+ $allowedDirection = ['asc', 'desc'];
+ if (!in_array($mode, $allowedMode) || !in_array($direction, $allowedDirection)) {
+ $response = new Response();
+ $response->setStatus(Http::STATUS_UNPROCESSABLE_ENTITY);
+ return $response;
+ }
+ $this->config->setUserValue($this->userSession->getUser()->getUID(), 'files', 'file_sorting', $mode);
+ $this->config->setUserValue($this->userSession->getUser()->getUID(), 'files', 'file_sorting_direction', $direction);
+ return new Response();
+ }
+
}
diff --git a/apps/files/controller/viewcontroller.php b/apps/files/controller/viewcontroller.php
index 800cf008fa7..6c5f4c6d2a0 100644
--- a/apps/files/controller/viewcontroller.php
+++ b/apps/files/controller/viewcontroller.php
@@ -1,5 +1,6 @@
<?php
/**
+ * @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Lukas Reschke <lukas@owncloud.com>
* @author Thomas Müller <thomas.mueller@tmit.eu>
*
@@ -27,11 +28,12 @@ use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Http\TemplateResponse;
+use OCP\IConfig;
use OCP\IL10N;
use OCP\INavigationManager;
use OCP\IRequest;
use OCP\IURLGenerator;
-use OCP\IConfig;
+use OCP\IUserSession;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
@@ -54,6 +56,8 @@ class ViewController extends Controller {
protected $config;
/** @var EventDispatcherInterface */
protected $eventDispatcher;
+ /** @var IUserSession */
+ protected $userSession;
/**
* @param string $appName
@@ -70,7 +74,8 @@ class ViewController extends Controller {
INavigationManager $navigationManager,
IL10N $l10n,
IConfig $config,
- EventDispatcherInterface $eventDispatcherInterface) {
+ EventDispatcherInterface $eventDispatcherInterface,
+ IUserSession $userSession) {
parent::__construct($appName, $request);
$this->appName = $appName;
$this->request = $request;
@@ -79,6 +84,7 @@ class ViewController extends Controller {
$this->l10n = $l10n;
$this->config = $config;
$this->eventDispatcher = $eventDispatcherInterface;
+ $this->userSession = $userSession;
}
/**
@@ -213,6 +219,9 @@ class ViewController extends Controller {
$params['mailNotificationEnabled'] = $this->config->getAppValue('core', 'shareapi_allow_mail_notification', 'no');
$params['mailPublicNotificationEnabled'] = $this->config->getAppValue('core', 'shareapi_allow_public_notification', 'no');
$params['allowShareWithLink'] = $this->config->getAppValue('core', 'shareapi_allow_links', 'yes');
+ $user = $this->userSession->getUser()->getUID();
+ $params['defaultFileSorting'] = $this->config->getUserValue($user, 'files', 'file_sorting', 'name');
+ $params['defaultFileSortingDirection'] = $this->config->getUserValue($user, 'files', 'file_sorting_direction', 'asc');
$params['appNavigation'] = $nav;
$params['appContents'] = $contentItems;
$this->navigationManager->setActiveEntry('files_index');
diff --git a/apps/files/js/app.js b/apps/files/js/app.js
index ff505d417f1..4ed805d2681 100644
--- a/apps/files/js/app.js
+++ b/apps/files/js/app.js
@@ -72,7 +72,11 @@
fileActions: fileActions,
allowLegacyActions: true,
scrollTo: urlParams.scrollto,
- filesClient: OC.Files.getClient()
+ filesClient: OC.Files.getClient(),
+ sorting: {
+ mode: $('#defaultFileSorting').val(),
+ direction: $('#defaultFileSortingDirection').val()
+ }
}
);
this.files.initialize();
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index c8f818701a9..7de64f8ade3 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -239,7 +239,11 @@
this.fileSummary = this._createSummary();
- this.setSort('name', 'asc');
+ if (options.sorting) {
+ this.setSort(options.sorting.mode, options.sorting.direction, false, false);
+ } else {
+ this.setSort('name', 'asc', false, false);
+ }
var breadcrumbOptions = {
onClick: _.bind(this._onClickBreadCrumb, this),
@@ -695,14 +699,14 @@
sort = $target.attr('data-sort');
if (sort) {
if (this._sort === sort) {
- this.setSort(sort, (this._sortDirection === 'desc')?'asc':'desc', true);
+ this.setSort(sort, (this._sortDirection === 'desc')?'asc':'desc', true, true);
}
else {
if ( sort === 'name' ) { //default sorting of name is opposite to size and mtime
- this.setSort(sort, 'asc', true);
+ this.setSort(sort, 'asc', true, true);
}
else {
- this.setSort(sort, 'desc', true);
+ this.setSort(sort, 'desc', true, true);
}
}
}
@@ -1370,8 +1374,9 @@
* @param sort sort attribute name
* @param direction sort direction, one of "asc" or "desc"
* @param update true to update the list, false otherwise (default)
+ * @param persist true to save changes in the database (default)
*/
- setSort: function(sort, direction, update) {
+ setSort: function(sort, direction, update, persist) {
var comparator = FileList.Comparators[sort] || FileList.Comparators.name;
this._sort = sort;
this._sortDirection = (direction === 'desc')?'desc':'asc';
@@ -1402,6 +1407,13 @@
this.reload();
}
}
+
+ if (persist) {
+ $.post(OC.generateUrl('/apps/files/api/v1/sorting'), {
+ mode: sort,
+ direction: direction
+ });
+ }
},
/**
diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php
index e825c300d31..db464ad2eca 100644
--- a/apps/files/templates/index.php
+++ b/apps/files/templates/index.php
@@ -18,4 +18,6 @@
<input type="hidden" name="mailNotificationEnabled" id="mailNotificationEnabled" value="<?php p($_['mailNotificationEnabled']) ?>" />
<input type="hidden" name="mailPublicNotificationEnabled" id="mailPublicNotificationEnabled" value="<?php p($_['mailPublicNotificationEnabled']) ?>" />
<input type="hidden" name="allowShareWithLink" id="allowShareWithLink" value="<?php p($_['allowShareWithLink']) ?>" />
+<input type="hidden" name="defaultFileSorting" id="defaultFileSorting" value="<?php p($_['defaultFileSorting']) ?>" />
+<input type="hidden" name="defaultFileSortingDirection" id="defaultFileSortingDirection" value="<?php p($_['defaultFileSortingDirection']) ?>" />
<?php endif;
diff --git a/apps/files/tests/controller/ViewControllerTest.php b/apps/files/tests/controller/ViewControllerTest.php
index 657ab6cb338..0446cc8982c 100644
--- a/apps/files/tests/controller/ViewControllerTest.php
+++ b/apps/files/tests/controller/ViewControllerTest.php
@@ -1,5 +1,6 @@
<?php
/**
+ * @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Joas Schilling <nickvergessen@owncloud.com>
* @author Lukas Reschke <lukas@owncloud.com>
* @author Vincent Petry <pvince81@owncloud.com>
@@ -33,6 +34,7 @@ use OCP\AppFramework\Http\RedirectResponse;
use OCP\INavigationManager;
use OCP\IL10N;
use OCP\IConfig;
+use OCP\IUserSession;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
@@ -55,6 +57,10 @@ class ViewControllerTest extends TestCase {
private $eventDispatcher;
/** @var ViewController */
private $viewController;
+ /** @var IUser */
+ private $user;
+ /** @var IUserSession */
+ private $userSession;
public function setUp() {
parent::setUp();
@@ -64,6 +70,11 @@ class ViewControllerTest extends TestCase {
$this->l10n = $this->getMock('\OCP\IL10N');
$this->config = $this->getMock('\OCP\IConfig');
$this->eventDispatcher = $this->getMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface');
+ $this->userSession = $this->getMock('\OCP\IUserSession');
+ $this->user = $this->getMock('\OCP\IUser');
+ $this->userSession->expects($this->any())
+ ->method('getUser')
+ ->will($this->returnValue($this->user));
$this->viewController = $this->getMockBuilder('\OCA\Files\Controller\ViewController')
->setConstructorArgs([
'files',
@@ -72,7 +83,8 @@ class ViewControllerTest extends TestCase {
$this->navigationManager,
$this->l10n,
$this->config,
- $this->eventDispatcher
+ $this->eventDispatcher,
+ $this->userSession
])
->setMethods([
'getStorageInfo',
@@ -143,6 +155,12 @@ class ViewControllerTest extends TestCase {
'owner' => 'MyName',
'ownerDisplayName' => 'MyDisplayName',
]));
+ $this->config->expects($this->exactly(2))
+ ->method('getUserValue')
+ ->will($this->returnValueMap([
+ [$this->user->getUID(), 'files', 'file_sorting', 'name', 'name'],
+ [$this->user->getUID(), 'files', 'file_sorting_direction', 'asc', 'asc']
+ ]));
$this->config
->expects($this->any())
@@ -224,6 +242,8 @@ class ViewControllerTest extends TestCase {
'owner' => 'MyName',
'ownerDisplayName' => 'MyDisplayName',
'isPublic' => false,
+ 'defaultFileSorting' => 'name',
+ 'defaultFileSortingDirection' => 'asc',
'mailNotificationEnabled' => 'no',
'mailPublicNotificationEnabled' => 'no',
'allowShareWithLink' => 'yes',
diff --git a/apps/files/tests/controller/apicontrollertest.php b/apps/files/tests/controller/apicontrollertest.php
index a9b248a36fe..59f53e8ee81 100644
--- a/apps/files/tests/controller/apicontrollertest.php
+++ b/apps/files/tests/controller/apicontrollertest.php
@@ -1,5 +1,6 @@
<?php
/**
+ * @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Lukas Reschke <lukas@owncloud.com>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Roeland Jago Douma <rullzer@owncloud.com>
@@ -43,6 +44,8 @@ use OCP\Image;
class ApiControllerTest extends TestCase {
/** @var string */
private $appName = 'files';
+ /** @var \OCP\IUser */
+ private $user;
/** @var IRequest */
private $request;
/** @var TagService */
@@ -53,19 +56,21 @@ class ApiControllerTest extends TestCase {
private $apiController;
/** @var \OCP\Share\IManager */
private $shareManager;
+ /** @var \OCP\IConfig */
+ private $config;
public function setUp() {
$this->request = $this->getMockBuilder('\OCP\IRequest')
->disableOriginalConstructor()
->getMock();
- $user = $this->getMock('\OCP\IUser');
- $user->expects($this->any())
+ $this->user = $this->getMock('\OCP\IUser');
+ $this->user->expects($this->any())
->method('getUID')
->will($this->returnValue('user1'));
$userSession = $this->getMock('\OCP\IUserSession');
$userSession->expects($this->any())
->method('getUser')
- ->will($this->returnValue($user));
+ ->will($this->returnValue($this->user));
$this->tagService = $this->getMockBuilder('\OCA\Files\Service\TagService')
->disableOriginalConstructor()
->getMock();
@@ -75,6 +80,7 @@ class ApiControllerTest extends TestCase {
$this->preview = $this->getMockBuilder('\OCP\IPreview')
->disableOriginalConstructor()
->getMock();
+ $this->config = $this->getMock('\OCP\IConfig');
$this->apiController = new ApiController(
$this->appName,
@@ -82,7 +88,8 @@ class ApiControllerTest extends TestCase {
$userSession,
$this->tagService,
$this->preview,
- $this->shareManager
+ $this->shareManager,
+ $this->config
);
}
@@ -335,4 +342,44 @@ class ApiControllerTest extends TestCase {
$this->assertEquals(Http::STATUS_OK, $ret->getStatus());
}
+
+ public function testUpdateFileSorting() {
+ $mode = 'mtime';
+ $direction = 'desc';
+
+ $this->config->expects($this->at(0))
+ ->method('setUserValue')
+ ->with($this->user->getUID(), 'files', 'file_sorting', $mode);
+ $this->config->expects($this->at(1))
+ ->method('setUserValue')
+ ->with($this->user->getUID(), 'files', 'file_sorting_direction', $direction);
+
+ $expected = new HTTP\Response();
+ $actual = $this->apiController->updateFileSorting($mode, $direction);
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function invalidSortingModeData() {
+ return [
+ ['color', 'asc'],
+ ['name', 'size'],
+ ['foo', 'bar']
+ ];
+ }
+
+ /**
+ * @dataProvider invalidSortingModeData
+ */
+ public function testUpdateInvalidFileSorting($mode, $direction) {
+ $this->config->expects($this->never())
+ ->method('setUserValue');
+
+ $expected = new Http\Response(null);
+ $expected->setStatus(Http::STATUS_UNPROCESSABLE_ENTITY);
+
+ $result = $this->apiController->updateFileSorting($mode, $direction);
+
+ $this->assertEquals($expected, $result);
+ }
+
}
diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js
index a83c8c4c0bc..cc3bcd74b46 100644
--- a/apps/files/tests/js/filelistSpec.js
+++ b/apps/files/tests/js/filelistSpec.js
@@ -2106,6 +2106,8 @@ describe('OCA.Files.FileList tests', function() {
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;
+ var request;
+ var sortingUrl = OC.generateUrl('/apps/files/api/v1/sorting');
fileList.$el.find('.column-size .columntitle').click();
// moves triangle to size column, check indicator on name is hidden
expect(
@@ -2118,6 +2120,10 @@ describe('OCA.Files.FileList tests', function() {
expect(
fileList.$el.find('.column-size .sort-indicator').hasClass(DESC_CLASS)
).toEqual(true);
+ // check if changes are persisted
+ expect(fakeServer.requests.length).toEqual(1);
+ request = fakeServer.requests[0];
+ expect(request.url).toEqual(sortingUrl);
// click again on size column, reverses direction
fileList.$el.find('.column-size .columntitle').click();
@@ -2127,6 +2133,10 @@ describe('OCA.Files.FileList tests', function() {
expect(
fileList.$el.find('.column-size .sort-indicator').hasClass(ASC_CLASS)
).toEqual(true);
+ // check if changes are persisted
+ expect(fakeServer.requests.length).toEqual(2);
+ request = fakeServer.requests[1];
+ expect(request.url).toEqual(sortingUrl);
// click again on size column, reverses direction
fileList.$el.find('.column-size .columntitle').click();
@@ -2136,6 +2146,9 @@ describe('OCA.Files.FileList tests', function() {
expect(
fileList.$el.find('.column-size .sort-indicator').hasClass(DESC_CLASS)
).toEqual(true);
+ expect(fakeServer.requests.length).toEqual(3);
+ request = fakeServer.requests[2];
+ expect(request.url).toEqual(sortingUrl);
// click on mtime column, moves indicator there
fileList.$el.find('.column-mtime .columntitle').click();
@@ -2148,6 +2161,9 @@ describe('OCA.Files.FileList tests', function() {
expect(
fileList.$el.find('.column-mtime .sort-indicator').hasClass(DESC_CLASS)
).toEqual(true);
+ expect(fakeServer.requests.length).toEqual(4);
+ request = fakeServer.requests[3];
+ expect(request.url).toEqual(sortingUrl);
});
it('Uses correct sort comparator when inserting files', function() {
testFiles.sort(OCA.Files.FileList.Comparators.size);