Skip to content

Commit b00e21d

Browse files
authored
Merge pull request #53309 from nextcloud/backport/53285/stable31
2 parents a2358fb + e69d68b commit b00e21d

4 files changed

Lines changed: 120 additions & 3 deletions

File tree

apps/files/src/router/router.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,16 @@
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
55
import type { RawLocation, Route } from 'vue-router'
6+
67
import { generateUrl } from '@nextcloud/router'
8+
import { relative } from 'path'
79
import queryString from 'query-string'
810
import Router, { isNavigationFailure, NavigationFailureType } from 'vue-router'
911
import Vue from 'vue'
12+
13+
import { useFilesStore } from '../store/files'
14+
import { useNavigation } from '../composables/useNavigation'
15+
import { usePathsStore } from '../store/paths'
1016
import logger from '../logger'
1117

1218
Vue.use(Router)
@@ -68,4 +74,60 @@ const router = new Router({
6874
},
6975
})
7076

77+
// If navigating back from a folder to a parent folder,
78+
// we need to keep the current dir fileid so it's highlighted
79+
// and scrolled into view.
80+
router.beforeEach((to, from, next) => {
81+
if (to.params?.parentIntercept) {
82+
delete to.params.parentIntercept
83+
next()
84+
return
85+
}
86+
87+
const fromDir = (from.query?.dir || '/') as string
88+
const toDir = (to.query?.dir || '/') as string
89+
90+
// We are going back to a parent directory
91+
if (relative(fromDir, toDir) === '..') {
92+
const { currentView } = useNavigation()
93+
const { getNode } = useFilesStore()
94+
const { getPath } = usePathsStore()
95+
96+
if (!currentView.value?.id) {
97+
logger.error('No current view id found, cannot navigate to parent directory', { fromDir, toDir })
98+
return next()
99+
}
100+
101+
// Get the previous parent's file id
102+
const fromSource = getPath(currentView.value?.id, fromDir)
103+
if (!fromSource) {
104+
logger.error('No source found for the parent directory', { fromDir, toDir })
105+
return next()
106+
}
107+
108+
const fileId = getNode(fromSource)?.fileid
109+
if (!fileId) {
110+
logger.error('No fileid found for the parent directory', { fromDir, toDir, fromSource })
111+
return next()
112+
}
113+
114+
logger.debug('Navigating back to parent directory', { fromDir, toDir, fileId })
115+
next({
116+
name: 'filelist',
117+
query: to.query,
118+
params: {
119+
...to.params,
120+
fileid: String(fileId),
121+
// Prevents the beforeEach from being called again
122+
parentIntercept: 'true',
123+
},
124+
// Replace the current history entry
125+
replace: true,
126+
})
127+
}
128+
129+
// else, we just continue
130+
next()
131+
})
132+
71133
export default router
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*!
2+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
import type { User } from '@nextcloud/cypress'
7+
import { getRowForFile, navigateToFolder } from './FilesUtils.ts'
8+
9+
describe('files: Navigate through folders and observe behavior', () => {
10+
let user: User
11+
12+
before(() => {
13+
cy.createRandomUser().then(($user) => {
14+
user = $user
15+
cy.mkdir(user, '/foo')
16+
cy.mkdir(user, '/foo/bar')
17+
cy.mkdir(user, '/foo/bar/baz')
18+
})
19+
})
20+
21+
it('Shows root folder and we can navigate to the last folder', () => {
22+
cy.login(user)
23+
cy.visit('/apps/files/')
24+
25+
getRowForFile('foo').should('be.visible')
26+
navigateToFolder('/foo/bar/baz')
27+
28+
// Last folder is empty
29+
cy.get('[data-cy-files-list-row-fileid]').should('not.exist')
30+
})
31+
32+
it('Highlight the previous folder when navigating back', () => {
33+
cy.go('back')
34+
getRowForFile('baz').should('be.visible')
35+
.invoke('attr', 'class').should('contain', 'active')
36+
37+
cy.go('back')
38+
getRowForFile('bar').should('be.visible')
39+
.invoke('attr', 'class').should('contain', 'active')
40+
41+
cy.go('back')
42+
getRowForFile('foo').should('be.visible')
43+
.invoke('attr', 'class').should('contain', 'active')
44+
})
45+
46+
it('Can navigate forward again', () => {
47+
cy.go('forward')
48+
getRowForFile('bar').should('be.visible')
49+
.invoke('attr', 'class').should('contain', 'active')
50+
51+
cy.go('forward')
52+
getRowForFile('baz').should('be.visible')
53+
.invoke('attr', 'class').should('contain', 'active')
54+
})
55+
})

dist/files-main.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/files-main.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)