Skip to content

Commit 4591c18

Browse files
authored
Merge pull request #47135 from nextcloud/fix/open-tags-in-folder
fix(systemtags): Sub folders should be opened in files
2 parents a041833 + 124288f commit 4591c18

File tree

5 files changed

+172
-3
lines changed

5 files changed

+172
-3
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
import { action } from './openInFilesAction'
6+
import { expect } from '@jest/globals'
7+
import { File, Folder, Permission, View, DefaultType, FileAction } from '@nextcloud/files'
8+
9+
const view = {
10+
id: 'files',
11+
name: 'Files',
12+
} as View
13+
14+
const systemTagsView = {
15+
id: 'tags',
16+
name: 'tags',
17+
} as View
18+
19+
const validNode = new Folder({
20+
id: 1,
21+
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foo',
22+
owner: 'admin',
23+
mime: 'httpd/unix-directory',
24+
root: '/files/admin',
25+
permissions: Permission.ALL,
26+
})
27+
28+
const validTag = new Folder({
29+
id: 1,
30+
source: 'https://cloud.domain.com/remote.php/dav/systemtags/2',
31+
displayname: 'Foo',
32+
owner: 'admin',
33+
mime: 'httpd/unix-directory',
34+
root: '/systemtags',
35+
permissions: Permission.ALL,
36+
attributes: {
37+
'is-tag': true,
38+
},
39+
})
40+
41+
describe('Open in files action conditions tests', () => {
42+
test('Default values', () => {
43+
expect(action).toBeInstanceOf(FileAction)
44+
expect(action.id).toBe('systemtags:open-in-files')
45+
expect(action.displayName([], systemTagsView)).toBe('Open in Files')
46+
expect(action.iconSvgInline([], systemTagsView)).toBe('')
47+
expect(action.default).toBe(DefaultType.HIDDEN)
48+
expect(action.order).toBe(-1000)
49+
expect(action.inline).toBeUndefined()
50+
})
51+
})
52+
53+
describe('Open in files action enabled tests', () => {
54+
test('Enabled with on valid view', () => {
55+
expect(action.enabled).toBeDefined()
56+
expect(action.enabled!([validNode], systemTagsView)).toBe(true)
57+
})
58+
59+
test('Disabled on wrong view', () => {
60+
expect(action.enabled).toBeDefined()
61+
expect(action.enabled!([validNode], view)).toBe(false)
62+
})
63+
64+
test('Disabled without nodes', () => {
65+
expect(action.enabled).toBeDefined()
66+
expect(action.enabled!([], view)).toBe(false)
67+
})
68+
69+
test('Disabled with too many nodes', () => {
70+
expect(action.enabled).toBeDefined()
71+
expect(action.enabled!([validNode, validNode], view)).toBe(false)
72+
})
73+
74+
test('Disabled with when node is a tag', () => {
75+
expect(action.enabled).toBeDefined()
76+
expect(action.enabled!([validTag], view)).toBe(false)
77+
})
78+
})
79+
80+
describe('Open in files action execute tests', () => {
81+
test('Open in files', async () => {
82+
const goToRouteMock = jest.fn()
83+
// @ts-expect-error We only mock what needed, we do not need Files.Router.goTo or Files.Navigation
84+
window.OCP = { Files: { Router: { goToRoute: goToRouteMock } } }
85+
86+
const file = new File({
87+
id: 1,
88+
source: 'https://cloud.domain.com/remote.php/dav/files/admin/Foo/foobar.txt',
89+
owner: 'admin',
90+
mime: 'text/plain',
91+
root: '/files/admin',
92+
permissions: Permission.ALL,
93+
})
94+
95+
const exec = await action.exec(file, view, '/')
96+
97+
// Silent action
98+
expect(exec).toBe(null)
99+
expect(goToRouteMock).toBeCalledTimes(1)
100+
expect(goToRouteMock).toBeCalledWith(null, { fileid: '1', view: 'files' }, { dir: '/Foo', openfile: 'true' })
101+
})
102+
103+
test('Open in files with folder', async () => {
104+
const goToRouteMock = jest.fn()
105+
// @ts-expect-error We only mock what needed, we do not need Files.Router.goTo or Files.Navigation
106+
window.OCP = { Files: { Router: { goToRoute: goToRouteMock } } }
107+
108+
const file = new Folder({
109+
id: 1,
110+
source: 'https://cloud.domain.com/remote.php/dav/files/admin/Foo/Bar',
111+
owner: 'admin',
112+
root: '/files/admin',
113+
permissions: Permission.ALL,
114+
})
115+
116+
const exec = await action.exec(file, view, '/')
117+
118+
// Silent action
119+
expect(exec).toBe(null)
120+
expect(goToRouteMock).toBeCalledTimes(1)
121+
expect(goToRouteMock).toBeCalledWith(null, { fileid: '1', view: 'files' }, { dir: '/Foo/Bar', openfile: 'true' })
122+
})
123+
})
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
import { translate as t } from '@nextcloud/l10n'
6+
import { type Node, FileType, FileAction, DefaultType } from '@nextcloud/files'
7+
8+
export const action = new FileAction({
9+
id: 'systemtags:open-in-files',
10+
displayName: () => t('systemtags', 'Open in Files'),
11+
iconSvgInline: () => '',
12+
13+
enabled(nodes, view) {
14+
// Only for the system tags view
15+
if (view.id !== 'tags') {
16+
return false
17+
}
18+
// Only for single nodes
19+
if (nodes.length !== 1) {
20+
return false
21+
}
22+
// Do not open tags (keep the default action) and only open folders
23+
return nodes[0].attributes['is-tag'] !== true
24+
&& nodes[0].type === FileType.Folder
25+
},
26+
27+
async exec(node: Node) {
28+
let dir = node.dirname
29+
if (node.type === FileType.Folder) {
30+
dir = node.path
31+
}
32+
33+
window.OCP.Files.Router.goToRoute(
34+
null, // use default route
35+
{ view: 'files', fileid: String(node.fileid) },
36+
{ dir, openfile: 'true' },
37+
)
38+
return null
39+
},
40+
41+
// Before openFolderAction
42+
order: -1000,
43+
default: DefaultType.HIDDEN,
44+
})

apps/systemtags/src/init.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
*/
55
import { registerDavProperty, registerFileAction } from '@nextcloud/files'
66
import { action as inlineSystemTagsAction } from './files_actions/inlineSystemTagsAction.js'
7+
import { action as openInFilesAction } from './files_actions/openInFilesAction.js'
78
import { registerSystemTagsView } from './files_views/systemtagsView.js'
89

910
registerDavProperty('nc:system-tags')
1011
registerFileAction(inlineSystemTagsAction)
12+
registerFileAction(openInFilesAction)
1113

1214
registerSystemTagsView()

dist/systemtags-init.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/systemtags-init.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)