mirror of https://github.com/nextcloud/server
Handle case with empty version list
Signed-off-by: Carl Schwan <carl@carlschwan.eu> Signed-off-by: Louis Chemineau <louis@chmn.me>
This commit is contained in:
parent
2c50153618
commit
7888aaf34f
|
@ -17,58 +17,78 @@
|
|||
-->
|
||||
<template>
|
||||
<div>
|
||||
<ul>
|
||||
<li v-for="version in versions" class="version">
|
||||
<NcListItem v-for="version in versions"
|
||||
class="version"
|
||||
key="version.url"
|
||||
:title="version.title"
|
||||
:href="version.url">
|
||||
<template #icon>
|
||||
<img lazy="true"
|
||||
:src="version.preview"
|
||||
alt=""
|
||||
height="256"
|
||||
width="256"
|
||||
class="version-image">
|
||||
</template>
|
||||
<template #subtitle>
|
||||
<div class="version-info">
|
||||
<a v-tooltip="version.dateTime" :href="version.url">{{ version.relativeTime }}</a>
|
||||
<div class="version-info-size">
|
||||
<span class="version-info-size">•</span>
|
||||
<span class="version-info-size">
|
||||
{{ version.size }}
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<NcButton v-tooltip="t('files_versions', `Download file ${fileInfo.name} with version ${version.displayVersionName}`)"
|
||||
type="secondary"
|
||||
class="download-button"
|
||||
:href="version.url"
|
||||
:aria-label="t('files_versions', `Download file ${fileInfo.name} with version ${version.displayVersionName}`)">
|
||||
</template>
|
||||
<template #actions>
|
||||
<NcActionLink :href="version.url">
|
||||
<template #icon>
|
||||
<Download :size="22" />
|
||||
</template>
|
||||
</NcButton>
|
||||
<NcButton v-tooltip="t('files_versions', `Restore file ${fileInfo.name} with version ${version.displayVersionName}`)"
|
||||
type="secondary"
|
||||
class="restore-button"
|
||||
:aria-label="t('files_versions', `Restore file ${fileInfo.name} with version ${version.displayVersionName}`)"
|
||||
@click="restoreVersion(version)">
|
||||
{{ t('files_versions', `Download file ${fileInfo.name} with version ${version.displayVersionName}`) }}
|
||||
</NcActionLink>
|
||||
<NcActionButton @click="restoreVersion(version)" v-if="!version.isCurrent">
|
||||
<template #icon>
|
||||
<BackupRestore :size="22" />
|
||||
</template>
|
||||
</NcButton>
|
||||
</li>
|
||||
</ul>
|
||||
{{ t('files_versions', `Restore file ${fileInfo.name} with version ${version.displayVersionName}`) }}
|
||||
</NcActionButton>
|
||||
</template>
|
||||
</NcListItem>
|
||||
<NcEmptyContent v-if="!loading && versions.length === 1"
|
||||
:title="t('files_version', 'No versions yet')">
|
||||
<!-- length === 1, since we don't want to show versions if there is only the current file -->
|
||||
<template #icon>
|
||||
<BackupRestore />
|
||||
</template>
|
||||
</NcEmptyContent>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { createClient, getPatcher } from 'webdav'
|
||||
import axios from '@nextcloud/axios'
|
||||
import parseUrl from 'url-parse'
|
||||
import { generateRemoteUrl, generateUrl } from '@nextcloud/router'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
import { translate } from '@nextcloud/l10n'
|
||||
import BackupRestore from 'vue-material-design-icons/BackupRestore.vue'
|
||||
import Download from 'vue-material-design-icons/Download.vue'
|
||||
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
|
||||
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
|
||||
import NcActionLink from '@nextcloud/vue/dist/Components/NcActionLink.js'
|
||||
import NcListItem from '@nextcloud/vue/dist/Components/NcListItem.js'
|
||||
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'
|
||||
import { showError, showSuccess } from '@nextcloud/dialogs'
|
||||
import moment from '@nextcloud/moment'
|
||||
import { basename, joinPaths } from '@nextcloud/paths'
|
||||
import { getLoggerBuilder } from '@nextcloud/logger'
|
||||
import { translate } from '@nextcloud/l10n'
|
||||
|
||||
const logger = getLoggerBuilder()
|
||||
.setApp('files_version')
|
||||
.detectUser()
|
||||
.build()
|
||||
|
||||
/**
|
||||
*
|
||||
* Get WebDAV request body for version list
|
||||
*/
|
||||
function getDavRequest() {
|
||||
return `<?xml version="1.0"?>
|
||||
|
@ -85,55 +105,64 @@ function getDavRequest() {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param version
|
||||
* @param fileInfo
|
||||
* Format version
|
||||
*/
|
||||
function formatVersion(version, fileInfo) {
|
||||
const fileVersion = basename(version.filename)
|
||||
const isCurrent = version.mime === ''
|
||||
|
||||
const preview = generateUrl('/apps/files_versions/preview?file={file}&version={fileVersion}', {
|
||||
file: joinPaths(fileInfo.path, fileInfo.name),
|
||||
fileVersion,
|
||||
})
|
||||
const preview = isCurrent
|
||||
? generateUrl('/core/preview?fileId={fileId}&c={fileEtag}&x=250&y=250&forceIcon=0&a=0', {
|
||||
fileId: fileInfo.id,
|
||||
fileEtag: fileInfo.etag,
|
||||
}) : generateUrl('/apps/files_versions/preview?file={file}&version={fileVersion}', {
|
||||
file: joinPaths(fileInfo.path, fileInfo.name),
|
||||
fileVersion,
|
||||
})
|
||||
|
||||
return {
|
||||
displayVersionName: fileVersion,
|
||||
title: isCurrent ? translate('files_versions', 'Current version') : '',
|
||||
fileName: version.filename,
|
||||
mimeType: version.mime,
|
||||
size: OC.Util.humanFileSize(version.size),
|
||||
size: OC.Util.humanFileSize(isCurrent ? fileInfo.size : version.size),
|
||||
type: version.type,
|
||||
dateTime: moment(version.lastmod),
|
||||
relativeTime: moment(version.lastmod).fromNow(),
|
||||
dateTime: moment(isCurrent ? fileInfo.mtime : version.lastmod),
|
||||
relativeTime: moment(isCurrent ? fileInfo.mtime : version.lastmod).fromNow(),
|
||||
preview,
|
||||
url: joinPaths('/remote.php/dav', version.filename),
|
||||
url: isCurrent ? joinPaths('/remote.php/dav', version.filename) : joinPaths('/remote.php/dav', fileInfo.path, fileInfo.name),
|
||||
fileVersion,
|
||||
isCurrent,
|
||||
}
|
||||
}
|
||||
|
||||
const rootPath = 'dav'
|
||||
|
||||
// force our axios
|
||||
const patcher = getPatcher()
|
||||
patcher.patch('request', axios)
|
||||
|
||||
// init webdav client on default dav endpoint
|
||||
const remote = generateRemoteUrl(rootPath)
|
||||
const client = createClient(remote)
|
||||
|
||||
export default {
|
||||
name: 'VersionTab',
|
||||
components: {
|
||||
NcButton,
|
||||
NcEmptyContent,
|
||||
NcActionLink,
|
||||
NcActionButton,
|
||||
NcListItem,
|
||||
BackupRestore,
|
||||
Download,
|
||||
},
|
||||
data() {
|
||||
const rootPath = 'dav'
|
||||
|
||||
// force our axios
|
||||
const patcher = getPatcher()
|
||||
patcher.patch('request', axios)
|
||||
|
||||
// init webdav client on default dav endpoint
|
||||
const remote = generateRemoteUrl(rootPath)
|
||||
const client = createClient(remote)
|
||||
|
||||
return {
|
||||
fileInfo: null,
|
||||
versions: [],
|
||||
client,
|
||||
remote,
|
||||
loading: true,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -153,13 +182,17 @@ export default {
|
|||
*/
|
||||
async fetchVersions() {
|
||||
const path = `/versions/${getCurrentUser().uid}/versions/${this.fileInfo.id}`
|
||||
const remotePath = parseUrl(this.remote).pathname
|
||||
|
||||
const response = await this.client.getDirectoryContents(path, {
|
||||
data: getDavRequest(),
|
||||
})
|
||||
this.versions = response.filter(version => version.mime !== '')
|
||||
.map(version => formatVersion(version, this.fileInfo))
|
||||
try {
|
||||
const response = await client.getDirectoryContents(path, {
|
||||
data: getDavRequest(),
|
||||
})
|
||||
this.versions = response.map(version => formatVersion(version, this.fileInfo))
|
||||
this.loading = false
|
||||
} catch (exception) {
|
||||
logger.error('Could not fetch version', {exception})
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -169,15 +202,15 @@ export default {
|
|||
*/
|
||||
async restoreVersion(version) {
|
||||
try {
|
||||
console.debug('restore version', version.url)
|
||||
const response = await this.client.moveFile(
|
||||
logger.debug('restoring version', version.url)
|
||||
const response = await client.moveFile(
|
||||
`/versions/${getCurrentUser().uid}/versions/${this.fileInfo.id}/${version.fileVersion}`,
|
||||
`/versions/${getCurrentUser().uid}/restore/target`
|
||||
)
|
||||
showSuccess(t('files_versions', 'Version restored'))
|
||||
await this.fetchVersions()
|
||||
} catch (exception) {
|
||||
console.error('Could not restore version', exception)
|
||||
logger.error('Could not restore version', {exception})
|
||||
showError(t('files_versions', 'Could not restore version'))
|
||||
}
|
||||
},
|
||||
|
@ -198,7 +231,9 @@ export default {
|
|||
flex-direction: row;
|
||||
&-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
&-size {
|
||||
color: var(--color-text-lighter);
|
||||
}
|
||||
|
@ -206,17 +241,9 @@ export default {
|
|||
&-image {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
filter: drop-shadow(0 1px 2px var(--color-box-shadow));
|
||||
border: 1px solid var(--color-border);
|
||||
margin-right: 1rem;
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
.restore-button {
|
||||
margin-left: 1rem;
|
||||
align-self: center;
|
||||
}
|
||||
.download-button {
|
||||
margin-left: auto;
|
||||
align-self: center;
|
||||
border-radius: var(--border-radius-large);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue