|
|
|
@ -39,20 +39,56 @@ |
|
|
|
:force-name="true" |
|
|
|
:force-menu="enabledInlineActions.length === 0 /* forceMenu only if no inline actions */" |
|
|
|
:inline="enabledInlineActions.length" |
|
|
|
:open.sync="openedMenu"> |
|
|
|
<NcActionButton v-for="action in enabledMenuActions" |
|
|
|
:key="action.id" |
|
|
|
:class="'files-list__row-action-' + action.id" |
|
|
|
:close-after-click="true" |
|
|
|
:data-cy-files-list-row-action="action.id" |
|
|
|
:title="action.title?.([source], currentView)" |
|
|
|
@click="onActionClick(action)"> |
|
|
|
<template #icon> |
|
|
|
<NcLoadingIcon v-if="loading === action.id" :size="18" /> |
|
|
|
<NcIconSvgWrapper v-else :svg="action.iconSvgInline([source], currentView)" /> |
|
|
|
</template> |
|
|
|
{{ actionDisplayName(action) }} |
|
|
|
</NcActionButton> |
|
|
|
:open.sync="openedMenu" |
|
|
|
@close="openedSubmenu = null"> |
|
|
|
<!-- Default actions list--> |
|
|
|
<template> |
|
|
|
<NcActionButton v-for="action in enabledMenuActions" |
|
|
|
:key="action.id" |
|
|
|
:class="{ |
|
|
|
[`files-list__row-action-${action.id}`]: true, |
|
|
|
[`files-list__row-action--menu`]: isMenu(action.id) |
|
|
|
}" |
|
|
|
:close-after-click="!isMenu(action.id)" |
|
|
|
:data-cy-files-list-row-action="action.id" |
|
|
|
:title="action.title?.([source], currentView)" |
|
|
|
@click="onActionClick(action)"> |
|
|
|
<template #icon> |
|
|
|
<ChevronRightIcon v-if="isMenu(action.id)" /> |
|
|
|
<NcLoadingIcon v-else-if="loading === action.id" :size="18" /> |
|
|
|
<NcIconSvgWrapper v-else :svg="action.iconSvgInline([source], currentView)" /> |
|
|
|
</template> |
|
|
|
{{ actionDisplayName(action) }} |
|
|
|
</NcActionButton> |
|
|
|
</template> |
|
|
|
|
|
|
|
<!-- Submenu actions list--> |
|
|
|
<template v-if="openedSubmenu && enabledSubmenuActions[openedSubmenu]"> |
|
|
|
<!-- Back to top-level button --> |
|
|
|
<NcActionButton class="files-list__row-action-back" @click="openedSubmenu = ''"> |
|
|
|
<template #icon> |
|
|
|
<ArrowLeftIcon /> |
|
|
|
</template> |
|
|
|
{{ t('files', 'Back') }} |
|
|
|
</NcActionButton> |
|
|
|
<NcActionSeparator /> |
|
|
|
|
|
|
|
<!-- Submenu actions --> |
|
|
|
<NcActionButton v-for="action in enabledSubmenuActions[openedSubmenu]" |
|
|
|
:key="action.id" |
|
|
|
:class="`files-list__row-action-${action.id}`" |
|
|
|
class="files-list__row-action--submenu" |
|
|
|
:close-after-click="true" |
|
|
|
:data-cy-files-list-row-action="action.id" |
|
|
|
:title="action.title?.([source], currentView)" |
|
|
|
@click="onActionClick(action)"> |
|
|
|
<template #icon> |
|
|
|
<NcLoadingIcon v-if="loading === action.id" :size="18" /> |
|
|
|
<NcIconSvgWrapper v-else :svg="action.iconSvgInline([source], currentView)" /> |
|
|
|
</template> |
|
|
|
{{ actionDisplayName(action) }} |
|
|
|
</NcActionButton> |
|
|
|
</template> |
|
|
|
</NcActions> |
|
|
|
</td> |
|
|
|
</template> |
|
|
|
@ -63,8 +99,11 @@ import { showError, showSuccess } from '@nextcloud/dialogs' |
|
|
|
import { translate as t } from '@nextcloud/l10n'; |
|
|
|
import Vue, { PropType } from 'vue' |
|
|
|
|
|
|
|
import ArrowLeftIcon from 'vue-material-design-icons/ArrowLeft.vue' |
|
|
|
import ChevronRightIcon from 'vue-material-design-icons/ChevronRight.vue' |
|
|
|
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js' |
|
|
|
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js' |
|
|
|
import NcActionSeparator from '@nextcloud/vue/dist/Components/NcActionSeparator.js' |
|
|
|
import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js' |
|
|
|
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js' |
|
|
|
|
|
|
|
@ -78,11 +117,14 @@ export default Vue.extend({ |
|
|
|
name: 'FileEntryActions', |
|
|
|
|
|
|
|
components: { |
|
|
|
ArrowLeftIcon, |
|
|
|
ChevronRightIcon, |
|
|
|
CustomElementRender, |
|
|
|
NcActionButton, |
|
|
|
NcActions, |
|
|
|
NcActionSeparator, |
|
|
|
NcIconSvgWrapper, |
|
|
|
NcLoadingIcon, |
|
|
|
CustomElementRender, |
|
|
|
}, |
|
|
|
|
|
|
|
props: { |
|
|
|
@ -108,8 +150,9 @@ export default Vue.extend({ |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
setup() { |
|
|
|
data() { |
|
|
|
return { |
|
|
|
openedSubmenu: '', |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
@ -159,7 +202,13 @@ export default Vue.extend({ |
|
|
|
|
|
|
|
// Actions shown in the menu |
|
|
|
enabledMenuActions() { |
|
|
|
return [ |
|
|
|
// If we're in a submenu, only render the inline |
|
|
|
// actions before the filtered submenu |
|
|
|
if (this.openedSubmenu) { |
|
|
|
return this.enabledInlineActions |
|
|
|
} |
|
|
|
|
|
|
|
const actions = [ |
|
|
|
// Showing inline first for the NcActions inline prop |
|
|
|
...this.enabledInlineActions, |
|
|
|
// Then the rest |
|
|
|
@ -168,6 +217,24 @@ export default Vue.extend({ |
|
|
|
// Then we filter duplicates to prevent inline actions to be shown twice |
|
|
|
return index === self.findIndex(action => action.id === value.id) |
|
|
|
}) |
|
|
|
|
|
|
|
// Generate list of all top-level actions ids |
|
|
|
const topActionsIds = actions.filter(action => !action.parent).map(action => action.id) as string[] |
|
|
|
|
|
|
|
// Filter actions that are not top-level AND have a valid parent |
|
|
|
return actions.filter(action => !(action.parent && topActionsIds.includes(action.parent))) |
|
|
|
}, |
|
|
|
|
|
|
|
enabledSubmenuActions() { |
|
|
|
return this.enabledActions |
|
|
|
.filter(action => action.parent) |
|
|
|
.reduce((arr, action) => { |
|
|
|
if (!arr[action.parent]) { |
|
|
|
arr[action.parent] = [] |
|
|
|
} |
|
|
|
arr[action.parent].push(action) |
|
|
|
return arr |
|
|
|
}, {} as Record<string, FileAction>) |
|
|
|
}, |
|
|
|
|
|
|
|
openedMenu: { |
|
|
|
@ -201,6 +268,12 @@ export default Vue.extend({ |
|
|
|
}, |
|
|
|
|
|
|
|
async onActionClick(action) { |
|
|
|
// If the action is a submenu, we open it |
|
|
|
if (this.enabledSubmenuActions[action.id]) { |
|
|
|
this.openedSubmenu = action.id |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
const displayName = action.displayName([this.source], this.currentView) |
|
|
|
try { |
|
|
|
// Set the loading marker |
|
|
|
@ -237,6 +310,10 @@ export default Vue.extend({ |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
isMenu(id: string) { |
|
|
|
return this.enabledSubmenuActions[id]?.length > 0 |
|
|
|
}, |
|
|
|
|
|
|
|
t, |
|
|
|
}, |
|
|
|
}) |
|
|
|
|