mirror of
https://github.com/nextcloud/server.git
synced 2026-02-20 00:12:30 -05:00
Merge pull request #51705 from nextcloud/fix/files-versions
fix(files_versions): correctly show version author also for shared files
This commit is contained in:
commit
c85b8aa36c
6 changed files with 114 additions and 45 deletions
|
|
@ -31,16 +31,19 @@
|
|||
<div class="version__info">
|
||||
<div v-if="versionLabel"
|
||||
class="version__info__label"
|
||||
data-cy-files-version-label
|
||||
:title="versionLabel">
|
||||
{{ versionLabel }}
|
||||
</div>
|
||||
<div v-if="versionAuthor" class="version__info">
|
||||
<div v-if="versionAuthor"
|
||||
class="version__info"
|
||||
data-cy-files-version-author-name>
|
||||
<span v-if="versionLabel">•</span>
|
||||
<NcAvatar class="avatar"
|
||||
:user="version.author"
|
||||
:size="16"
|
||||
:disable-menu="true"
|
||||
:disable-tooltip="true"
|
||||
:size="20"
|
||||
disable-menu
|
||||
disable-tooltip
|
||||
:show-user-status="false" />
|
||||
<div>{{ versionAuthor }}</div>
|
||||
</div>
|
||||
|
|
@ -53,7 +56,7 @@
|
|||
<NcDateTime class="version__info__date"
|
||||
relative-time="short"
|
||||
:timestamp="version.mtime" />
|
||||
<!-- Separate dot to improve alignement -->
|
||||
<!-- Separate dot to improve alignment -->
|
||||
<span>•</span>
|
||||
<span>{{ humanReadableSize }}</span>
|
||||
</div>
|
||||
|
|
@ -114,8 +117,18 @@
|
|||
import type { PropType } from 'vue'
|
||||
import type { Version } from '../utils/versions'
|
||||
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
import { Permission, formatFileSize } from '@nextcloud/files'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import { joinPaths } from '@nextcloud/paths'
|
||||
import { getRootUrl, generateUrl } from '@nextcloud/router'
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
import axios from '@nextcloud/axios'
|
||||
import moment from '@nextcloud/moment'
|
||||
import logger from '../utils/logger'
|
||||
|
||||
import BackupRestore from 'vue-material-design-icons/BackupRestore.vue'
|
||||
import Delete from 'vue-material-design-icons/Delete.vue'
|
||||
import Download from 'vue-material-design-icons/Download.vue'
|
||||
|
|
@ -130,14 +143,6 @@ import NcDateTime from '@nextcloud/vue/components/NcDateTime'
|
|||
import NcListItem from '@nextcloud/vue/components/NcListItem'
|
||||
import Tooltip from '@nextcloud/vue/directives/Tooltip'
|
||||
|
||||
import { Permission, formatFileSize } from '@nextcloud/files'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import { joinPaths } from '@nextcloud/paths'
|
||||
import { getRootUrl, generateOcsUrl } from '@nextcloud/router'
|
||||
import axios from '@nextcloud/axios'
|
||||
import moment from '@nextcloud/moment'
|
||||
|
||||
const hasPermission = (permissions: number, permission: number): boolean => (permissions & permission) !== 0
|
||||
|
||||
export default defineComponent({
|
||||
|
|
@ -295,21 +300,26 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
async fetchDisplayName() {
|
||||
// check to make sure that we have a valid author - in case database did not migrate, null author, etc.
|
||||
if (this.version.author) {
|
||||
this.versionAuthor = null
|
||||
if (!this.version.author) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.version.author === getCurrentUser()?.uid) {
|
||||
this.versionAuthor = t('files_versions', 'You')
|
||||
} else {
|
||||
try {
|
||||
const { data } = await axios.get(generateOcsUrl(`/cloud/users/${this.version.author}`))
|
||||
this.versionAuthor = data.ocs.data.displayname
|
||||
} catch (e) {
|
||||
// Promise got rejected - default to null author to not try to load author profile
|
||||
this.versionAuthor = null
|
||||
const { data } = await axios.post(generateUrl('/displaynames'), { users: [this.version.author] })
|
||||
this.versionAuthor = data.users[this.version.author]
|
||||
} catch (error) {
|
||||
logger.warn('Could not load user display name', { error })
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
click() {
|
||||
if (!this.canView) {
|
||||
window.location = this.downloadURL
|
||||
window.location.href = this.downloadURL
|
||||
return
|
||||
}
|
||||
this.$emit('click', { version: this.version })
|
||||
|
|
|
|||
|
|
@ -4,28 +4,27 @@
|
|||
-->
|
||||
<template>
|
||||
<div class="versions-tab__container">
|
||||
<VirtualScrolling :sections="sections"
|
||||
<VirtualScrolling v-slot="{ visibleSections }"
|
||||
:sections="sections"
|
||||
:header-height="0">
|
||||
<template slot-scope="{visibleSections}">
|
||||
<ul data-files-versions-versions-list>
|
||||
<template v-if="visibleSections.length === 1">
|
||||
<Version v-for="(row) of visibleSections[0].rows"
|
||||
:key="row.items[0].mtime"
|
||||
:can-view="canView"
|
||||
:can-compare="canCompare"
|
||||
:load-preview="isActive"
|
||||
:version="row.items[0]"
|
||||
:file-info="fileInfo"
|
||||
:is-current="row.items[0].mtime === fileInfo.mtime"
|
||||
:is-first-version="row.items[0].mtime === initialVersionMtime"
|
||||
@click="openVersion"
|
||||
@compare="compareVersion"
|
||||
@restore="handleRestore"
|
||||
@label-update-request="handleLabelUpdateRequest(row.items[0])"
|
||||
@delete="handleDelete" />
|
||||
</template>
|
||||
</ul>
|
||||
</template>
|
||||
<ul :aria-label="t('files_versions', 'File versions')" data-files-versions-versions-list>
|
||||
<template v-if="visibleSections.length === 1">
|
||||
<Version v-for="(row) of visibleSections[0].rows"
|
||||
:key="row.items[0].mtime"
|
||||
:can-view="canView"
|
||||
:can-compare="canCompare"
|
||||
:load-preview="isActive"
|
||||
:version="row.items[0]"
|
||||
:file-info="fileInfo"
|
||||
:is-current="row.items[0].mtime === fileInfo.mtime"
|
||||
:is-first-version="row.items[0].mtime === initialVersionMtime"
|
||||
@click="openVersion"
|
||||
@compare="compareVersion"
|
||||
@restore="handleRestore"
|
||||
@label-update-request="handleLabelUpdateRequest(row.items[0])"
|
||||
@delete="handleDelete" />
|
||||
</template>
|
||||
</ul>
|
||||
<NcLoadingIcon v-if="loading" slot="loader" class="files-list-viewer__loader" />
|
||||
</VirtualScrolling>
|
||||
<VersionLabelDialog v-if="editedVersion"
|
||||
|
|
|
|||
|
|
@ -30,4 +30,18 @@ describe('Versions creation', () => {
|
|||
cy.get('[data-files-versions-version]').eq(2).contains('Initial version')
|
||||
})
|
||||
})
|
||||
|
||||
it('See yourself as version author', () => {
|
||||
cy.visit('/apps/files')
|
||||
openVersionsPanel(randomFileName)
|
||||
|
||||
cy.findByRole('tabpanel', { name: 'Versions' })
|
||||
.findByRole('list', { name: 'File versions' })
|
||||
.findAllByRole('listitem')
|
||||
.should('have.length', 3)
|
||||
.first()
|
||||
.find('[data-cy-files-version-author-name]')
|
||||
.should('exist')
|
||||
.and('contain.text', 'You')
|
||||
})
|
||||
})
|
||||
|
|
|
|||
46
cypress/e2e/files_versions/version_sharing.cy.ts
Normal file
46
cypress/e2e/files_versions/version_sharing.cy.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
import type { User } from '@nextcloud/cypress'
|
||||
import { openVersionsPanel, setupTestSharedFileFromUser, uploadThreeVersions } from './filesVersionsUtils.ts'
|
||||
import { navigateToFolder, triggerActionForFile } from '../files/FilesUtils.ts'
|
||||
|
||||
describe('Versions on shares', () => {
|
||||
const randomSharedFolderName = Math.random().toString(36).replace(/[^a-z]+/g, '').substring(0, 10)
|
||||
const randomFileName = Math.random().toString(36).replace(/[^a-z]+/g, '').substring(0, 10) + '.txt'
|
||||
const randomFilePath = `${randomSharedFolderName}/${randomFileName}`
|
||||
let alice: User
|
||||
let bob: User
|
||||
|
||||
before(() => {
|
||||
cy.createRandomUser()
|
||||
.then((user) => {
|
||||
alice = user
|
||||
})
|
||||
.then(() => {
|
||||
cy.mkdir(alice, `/${randomSharedFolderName}`)
|
||||
return setupTestSharedFileFromUser(alice, randomSharedFolderName, {})
|
||||
})
|
||||
.then((user) => { bob = user })
|
||||
.then(() => uploadThreeVersions(alice, randomFilePath))
|
||||
})
|
||||
|
||||
it('See sharees display name as author', () => {
|
||||
cy.login(bob)
|
||||
cy.visit('/apps/files')
|
||||
|
||||
navigateToFolder(randomSharedFolderName)
|
||||
|
||||
triggerActionForFile(randomFileName, 'details')
|
||||
cy.findByRole('tab', { name: 'Versions' }).click()
|
||||
|
||||
cy.findByRole('tabpanel', { name: 'Versions' })
|
||||
.findByRole('list', { name: 'File versions' })
|
||||
.findAllByRole('listitem')
|
||||
.first()
|
||||
.find('[data-cy-files-version-author-name]')
|
||||
.should('be.visible')
|
||||
.and('contain.text', alice.userId)
|
||||
})
|
||||
})
|
||||
4
dist/files_versions-files_versions.js
vendored
4
dist/files_versions-files_versions.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files_versions-files_versions.js.map
vendored
2
dist/files_versions-files_versions.js.map
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue