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

Add drop down menu to app top bar #11057

Merged
merged 2 commits into from
Jun 18, 2024
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
@@ -0,0 +1,7 @@
Enhancement: add action drop down top app top bar
Copy link
Member

Choose a reason for hiding this comment

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

nobody noticed the typo 😓 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh no :( gonna fix this asap as possible !

Copy link
Member

Choose a reason for hiding this comment

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

Beste!


We've added an action drop down with various file actions to the app top bar,
so the user can now call different actions like download, directly from the app.

https://github.com/owncloud/web/pull/11057
https://github.com/owncloud/web/issues/11019
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<audio :key="`media-audio-${file.id}`" controls preload="preload" :autoplay="isAutoPlayEnabled">
<source :src="file.url" :type="file.mimeType" />
</audio>
<p class="oc-text-muted oc-text-small" v-if="audioText" v-text="audioText"></p>
<p v-if="audioText" class="oc-text-muted oc-text-small" v-text="audioText"></p>
</div>
</template>
<script lang="ts">
Expand Down
99 changes: 84 additions & 15 deletions packages/web-pkg/src/components/AppTemplates/AppWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<app-top-bar
v-if="!loading && !loadingError"
:main-actions="fileActions"
:drop-down-menu-sections="dropDownMenuSections"
:drop-down-action-options="dropDownActionOptions"
:resource="resource"
@close="closeApp"
/>
Expand Down Expand Up @@ -57,11 +59,16 @@ import {
useAppsStore,
useConfigStore,
useResourcesStore,
FileContentOptions
FileContentOptions,
useFileActionsCopyQuickLink,
useFileActionsDownloadFile,
useFileActionsShowDetails,
useFileActionsShowShares,
FileActionOptions,
FileAction
} from '../../composables'
import {
Action,
ActionOptions,
Modifier,
Key,
useAppMeta,
Expand Down Expand Up @@ -127,6 +134,11 @@ export default defineComponent({
const configStore = useConfigStore()
const resourcesStore = useResourcesStore()

const { actions: createQuickLinkActions } = useFileActionsCopyQuickLink()
const { actions: downloadFileActions } = useFileActionsDownloadFile()
const { actions: showDetailsActions } = useFileActionsShowDetails()
const { actions: showSharesActions } = useFileActionsShowShares()

const applicationName = ref('')
const resource: Ref<Resource> = ref()
const space: Ref<SpaceResource> = ref()
Expand Down Expand Up @@ -411,21 +423,76 @@ export default defineComponent({
save()
})

const fileActions = computed((): Action<ActionOptions>[] => [
{
name: 'save-file',
disabledTooltip: () => '',
isVisible: () => unref(isEditor),
isDisabled: () => isReadOnly.value || !isDirty.value,
componentType: 'button',
icon: 'save',
id: 'app-save-action',
label: () => 'Save',
handler: () => {
save()
const fileActionsSave = computed<FileAction[]>(() => {
return [
{
name: 'save-file',
disabledTooltip: () => '',
isVisible: () => unref(isEditor),
isDisabled: () => isReadOnly.value || !isDirty.value,
componentType: 'button',
icon: 'save',
id: 'app-save-action',
label: () => 'Save',
handler: () => {
save()
}
}
]
})

const actionOptions = computed<FileActionOptions>(() => {
return {
space: unref(space),
resources: [unref(resource)]
}
])
})

const menuItemsContext = computed(() => {
return [...unref(fileActionsSave)].filter((item) => item.isVisible(unref(actionOptions)))
})
const menuItemsShare = computed(() => {
return [...unref(showSharesActions), ...unref(createQuickLinkActions)].filter((item) =>
item.isVisible(unref(actionOptions))
)
})
const menuItemsActions = computed(() => {
return [...unref(downloadFileActions)].filter((item) => item.isVisible(unref(actionOptions)))
})
const menuItemsSidebar = computed(() => {
return [...unref(showDetailsActions)].filter((item) => item.isVisible(unref(actionOptions)))
})
const dropDownMenuSections = computed(() => {
const sections = []

if (unref(menuItemsContext).length) {
sections.push({
name: 'context',
items: unref(menuItemsContext)
})
}
if (unref(menuItemsShare).length) {
sections.push({
name: 'share',
items: unref(menuItemsShare)
})
}
if (unref(menuItemsActions).length) {
sections.push({
name: 'actions',
items: unref(menuItemsActions)
})
}
if (unref(menuItemsSidebar).length) {
sections.push({
name: 'sidebar',
items: unref(menuItemsSidebar)
})
}
return sections
})

const fileActions = computed((): Action[] => [...unref(fileActionsSave)])

onBeforeRouteLeave((_to, _from, next) => {
if (unref(isDirty)) {
Expand Down Expand Up @@ -472,6 +539,8 @@ export default defineComponent({

return {
...useSideBar(),
dropDownMenuSections,
dropDownActionOptions: actionOptions,
isEditor,
closeApp,
fileActions,
Expand Down
67 changes: 40 additions & 27 deletions packages/web-pkg/src/components/AppTopBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,7 @@
/>
</div>
<div class="oc-flex main-actions">
<template v-if="mainActions.length && resource">
<context-action-menu
:menu-sections="[
{
name: 'main-actions',
items: mainActions
.filter((action) => action.isVisible())
.map((action) => {
return { ...action, class: 'oc-p-xs', hideLabel: true }
})
}
]"
:action-options="{
resources: [resource]
}"
appearance="raw-inverse"
variation="brand"
/>
</template>
<template v-if="dropDownActions.length">
<template v-if="dropDownMenuSections.length">
<oc-button
id="oc-openfile-contextmenu-trigger"
v-oc-tooltip="contextMenuLabel"
Expand All @@ -57,11 +38,30 @@
@click.stop.prevent
>
<context-action-menu
:menu-sections="[{ name: 'dropdown-actions', items: dropDownActions }]"
:action-options="{ resources: [resource] }"
:menu-sections="dropDownMenuSections"
:action-options="dropDownActionOptions"
/>
</oc-drop>
</template>
<template v-if="mainActions.length && resource">
<context-action-menu
:menu-sections="[
{
name: 'main-actions',
items: mainActions
.filter((action) => action.isVisible())
.map((action) => {
return { ...action, class: 'oc-p-xs', hideLabel: true }
})
}
]"
:action-options="{
resources: [resource]
}"
appearance="raw-inverse"
variation="brand"
/>
</template>
<oc-button
id="app-top-bar-close"
v-oc-tooltip="closeButtonLabel"
Expand All @@ -80,9 +80,15 @@

<script lang="ts">
import { computed, defineComponent, PropType, unref } from 'vue'
import ContextActionMenu from './ContextActions/ContextActionMenu.vue'
import ContextActionMenu, { MenuSection } from './ContextActions/ContextActionMenu.vue'
import { useGettext } from 'vue3-gettext'
import { Action, useFolderLink, useGetMatchingSpace, useResourcesStore } from '../composables'
import {
Action,
FileActionOptions,
useFolderLink,
useGetMatchingSpace,
useResourcesStore
} from '../composables'
import ResourceListItem from './FilesList/ResourceListItem.vue'
import { Resource, isPublicSpaceResource, isShareSpaceResource } from '@ownclouders/web-client'

Expand All @@ -93,9 +99,16 @@ export default defineComponent({
ResourceListItem
},
props: {
dropDownActions: {
type: Array as PropType<Action[]>,
default: (): Action[] => []
dropDownMenuSections: {
type: Array as PropType<MenuSection[]>,
default: (): MenuSection[] => []
},
dropDownActionOptions: {
type: Object as PropType<FileActionOptions>,
default: (): FileActionOptions => ({
space: null,
resources: []
})
},
mainActions: {
type: Array as PropType<Action[]>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { defineComponent, PropType } from 'vue'
import ActionMenuItem from './ActionMenuItem.vue'
import { Action, ActionOptions } from '../../composables'

type MenuSection = {
export type MenuSection = {
name: string
items: Action[]
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { isLocationTrashActive } from '../../../router'
import { eventBus } from '../../../services/eventBus'
import { SideBarEventTopics } from '../../sideBar'
import { computed, unref } from 'vue'
import { computed } from 'vue'
import { useGettext } from 'vue3-gettext'
import { useIsFilesAppActive } from '../helpers'
import { useRouter } from '../../router'
import { FileAction } from '../types'
import { useResourcesStore } from '../../piniaStores'
Expand All @@ -13,7 +12,6 @@ export const useFileActionsShowDetails = () => {
const resourcesStore = useResourcesStore()

const { $gettext } = useGettext()
const isFilesAppActive = useIsFilesAppActive()

const actions = computed((): FileAction[] => [
{
Expand All @@ -25,11 +23,6 @@ export const useFileActionsShowDetails = () => {
// we don't have details in the trashbin, yet.
// remove trashbin route rule once we have them.
isVisible: ({ resources }) => {
// sidebar is currently only available inside files app
if (!unref(isFilesAppActive)) {
return false
}

if (isLocationTrashActive(router, 'files-trash-generic')) {
return false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { isLocationTrashActive } from '../../../router'
import { ShareResource } from '@ownclouders/web-client'
import { eventBus } from '../../../services'
import { SideBarEventTopics } from '../../sideBar'
import { computed, unref } from 'vue'
import { computed } from 'vue'
import { useGettext } from 'vue3-gettext'
import { useIsFilesAppActive } from '../helpers'
import { useRouter } from '../../router'
Expand All @@ -29,11 +29,6 @@ export const useFileActionsShowShares = () => {
label: () => $gettext('Share'),
handler,
isVisible: ({ space, resources }) => {
// sidebar is currently only available inside files app
if (!unref(isFilesAppActive)) {
return false
}

if (isLocationTrashActive(router, 'files-trash-generic')) {
return false
}
Expand Down
Loading