mirror of
https://github.com/nextcloud/server.git
synced 2026-02-26 03:11:28 -05:00
Merge pull request #46691 from nextcloud/fix-show-original-owner
feat(sidebar): Show node owner in metadata subline
This commit is contained in:
commit
fcbb064ae3
21 changed files with 94 additions and 45 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>
|
||||
|
|
|
|||
4
dist/9196-9196.js → dist/7789-7789.js
vendored
4
dist/9196-9196.js → dist/7789-7789.js
vendored
|
|
@ -1,2 +1,2 @@
|
|||
"use strict";(self.webpackChunknextcloud=self.webpackChunknextcloud||[]).push([[9196],{4532:(e,t,n)=>{n.d(t,{A:()=>a});var o=n(71354),r=n.n(o),i=n(76314),s=n.n(i)()(r());s.push([e.id,"\n.note-to-recipient[data-v-514f64d7] {\n\tmargin-inline: var(--row-height)\n}\n.note-to-recipient__text[data-v-514f64d7] {\n\t/* respect new lines */\n\twhite-space: pre-line;\n}\n.note-to-recipient__heading[data-v-514f64d7] {\n\tfont-weight: bold;\n}\n@media screen and (max-width: 512px) {\n.note-to-recipient[data-v-514f64d7] {\n\t\tmargin-inline: var(--default-grid-baseline);\n}\n}\n","",{version:3,sources:["webpack://./apps/files_sharing/src/views/FilesHeaderNoteToRecipient.vue"],names:[],mappings:";AAsDA;CACA;AACA;AAEA;CACA,sBAAA;CACA,qBAAA;AACA;AAEA;CACA,iBAAA;AACA;AAEA;AACA;EACA,2CAAA;AACA;AACA",sourcesContent:["\x3c!--\n - SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n--\x3e\n<template>\n\t<NcNoteCard v-if=\"note.length > 0\"\n\t\tclass=\"note-to-recipient\"\n\t\ttype=\"info\">\n\t\t<p v-if=\"user\" class=\"note-to-recipient__heading\">\n\t\t\t{{ t('files_sharing', 'Note from') }}\n\t\t\t<NcUserBubble :user=\"user.id\" :display-name=\"user.displayName\" />\n\t\t</p>\n\t\t<p v-else class=\"note-to-recipient__heading\">\n\t\t\t{{ t('files_sharing', 'Note:') }}\n\t\t</p>\n\t\t<p class=\"note-to-recipient__text\" v-text=\"note\" />\n\t</NcNoteCard>\n</template>\n\n<script setup lang=\"ts\">\nimport type { Folder } from '@nextcloud/files'\nimport { getCurrentUser } from '@nextcloud/auth'\nimport { t } from '@nextcloud/l10n'\nimport { computed, ref } from 'vue'\n\nimport NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js'\nimport NcUserBubble from '@nextcloud/vue/dist/Components/NcUserBubble.js'\n\nconst folder = ref<Folder>()\nconst note = computed<string>(() => folder.value?.attributes.note ?? '')\nconst user = computed(() => {\n\tconst id = folder.value?.owner\n\tconst displayName = folder.value?.attributes?.['owner-display-name']\n\tif (id !== getCurrentUser()?.uid) {\n\t\treturn {\n\t\t\tid,\n\t\t\tdisplayName,\n\t\t}\n\t}\n\treturn null\n})\n\n/**\n * Update the current folder\n * @param newFolder the new folder to show note for\n */\nfunction updateFolder(newFolder: Folder) {\n\tfolder.value = newFolder\n}\n\ndefineExpose({ updateFolder })\n<\/script>\n\n<style scoped>\n.note-to-recipient {\n\tmargin-inline: var(--row-height)\n}\n\n.note-to-recipient__text {\n\t/* respect new lines */\n\twhite-space: pre-line;\n}\n\n.note-to-recipient__heading {\n\tfont-weight: bold;\n}\n\n@media screen and (max-width: 512px) {\n\t.note-to-recipient {\n\t\tmargin-inline: var(--default-grid-baseline);\n\t}\n}\n</style>\n"],sourceRoot:""}]);const a=s},59196:(e,t,n)=>{n.d(t,{default:()=>b});var o=n(85471),r=n(21777),i=n(53334),s=n(80910),a=n(86719);const l=(0,o.pM)({__name:"FilesHeaderNoteToRecipient",setup(e,t){let{expose:n}=t;const l=(0,o.KR)(),d=(0,o.EW)((()=>l.value?.attributes.note??"")),c=(0,o.EW)((()=>{const e=l.value?.owner,t=l.value?.attributes?.["owner-display-name"];return e!==(0,r.HW)()?.uid?{id:e,displayName:t}:null}));function p(e){l.value=e}return n({updateFolder:p}),{__sfc:!0,folder:l,note:d,user:c,updateFolder:p,t:i.t,NcNoteCard:s.A,NcUserBubble:a.N}}});var d=n(85072),c=n.n(d),p=n(97825),u=n.n(p),A=n(77659),f=n.n(A),m=n(55056),_=n.n(m),C=n(10540),h=n.n(C),v=n(41113),N=n.n(v),g=n(4532),x={};x.styleTagTransform=N(),x.setAttributes=_(),x.insert=f().bind(null,"head"),x.domAPI=u(),x.insertStyleElement=h(),c()(g.A,x),g.A&&g.A.locals&&g.A.locals;const b=(0,n(14486).A)(l,(function(){var e=this,t=e._self._c,n=e._self._setupProxy;return n.note.length>0?t(n.NcNoteCard,{staticClass:"note-to-recipient",attrs:{type:"info"}},[n.user?t("p",{staticClass:"note-to-recipient__heading"},[e._v("\n\t\t"+e._s(n.t("files_sharing","Note from"))+"\n\t\t"),t(n.NcUserBubble,{attrs:{user:n.user.id,"display-name":n.user.displayName}})],1):t("p",{staticClass:"note-to-recipient__heading"},[e._v("\n\t\t"+e._s(n.t("files_sharing","Note:"))+"\n\t")]),e._v(" "),t("p",{staticClass:"note-to-recipient__text",domProps:{textContent:e._s(n.note)}})]):e._e()}),[],!1,null,"514f64d7",null).exports}}]);
|
||||
//# sourceMappingURL=9196-9196.js.map?v=57c0170703ca9333e4fe
|
||||
"use strict";(self.webpackChunknextcloud=self.webpackChunknextcloud||[]).push([[7789],{4532:(e,t,n)=>{n.d(t,{A:()=>a});var o=n(71354),r=n.n(o),i=n(76314),s=n.n(i)()(r());s.push([e.id,"\n.note-to-recipient[data-v-514f64d7] {\n\tmargin-inline: var(--row-height)\n}\n.note-to-recipient__text[data-v-514f64d7] {\n\t/* respect new lines */\n\twhite-space: pre-line;\n}\n.note-to-recipient__heading[data-v-514f64d7] {\n\tfont-weight: bold;\n}\n@media screen and (max-width: 512px) {\n.note-to-recipient[data-v-514f64d7] {\n\t\tmargin-inline: var(--default-grid-baseline);\n}\n}\n","",{version:3,sources:["webpack://./apps/files_sharing/src/views/FilesHeaderNoteToRecipient.vue"],names:[],mappings:";AAsDA;CACA;AACA;AAEA;CACA,sBAAA;CACA,qBAAA;AACA;AAEA;CACA,iBAAA;AACA;AAEA;AACA;EACA,2CAAA;AACA;AACA",sourcesContent:["\x3c!--\n - SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n--\x3e\n<template>\n\t<NcNoteCard v-if=\"note.length > 0\"\n\t\tclass=\"note-to-recipient\"\n\t\ttype=\"info\">\n\t\t<p v-if=\"user\" class=\"note-to-recipient__heading\">\n\t\t\t{{ t('files_sharing', 'Note from') }}\n\t\t\t<NcUserBubble :user=\"user.id\" :display-name=\"user.displayName\" />\n\t\t</p>\n\t\t<p v-else class=\"note-to-recipient__heading\">\n\t\t\t{{ t('files_sharing', 'Note:') }}\n\t\t</p>\n\t\t<p class=\"note-to-recipient__text\" v-text=\"note\" />\n\t</NcNoteCard>\n</template>\n\n<script setup lang=\"ts\">\nimport type { Folder } from '@nextcloud/files'\nimport { getCurrentUser } from '@nextcloud/auth'\nimport { t } from '@nextcloud/l10n'\nimport { computed, ref } from 'vue'\n\nimport NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js'\nimport NcUserBubble from '@nextcloud/vue/dist/Components/NcUserBubble.js'\n\nconst folder = ref<Folder>()\nconst note = computed<string>(() => folder.value?.attributes.note ?? '')\nconst user = computed(() => {\n\tconst id = folder.value?.owner\n\tconst displayName = folder.value?.attributes?.['owner-display-name']\n\tif (id !== getCurrentUser()?.uid) {\n\t\treturn {\n\t\t\tid,\n\t\t\tdisplayName,\n\t\t}\n\t}\n\treturn null\n})\n\n/**\n * Update the current folder\n * @param newFolder the new folder to show note for\n */\nfunction updateFolder(newFolder: Folder) {\n\tfolder.value = newFolder\n}\n\ndefineExpose({ updateFolder })\n<\/script>\n\n<style scoped>\n.note-to-recipient {\n\tmargin-inline: var(--row-height)\n}\n\n.note-to-recipient__text {\n\t/* respect new lines */\n\twhite-space: pre-line;\n}\n\n.note-to-recipient__heading {\n\tfont-weight: bold;\n}\n\n@media screen and (max-width: 512px) {\n\t.note-to-recipient {\n\t\tmargin-inline: var(--default-grid-baseline);\n\t}\n}\n</style>\n"],sourceRoot:""}]);const a=s},37789:(e,t,n)=>{n.d(t,{default:()=>b});var o=n(85471),r=n(21777),i=n(53334),s=n(80910),a=n(77764);const l=(0,o.pM)({__name:"FilesHeaderNoteToRecipient",setup(e,t){let{expose:n}=t;const l=(0,o.KR)(),d=(0,o.EW)((()=>l.value?.attributes.note??"")),c=(0,o.EW)((()=>{const e=l.value?.owner,t=l.value?.attributes?.["owner-display-name"];return e!==(0,r.HW)()?.uid?{id:e,displayName:t}:null}));function p(e){l.value=e}return n({updateFolder:p}),{__sfc:!0,folder:l,note:d,user:c,updateFolder:p,t:i.t,NcNoteCard:s.A,NcUserBubble:a.A}}});var d=n(85072),c=n.n(d),p=n(97825),u=n.n(p),A=n(77659),f=n.n(A),m=n(55056),_=n.n(m),C=n(10540),h=n.n(C),v=n(41113),g=n.n(v),N=n(4532),x={};x.styleTagTransform=g(),x.setAttributes=_(),x.insert=f().bind(null,"head"),x.domAPI=u(),x.insertStyleElement=h(),c()(N.A,x),N.A&&N.A.locals&&N.A.locals;const b=(0,n(14486).A)(l,(function(){var e=this,t=e._self._c,n=e._self._setupProxy;return n.note.length>0?t(n.NcNoteCard,{staticClass:"note-to-recipient",attrs:{type:"info"}},[n.user?t("p",{staticClass:"note-to-recipient__heading"},[e._v("\n\t\t"+e._s(n.t("files_sharing","Note from"))+"\n\t\t"),t(n.NcUserBubble,{attrs:{user:n.user.id,"display-name":n.user.displayName}})],1):t("p",{staticClass:"note-to-recipient__heading"},[e._v("\n\t\t"+e._s(n.t("files_sharing","Note:"))+"\n\t")]),e._v(" "),t("p",{staticClass:"note-to-recipient__text",domProps:{textContent:e._s(n.note)}})]):e._e()}),[],!1,null,"514f64d7",null).exports}}]);
|
||||
//# sourceMappingURL=7789-7789.js.map?v=016cebcd403e1f1d7129
|
||||
File diff suppressed because one or more lines are too long
1
dist/7789-7789.js.map.license
vendored
Symbolic link
1
dist/7789-7789.js.map.license
vendored
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
7789-7789.js.license
|
||||
1
dist/9196-9196.js.map.license
vendored
1
dist/9196-9196.js.map.license
vendored
|
|
@ -1 +0,0 @@
|
|||
9196-9196.js.license
|
||||
4
dist/core-common.js
vendored
4
dist/core-common.js
vendored
File diff suppressed because one or more lines are too long
2
dist/core-common.js.map
vendored
2
dist/core-common.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/files-init.js.map
vendored
2
dist/files-init.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/files-main.js
vendored
4
dist/files-main.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files-main.js.map
vendored
2
dist/files-main.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/files-sidebar.js
vendored
4
dist/files-sidebar.js
vendored
File diff suppressed because one or more lines are too long
3
dist/files-sidebar.js.license
vendored
3
dist/files-sidebar.js.license
vendored
|
|
@ -421,6 +421,9 @@ This file is generated from multiple sources. Included packages:
|
|||
- vue-loader
|
||||
- version: 15.11.1
|
||||
- license: MIT
|
||||
- vue-router
|
||||
- version: 3.6.5
|
||||
- license: MIT
|
||||
- vue
|
||||
- version: 2.7.16
|
||||
- license: MIT
|
||||
|
|
|
|||
2
dist/files-sidebar.js.map
vendored
2
dist/files-sidebar.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/files_sharing-init-public.js.map
vendored
2
dist/files_sharing-init-public.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/files_sharing-init.js
vendored
4
dist/files_sharing-init.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files_sharing-init.js.map
vendored
2
dist/files_sharing-init.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/files_trashbin-init.js
vendored
4
dist/files_trashbin-init.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files_trashbin-init.js.map
vendored
2
dist/files_trashbin-init.js.map
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue