diff options
Diffstat (limited to 'apps/files_versions/src/components/Version.vue')
-rw-r--r-- | apps/files_versions/src/components/Version.vue | 147 |
1 files changed, 90 insertions, 57 deletions
diff --git a/apps/files_versions/src/components/Version.vue b/apps/files_versions/src/components/Version.vue index 144aae33922..dc36e4134f9 100644 --- a/apps/files_versions/src/components/Version.vue +++ b/apps/files_versions/src/components/Version.vue @@ -5,12 +5,13 @@ <template> <NcListItem class="version" :force-display-actions="true" + :actions-aria-label="t('files_versions', 'Actions for version from {versionHumanExplicitDate}', { versionHumanExplicitDate })" :data-files-versions-version="version.fileVersion" @click="click"> <!-- Icon --> <template #icon> <div v-if="!(loadPreview || previewLoaded)" class="version__image" /> - <img v-else-if="(isCurrent || version.hasPreview) && !previewErrored" + <img v-else-if="version.previewUrl && !previewErrored" :src="version.previewUrl" alt="" decoding="async" @@ -28,16 +29,26 @@ <!-- author --> <template #name> <div class="version__info"> - <div v-if="versionLabel" class="version__info__label">{{ versionLabel }}</div> - <div v-if="versionAuthor" class="version__info"> - <div v-if="versionLabel">•</div> + <div v-if="versionLabel" + class="version__info__label" + data-cy-files-version-label + :title="versionLabel"> + {{ versionLabel }} + </div> + <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 class="version__info__author_name" + :title="versionAuthor"> + {{ versionAuthor }} + </div> </div> </div> </template> @@ -45,10 +56,12 @@ <!-- Version file size as subline --> <template #subname> <div class="version__info version__info__subline"> - <span :title="formattedDate">{{ version.mtime | humanDateFromNow }}</span> - <!-- Separate dot to improve alignement --> + <NcDateTime class="version__info__date" + relative-time="short" + :timestamp="version.mtime" /> + <!-- Separate dot to improve alignment --> <span>•</span> - <span>{{ version.size | humanReadableSize }}</span> + <span>{{ humanReadableSize }}</span> </div> </template> @@ -103,31 +116,35 @@ </template> </NcListItem> </template> - <script lang="ts"> +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' import FileCompare from 'vue-material-design-icons/FileCompare.vue' import ImageOffOutline from 'vue-material-design-icons/ImageOffOutline.vue' -import Pencil from 'vue-material-design-icons/Pencil.vue' +import Pencil from 'vue-material-design-icons/PencilOutline.vue' -import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js' -import NcActionLink from '@nextcloud/vue/dist/Components/NcActionLink.js' -import NcAvatar from '@nextcloud/vue/dist/Components/NcAvatar.js' -import NcListItem from '@nextcloud/vue/dist/Components/NcListItem.js' -import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip.js' - -import { defineComponent, type PropType } from 'vue' -import axios from '@nextcloud/axios' -import { getRootUrl, generateOcsUrl } from '@nextcloud/router' -import { joinPaths } from '@nextcloud/paths' -import { loadState } from '@nextcloud/initial-state' -import { Permission, formatFileSize } from '@nextcloud/files' -import { translate as t } from '@nextcloud/l10n' -import moment from '@nextcloud/moment' +import NcActionButton from '@nextcloud/vue/components/NcActionButton' +import NcActionLink from '@nextcloud/vue/components/NcActionLink' +import NcAvatar from '@nextcloud/vue/components/NcAvatar' +import NcDateTime from '@nextcloud/vue/components/NcDateTime' +import NcListItem from '@nextcloud/vue/components/NcListItem' +import Tooltip from '@nextcloud/vue/directives/Tooltip' const hasPermission = (permissions: number, permission: number): boolean => (permissions & permission) !== 0 @@ -138,6 +155,7 @@ export default defineComponent({ NcActionLink, NcActionButton, NcAvatar, + NcDateTime, NcListItem, BackupRestore, Download, @@ -151,20 +169,6 @@ export default defineComponent({ tooltip: Tooltip, }, - created() { - this.fetchDisplayName() - }, - - filters: { - humanReadableSize(bytes: number): string { - return formatFileSize(bytes) - }, - - humanDateFromNow(timestamp: number): string { - return moment(timestamp).fromNow() - }, - }, - props: { version: { type: Object as PropType<Version>, @@ -203,11 +207,15 @@ export default defineComponent({ previewLoaded: false, previewErrored: false, capabilities: loadState('core', 'capabilities', { files: { version_labeling: false, version_deletion: false } }), - versionAuthor: '', + versionAuthor: '' as string | null, } }, computed: { + humanReadableSize() { + return formatFileSize(this.version.size) + }, + versionLabel(): string { const label = this.version.label ?? '' @@ -226,6 +234,10 @@ export default defineComponent({ return label }, + versionHumanExplicitDate(): string { + return moment(this.version.mtime).format('LLLL') + }, + downloadURL(): string { if (this.isCurrent) { return getRootUrl() + joinPaths('/remote.php/webdav', this.fileInfo.path, this.fileInfo.name) @@ -234,10 +246,6 @@ export default defineComponent({ } }, - formattedDate(): string { - return moment(this.version.mtime).format('LLL') - }, - enableLabeling(): boolean { return this.capabilities.files.version_labeling === true }, @@ -264,7 +272,7 @@ export default defineComponent({ const downloadAttribute = this.fileInfo.shareAttributes .find((attribute) => attribute.scope === 'permissions' && attribute.key === 'download') || {} // If the download attribute is set to false, the file is not downloadable - if (downloadAttribute?.enabled === false) { + if (downloadAttribute?.value === false) { return false } } @@ -273,6 +281,10 @@ export default defineComponent({ }, }, + created() { + this.fetchDisplayName() + }, + methods: { labelUpdate() { this.$emit('label-update-request') @@ -291,21 +303,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 }) @@ -335,14 +352,30 @@ export default defineComponent({ gap: 0.5rem; color: var(--color-main-text); font-weight: 500; + overflow: hidden; &__label { font-weight: 700; + // Fix overflow on narrow screens + overflow: hidden; + text-overflow: ellipsis; + min-width: 110px; + } + + &__author_name { + overflow: hidden; + text-overflow: ellipsis; + } + + &__date { + // Fix overflow on narrow screens + overflow: hidden; + text-overflow: ellipsis; } &__subline { - color: var(--color-text-maxcontrast) - } + color: var(--color-text-maxcontrast) + } } &__image { |