mirror of
https://github.com/nextcloud/server.git
synced 2026-02-20 00:12:30 -05:00
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>
This commit is contained in:
parent
414430980a
commit
faa29a0feb
3 changed files with 70 additions and 24 deletions
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 => ({
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Reference in a new issue