Skip to content

Commit

Permalink
fix(files): Fix legacy files list sorting
Browse files Browse the repository at this point in the history
The sorting was not saved since files2vue changes in Nextcloud 27, as a new API endpoint
was introduced and the old one was dropped without adjusting the legacy file list to use it.

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
  • Loading branch information
susnux committed Aug 18, 2023
1 parent 820d05d commit e79509a
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 29 deletions.
21 changes: 16 additions & 5 deletions apps/files/js/filelist.js
Expand Up @@ -2185,11 +2185,22 @@
}

if (persist && OC.getCurrentUser().uid) {
$.post(OC.generateUrl('/apps/files/api/v1/sorting'), {
// Compatibility with new files-to-vue API
mode: sort === 'name' ? 'basename' : sort,
direction: direction,
view: 'files'
$.ajax({
type: 'PUT',
url: OC.generateUrl('apps/files/api/v1/views/files/sorting_mode'),
contentType: 'application/json',
data: JSON.stringify({
// Compatibility with new files-to-vue API
value: sort === 'name' ? 'basename' : sort,
})
});
$.ajax({
type: 'PUT',
url: OC.generateUrl('apps/files/api/v1/views/files/sorting_direction'),
contentType: 'application/json',
data: JSON.stringify({
value: direction,
})
});
}
},
Expand Down
6 changes: 3 additions & 3 deletions apps/files/lib/Controller/ViewController.php
Expand Up @@ -255,7 +255,7 @@ public function index($dir = '', $view = '', $fileid = null, $fileNotFound = fal
$this->initialState->provideInitialState('viewConfigs', $this->viewConfig->getConfigs());

// File sorting user config
$filesSortingConfig = json_decode($this->config->getUserValue($userId, 'files', 'files_sorting_configs', '{}'), true);
$filesSortingConfig = $this->viewConfig->getConfigs();
$this->initialState->provideInitialState('filesSortingConfig', $filesSortingConfig);

// render the container content for every navigation item
Expand Down Expand Up @@ -301,8 +301,8 @@ public function index($dir = '', $view = '', $fileid = null, $fileNotFound = fal
$params['ownerDisplayName'] = $storageInfo['ownerDisplayName'] ?? '';
$params['isPublic'] = false;
$params['allowShareWithLink'] = $this->shareManager->shareApiAllowLinks() ? 'yes' : 'no';
$params['defaultFileSorting'] = $filesSortingConfig['files']['mode'] ?? 'basename';
$params['defaultFileSortingDirection'] = $filesSortingConfig['files']['direction'] ?? 'asc';
$params['defaultFileSorting'] = $filesSortingConfig['files']['sorting_mode'] ?? 'basename';
$params['defaultFileSortingDirection'] = $filesSortingConfig['files']['sorting_direction'] ?? 'asc';
$params['showgridview'] = $this->config->getUserValue($userId, 'files', 'show_grid', false);
$showHidden = (bool) $this->config->getUserValue($userId, 'files', 'show_hidden', false);
$params['showHiddenFiles'] = $showHidden ? 1 : 0;
Expand Down
32 changes: 17 additions & 15 deletions apps/files/tests/js/filelistSpec.js
Expand Up @@ -2561,10 +2561,11 @@ 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;
const ASC_CLASS = fileList.SORT_INDICATOR_ASC_CLASS;
const DESC_CLASS = fileList.SORT_INDICATOR_DESC_CLASS;
var request;
var sortingUrl = OC.generateUrl('/apps/files/api/v1/sorting');
const sortingDirectionUrl = OC.generateUrl('/apps/files/api/v1/views/files/sorting_direction');
const sortingModeUrl = OC.generateUrl('/apps/files/api/v1/views/files/sorting_mode');
fileList.$el.find('.column-size .columntitle').click();
// moves triangle to size column, check indicator on name is hidden
expect(
Expand All @@ -2578,9 +2579,9 @@ describe('OCA.Files.FileList tests', function() {
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);
expect(fakeServer.requests.length).toEqual(2);
expect(fakeServer.requests.some((request) => request.url === sortingDirectionUrl)).toBe(true)
expect(fakeServer.requests.some((request) => request.url === sortingModeUrl)).toBe(true)

// click again on size column, reverses direction
fileList.$el.find('.column-size .columntitle').click();
Expand All @@ -2591,9 +2592,9 @@ describe('OCA.Files.FileList tests', function() {
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);
expect(fakeServer.requests.length).toEqual(4);
expect(fakeServer.requests.slice(2).some((request) => request.url === sortingDirectionUrl)).toBe(true)
expect(fakeServer.requests.slice(2).some((request) => request.url === sortingModeUrl)).toBe(true)

// click again on size column, reverses direction
fileList.$el.find('.column-size .columntitle').click();
Expand All @@ -2603,9 +2604,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);
expect(fakeServer.requests.length).toEqual(6);
expect(fakeServer.requests.slice(4).some((request) => request.url === sortingDirectionUrl)).toBe(true)
expect(fakeServer.requests.slice(4).some((request) => request.url === sortingModeUrl)).toBe(true)

// click on mtime column, moves indicator there
fileList.$el.find('.column-mtime .columntitle').click();
Expand All @@ -2618,10 +2619,11 @@ 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);
expect(fakeServer.requests.length).toEqual(8);
expect(fakeServer.requests.slice(6).some((request) => request.url === sortingDirectionUrl)).toBe(true)
expect(fakeServer.requests.slice(6).some((request) => request.url === sortingModeUrl)).toBe(true)
});

it('Uses correct sort comparator when inserting files', function() {
testFiles.sort(OCA.Files.FileList.Comparators.size);
testFiles.reverse(); //default is descending
Expand Down
41 changes: 35 additions & 6 deletions cypress/e2e/files.cy.ts
Expand Up @@ -30,18 +30,13 @@ const startCopyMove = (file: string) => {
}

describe('Login with a new user and open the files app', function() {
let currentUser: User
beforeEach(function() {
before(function() {
cy.createRandomUser().then((user) => {
currentUser = user
cy.login(user)
})
})

afterEach(function() {
cy.deleteUser(currentUser)
})

Cypress.on('uncaught:exception', (err) => {
// This can happen because of blink engine & skeleton animation, its not a bug just engine related.
if (err.message.includes('ResizeObserver loop limit exceeded')) {
Expand All @@ -54,6 +49,40 @@ describe('Login with a new user and open the files app', function() {
cy.get('.files-fileList tr').should('contain', 'welcome.txt')
})

it('See the file list sorting order is saved', function() {
cy.intercept('PUT', /api\/v1\/views\/files\/sorting_direction$/).as('sorting_direction')

cy.visit('/apps/files')
// default to sorting by name
cy.get('.files-filestable th.column-name .sort-indicator').should('be.visible')
// change to size
cy.get('.files-filestable th').contains('Size').click()
// size sorting should be active
cy.get('.files-filestable th.column-name .sort-indicator').should('not.be.visible')
cy.get('.files-filestable th.column-size .sort-indicator').should('be.visible')
cy.wait('@sorting_direction')

// Re-visit
cy.visit('/apps/files')
// now sorting by name should be disabled and sorting by size should be enabled
cy.get('.files-filestable th.column-name .sort-indicator').should('not.be.visible')
cy.get('.files-filestable th.column-size .sort-indicator').should('be.visible')
})
})

describe('Testing the copy move action (FilePicker)', () => {
let currentUser: User
beforeEach(function() {
cy.createRandomUser().then((user) => {
currentUser = user
cy.login(user)
})
})

afterEach(function() {
cy.deleteUser(currentUser)
})

it('Copy a file in its same folder', () => {
cy.visit('/apps/files')
// When I start the move or copy operation for "welcome.txt"
Expand Down

0 comments on commit e79509a

Please sign in to comment.