Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[full-ci] Enhancement: Add whitespace context-menu #8921

Merged
merged 21 commits into from
May 9, 2023
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
6 changes: 6 additions & 0 deletions changelog/unreleased/enhancement-add-whitespace-context-menu
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Enhancement: Add whitespace context-menu

We've added a generic context-menu for right clicking on whitespace.

https://github.com/owncloud/web/pull/8921
https://github.com/owncloud/web/issues/5861
2 changes: 1 addition & 1 deletion packages/design-system/src/components/OcTable/OcTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
</oc-th>
</oc-tr>
</oc-thead>
<oc-tbody>
<oc-tbody class="has-item-context-menu">
<oc-tr
v-for="(item, trIndex) in data"
:key="`oc-tbody-tr-${itemDomSelector(item) || trIndex}`"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ exports[`SpacesList should render all spaces in a table 1`] = `
</th>
</tr>
</thead>
<tbody>
<tbody class="has-item-context-menu">
<tr class="oc-tbody-tr oc-tbody-tr-1" data-item-id="1" draggable="false" tabindex="-1">
<td class="oc-table-cell oc-table-cell-align-left oc-table-cell-align-middle oc-table-cell-width-shrink oc-td oc-table-data-cell oc-table-data-cell-select oc-pl-s">
<oc-checkbox-stub class="oc-ml-s" disabled="false" hidelabel="true" id="oc-checkbox-2" label="Select 1 Some space" modelvalue="false" option="[object Object]" outline="false" size="large"></oc-checkbox-stub>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
</oc-drop>
</div>
<oc-list class="oc-tiles oc-flex" :class="resizable ? 'resizableTiles' : ''">
<li v-for="resource in data" :key="resource.id" class="oc-tiles-item">
<li v-for="resource in data" :key="resource.id" class="oc-tiles-item has-item-context-menu">
<oc-tile
:ref="(el) => (tileRefs.tiles[resource.id] = el)"
:resource="resource"
Expand Down
100 changes: 100 additions & 0 deletions packages/web-app-files/src/components/Spaces/WhitespaceContextMenu.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<template>
<oc-button id="context-menu-trigger-whitespace" appearance="raw">
<oc-drop
drop-id="context-menu-drop-whitespace"
toggle="#context-menu-trigger-whitespace"
position="bottom-end"
mode="click"
class="whitespace-context-actions-list"
close-on-click
padding-size="small"
>
<oc-list>
<action-menu-item
v-for="(action, actionIndex) in menuItemsActions"
:key="`section-${action.name}-action-${actionIndex}`"
:action="action"
:action-options="actionOptions"
class="oc-px-s oc-rounded oc-menu-item-hover"
:data-testid="`whitespace-context-menu-item-${action.name}`"
/>
</oc-list>
</oc-drop>
</oc-button>
</template>

<script lang="ts">
import { computed, defineComponent, PropType, unref } from 'vue'
import { useGettext } from 'vue3-gettext'
import { useFileActionsPaste, useFileActionsShowDetails } from 'web-app-files/src/composables'
import { useFileActionsCreateNewFolder } from 'web-app-files/src/composables/actions/files/useFileActionsCreateNewFolder'
import { SpaceResource } from 'web-client/src'
import { useStore } from 'web-pkg/src'
import ActionMenuItem from 'web-pkg/src/components/ContextActions/ActionMenuItem.vue'

export default defineComponent({
name: 'WhitespaceContextMenu',
components: { ActionMenuItem },
props: {
space: {
type: Object as PropType<SpaceResource>,
required: false,
default: null
}
},
setup(props) {
const { $gettext } = useGettext()
const store = useStore()
const contextMenuLabel = computed(() => $gettext('Show context menu'))
const currentFolder = computed(() => store.getters['Files/currentFolder'])
const actionOptions = computed(() => ({
space: props.space,
resources: [currentFolder.value]
}))
const { actions: createNewFolderAction } = useFileActionsCreateNewFolder({
store,
space: props.space
})
const { actions: showDetailsAction } = useFileActionsShowDetails({ store })
const { actions: pasteAction } = useFileActionsPaste({ store })

const menuItemsActions = computed(() => {
return [
...unref(createNewFolderAction),
...unref(pasteAction),
...unref(showDetailsAction)
].filter((item) => item.isEnabled(unref(actionOptions)))
})

return { contextMenuLabel, actionOptions, currentFolder, menuItemsActions }
}
})
</script>

<style lang="scss">
#context-menu-trigger-whitespace {
visibility: hidden;
width: 0;
height: 0;
}
.whitespace-context-actions-list {
.oc-card {
padding-left: 0px !important;
padding-right: 0px !important;
}
text-align: left;
white-space: normal;

a,
button,
span {
display: inline-flex;
font-weight: normal !important;
gap: 10px;
justify-content: flex-start;
vertical-align: top;
width: 100%;
text-align: left;
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ export const useFileActionsCreateNewFile = ({
icon: 'add',
handler: (args) => handler(args, newFileHandler.ext, openAction),
label: () => newFileHandler.menuTitle($gettext),
isEnabled: ({ resources }) => {
return true
isEnabled: () => {
return unref(currentFolder)?.canUpload({ user: store.getters.user })
},
canBeDefault: true,
componentType: 'button',
Expand All @@ -234,8 +234,8 @@ export const useFileActionsCreateNewFile = ({
icon: 'add',
handler: (args) => handler(args, mimeType.ext, openAction),
label: () => mimeType.name,
isEnabled: ({ resources }) => {
return true
isEnabled: () => {
return unref(currentFolder)?.canUpload({ user: store.getters.user })
},
canBeDefault: true,
componentType: 'button',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,13 @@ export const useFileActionsCreateNewFolder = ({
return [
{
name: 'create-folder',
icon: 'add',
icon: 'folder',
handler,
label: () => {
return $gettext('Create new Folder')
return $gettext('New Folder')
},
isEnabled: ({ resources }) => {
return true
isEnabled: () => {
return unref(currentFolder)?.canCreate()
},
canBeDefault: true,
componentType: 'button',
Expand Down
31 changes: 28 additions & 3 deletions packages/web-app-files/src/views/spaces/GenericSpace.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<div class="oc-flex oc-width-1-1" :class="{ 'space-frontpage': isSpaceFrontpage }">
<whitespace-context-menu ref="whitespaceContextMenu" :space="space" />
<keyboard-actions :paginated-resources="paginatedResources" :space="space" />
<files-view-wrapper>
<app-bar
Expand Down Expand Up @@ -128,7 +129,7 @@
<script lang="ts">
import { debounce, omit, last } from 'lodash-es'
import { basename } from 'path'
import { computed, defineComponent, PropType, onBeforeUnmount, onMounted, unref } from 'vue'
import { computed, defineComponent, PropType, onBeforeUnmount, onMounted, unref, ref } from 'vue'
import { RouteLocationNamedRaw } from 'vue-router'
import { mapGetters, mapState, mapActions, mapMutations, useStore } from 'vuex'
import { useGettext } from 'vue3-gettext'
Expand Down Expand Up @@ -158,6 +159,7 @@ import SideBar from '../../components/SideBar/SideBar.vue'
import SpaceHeader from '../../components/Spaces/SpaceHeader.vue'
import AppLoadingSpinner from 'web-pkg/src/components/AppLoadingSpinner.vue'
import NoContentMessage from 'web-pkg/src/components/NoContentMessage.vue'
import WhitespaceContextMenu from 'web-app-files/src/components/Spaces/WhitespaceContextMenu.vue'
import { useRoute } from 'web-pkg/src/composables'
import { useDocumentTitle } from 'web-pkg/src/composables/appDefaults/useDocumentTitle'
import { ImageType } from 'web-pkg/src/constants'
Expand All @@ -171,6 +173,7 @@ import { ResourceTransfer, TransferType } from '../../helpers/resource'
import { FolderLoaderOptions } from '../../services/folder'
import { CreateTargetRouteOptions } from 'web-app-files/src/helpers/folderLink/types'
import { BreadcrumbItem } from 'design-system/src/components/OcBreadcrumb/types'
import { displayPositionedDropdown } from 'web-pkg/src'

const visibilityObserver = new VisibilityObserver()

Expand All @@ -192,7 +195,8 @@ export default defineComponent({
ResourceTable,
ResourceTiles,
SideBar,
SpaceHeader
SpaceHeader,
WhitespaceContextMenu
},
props: {
space: {
Expand Down Expand Up @@ -393,13 +397,33 @@ export default defineComponent({
performLoaderTask(true, path, fileId)
}
)
const filesViewWrapper = document.getElementsByClassName('files-view-wrapper')[0]
filesViewWrapper?.addEventListener('contextmenu', (event) => {
const { target } = event
if ((target as HTMLElement).closest('.has-item-context-menu')) {
return
}
event.preventDefault()
const newEvent = new MouseEvent('contextmenu', event)
showContextMenu(newEvent)
})
})

onBeforeUnmount(() => {
visibilityObserver.disconnect()
eventBus.unsubscribe('app.files.list.load', loadResourcesEventToken)
})

const whitespaceContextMenu = ref(null)
const showContextMenu = (event) => {
lookacat marked this conversation as resolved.
Show resolved Hide resolved
store.commit('Files/RESET_SELECTION')
displayPositionedDropdown(
unref(whitespaceContextMenu).$el._tippy,
event,
unref(whitespaceContextMenu)
)
}

return {
...useFileActions(),
...resourcesViewDefaults,
Expand All @@ -412,7 +436,8 @@ export default defineComponent({
viewModes,
uploadHint: $gettext(
'Drag files and folders here or use the "New" or "Upload" buttons to add files'
)
),
whitespaceContextMenu
}
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ exports[`ResourceTiles component renders an array of spaces correctly 1`] = `
<div>
<!--v-if-->
<oc-list class="oc-tiles oc-flex">
<li class="oc-tiles-item">
<li class="oc-tiles-item has-item-context-menu">
<oc-tile draggable="false" is-resource-selected="false" resource="[object Object]" resource-icon-size="xlarge" resource-route="[object Object]"></oc-tile>
</li>
<li class="oc-tiles-item">
<li class="oc-tiles-item has-item-context-menu">
<oc-tile draggable="false" is-resource-selected="false" resource="[object Object]" resource-icon-size="xlarge" resource-route="[object Object]"></oc-tile>
</li>
</oc-list>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,15 @@ describe('GenericSpace view', () => {
expect(wrapper.find('.file-empty-upload-hint').exists()).toBeFalsy()
})
})
describe('whitespace context menu', () => {
it('shows whitespace context menu on right click in whitespace', async () => {
const { wrapper } = getMountedWrapper()
await wrapper.vm.loadResourcesTask.last
await wrapper.find('#files-view').trigger('contextmenu')
await wrapper.vm.$nextTick()
expect(wrapper.vm.whitespaceContextMenu).toBeDefined()
})
})
})

function getMountedWrapper({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ exports[`Projects view different files view states lists all available project s
</div>
</div>
<ul class="oc-list oc-my-rm oc-mx-rm oc-tiles oc-flex resizableTiles">
<li class="oc-tiles-item">
<li class="oc-tiles-item has-item-context-menu">
<oc-tile-stub draggable="false" is-resource-selected="false" resource="[object Object]" resource-icon-size="xlarge" resource-route="[object Object]"></oc-tile-stub>
</li>
<li class="oc-tiles-item">
<li class="oc-tiles-item has-item-context-menu">
<oc-tile-stub draggable="false" is-resource-selected="false" resource="[object Object]" resource-icon-size="xlarge" resource-route="[object Object]"></oc-tile-stub>
</li>
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ exports[`TrashOverview view states should render spaces list 1`] = `
</th>
</tr>
</thead>
<tbody>
<tbody class="has-item-context-menu">
<tr class="oc-tbody-tr oc-tbody-tr-1" data-item-id="1" draggable="false" tabindex="-1">
<td class="oc-table-cell oc-table-cell-align-left oc-table-cell-align-middle oc-table-cell-width-shrink oc-td oc-table-data-cell oc-table-data-cell-icon oc-pl-s">
<span class="oc-icon oc-icon-m oc-icon-passive oc-pl-m">
Expand Down
1 change: 1 addition & 0 deletions packages/web-test-helpers/src/mocks/defaultStubs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ export const defaultStubs = {
'shared-with-me-section': true,
'side-bar': true,
'space-header': true,
'whitespace-context-menu': true,
translate: true
}