Skip to content

Commit 4ca9fb8

Browse files
committed
feat(files): move "reload" and "share" breadcrumb actions to menu
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent 985b66c commit 4ca9fb8

2 files changed

Lines changed: 59 additions & 88 deletions

File tree

apps/files/src/components/BreadCrumbs.vue

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,37 @@
1717
dir="auto"
1818
:to="section.to"
1919
:force-icon-text="index === 0 && !isNarrow"
20+
force-menu
21+
:open.sync="isMenuOpen"
2022
:title="titleForSection(index, section)"
2123
:aria-description="ariaForSection(section)"
22-
@click.native="onClick(section.to)"
2324
@dragover.native="onDragOver($event, section.dir)"
2425
@drop="onDrop($event, section.dir)">
2526
<template v-if="index === 0" #icon>
2627
<NcIconSvgWrapper
2728
:size="20"
2829
:svg="viewIcon" />
2930
</template>
31+
<template v-if="index === sections.length - 1" #menu-icon>
32+
<NcIconSvgWrapper :path="isMenuOpen ? mdiChevronUp : mdiChevronDown" />
33+
</template>
34+
<template v-if="index === sections.length - 1" #default>
35+
<!-- Sharing button -->
36+
<NcActionButton v-if="canShare" close-after-click @click="openSharingSidebar">
37+
<template #icon>
38+
<NcIconSvgWrapper :path="mdiAccountPlus" />
39+
</template>
40+
{{ t('files', 'Share') }}
41+
</NcActionButton>
42+
43+
<!-- Reload button -->
44+
<NcActionButton close-after-click @click="$emit('reload')">
45+
<template #icon>
46+
<NcIconSvgWrapper :path="mdiReload" />
47+
</template>
48+
{{ t('files', 'Reload content') }}
49+
</NcActionButton>
50+
</template>
3051
</NcBreadcrumb>
3152

3253
<!-- Forward the actions slot -->
@@ -40,12 +61,16 @@
4061
import type { Node } from '@nextcloud/files'
4162
import type { FileSource } from '../types.ts'
4263
64+
import { mdiAccountPlus, mdiChevronDown, mdiChevronUp, mdiReload } from '@mdi/js'
4365
import HomeSvg from '@mdi/svg/svg/home.svg?raw'
66+
import { getCapabilities } from '@nextcloud/capabilities'
4467
import { showError } from '@nextcloud/dialogs'
45-
import { Permission } from '@nextcloud/files'
46-
import { translate as t } from '@nextcloud/l10n'
68+
import { getSidebar, Permission } from '@nextcloud/files'
69+
import { t } from '@nextcloud/l10n'
70+
import { isPublicShare } from '@nextcloud/sharing/public'
4771
import { basename } from 'path'
48-
import { defineComponent } from 'vue'
72+
import { computed, defineComponent, ref, watch } from 'vue'
73+
import NcActionButton from '@nextcloud/vue/components/NcActionButton'
4974
import NcBreadcrumb from '@nextcloud/vue/components/NcBreadcrumb'
5075
import NcBreadcrumbs from '@nextcloud/vue/components/NcBreadcrumbs'
5176
import NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper'
@@ -64,6 +89,7 @@ export default defineComponent({
6489
name: 'BreadCrumbs',
6590
6691
components: {
92+
NcActionButton,
6793
NcBreadcrumbs,
6894
NcBreadcrumb,
6995
NcIconSvgWrapper,
@@ -89,6 +115,20 @@ export default defineComponent({
89115
const { isNarrow } = useFileListWidth()
90116
const views = useViews()
91117
118+
const isMenuOpen = ref(false)
119+
watch(() => activeStore.activeFolder, () => {
120+
isMenuOpen.value = false
121+
})
122+
123+
const isSharingEnabled = (getCapabilities() as { files_sharing?: boolean })?.files_sharing !== undefined
124+
const isPublic = isPublicShare()
125+
const canShare = computed(() => {
126+
return isSharingEnabled
127+
&& !isPublic
128+
&& activeStore.activeFolder
129+
&& (activeStore.activeFolder.permissions & Permission.SHARE) !== 0
130+
})
131+
92132
return {
93133
activeStore,
94134
draggingStore,
@@ -97,8 +137,23 @@ export default defineComponent({
97137
selectionStore,
98138
uploaderStore,
99139
140+
canShare,
141+
isMenuOpen,
100142
isNarrow,
101143
views,
144+
openSharingSidebar,
145+
146+
mdiAccountPlus,
147+
mdiChevronDown,
148+
mdiChevronUp,
149+
mdiReload,
150+
}
151+
152+
/**
153+
* Open the sharing sidebar for the current folder
154+
*/
155+
function openSharingSidebar() {
156+
getSidebar().open(activeStore.activeFolder!, 'sharing')
102157
}
103158
},
104159
@@ -193,12 +248,6 @@ export default defineComponent({
193248
}
194249
},
195250
196-
onClick(to) {
197-
if (to?.query?.dir === this.$route.query.dir) {
198-
this.$emit('reload')
199-
}
200-
},
201-
202251
onDragOver(event: DragEvent, path: string) {
203252
if (!event.dataTransfer) {
204253
return

apps/files/src/views/FilesList.vue

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,6 @@
88
<!-- Current folder breadcrumbs -->
99
<BreadCrumbs :path="directory" @reload="fetchContent">
1010
<template #actions>
11-
<!-- Sharing button -->
12-
<NcButton
13-
v-if="canShare && !isNarrow"
14-
:aria-label="shareButtonLabel"
15-
:class="{ 'files-list__header-share-button--shared': shareButtonType }"
16-
:title="shareButtonLabel"
17-
class="files-list__header-share-button"
18-
variant="tertiary"
19-
@click="openSharingSidebar">
20-
<template #icon>
21-
<LinkIcon v-if="shareButtonType === ShareType.Link" />
22-
<AccountPlusIcon v-else :size="20" />
23-
</template>
24-
</NcButton>
25-
2611
<!-- Uploader -->
2712
<UploadPicker
2813
v-if="canUpload && !isQuotaExceeded && currentFolder"
@@ -168,7 +153,6 @@ import type { Route } from 'vue-router'
168153
import type { UserConfig } from '../types.ts'
169154
170155
import { getCurrentUser } from '@nextcloud/auth'
171-
import { getCapabilities } from '@nextcloud/capabilities'
172156
import { showError, showSuccess, showWarning } from '@nextcloud/dialogs'
173157
import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus'
174158
import { Folder, getFileListActions, Permission, sortNodes } from '@nextcloud/files'
@@ -188,10 +172,8 @@ import NcButton from '@nextcloud/vue/components/NcButton'
188172
import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent'
189173
import NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper'
190174
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
191-
import AccountPlusIcon from 'vue-material-design-icons/AccountPlusOutline.vue'
192175
import IconAlertCircleOutline from 'vue-material-design-icons/AlertCircleOutline.vue'
193176
import ListViewIcon from 'vue-material-design-icons/FormatListBulletedSquare.vue'
194-
import LinkIcon from 'vue-material-design-icons/Link.vue'
195177
import IconReload from 'vue-material-design-icons/Reload.vue'
196178
import ViewGridIcon from 'vue-material-design-icons/ViewGridOutline.vue'
197179
import BreadCrumbs from '../components/BreadCrumbs.vue'
@@ -215,8 +197,6 @@ import { humanizeWebDAVError } from '../utils/davUtils.ts'
215197
import { defaultView } from '../utils/filesViews.ts'
216198
import { getSummaryFor } from '../utils/fileUtils.ts'
217199
218-
const isSharingEnabled = (getCapabilities() as { files_sharing?: boolean })?.files_sharing !== undefined
219-
220200
export default defineComponent({
221201
name: 'FilesList',
222202
@@ -225,7 +205,6 @@ export default defineComponent({
225205
DragAndDropNotice,
226206
FileListFilters,
227207
FilesListVirtual,
228-
LinkIcon,
229208
ListViewIcon,
230209
NcAppContent,
231210
NcActions,
@@ -234,7 +213,6 @@ export default defineComponent({
234213
NcEmptyContent,
235214
NcIconSvgWrapper,
236215
NcLoadingIcon,
237-
AccountPlusIcon,
238216
UploadPicker,
239217
ViewGridIcon,
240218
IconAlertCircleOutline,
@@ -436,37 +414,6 @@ export default defineComponent({
436414
return { ...this.$route, query: { dir } }
437415
},
438416
439-
shareTypesAttributes(): number[] | undefined {
440-
if (!this.currentFolder?.attributes?.['share-types']) {
441-
return undefined
442-
}
443-
return Object.values(this.currentFolder?.attributes?.['share-types'] || {}).flat() as number[]
444-
},
445-
446-
shareButtonLabel() {
447-
if (!this.shareTypesAttributes) {
448-
return t('files', 'Share')
449-
}
450-
451-
if (this.shareButtonType === ShareType.Link) {
452-
return t('files', 'Shared by link')
453-
}
454-
return t('files', 'Shared')
455-
},
456-
457-
shareButtonType(): ShareType | null {
458-
if (!this.shareTypesAttributes) {
459-
return null
460-
}
461-
462-
// If all types are links, show the link icon
463-
if (this.shareTypesAttributes.some((type) => type === ShareType.Link)) {
464-
return ShareType.Link
465-
}
466-
467-
return ShareType.User
468-
},
469-
470417
gridViewButtonLabel() {
471418
return this.userConfig.grid_view
472419
? t('files', 'Switch to list view')
@@ -484,14 +431,6 @@ export default defineComponent({
484431
return this.currentFolder?.attributes?.['quota-available-bytes'] === 0
485432
},
486433
487-
/**
488-
* Check if current folder has share permissions
489-
*/
490-
canShare() {
491-
return isSharingEnabled && !this.isPublic
492-
&& this.currentFolder && (this.currentFolder.permissions & Permission.SHARE) !== 0
493-
},
494-
495434
showCustomEmptyView() {
496435
return !this.loading && this.isEmptyDir && this.currentView?.emptyView !== undefined
497436
},
@@ -763,15 +702,6 @@ export default defineComponent({
763702
}
764703
},
765704
766-
openSharingSidebar() {
767-
if (!this.currentFolder) {
768-
logger.debug('No current folder found for opening sharing sidebar')
769-
return
770-
}
771-
772-
this.sidebar.open(this.currentFolder, 'sharing')
773-
},
774-
775705
toggleGridView() {
776706
this.userConfigStore.update('grid_view', !this.userConfig.grid_view)
777707
},
@@ -865,14 +795,6 @@ export default defineComponent({
865795
flex: 0 0;
866796
}
867797
868-
&-share-button {
869-
color: var(--color-text-maxcontrast) !important;
870-
871-
&--shared {
872-
color: var(--color-main-text) !important;
873-
}
874-
}
875-
876798
&-actions {
877799
min-width: fit-content !important;
878800
margin-inline: calc(var(--default-grid-baseline) * 2);

0 commit comments

Comments
 (0)