Skip to content

Commit a512bfd

Browse files
committed
feat(sidebar): Show node owner in metadata subline
Resolves: #46178 Signed-off-by: fenn-cs <[email protected]>
1 parent 6b85a3a commit a512bfd

File tree

2 files changed

+75
-18
lines changed

2 files changed

+75
-18
lines changed

apps/files/src/services/WebdavClient.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
5-
import { davGetClient } from '@nextcloud/files'
5+
import { davGetClient, davGetDefaultPropfind, davResultToNode, davRootPath } from '@nextcloud/files'
6+
import type { FileStat, ResponseDataDetailed } from 'webdav'
7+
import type { Node } from '@nextcloud/files'
68

79
export const client = davGetClient()
10+
11+
export const fetchNode = async (node: Node): Promise<Node> => {
12+
const propfindPayload = davGetDefaultPropfind()
13+
const result = await client.stat(`${davRootPath}${node.path}`, {
14+
details: true,
15+
data: propfindPayload,
16+
}) as ResponseDataDetailed<FileStat>
17+
return davResultToNode(result.data)
18+
}

apps/files/src/views/Sidebar.vue

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,20 @@
1717
@closing="handleClosing"
1818
@closed="handleClosed">
1919
<template v-if="fileInfo" #subname>
20-
<NcIconSvgWrapper v-if="fileInfo.isFavourited"
21-
:path="mdiStar"
22-
:name="t('files', 'Favorite')"
23-
inline />
24-
{{ size }}
25-
<NcDateTime :timestamp="fileInfo.mtime" />
20+
<div class="sidebar__subname">
21+
<NcIconSvgWrapper v-if="fileInfo.isFavourited"
22+
:path="mdiStar"
23+
:name="t('files', 'Favorite')"
24+
inline />
25+
<span>{{ size }}</span>
26+
<span class="sidebar__subname-separator">.</span>
27+
<NcDateTime :timestamp="fileInfo.mtime" />
28+
<span class="sidebar__subname-separator">.</span>
29+
<span>{{ ownedByText }}</span>
30+
<NcUserBubble :user="ownerId"
31+
:display-name="nodeOwnerLabel" />
32+
</div>
2633
</template>
27-
2834
<!-- TODO: create a standard to allow multiple elements here? -->
2935
<template v-if="fileInfo" #description>
3036
<div class="sidebar__description">
@@ -96,6 +102,7 @@ import { encodePath } from '@nextcloud/paths'
96102
import { generateRemoteUrl, generateUrl } from '@nextcloud/router'
97103
import { ShareType } from '@nextcloud/sharing'
98104
import { mdiStar, mdiStarOutline } from '@mdi/js'
105+
import { fetchNode } from '../services/WebdavClient.ts'
99106
import axios from '@nextcloud/axios'
100107
import $ from 'jquery'
101108
@@ -104,6 +111,7 @@ import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
104111
import NcDateTime from '@nextcloud/vue/dist/Components/NcDateTime.js'
105112
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'
106113
import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
114+
import NcUserBubble from '@nextcloud/vue/dist/Components/NcUserBubble.js'
107115
108116
import FileInfo from '../services/FileInfo.js'
109117
import LegacyView from '../components/LegacyView.vue'
@@ -123,15 +131,12 @@ export default {
123131
NcIconSvgWrapper,
124132
SidebarTab,
125133
SystemTags,
134+
NcUserBubble,
126135
},
127136
128137
setup() {
129-
const currentUser = getCurrentUser()
130-
131138
// Non reactive properties
132139
return {
133-
currentUser,
134-
135140
mdiStar,
136141
mdiStarOutline,
137142
}
@@ -140,12 +145,14 @@ export default {
140145
data() {
141146
return {
142147
// reactive state
148+
currentUser: getCurrentUser(),
143149
Sidebar: OCA.Files.Sidebar.state,
144150
showTags: false,
145151
showTagsDefault: true,
146152
error: null,
147153
loading: true,
148154
fileInfo: null,
155+
node: null,
149156
isFullScreen: false,
150157
hasLowHeight: false,
151158
}
@@ -288,6 +295,24 @@ export default {
288295
isSystemTagsEnabled() {
289296
return getCapabilities()?.systemtags?.enabled === true
290297
},
298+
ownerId() {
299+
return this.node?.attributes?.['owner-id'] ?? this.currentUser.uid
300+
},
301+
currentUserIsOwner() {
302+
return this.ownerId === this.currentUser.uid
303+
},
304+
ownedByText() {
305+
return this.currentUserIsOwner ? t('files', 'Owned by you') : t('files', 'Owned by')
306+
},
307+
nodeOwnerLabel() {
308+
return this.node?.attributes?.['owner-display-name'] ?? 'Unknown'
309+
},
310+
sharedMultipleTimes() {
311+
if (Array.isArray(node.attributes?.['share-types']) && node.attributes?.['share-types'].length > 1) {
312+
return t('files', 'Shared multiple times with different people')
313+
}
314+
return null
315+
},
291316
},
292317
created() {
293318
subscribe('files:node:deleted', this.onNodeDeleted)
@@ -299,7 +324,6 @@ export default {
299324
unsubscribe('file:node:deleted', this.onNodeDeleted)
300325
window.removeEventListener('resize', this.handleWindowResize)
301326
},
302-
303327
methods: {
304328
/**
305329
* Can this tab be displayed ?
@@ -461,6 +485,7 @@ export default {
461485
this.fileInfo = await FileInfo(this.davPath)
462486
// adding this as fallback because other apps expect it
463487
this.fileInfo.dir = this.file.split('/').slice(0, -1).join('/')
488+
this.node = await fetchNode({ path: (this.fileInfo.path + '/' + this.fileInfo.name).replace('//', '/') })
464489
465490
// DEPRECATED legacy views
466491
// TODO: remove
@@ -550,6 +575,12 @@ export default {
550575
handleWindowResize() {
551576
this.hasLowHeight = document.documentElement.clientHeight < 1024
552577
},
578+
sharedMultipleTimes() {
579+
// Mixed share types
580+
if (Array.isArray(this.node.attributes?.['share-types']) && this.node.attributes?.['share-types'].length > 1) {
581+
return t('files', 'Shared multiple times with different people')
582+
}
583+
},
553584
},
554585
}
555586
</script>
@@ -590,10 +621,25 @@ export default {
590621
}
591622
}
592623
593-
.sidebar__description {
594-
display: flex;
595-
flex-direction: column;
596-
width: 100%;
597-
gap: 8px 0;
624+
.sidebar__subname {
625+
display: flex;
626+
align-items: center;
627+
gap: 0 8px;
628+
629+
&-separator {
630+
display: inline-block;
631+
font-weight: bold !important;
632+
}
633+
634+
.user-bubble__wrapper {
635+
display: inline-flex;
636+
}
598637
}
638+
639+
.sidebar__description {
640+
display: flex;
641+
flex-direction: column;
642+
width: 100%;
643+
gap: 8px 0;
644+
}
599645
</style>

0 commit comments

Comments
 (0)