Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
v-if="recipient.shareType === ShareTypes.user.value"
:user-id="recipient.id"
:user-name="recipient.displayName"
width="16.8"
:width="16.8"
/>
</template>
<template #append>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div id="oc-trash-no-selection" class="oc-text-center oc-mt-xl">
<oc-icon size="xxlarge" name="delete-bin" fill-type="line" />
<p data-testid="selectTrashText" v-text="$gettext('Select a trash to view details')" />
<p data-testid="selectTrashText" v-text="$gettext('Select a trash bin to view details')" />
</div>
</template>
<script lang="ts">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,42 @@
<template>
<context-action-menu :menu-sections="menuSections" :action-options="actionOptions" />
<div v-if="loading" class="oc-flex oc-flex-center oc-my-m">
<oc-spinner :aria-label="$gettext('Loading actions')" />
</div>
<div v-else>
<context-action-menu :menu-sections="menuSections" :action-options="actionOptions" />
</div>
</template>

<script setup lang="ts">
import {
ContextActionMenu,
MenuSection,
SpaceActionOptions,
useFileActionsEmptyTrashBin,
useSpaceActionsNavigateToTrash
} from '@opencloud-eu/web-pkg'
import { computed, toRef, unref } from 'vue'

const props = defineProps<{
actionOptions: SpaceActionOptions
loading?: boolean
}>()

const actionOptions = toRef(props, 'actionOptions')

const { actions: navigateToTrashActions } = useSpaceActionsNavigateToTrash()
const { actions: emptyTrashBinActions } = useFileActionsEmptyTrashBin()

const menuItemsPrimaryActions = computed(() => {
const fileHandlers = [...unref(navigateToTrashActions)]
return fileHandlers.filter((item) => item.isVisible(unref(actionOptions)))
})
const menuItemsPrimaryActions = computed(() =>
[...unref(navigateToTrashActions), ...unref(emptyTrashBinActions)].filter((item) =>
item.isVisible(unref(actionOptions))
)
)

const menuSections = computed<MenuSection[]>(() => {
const sections: MenuSection[] = []

if (unref(menuItemsPrimaryActions)) {
if (unref(menuItemsPrimaryActions).length) {
sections.push({
name: 'primaryActions',
items: unref(menuItemsPrimaryActions)
Expand Down
38 changes: 38 additions & 0 deletions packages/web-app-files/src/components/Trash/TrashQuickActions.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<template>
<div v-if="!isEmbedModeEnabled" class="oc-flex">
<oc-button
v-for="action in filteredActions"
:key="action.label()"
Copy link

Copilot AI Jul 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Using action.label() as the list key may lead to duplicate keys if labels repeat. Consider using action.name for a stable, unique key.

Suggested change
:key="action.label()"
:key="action.name"

Copilot uses AI. Check for mistakes.
v-oc-tooltip="action.label()"
:aria-label="action.label()"
appearance="raw"
class="oc-ml-xs quick-action-button oc-p-xs"
:class="`files-quick-action-${action.name}`"
:disabled="action.isDisabled({ resources: [space] })"
@click="action.handler({ resources: [space] })"
>
<oc-icon :name="action.icon" fill-type="line" />
</oc-button>
</div>
</template>

<script setup lang="ts">
import { computed, unref } from 'vue'
import { useEmbedMode, useExtensionRegistry } from '@opencloud-eu/web-pkg'
import { SpaceResource } from '@opencloud-eu/web-client'
import { trashQuickActionsExtensionPoint } from '../../extensionPoints'

const props = defineProps<{
space?: SpaceResource
}>()

const extensionRegistry = useExtensionRegistry()
const { isEnabled: isEmbedModeEnabled } = useEmbedMode()

const filteredActions = computed(() => {
return unref(extensionRegistry)
.requestExtensions(trashQuickActionsExtensionPoint)
.map((e) => e.action)
.filter(({ isVisible }) => isVisible({ resources: [props.space] }))
})
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { ActionExtension, useFileActionsEmptyTrashBin } from '@opencloud-eu/web-pkg'
import { trashQuickActionsExtensionPoint } from '../../extensionPoints'
import { unref } from 'vue'

export const useTrashActions = (): ActionExtension[] => {
const { actions: emptyTrashBinActions } = useFileActionsEmptyTrashBin()

return [
{
id: 'com.github.opencloud-eu.web.files.quick-action.empty-trash-bin',
extensionPointIds: [trashQuickActionsExtensionPoint.id],
type: 'action',
action: unref(emptyTrashBinActions)[0]
}
]
}
6 changes: 6 additions & 0 deletions packages/web-app-files/src/extensionPoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export const quickActionsExtensionPoint: ExtensionPoint<ActionExtension> = {
extensionType: 'action',
multiple: true
}
export const trashQuickActionsExtensionPoint: ExtensionPoint<ActionExtension> = {
id: 'app.files.trash-quick-actions',
extensionType: 'action',
multiple: true
}
export const batchActionsExtensionPoint: ExtensionPoint<ActionExtension> = {
id: 'global.files.batch-actions',
extensionType: 'action',
Expand Down Expand Up @@ -54,6 +59,7 @@ export const extensionPoints = () => {
return [
uploadMenuExtensionPoint,
quickActionsExtensionPoint,
trashQuickActionsExtensionPoint,
batchActionsExtensionPoint,
contextActionsExtensionPoint,
defaultActionsExtensionPoint,
Expand Down
3 changes: 3 additions & 0 deletions packages/web-app-files/src/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { SDKSearch } from './search'
import { useSideBarPanels } from './composables/extensions/useFileSideBars'
import { useFolderViews } from './composables/extensions/useFolderViews'
import { useFileActions } from './composables/extensions/useFileActions'
import { useTrashActions } from './composables/extensions/useTrashActions'
import { urlJoin } from '@opencloud-eu/web-client'

export const extensions = (appInfo: ApplicationInformation) => {
Expand All @@ -22,11 +23,13 @@ export const extensions = (appInfo: ApplicationInformation) => {
const { search: searchFunction } = useSearch()

const fileActionExtensions = useFileActions()
const trashActionExtensions = useTrashActions()
const folderViewExtensions = useFolderViews()
const sideBarPanelExtensions = useSideBarPanels()

return computed<Extension[]>(() => [
...fileActionExtensions,
...trashActionExtensions,
...folderViewExtensions,
...sideBarPanelExtensions,
{
Expand Down
Loading