Skip to content

Commit

Permalink
fix(systemtags): Sub folders should be opened in files
Browse files Browse the repository at this point in the history
Currently this is simply broken and here are two ways:
1. Open subfolders in files view
2. Implement logic to save last request

1 is the way this is now implemented, basically copy-paste from the recent view.
2 is much more complicated because if we get `/2/foo/bar` as the path we need to know the source of `foo`, so we would need at least 2 requests or cache the previous directory. We do not do it like this for any view so lets just stick with 1 for now.

Signed-off-by: Ferdinand Thiessen <[email protected]>
  • Loading branch information
susnux committed Aug 8, 2024
1 parent e49c55d commit 430625e
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 0 deletions.
123 changes: 123 additions & 0 deletions apps/systemtags/src/files_actions/openInFilesAction.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { action } from './openInFilesAction'
import { expect } from '@jest/globals'
import { File, Folder, Permission, View, DefaultType, FileAction } from '@nextcloud/files'

const view = {
id: 'files',
name: 'Files',
} as View

const systemTagsView = {
id: 'tags',
name: 'tags',
} as View

const validNode = new Folder({
id: 1,
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foo',
owner: 'admin',
mime: 'httpd/unix-directory',
root: '/files/admin',
permissions: Permission.ALL,
})

const validTag = new Folder({
id: 1,
source: 'https://cloud.domain.com/remote.php/dav/systemtags/2',
displayname: 'Foo',
owner: 'admin',
mime: 'httpd/unix-directory',
root: '/systemtags',
permissions: Permission.ALL,
attributes: {
'is-tag': true,
},
})

describe('Open in files action conditions tests', () => {
test('Default values', () => {
expect(action).toBeInstanceOf(FileAction)
expect(action.id).toBe('systemtags:open-in-files')
expect(action.displayName([], systemTagsView)).toBe('Open in Files')
expect(action.iconSvgInline([], systemTagsView)).toBe('')
expect(action.default).toBe(DefaultType.HIDDEN)
expect(action.order).toBe(-1000)
expect(action.inline).toBeUndefined()
})
})

describe('Open in files action enabled tests', () => {
test('Enabled with on valid view', () => {
expect(action.enabled).toBeDefined()
expect(action.enabled!([validNode], systemTagsView)).toBe(true)
})

test('Disabled on wrong view', () => {
expect(action.enabled).toBeDefined()
expect(action.enabled!([validNode], view)).toBe(false)
})

test('Disabled without nodes', () => {
expect(action.enabled).toBeDefined()
expect(action.enabled!([], view)).toBe(false)
})

test('Disabled with too many nodes', () => {
expect(action.enabled).toBeDefined()
expect(action.enabled!([validNode, validNode], view)).toBe(false)
})

test('Disabled with when node is a tag', () => {
expect(action.enabled).toBeDefined()
expect(action.enabled!([validTag], view)).toBe(false)
})
})

describe('Open in files action execute tests', () => {
test('Open in files', async () => {
const goToRouteMock = jest.fn()
// @ts-expect-error We only mock what needed, we do not need Files.Router.goTo or Files.Navigation
window.OCP = { Files: { Router: { goToRoute: goToRouteMock } } }

const file = new File({
id: 1,
source: 'https://cloud.domain.com/remote.php/dav/files/admin/Foo/foobar.txt',
owner: 'admin',
mime: 'text/plain',
root: '/files/admin',
permissions: Permission.ALL,
})

const exec = await action.exec(file, view, '/')

// Silent action
expect(exec).toBe(null)
expect(goToRouteMock).toBeCalledTimes(1)
expect(goToRouteMock).toBeCalledWith(null, { fileid: '1', view: 'files' }, { dir: '/Foo', openfile: 'true' })
})

test('Open in files with folder', async () => {
const goToRouteMock = jest.fn()
// @ts-expect-error We only mock what needed, we do not need Files.Router.goTo or Files.Navigation
window.OCP = { Files: { Router: { goToRoute: goToRouteMock } } }

const file = new Folder({
id: 1,
source: 'https://cloud.domain.com/remote.php/dav/files/admin/Foo/Bar',
owner: 'admin',
root: '/files/admin',
permissions: Permission.ALL,
})

const exec = await action.exec(file, view, '/')

// Silent action
expect(exec).toBe(null)
expect(goToRouteMock).toBeCalledTimes(1)
expect(goToRouteMock).toBeCalledWith(null, { fileid: '1', view: 'files' }, { dir: '/Foo/Bar', openfile: 'true' })
})
})
44 changes: 44 additions & 0 deletions apps/systemtags/src/files_actions/openInFilesAction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { translate as t } from '@nextcloud/l10n'
import { type Node, FileType, FileAction, DefaultType } from '@nextcloud/files'

export const action = new FileAction({
id: 'systemtags:open-in-files',
displayName: () => t('systemtags', 'Open in Files'),
iconSvgInline: () => '',

enabled(nodes, view) {
// Only for the system tags view
if (view.id !== 'tags') {
return false
}
// Only for single nodes
if (nodes.length !== 1) {
return false
}
// Do not open tags (keep the default action) and only open folders
return nodes[0].attributes['is-tag'] !== true
&& nodes[0].type === FileType.Folder
},

async exec(node: Node) {
let dir = node.dirname
if (node.type === FileType.Folder) {
dir = node.path
}

window.OCP.Files.Router.goToRoute(
null, // use default route
{ view: 'files', fileid: String(node.fileid) },
{ dir, openfile: 'true' },
)
return null
},

// Before openFolderAction
order: -1000,
default: DefaultType.HIDDEN,
})
2 changes: 2 additions & 0 deletions apps/systemtags/src/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
*/
import { registerDavProperty, registerFileAction } from '@nextcloud/files'
import { action as inlineSystemTagsAction } from './files_actions/inlineSystemTagsAction.js'
import { action as openInFilesAction } from './files_actions/openInFilesAction.js'
import { registerSystemTagsView } from './files_views/systemtagsView.js'

registerDavProperty('nc:system-tags')
registerFileAction(inlineSystemTagsAction)
registerFileAction(openInFilesAction)

registerSystemTagsView()

0 comments on commit 430625e

Please sign in to comment.