diff options
author | Ferdinand Thiessen <opensource@fthiessen.de> | 2024-07-26 01:42:31 +0200 |
---|---|---|
committer | Ferdinand Thiessen <opensource@fthiessen.de> | 2024-08-01 01:54:42 +0200 |
commit | a39f13e94e3b943f2b073e0aa2dfd9d4e3b5f6b8 (patch) | |
tree | 09482793f3753158d83991f781eb3eb0a5b76b55 /apps/files/src/components/FileEntry | |
parent | bfde05340a22fbb97eec6645eb74e7e0372eada2 (diff) | |
download | nextcloud-server-a39f13e94e3b943f2b073e0aa2dfd9d4e3b5f6b8.tar.gz nextcloud-server-a39f13e94e3b943f2b073e0aa2dfd9d4e3b5f6b8.zip |
fix(files): Provide file actions from list entry to make it reactive
This fixes non reactive default action text of the name component.
Also use download action as default action so that only one place
is needed to define how to download a file.
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
Diffstat (limited to 'apps/files/src/components/FileEntry')
-rw-r--r-- | apps/files/src/components/FileEntry/FileEntryActions.vue | 41 | ||||
-rw-r--r-- | apps/files/src/components/FileEntry/FileEntryName.vue | 54 |
2 files changed, 39 insertions, 56 deletions
diff --git a/apps/files/src/components/FileEntry/FileEntryActions.vue b/apps/files/src/components/FileEntry/FileEntryActions.vue index 3df4289b1a0..f886d4be3ec 100644 --- a/apps/files/src/components/FileEntry/FileEntryActions.vue +++ b/apps/files/src/components/FileEntry/FileEntryActions.vue @@ -79,10 +79,10 @@ import type { PropType, ShallowRef } from 'vue' import type { FileAction, Node, View } from '@nextcloud/files' -import { DefaultType, NodeStatus, getFileActions } from '@nextcloud/files' +import { DefaultType, NodeStatus } from '@nextcloud/files' import { showError, showSuccess } from '@nextcloud/dialogs' import { translate as t } from '@nextcloud/l10n' -import { defineComponent } from 'vue' +import { defineComponent, inject } from 'vue' import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js' import NcActions from '@nextcloud/vue/dist/Components/NcActions.js' @@ -95,9 +95,6 @@ import CustomElementRender from '../CustomElementRender.vue' import { useNavigation } from '../../composables/useNavigation' import logger from '../../logger.js' -// The registered actions list -const actions = getFileActions() - export default defineComponent({ name: 'FileEntryActions', @@ -136,10 +133,12 @@ export default defineComponent({ setup() { const { currentView } = useNavigation() + const enabledFileActions = inject<FileAction[]>('enabledFileActions', []) return { // The file list is guaranteed to be only shown with active view currentView: currentView as ShallowRef<View>, + enabledFileActions, } }, @@ -158,23 +157,12 @@ export default defineComponent({ return this.source.status === NodeStatus.LOADING }, - // Sorted actions that are enabled for this node - enabledActions() { - if (this.source.status === NodeStatus.FAILED) { - return [] - } - - return actions - .filter(action => !action.enabled || action.enabled([this.source], this.currentView)) - .sort((a, b) => (a.order || 0) - (b.order || 0)) - }, - // Enabled action that are displayed inline enabledInlineActions() { if (this.filesListWidth < 768 || this.gridMode) { return [] } - return this.enabledActions.filter(action => action?.inline?.(this.source, this.currentView)) + return this.enabledFileActions.filter(action => action?.inline?.(this.source, this.currentView)) }, // Enabled action that are displayed inline with a custom render function @@ -182,12 +170,7 @@ export default defineComponent({ if (this.gridMode) { return [] } - return this.enabledActions.filter(action => typeof action.renderInline === 'function') - }, - - // Default actions - enabledDefaultActions() { - return this.enabledActions.filter(action => !!action?.default) + return this.enabledFileActions.filter(action => typeof action.renderInline === 'function') }, // Actions shown in the menu @@ -202,7 +185,7 @@ export default defineComponent({ // Showing inline first for the NcActions inline prop ...this.enabledInlineActions, // Then the rest - ...this.enabledActions.filter(action => action.default !== DefaultType.HIDDEN && typeof action.renderInline !== 'function'), + ...this.enabledFileActions.filter(action => action.default !== DefaultType.HIDDEN && typeof action.renderInline !== 'function'), ].filter((value, index, self) => { // Then we filter duplicates to prevent inline actions to be shown twice return index === self.findIndex(action => action.id === value.id) @@ -216,7 +199,7 @@ export default defineComponent({ }, enabledSubmenuActions() { - return this.enabledActions + return this.enabledFileActions .filter(action => action.parent) .reduce((arr, action) => { if (!arr[action.parent!]) { @@ -305,14 +288,6 @@ export default defineComponent({ } } }, - execDefaultAction(event) { - if (this.enabledDefaultActions.length > 0) { - event.preventDefault() - event.stopPropagation() - // Execute the first default action if any - this.enabledDefaultActions[0].exec(this.source, this.currentView, this.currentDir) - } - }, isMenu(id: string) { return this.enabledSubmenuActions[id]?.length > 0 diff --git a/apps/files/src/components/FileEntry/FileEntryName.vue b/apps/files/src/components/FileEntry/FileEntryName.vue index 7a6ad2a1051..329ec7fdf19 100644 --- a/apps/files/src/components/FileEntry/FileEntryName.vue +++ b/apps/files/src/components/FileEntry/FileEntryName.vue @@ -37,19 +37,20 @@ </template> <script lang="ts"> -import type { Node } from '@nextcloud/files' +import type { FileAction, Node } from '@nextcloud/files' import type { PropType } from 'vue' import axios, { isAxiosError } from '@nextcloud/axios' import { showError, showSuccess } from '@nextcloud/dialogs' import { emit } from '@nextcloud/event-bus' -import { FileType, NodeStatus, Permission } from '@nextcloud/files' +import { FileType, NodeStatus } from '@nextcloud/files' import { translate as t } from '@nextcloud/l10n' -import { defineComponent } from 'vue' +import { defineComponent, inject } from 'vue' import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js' import { useNavigation } from '../../composables/useNavigation' +import { useRouteParameters } from '../../composables/useRouteParameters.ts' import { useRenamingStore } from '../../store/renaming.ts' import { getFilenameValidity } from '../../utils/filenameValidity.ts' import logger from '../../logger.js' @@ -98,8 +99,11 @@ export default defineComponent({ const { currentView } = useNavigation() const renamingStore = useRenamingStore() + const defaultFileAction = inject<FileAction | undefined>('defaultFileAction') + return { currentView, + defaultFileAction, renamingStore, } @@ -139,32 +143,20 @@ export default defineComponent({ } } - const enabledDefaultActions = this.$parent?.$refs?.actions?.enabledDefaultActions - if (enabledDefaultActions?.length > 0) { - const action = enabledDefaultActions[0] - const displayName = action.displayName([this.source], this.currentView) + if (this.defaultFileAction && this.currentView) { + const displayName = this.defaultFileAction.displayName([this.source], this.currentView) return { - is: 'a', + is: 'button', params: { + 'aria-label': displayName, title: displayName, - role: 'button', - tabindex: '0', - }, - } - } - - if (this.source?.permissions & Permission.READ) { - return { - is: 'a', - params: { - download: this.source.basename, - href: this.source.source, - title: t('files', 'Download file {name}', { name: `${this.basename}${this.extension}` }), tabindex: '0', }, } } + // nothing interactive here, there is no default action + // so if not even the download action works we only can show the list entry return { is: 'span', } @@ -280,12 +272,15 @@ export default defineComponent({ // Reset the renaming store this.stopRenaming() this.$nextTick(() => { - this.$refs.basename?.focus() + const nameContainter = this.$refs.basename as HTMLElement | undefined + nameContainter?.focus() }) } catch (error) { logger.error('Error while renaming file', { error }) + // Rename back as it failed this.source.rename(oldName) - this.$refs.renameInput?.focus() + // And ensure we reset to the renaming state + this.startRenaming() if (isAxiosError(error)) { // TODO: 409 means current folder does not exist, redirect ? @@ -309,3 +304,16 @@ export default defineComponent({ }, }) </script> + +<style scoped lang="scss"> +button.files-list__row-name-link { + background-color: unset; + border: none; + font-weight: normal; + + &:active { + // No active styles - handled by the row entry + background-color: unset !important; + } +} +</style> |