mirror of
https://github.com/nextcloud/server.git
synced 2026-06-11 01:30:50 -04:00
Merge pull request #38441 from nextcloud/feat/make-open-folder-action
fix(files): make open folder a default action
This commit is contained in:
commit
b8ae166eb2
5 changed files with 90 additions and 19 deletions
69
apps/files/src/actions/openFolderAction.ts
Normal file
69
apps/files/src/actions/openFolderAction.ts
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import { Permission, Node, FileType } from '@nextcloud/files'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import Folder from '@mdi/svg/svg/folder.svg?raw'
|
||||
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
import { join } from 'path'
|
||||
import { registerFileAction, FileAction } from '../services/FileAction'
|
||||
|
||||
registerFileAction(new FileAction({
|
||||
id: 'open-folder',
|
||||
displayName(files: Node[]) {
|
||||
// Only works on single node
|
||||
const displayName = files[0].attributes.displayName || files[0].basename
|
||||
return t('files', 'Open folder {displayName}', { displayName })
|
||||
},
|
||||
iconSvgInline: () => Folder,
|
||||
|
||||
enabled(nodes: Node[]) {
|
||||
// Only works on single node
|
||||
if (nodes.length !== 1) {
|
||||
return false
|
||||
}
|
||||
|
||||
const node = nodes[0]
|
||||
return node.type === FileType.Folder
|
||||
&& (node.permissions & Permission.READ) !== 0
|
||||
},
|
||||
|
||||
async exec(node: Node, view: Navigation, dir: string) {
|
||||
if (!node || node.type !== FileType.Folder) {
|
||||
return false
|
||||
}
|
||||
|
||||
window.OCP.Files.Router.goToRoute(
|
||||
null,
|
||||
null,
|
||||
{ dir: join(dir, node.basename) },
|
||||
)
|
||||
return null
|
||||
},
|
||||
async execBatch(nodes: Node[], view: Navigation, dir: string) {
|
||||
return Promise.all(nodes.map(node => this.exec(node, view, dir)))
|
||||
},
|
||||
|
||||
// Main action if enabled, meaning folders only
|
||||
order: -100,
|
||||
default: true,
|
||||
}))
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
<!-- Link to file -->
|
||||
<td class="files-list__row-name">
|
||||
<a ref="name" v-bind="linkTo" @click="execDefaultAction">
|
||||
<a ref="name" v-bind="linkAttrs" @click="execDefaultAction">
|
||||
<!-- Icon or preview -->
|
||||
<span class="files-list__row-icon">
|
||||
<FolderIcon v-if="source.type === 'folder'" />
|
||||
|
|
@ -261,7 +261,22 @@ export default Vue.extend({
|
|||
return minOpacity + (1 - minOpacity) * Math.pow((this.source.size / maxOpacitySize), 2)
|
||||
},
|
||||
|
||||
linkTo() {
|
||||
linkAttrs() {
|
||||
if (this.enabledDefaultActions.length > 0) {
|
||||
const action = this.enabledDefaultActions[0]
|
||||
const displayName = action.displayName([this.source], this.currentView)
|
||||
return {
|
||||
class: ['files-list__row-default-action', 'files-list__row-action-' + action.id],
|
||||
role: 'button',
|
||||
title: displayName,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A folder would never reach this point
|
||||
* as it has open-folder as default action.
|
||||
* Just to be safe, let's handle it.
|
||||
*/
|
||||
if (this.source.type === 'folder') {
|
||||
const to = { ...this.$route, query: { dir: join(this.dir, this.source.basename) } }
|
||||
return {
|
||||
|
|
@ -271,15 +286,6 @@ export default Vue.extend({
|
|||
}
|
||||
}
|
||||
|
||||
if (this.enabledDefaultActions.length > 0) {
|
||||
const action = this.enabledDefaultActions[0]
|
||||
const displayName = action.displayName([this.source], this.currentView)
|
||||
return {
|
||||
title: displayName,
|
||||
role: 'button',
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
href: this.source.source,
|
||||
// TODO: Use first action title ?
|
||||
|
|
@ -526,11 +532,6 @@ export default Vue.extend({
|
|||
}
|
||||
},
|
||||
execDefaultAction(event) {
|
||||
// Do not execute the default action on the folder, navigate instead
|
||||
if (this.source.type === 'folder') {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.enabledDefaultActions.length > 0) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import './templates.js'
|
||||
import './legacy/filelistSearch.js'
|
||||
import './actions/deleteAction'
|
||||
import './actions/openFolderAction'
|
||||
import './actions/sidebarAction'
|
||||
|
||||
import Vue from 'vue'
|
||||
|
|
|
|||
4
dist/files-main.js
vendored
4
dist/files-main.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files-main.js.map
vendored
2
dist/files-main.js.map
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue