-
-
+ >
+
+
{{ getResourceSize(highlightedFile.size) }},
@@ -202,6 +207,22 @@ export default {
expandActionsAccordion() {
this.SET_APP_SIDEBAR_EXPANDED_ACCORDION('files-actions')
+ },
+
+ onClickOutside(event) {
+ /*
+ * We need to go for this opt-out solution because under circumstances a modal will be rendered,
+ * for example if we click rename, clicking in this modal would otherwise falsy close the sidebar.
+ */
+
+ if (
+ document.querySelector('.files-topbar').contains(event.target) ||
+ document.querySelector('.oc-topbar').contains(event.target) ||
+ document.querySelector('.oc-app-navigation').contains(event.target) ||
+ event.target.id === 'files-view'
+ ) {
+ this.close()
+ }
}
}
}
diff --git a/packages/web-app-files/src/components/Sidebar/ActionsAccordion.vue b/packages/web-app-files/src/components/Sidebar/ActionsAccordion.vue
index 4db39f1f327..8d6ad59815e 100644
--- a/packages/web-app-files/src/components/Sidebar/ActionsAccordion.vue
+++ b/packages/web-app-files/src/components/Sidebar/ActionsAccordion.vue
@@ -1,15 +1,22 @@
-
@@ -38,6 +45,37 @@ export default {
})
)
}
+ },
+ methods: {
+ getComponentProps(action, highlightedFile) {
+ if (action.componentType === 'router-link' && action.route) {
+ return {
+ to: {
+ name: action.route,
+ params: {
+ item: highlightedFile.path
+ }
+ }
+ }
+ }
+
+ return {
+ appearance: 'raw'
+ }
+ }
}
}
+
+
diff --git a/packages/web-app-files/src/mixins/actions/copy.js b/packages/web-app-files/src/mixins/actions/copy.js
index 756ea1dcfb8..af992a46c0f 100644
--- a/packages/web-app-files/src/mixins/actions/copy.js
+++ b/packages/web-app-files/src/mixins/actions/copy.js
@@ -11,7 +11,7 @@ export default {
{
icon: 'file_copy',
handler: this.$_copy_trigger,
- ariaLabel: () => this.$gettext('Copy'),
+ label: () => this.$gettext('Copy'),
isEnabled: () => {
if (
!checkRoute(
@@ -27,7 +27,9 @@ export default {
}
return true
- }
+ },
+ componentType: 'oc-button',
+ class: 'oc-files-actions-sidebar-copy-trigger'
}
]
}
diff --git a/packages/web-app-files/src/mixins/actions/delete.js b/packages/web-app-files/src/mixins/actions/delete.js
index 6f5bf9b2f42..26e6dc048f2 100644
--- a/packages/web-app-files/src/mixins/actions/delete.js
+++ b/packages/web-app-files/src/mixins/actions/delete.js
@@ -8,7 +8,7 @@ export default {
return [
{
icon: 'delete',
- ariaLabel: () => {
+ label: () => {
return this.$gettext('Delete')
},
handler: this.$_delete_trigger,
@@ -18,13 +18,17 @@ export default {
}
return resource.canBeDeleted()
- }
+ },
+ componentType: 'oc-button',
+ class: 'oc-files-actions-sidebar-delete-trigger'
},
{
icon: 'delete',
- ariaLabel: () => this.$gettext('Delete'),
+ label: () => this.$gettext('Delete'),
handler: this.$_delete_trigger,
- isEnabled: () => checkRoute(['files-trashbin'], this.$route.name)
+ isEnabled: () => checkRoute(['files-trashbin'], this.$route.name),
+ componentType: 'oc-button',
+ class: 'oc-files-actions-sidebar-delete-trigger'
}
]
}
diff --git a/packages/web-app-files/src/mixins/actions/download.js b/packages/web-app-files/src/mixins/actions/download.js
index 0c7fb84844e..127c9ffc30b 100644
--- a/packages/web-app-files/src/mixins/actions/download.js
+++ b/packages/web-app-files/src/mixins/actions/download.js
@@ -7,7 +7,7 @@ export default {
{
icon: 'file_download',
handler: this.$_download_trigger,
- ariaLabel: () => {
+ label: () => {
return this.$gettext('Download')
},
isEnabled: ({ resource }) => {
@@ -17,7 +17,9 @@ export default {
return resource.canDownload()
},
- canBeDefault: true
+ canBeDefault: true,
+ componentType: 'oc-button',
+ class: 'oc-files-actions-sidebar-download-trigger'
}
]
}
diff --git a/packages/web-app-files/src/mixins/actions/favorite.js b/packages/web-app-files/src/mixins/actions/favorite.js
index a538d0eb8ea..9ab785188ad 100644
--- a/packages/web-app-files/src/mixins/actions/favorite.js
+++ b/packages/web-app-files/src/mixins/actions/favorite.js
@@ -9,7 +9,7 @@ export default {
{
icon: 'star',
handler: this.$_favorite_trigger,
- ariaLabel: item => {
+ label: item => {
if (item.starred) {
return this.$gettext('Unmark as favorite')
}
@@ -27,7 +27,9 @@ export default {
this.capabilities.files.favorites &&
isRouteAllowed
)
- }
+ },
+ componentType: 'oc-button',
+ class: 'oc-files-actions-sidebar-favorite-trigger'
}
]
}
diff --git a/packages/web-app-files/src/mixins/actions/fetch.js b/packages/web-app-files/src/mixins/actions/fetch.js
index 63ad682d5fb..4ef2e182d97 100644
--- a/packages/web-app-files/src/mixins/actions/fetch.js
+++ b/packages/web-app-files/src/mixins/actions/fetch.js
@@ -10,7 +10,7 @@ export default {
{
icon: 'remove_red_eye',
handler: file => this.$_fetch_trigger(file, 'application/pdf', this.isPublicFilesRoute),
- ariaLabel: () => {
+ label: () => {
return this.$gettext('Open in browser')
},
isEnabled: ({ resource }) => {
@@ -20,7 +20,10 @@ export default {
return resource.extension === 'pdf'
},
- canBeDefault: true
+ canBeDefault: true,
+ componentType: 'oc-button',
+ class: 'oc-files-actions-sidebar-fetch-trigger',
+ opensInNewWindow: true
}
]
}
diff --git a/packages/web-app-files/src/mixins/actions/move.js b/packages/web-app-files/src/mixins/actions/move.js
index 9b4a70650e9..23d0eef3c6d 100644
--- a/packages/web-app-files/src/mixins/actions/move.js
+++ b/packages/web-app-files/src/mixins/actions/move.js
@@ -12,7 +12,7 @@ export default {
{
icon: 'folder-move',
handler: resource => this.$_move_trigger(resource),
- ariaLabel: () =>
+ label: () =>
this.$pgettext(
'Action in the files list row to initiate move of a single resource',
'Move'
@@ -32,7 +32,9 @@ export default {
}
return canBeMoved(resource, this.currentFolder.path)
- }
+ },
+ componentType: 'oc-button',
+ class: 'oc-files-actions-sidebar-move-trigger'
}
]
}
diff --git a/packages/web-app-files/src/mixins/actions/navigate.js b/packages/web-app-files/src/mixins/actions/navigate.js
index fb243dfc0e0..21acf5fbc5b 100644
--- a/packages/web-app-files/src/mixins/actions/navigate.js
+++ b/packages/web-app-files/src/mixins/actions/navigate.js
@@ -9,7 +9,7 @@ export default {
{
icon: 'folder-open',
handler: resource => this.$_navigate_trigger(resource),
- ariaLabel: () =>
+ label: () =>
this.$pgettext('Action in the files list row to open a folder', 'Open folder'),
isEnabled: ({ resource }) => {
if (checkRoute(['files-trashbin'], this.$route.name)) {
@@ -18,9 +18,20 @@ export default {
return resource.type === 'folder'
},
- canBeDefault: true
+ canBeDefault: true,
+ componentType: 'router-link',
+ route: this.route,
+ class: 'oc-files-actions-sidebar-navigate'
}
]
+ },
+ route() {
+ let route = 'files-personal'
+ if (this.publicPage()) {
+ route = 'files-public-list'
+ }
+
+ return route
}
},
methods: {
@@ -30,12 +41,9 @@ export default {
if (this.searchTerm !== '' && this.$route.params.item === folder.path) {
this.resetSearch()
}
- let route = 'files-personal'
- if (this.publicPage()) {
- route = 'files-public-list'
- }
+
this.$router.push({
- name: route,
+ name: this.route,
params: {
item: folder.path
}
diff --git a/packages/web-app-files/src/mixins/actions/rename.js b/packages/web-app-files/src/mixins/actions/rename.js
index fd4467840b7..427a358b274 100644
--- a/packages/web-app-files/src/mixins/actions/rename.js
+++ b/packages/web-app-files/src/mixins/actions/rename.js
@@ -10,7 +10,7 @@ export default {
return [
{
icon: 'edit',
- ariaLabel: () => {
+ label: () => {
return this.$gettext('Rename')
},
handler: this.$_rename_trigger,
@@ -20,7 +20,9 @@ export default {
}
return resource.canRename()
- }
+ },
+ componentType: 'oc-button',
+ class: 'oc-files-actions-sidebar-rename-trigger'
}
]
}
diff --git a/packages/web-app-files/src/mixins/actions/restore.js b/packages/web-app-files/src/mixins/actions/restore.js
index ccafed6a454..b0af47dcb21 100644
--- a/packages/web-app-files/src/mixins/actions/restore.js
+++ b/packages/web-app-files/src/mixins/actions/restore.js
@@ -8,9 +8,11 @@ export default {
return [
{
icon: 'restore',
- ariaLabel: () => this.$gettext('Restore'),
+ label: () => this.$gettext('Restore'),
handler: this.$_restore_trigger,
- isEnabled: () => checkRoute(['files-trashbin'], this.$route.name)
+ isEnabled: () => checkRoute(['files-trashbin'], this.$route.name),
+ componentType: 'oc-button',
+ class: 'oc-files-actions-sidebar-restore-trigger'
}
]
}
diff --git a/packages/web-app-files/src/mixins/fileActions.js b/packages/web-app-files/src/mixins/fileActions.js
index 086be675d0e..777321ae32b 100644
--- a/packages/web-app-files/src/mixins/fileActions.js
+++ b/packages/web-app-files/src/mixins/fileActions.js
@@ -10,6 +10,7 @@ import Move from './actions/move'
import Navigate from './actions/navigate'
import Rename from './actions/rename'
import Restore from './actions/restore'
+import { kebabCase } from 'lodash'
const actionsMixins = [
'fetch',
@@ -43,7 +44,7 @@ export default {
$_fileActions_editorActions() {
return this.apps.fileEditors.map(editor => {
return {
- ariaLabel: () => {
+ label: () => {
return `Open in ${this.apps.meta[editor.app].name}`
},
icon: this.apps.meta[editor.app].icon,
@@ -55,7 +56,11 @@ export default {
return resource.extension === editor.extension
},
- canBeDefault: true
+ canBeDefault: true,
+ componentType: 'oc-button',
+ class: `oc-files-actions-sidebar-${kebabCase(
+ this.apps.meta[editor.app].name
+ ).toLowerCase()}-trigger`
}
})
}
diff --git a/packages/web-runtime/src/directives/clickOutside.js b/packages/web-runtime/src/directives/clickOutside.js
new file mode 100644
index 00000000000..5c254bf9d87
--- /dev/null
+++ b/packages/web-runtime/src/directives/clickOutside.js
@@ -0,0 +1,13 @@
+export default {
+ bind: function(el, binding, vnode) {
+ window.event = function(event) {
+ if (!(el === event.target || el.contains(event.target))) {
+ vnode.context[binding.expression](event)
+ }
+ }
+ document.body.addEventListener('click', window.event)
+ },
+ unbind: function(el) {
+ document.body.removeEventListener('click', window.event)
+ }
+}
diff --git a/packages/web-runtime/src/index.js b/packages/web-runtime/src/index.js
index 6057d136ecb..8b40c7beb11 100644
--- a/packages/web-runtime/src/index.js
+++ b/packages/web-runtime/src/index.js
@@ -26,6 +26,9 @@ import Vue2TouchEvents from 'vue2-touch-events'
import focusMixin from './mixins/focusMixin'
import lifecycleMixin from './mixins/lifecycleMixin'
+// --- Directive ---
+import ClickOutsideDirective from './directives/clickOutside'
+
// --- Gettext ----
import GetTextPlugin from 'vue-gettext'
import coreTranslations from '../l10n/translations.json'
@@ -79,6 +82,8 @@ Vue.component('avatar-image', Avatar)
Vue.mixin(focusMixin)
Vue.mixin(lifecycleMixin)
+Vue.directive('click-outside', ClickOutsideDirective)
+
// --- Router ----
let config
diff --git a/tests/acceptance/features/webUIFilesActionMenu/fileFolderActionMenu.feature b/tests/acceptance/features/webUIFilesActionMenu/fileFolderActionMenu.feature
index 1785266bdc9..55c76e4d5aa 100644
--- a/tests/acceptance/features/webUIFilesActionMenu/fileFolderActionMenu.feature
+++ b/tests/acceptance/features/webUIFilesActionMenu/fileFolderActionMenu.feature
@@ -7,7 +7,7 @@ Background: prepare user and files
Given user "Alice" has been created with default attributes
And user "Alice" has logged in using the webUI
And the user has browsed to the files page
-
+
Scenario: observe different actions menu options on selecting different file types or folder
Given user "Alice" has uploaded file with content "pdf file" to "lorem.pdf"
And the user has reloaded the current page of the webUI
@@ -35,4 +35,3 @@ Background: prepare user and files
| items |
| open in mediaviewer |
| download |
-
\ No newline at end of file
diff --git a/tests/acceptance/pageObjects/FilesPageElement/appSideBar.js b/tests/acceptance/pageObjects/FilesPageElement/appSideBar.js
index b70ac75ae02..d65ee055589 100644
--- a/tests/acceptance/pageObjects/FilesPageElement/appSideBar.js
+++ b/tests/acceptance/pageObjects/FilesPageElement/appSideBar.js
@@ -198,7 +198,8 @@ module.exports = {
selector: '#oc-files-actions-sidebar'
},
actionPanelItems: {
- selector: '//div[@class="oc-accordion-content"]//li/button',
+ selector:
+ '//div[@class="oc-accordion-content"]//li/button/span[@class="oc-files-actions-sidebar-action-label"] | //div[@class="oc-accordion-content"]//li/a/span[@class="oc-files-actions-sidebar-action-label"]',
locateStrategy: 'xpath'
}
}
diff --git a/tests/acceptance/pageObjects/FilesPageElement/fileActionsMenu.js b/tests/acceptance/pageObjects/FilesPageElement/fileActionsMenu.js
index b4703bca787..0938fa1f830 100644
--- a/tests/acceptance/pageObjects/FilesPageElement/fileActionsMenu.js
+++ b/tests/acceptance/pageObjects/FilesPageElement/fileActionsMenu.js
@@ -160,27 +160,27 @@ module.exports = {
locateStrategy: 'xpath'
},
deleteButtonInAccordion: {
- selector: '//button[@aria-label="Delete"]',
+ selector: '//button[contains(@class, "oc-files-actions-sidebar-delete-trigger")]',
locateStrategy: 'xpath'
},
downloadButtonInAccordion: {
- selector: '//button[@aria-label="Download"]',
+ selector: '//button[contains(@class, "oc-files-actions-sidebar-download-trigger")]',
locateStrategy: 'xpath'
},
favoriteButtonInAccordion: {
- selector: '//button[@aria-label="Mark as favorite"]',
+ selector: '//button[contains(@class, "oc-files-actions-sidebar-favorite-trigger")]',
locateStrategy: 'xpath'
},
unmarkFavoriteButtonInAccordion: {
- selector: '//button[@aria-label="Unmark as favorite"]',
+ selector: '//button[contains(@class, "oc-files-actions-sidebar-favorite-trigger")]',
locateStrategy: 'xpath'
},
restoreButtonInAccordion: {
- selector: '//button[@aria-label="Restore"]',
+ selector: '//button[contains(@class, "oc-files-actions-sidebar-restore-trigger")]',
locateStrategy: 'xpath'
},
renameButtonInAccordion: {
- selector: '//button[@aria-label="Rename"]',
+ selector: '//button[contains(@class, "oc-files-actions-sidebar-rename-trigger")]',
locateStrategy: 'xpath'
},
// TODO: Merge with selectors in personalPage
@@ -194,19 +194,19 @@ module.exports = {
selector: '.oc-modal-body-input > input'
},
moveButtonInAccordion: {
- selector: '//button[@aria-label="Move"]',
+ selector: '//button[contains(@class, "oc-files-actions-sidebar-move-trigger")]',
locateStrategy: 'xpath'
},
copyButtonInAccordion: {
- selector: '//button[@aria-label="Copy"]',
+ selector: '//button[contains(@class, "oc-files-actions-sidebar-copy-trigger")]',
locateStrategy: 'xpath'
},
mediaViewerButtonInAccordion: {
- selector: '//button[@aria-label="Open in Mediaviewer"]',
+ selector: '//button[contains(@class, "oc-files-actions-sidebar-mediaviewer-trigger")]',
locateStrategy: 'xpath'
},
markdownEditorButtonInAccordion: {
- selector: '//button[@aria-label="Open in MarkdownEditor"]',
+ selector: '//button[contains(@class, "oc-files-actions-sidebar-markdown-editor-trigger")]',
locateStrategy: 'xpath'
}
}