Skip to content

Commit

Permalink
Add navigate to trash for spaces (#10179)
Browse files Browse the repository at this point in the history
* Add navigate to trash for spaces

* Update snapshots

* fix func signature

* Add unit tests
  • Loading branch information
AlexAndBear authored Dec 15, 2023
1 parent 2b3fe6a commit 3daa591
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 1 deletion.
6 changes: 6 additions & 0 deletions changelog/unreleased/bugfix-space-navigate-to-trash-missing
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Bugfix: Space navigate to trash missing

We've fixed the bug that it was not possible to directly navigate into a space-specific trash,
from within the space root.

https://github.com/owncloud/web/pull/10179
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
</template>

<script lang="ts">
import { ContextActionMenu } from '@ownclouders/web-pkg'
import { ContextActionMenu, useSpaceActionsNavigateToTrash } from '@ownclouders/web-pkg'
import { QuotaModal } from '@ownclouders/web-pkg'
import { ReadmeContentModal } from '@ownclouders/web-pkg'
Expand Down Expand Up @@ -94,6 +94,7 @@ export default defineComponent({
const { actions: showDetailsActions } = useFileActionsShowDetails({ store })
const { actions: showMembersActions } = useSpaceActionsShowMembers({ store })
const { actions: downloadArchiveActions } = useFileActionsDownloadArchive({ store })
const { actions: navigateToTrashActions } = useSpaceActionsNavigateToTrash()
const spaceImageInput: VNodeRef = ref(null)
const { actions: uploadImageActions, uploadImageSpace } = useSpaceActionsUploadImage({
Expand Down Expand Up @@ -126,6 +127,7 @@ export default defineComponent({
...unref(editQuotaActions),
...unref(disableActions),
...unref(restoreActions),
...unref(navigateToTrashActions),
...unref(deleteActions)
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ exports[`SpaceContextActions action handlers renders actions that are always ava
<!--v-if-->
</button>
</li>
<li class="context-menu oc-files-context-action oc-px-s oc-rounded oc-menu-item-hover">
<button aria-label="" class="oc-button oc-rounded oc-button-s oc-button-justify-content-left oc-button-gap-m oc-button-passive oc-button-passive-raw oc-files-actions-navigate-to-trash-trigger action-menu-item oc-py-s oc-px-m oc-width-1-1" type="button">
<!--v-if-->
<!-- @slot Content of the button -->
<span class="oc-icon oc-icon-m oc-icon-passive">
<!---->
</span>
<span class="oc-files-context-action-label">Show deleted files</span>
<!--v-if-->
<!--v-if-->
</button>
</li>
</ul>
<ul class="oc-list oc-my-rm oc-mx-rm oc-files-context-actions oc-pt-s" id="oc-files-context-actions-sidebar">
<li class="context-menu oc-files-context-action oc-px-s oc-rounded oc-menu-item-hover">
Expand Down
1 change: 1 addition & 0 deletions packages/web-pkg/src/composables/actions/spaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export * from './useSpaceActionsEditReadmeContent'
export * from './useSpaceActionsRename'
export * from './useSpaceActionsRestore'
export * from './useSpaceActionsShowMembers'
export * from './useSpaceActionsNavigateToTrash'
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { computed } from 'vue'
import { SpaceAction } from '../types'
import { useGettext } from 'vue3-gettext'
import { useRouter } from '../../router'
import { SpaceResource } from '@ownclouders/web-client'
import { createLocationTrash } from '../../../router'
import { createFileRouteOptions } from '../../../helpers'
import { isProjectSpaceResource } from '@ownclouders/web-client/src/helpers'

export const useSpaceActionsNavigateToTrash = () => {
const router = useRouter()
const { $gettext } = useGettext()

const getTrashLink = (space: SpaceResource) => {
return createLocationTrash('files-trash-generic', {
...createFileRouteOptions(space, { fileId: space.fileId })
})
}

const actions = computed((): SpaceAction[] => [
{
name: 'navigateToTrash',
icon: 'delete-bin',
label: () => $gettext('Show deleted files'),
handler: ({ resources }) => {
router.push(getTrashLink(resources[0]))
},
isEnabled: ({ resources }) => {
if (resources.length !== 1) {
return false
}

if (!isProjectSpaceResource(resources[0])) {
return false
}

if (resources[0].disabled) {
return false
}

return true
},
componentType: 'button',
class: 'oc-files-actions-navigate-to-trash-trigger'
}
])

return {
actions
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { useSpaceActionsNavigateToTrash } from '../../../../../src'
import { mock } from 'jest-mock-extended'
import {
createStore,
defaultComponentMocks,
defaultStoreMockOptions,
RouteLocation,
getComposableWrapper
} from 'web-test-helpers'
import { unref } from 'vue'
import { SpaceResource } from '@ownclouders/web-client/src'

describe('navigateToSpace', () => {
describe('isEnabled property', () => {
it('should be false when no resource given', () => {
getWrapper({
setup: ({ actions }) => {
expect(unref(actions)[0].isEnabled({ resources: [] })).toBe(false)
}
})
})
it('should be false when the space is disabled', () => {
getWrapper({
setup: ({ actions }) => {
expect(
unref(actions)[0].isEnabled({
resources: [
mock<SpaceResource>({
disabled: true,
driveType: 'project'
})
]
})
).toBe(false)
}
})
})
it('should be false when the space is no project space', () => {
getWrapper({
setup: ({ actions }) => {
expect(
unref(actions)[0].isEnabled({
resources: [
mock<SpaceResource>({
disabled: false,
driveType: 'personal'
})
]
})
).toBe(false)
}
})
})
})
describe('handler', () => {
it('should redirect to respective trash', async () => {
const { mocks } = getWrapper({
setup: async ({ actions }) => {
await unref(actions)[0].handler({
resources: [mock<SpaceResource>()]
})
expect(mocks.$router.push).toHaveBeenCalled()
}
})
})
})
})

function getWrapper({
setup
}: {
setup: (
instance: ReturnType<typeof useSpaceActionsNavigateToTrash>,
{
storeOptions
}: {
storeOptions: typeof defaultStoreMockOptions
}
) => void
}) {
const storeOptions = {
...defaultStoreMockOptions,
modules: { ...defaultStoreMockOptions.modules, user: { state: { id: 'alice', uuid: 1 } } }
}
const store = createStore(storeOptions)
const mocks = defaultComponentMocks({
currentRoute: mock<RouteLocation>({ name: 'files-spaces-projects' })
})
return {
mocks,
wrapper: getComposableWrapper(
() => {
const instance = useSpaceActionsNavigateToTrash()
setup(instance, { storeOptions })
},
{
store,
mocks,
provide: mocks
}
)
}
}

0 comments on commit 3daa591

Please sign in to comment.