]> source.dussan.org Git - nextcloud-server.git/commitdiff
Handle case with empty version list
authorCarl Schwan <carl@carlschwan.eu>
Tue, 25 Oct 2022 12:19:53 +0000 (14:19 +0200)
committerLouis Chemineau <louis@chmn.me>
Mon, 28 Nov 2022 16:29:11 +0000 (17:29 +0100)
Signed-off-by: Carl Schwan <carl@carlschwan.eu>
Signed-off-by: Louis Chemineau <louis@chmn.me>
apps/files_versions/src/views/VersionTab.vue

index f7162a3f9e13495294ea6b192310c51cda4b6073..7c5da82ad2ed890de2296cb07ef32b7badfe3ebf 100644 (file)
  -->
 <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>