Skip to content

Commit

Permalink
Merge pull request #49685 from nextcloud/fix/fail-safe-files-actions
Browse files Browse the repository at this point in the history
  • Loading branch information
skjnldsv authored Dec 11, 2024
2 parents 3baa91d + cb08c9f commit 91a83b6
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 19 deletions.
39 changes: 29 additions & 10 deletions apps/files/src/components/FileEntry/FileEntryActions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,14 @@ export default defineComponent({
if (this.filesListWidth < 768 || this.gridMode) {
return []
}
return this.enabledFileActions.filter(action => action?.inline?.(this.source, this.currentView))
return this.enabledFileActions.filter(action => {
try {
return action?.inline?.(this.source, this.currentView)
} catch (error) {
logger.error('Error while checking if action is inline', { action, error })
return false
}
})
},

// Enabled action that are displayed inline with a custom render function
Expand Down Expand Up @@ -236,13 +243,19 @@ export default defineComponent({

methods: {
actionDisplayName(action: FileAction) {
if ((this.gridMode || (this.filesListWidth < 768 && action.inline)) && typeof action.title === 'function') {
// if an inline action is rendered in the menu for
// lack of space we use the title first if defined
const title = action.title([this.source], this.currentView)
if (title) return title
try {
if ((this.gridMode || (this.filesListWidth < 768 && action.inline)) && typeof action.title === 'function') {
// if an inline action is rendered in the menu for
// lack of space we use the title first if defined
const title = action.title([this.source], this.currentView)
if (title) return title
}
return action.displayName([this.source], this.currentView)
} catch (error) {
logger.error('Error while getting action display name', { action, error })
// Not ideal, but better than nothing
return action.id
}
return action.displayName([this.source], this.currentView)
},

async onActionClick(action, isSubmenu = false) {
Expand All @@ -257,7 +270,13 @@ export default defineComponent({
return
}

const displayName = action.displayName([this.source], this.currentView)
let displayName = action.id
try {
displayName = action.displayName([this.source], this.currentView)
} catch (error) {
logger.error('Error while getting action display name', { action, error })
}

try {
// Set the loading marker
this.$emit('update:loading', action.id)
Expand All @@ -275,8 +294,8 @@ export default defineComponent({
return
}
showError(t('files', '"{displayName}" action failed', { displayName }))
} catch (e) {
logger.error('Error while executing action', { action, e })
} catch (error) {
logger.error('Error while executing action', { action, error })
showError(t('files', '"{displayName}" action failed', { displayName }))
} finally {
// Reset the loading marker
Expand Down
25 changes: 19 additions & 6 deletions apps/files/src/components/FileEntryMixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@
import type { PropType } from 'vue'
import type { FileSource } from '../types.ts'

import { showError } from '@nextcloud/dialogs'
import { extname } from 'path'
import { FileType, Permission, Folder, File as NcFile, NodeStatus, Node, getFileActions } from '@nextcloud/files'
import { translate as t } from '@nextcloud/l10n'
import { generateUrl } from '@nextcloud/router'
import { isPublicShare } from '@nextcloud/sharing/public'
import { showError } from '@nextcloud/dialogs'
import { t } from '@nextcloud/l10n'
import { vOnClickOutside } from '@vueuse/components'
import { extname } from 'path'
import Vue, { computed, defineComponent } from 'vue'

import { action as sidebarAction } from '../actions/sidebarAction.ts'
import { dataTransferToFileTree, onDropExternalFiles, onDropInternalFiles } from '../services/DropService.ts'
import { getDragAndDropPreview } from '../utils/dragUtils.ts'
import { hashCode } from '../utils/hashUtils.ts'
import { dataTransferToFileTree, onDropExternalFiles, onDropInternalFiles } from '../services/DropService.ts'
import logger from '../logger.ts'
import { isDownloadable } from '../utils/permissions.ts'
import logger from '../logger.ts'

Vue.directive('onClickOutside', vOnClickOutside)

Expand Down Expand Up @@ -200,7 +200,20 @@ export default defineComponent({
}

return actions
.filter(action => !action.enabled || action.enabled([this.source], this.currentView))
.filter(action => {
if (!action.enabled) {
return true
}

// In case something goes wrong, since we don't want to break
// the entire list, we filter out actions that throw an error.
try {
return action.enabled([this.source], this.currentView)
} catch (error) {
logger.error('Error while checking action', { action, error })
return false
}
})
.sort((a, b) => (a.order || 0) - (b.order || 0))
},

Expand Down
4 changes: 2 additions & 2 deletions dist/files-main.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files-main.js.map

Large diffs are not rendered by default.

0 comments on commit 91a83b6

Please sign in to comment.