aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorfenn-cs <fenn25.fn@gmail.com>2024-07-22 17:54:39 +0100
committerfenn-cs <fenn25.fn@gmail.com>2024-10-07 15:15:55 +0200
commitfaa29a0feb9fa982b66e0ab433c826d05a367d0f (patch)
tree04edc66e72da4cc62d91c6a382d346adf4f7f03e /apps
parent414430980a9efa3ced924d092ef50d336b2b7dde (diff)
downloadnextcloud-server-faa29a0feb9fa982b66e0ab433c826d05a367d0f.tar.gz
nextcloud-server-faa29a0feb9fa982b66e0ab433c826d05a367d0f.zip
feat(sidebar): Show node owner in metadata subline
Resolves: https://github.com/nextcloud/server/issues/46178 Signed-off-by: fenn-cs <fenn25.fn@gmail.com>
Diffstat (limited to 'apps')
-rw-r--r--apps/files/src/services/WebdavClient.ts13
-rw-r--r--apps/files/src/store/files.ts13
-rw-r--r--apps/files/src/views/Sidebar.vue68
3 files changed, 70 insertions, 24 deletions
diff --git a/apps/files/src/services/WebdavClient.ts b/apps/files/src/services/WebdavClient.ts
index 5563508e2c7..cd33147b03f 100644
--- a/apps/files/src/services/WebdavClient.ts
+++ b/apps/files/src/services/WebdavClient.ts
@@ -2,6 +2,17 @@
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
-import { davGetClient } from '@nextcloud/files'
+import { davGetClient, davGetDefaultPropfind, davResultToNode, davRootPath } from '@nextcloud/files'
+import type { FileStat, ResponseDataDetailed } from 'webdav'
+import type { Node } from '@nextcloud/files'
export const client = davGetClient()
+
+export const fetchNode = async (node: Node): Promise<Node> => {
+ const propfindPayload = davGetDefaultPropfind()
+ const result = await client.stat(`${davRootPath}${node.path}`, {
+ details: true,
+ data: propfindPayload,
+ }) as ResponseDataDetailed<FileStat>
+ return davResultToNode(result.data)
+}
diff --git a/apps/files/src/store/files.ts b/apps/files/src/store/files.ts
index 1af675e67ce..952e3cd41c5 100644
--- a/apps/files/src/store/files.ts
+++ b/apps/files/src/store/files.ts
@@ -4,27 +4,16 @@
*/
import type { FilesStore, RootsStore, RootOptions, Service, FilesState, FileSource } from '../types'
-import type { FileStat, ResponseDataDetailed } from 'webdav'
import type { Folder, Node } from '@nextcloud/files'
-import { davGetDefaultPropfind, davResultToNode, davRootPath } from '@nextcloud/files'
import { defineStore } from 'pinia'
import { subscribe } from '@nextcloud/event-bus'
import logger from '../logger'
import Vue from 'vue'
-import { client } from '../services/WebdavClient.ts'
+import { fetchNode } from '../services/WebdavClient.ts'
import { usePathsStore } from './paths.ts'
-const fetchNode = async (node: Node): Promise<Node> => {
- const propfindPayload = davGetDefaultPropfind()
- const result = await client.stat(`${davRootPath}${node.path}`, {
- details: true,
- data: propfindPayload,
- }) as ResponseDataDetailed<FileStat>
- return davResultToNode(result.data)
-}
-
export const useFilesStore = function(...args) {
const store = defineStore('files', {
state: (): FilesState => ({
diff --git a/apps/files/src/views/Sidebar.vue b/apps/files/src/views/Sidebar.vue
index 5d9f2079253..ca7afac7780 100644
--- a/apps/files/src/views/Sidebar.vue
+++ b/apps/files/src/views/Sidebar.vue
@@ -17,12 +17,19 @@
@closing="handleClosing"
@closed="handleClosed">
<template v-if="fileInfo" #subname>
- <NcIconSvgWrapper v-if="fileInfo.isFavourited"
- :path="mdiStar"
- :name="t('files', 'Favorite')"
- inline />
- {{ size }}
- <NcDateTime :timestamp="fileInfo.mtime" />
+ <div class="sidebar__subname">
+ <NcIconSvgWrapper v-if="fileInfo.isFavourited"
+ :path="mdiStar"
+ :name="t('files', 'Favorite')"
+ inline />
+ <span>{{ size }}</span>
+ <span class="sidebar__subname-separator">•</span>
+ <NcDateTime :timestamp="fileInfo.mtime" />
+ <span class="sidebar__subname-separator">•</span>
+ <span>{{ t('files', 'Owner') }}</span>
+ <NcUserBubble :user="ownerId"
+ :display-name="nodeOwnerLabel" />
+ </div>
</template>
<!-- TODO: create a standard to allow multiple elements here? -->
@@ -96,6 +103,7 @@ import { encodePath } from '@nextcloud/paths'
import { generateUrl } from '@nextcloud/router'
import { ShareType } from '@nextcloud/sharing'
import { mdiStar, mdiStarOutline } from '@mdi/js'
+import { fetchNode } from '../services/WebdavClient.ts'
import axios from '@nextcloud/axios'
import $ from 'jquery'
@@ -104,6 +112,7 @@ import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcDateTime from '@nextcloud/vue/dist/Components/NcDateTime.js'
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'
import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
+import NcUserBubble from '@nextcloud/vue/dist/Components/NcUserBubble.js'
import FileInfo from '../services/FileInfo.js'
import LegacyView from '../components/LegacyView.vue'
@@ -123,6 +132,7 @@ export default {
NcIconSvgWrapper,
SidebarTab,
SystemTags,
+ NcUserBubble,
},
setup() {
@@ -146,6 +156,7 @@ export default {
error: null,
loading: true,
fileInfo: null,
+ node: null,
isFullScreen: false,
hasLowHeight: false,
}
@@ -287,6 +298,25 @@ export default {
isSystemTagsEnabled() {
return getCapabilities()?.systemtags?.enabled === true
},
+ ownerId() {
+ return this.node?.attributes?.['owner-id'] ?? this.currentUser.uid
+ },
+ currentUserIsOwner() {
+ return this.ownerId === this.currentUser.uid
+ },
+ nodeOwnerLabel() {
+ let ownerDisplayName = this.node?.attributes?.['owner-display-name']
+ if (this.currentUserIsOwner) {
+ ownerDisplayName = `${ownerDisplayName} (${t('files', 'You')})`
+ }
+ return ownerDisplayName
+ },
+ sharedMultipleTimes() {
+ if (Array.isArray(node.attributes?.['share-types']) && node.attributes?.['share-types'].length > 1) {
+ return t('files', 'Shared multiple times with different people')
+ }
+ return null
+ },
},
created() {
subscribe('files:node:deleted', this.onNodeDeleted)
@@ -460,6 +490,7 @@ export default {
this.fileInfo = await FileInfo(this.davPath)
// adding this as fallback because other apps expect it
this.fileInfo.dir = this.file.split('/').slice(0, -1).join('/')
+ this.node = await fetchNode({ path: (this.fileInfo.path + '/' + this.fileInfo.name).replace('//', '/') })
// DEPRECATED legacy views
// TODO: remove
@@ -589,10 +620,25 @@ export default {
}
}
-.sidebar__description {
- display: flex;
- flex-direction: column;
- width: 100%;
- gap: 8px 0;
+.sidebar__subname {
+ display: flex;
+ align-items: center;
+ gap: 0 8px;
+
+ &-separator {
+ display: inline-block;
+ font-weight: bold !important;
+ }
+
+ .user-bubble__wrapper {
+ display: inline-flex;
+ }
}
+
+.sidebar__description {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ gap: 8px 0;
+ }
</style>