mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
Move modal outside of the Version component.
This is for accessibility, to have the NcListItem (<li>) as a direct child of the <ul> Signed-off-by: Louis Chemineau <louis@chmn.me>
This commit is contained in:
parent
8d114c9e74
commit
3f63375a06
4 changed files with 290 additions and 237 deletions
|
|
@ -16,110 +16,78 @@
|
|||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<NcListItem class="version"
|
||||
:name="versionLabel"
|
||||
:force-display-actions="true"
|
||||
data-files-versions-version
|
||||
@click="click">
|
||||
<template #icon>
|
||||
<div v-if="!(loadPreview || previewLoaded)" class="version__image" />
|
||||
<img v-else-if="(isCurrent || version.hasPreview) && !previewErrored"
|
||||
:src="version.previewUrl"
|
||||
alt=""
|
||||
decoding="async"
|
||||
fetchpriority="low"
|
||||
loading="lazy"
|
||||
class="version__image"
|
||||
@load="previewLoaded = true"
|
||||
@error="previewErrored = true">
|
||||
<div v-else
|
||||
class="version__image">
|
||||
<ImageOffOutline :size="20" />
|
||||
</div>
|
||||
</template>
|
||||
<template #subname>
|
||||
<div class="version__info">
|
||||
<span :title="formattedDate">{{ version.mtime | humanDateFromNow }}</span>
|
||||
<!-- Separate dot to improve alignement -->
|
||||
<span class="version__info__size">•</span>
|
||||
<span class="version__info__size">{{ version.size | humanReadableSize }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #actions>
|
||||
<NcActionButton v-if="enableLabeling"
|
||||
:close-after-click="true"
|
||||
@click="openVersionLabelModal">
|
||||
<template #icon>
|
||||
<Pencil :size="22" />
|
||||
</template>
|
||||
{{ version.label === '' ? t('files_versions', 'Name this version') : t('files_versions', 'Edit version name') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="!isCurrent && canView && canCompare"
|
||||
:close-after-click="true"
|
||||
@click="compareVersion">
|
||||
<template #icon>
|
||||
<FileCompare :size="22" />
|
||||
</template>
|
||||
{{ t('files_versions', 'Compare to current version') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="!isCurrent"
|
||||
:close-after-click="true"
|
||||
@click="restoreVersion">
|
||||
<template #icon>
|
||||
<BackupRestore :size="22" />
|
||||
</template>
|
||||
{{ t('files_versions', 'Restore version') }}
|
||||
</NcActionButton>
|
||||
<NcActionLink :href="downloadURL"
|
||||
:close-after-click="true"
|
||||
:download="downloadURL">
|
||||
<template #icon>
|
||||
<Download :size="22" />
|
||||
</template>
|
||||
{{ t('files_versions', 'Download version') }}
|
||||
</NcActionLink>
|
||||
<NcActionButton v-if="!isCurrent && enableDeletion"
|
||||
:close-after-click="true"
|
||||
@click="deleteVersion">
|
||||
<template #icon>
|
||||
<Delete :size="22" />
|
||||
</template>
|
||||
{{ t('files_versions', 'Delete version') }}
|
||||
</NcActionButton>
|
||||
</template>
|
||||
</NcListItem>
|
||||
<NcModal v-if="showVersionLabelForm"
|
||||
:title="t('files_versions', 'Name this version')"
|
||||
@close="showVersionLabelForm = false">
|
||||
<form class="version-label-modal"
|
||||
@submit.prevent="setVersionLabel(formVersionLabelValue)">
|
||||
<label>
|
||||
<div class="version-label-modal__title">{{ t('files_versions', 'Version name') }}</div>
|
||||
<NcTextField ref="labelInput"
|
||||
:value.sync="formVersionLabelValue"
|
||||
:placeholder="t('files_versions', 'Version name')"
|
||||
:label-outside="true" />
|
||||
</label>
|
||||
|
||||
<div class="version-label-modal__info">
|
||||
{{ t('files_versions', 'Named versions are persisted, and excluded from automatic cleanups when your storage quota is full.') }}
|
||||
</div>
|
||||
|
||||
<div class="version-label-modal__actions">
|
||||
<NcButton :disabled="formVersionLabelValue.trim().length === 0" @click="setVersionLabel('')">
|
||||
{{ t('files_versions', 'Remove version name') }}
|
||||
</NcButton>
|
||||
<NcButton type="primary" native-type="submit">
|
||||
<template #icon>
|
||||
<Check />
|
||||
</template>
|
||||
{{ t('files_versions', 'Save version name') }}
|
||||
</NcButton>
|
||||
</div>
|
||||
</form>
|
||||
</NcModal>
|
||||
</div>
|
||||
<NcListItem class="version"
|
||||
:name="versionLabel"
|
||||
:force-display-actions="true"
|
||||
data-files-versions-version
|
||||
@click="click">
|
||||
<template #icon>
|
||||
<div v-if="!(loadPreview || previewLoaded)" class="version__image" />
|
||||
<img v-else-if="(isCurrent || version.hasPreview) && !previewErrored"
|
||||
:src="version.previewUrl"
|
||||
alt=""
|
||||
decoding="async"
|
||||
fetchpriority="low"
|
||||
loading="lazy"
|
||||
class="version__image"
|
||||
@load="previewLoaded = true"
|
||||
@error="previewErrored = true">
|
||||
<div v-else
|
||||
class="version__image">
|
||||
<ImageOffOutline :size="20" />
|
||||
</div>
|
||||
</template>
|
||||
<template #subname>
|
||||
<div class="version__info">
|
||||
<span :title="formattedDate">{{ version.mtime | humanDateFromNow }}</span>
|
||||
<!-- Separate dot to improve alignement -->
|
||||
<span class="version__info__size">•</span>
|
||||
<span class="version__info__size">{{ version.size | humanReadableSize }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #actions>
|
||||
<NcActionButton v-if="enableLabeling"
|
||||
:close-after-click="true"
|
||||
@click="labelUpdate">
|
||||
<template #icon>
|
||||
<Pencil :size="22" />
|
||||
</template>
|
||||
{{ version.label === '' ? t('files_versions', 'Name this version') : t('files_versions', 'Edit version name') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="!isCurrent && canView && canCompare"
|
||||
:close-after-click="true"
|
||||
@click="compareVersion">
|
||||
<template #icon>
|
||||
<FileCompare :size="22" />
|
||||
</template>
|
||||
{{ t('files_versions', 'Compare to current version') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="!isCurrent"
|
||||
:close-after-click="true"
|
||||
@click="restoreVersion">
|
||||
<template #icon>
|
||||
<BackupRestore :size="22" />
|
||||
</template>
|
||||
{{ t('files_versions', 'Restore version') }}
|
||||
</NcActionButton>
|
||||
<NcActionLink :href="downloadURL"
|
||||
:close-after-click="true"
|
||||
:download="downloadURL">
|
||||
<template #icon>
|
||||
<Download :size="22" />
|
||||
</template>
|
||||
{{ t('files_versions', 'Download version') }}
|
||||
</NcActionLink>
|
||||
<NcActionButton v-if="!isCurrent && enableDeletion"
|
||||
:close-after-click="true"
|
||||
@click="deleteVersion">
|
||||
<template #icon>
|
||||
<Delete :size="22" />
|
||||
</template>
|
||||
{{ t('files_versions', 'Delete version') }}
|
||||
</NcActionButton>
|
||||
</template>
|
||||
</NcListItem>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
@ -127,15 +95,11 @@ import BackupRestore from 'vue-material-design-icons/BackupRestore.vue'
|
|||
import Download from 'vue-material-design-icons/Download.vue'
|
||||
import FileCompare from 'vue-material-design-icons/FileCompare.vue'
|
||||
import Pencil from 'vue-material-design-icons/Pencil.vue'
|
||||
import Check from 'vue-material-design-icons/Check.vue'
|
||||
import Delete from 'vue-material-design-icons/Delete.vue'
|
||||
import ImageOffOutline from 'vue-material-design-icons/ImageOffOutline.vue'
|
||||
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 NcModal from '@nextcloud/vue/dist/Components/NcModal.js'
|
||||
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
|
||||
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
|
||||
import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip.js'
|
||||
import moment from '@nextcloud/moment'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
|
|
@ -149,14 +113,10 @@ export default {
|
|||
NcActionLink,
|
||||
NcActionButton,
|
||||
NcListItem,
|
||||
NcModal,
|
||||
NcButton,
|
||||
NcTextField,
|
||||
BackupRestore,
|
||||
Download,
|
||||
FileCompare,
|
||||
Pencil,
|
||||
Check,
|
||||
Delete,
|
||||
ImageOffOutline,
|
||||
},
|
||||
|
|
@ -180,7 +140,7 @@ export default {
|
|||
},
|
||||
},
|
||||
props: {
|
||||
/** @type {Vue.PropOptions<import('../utils/versions.js').Version>} */
|
||||
/** @type {Vue.PropOptions<import('../utils/versions.ts').Version>} */
|
||||
version: {
|
||||
type: Object,
|
||||
required: true,
|
||||
|
|
@ -214,8 +174,6 @@ export default {
|
|||
return {
|
||||
previewLoaded: false,
|
||||
previewErrored: false,
|
||||
showVersionLabelForm: false,
|
||||
formVersionLabelValue: this.version.label,
|
||||
capabilities: loadState('core', 'capabilities', { files: { version_labeling: false, version_deletion: false } }),
|
||||
}
|
||||
},
|
||||
|
|
@ -268,23 +226,14 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
openVersionLabelModal() {
|
||||
this.showVersionLabelForm = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.labelInput.$el.getElementsByTagName('input')[0].focus()
|
||||
})
|
||||
labelUpdate() {
|
||||
this.$emit('label-update-request')
|
||||
},
|
||||
|
||||
restoreVersion() {
|
||||
this.$emit('restore', this.version)
|
||||
},
|
||||
|
||||
setVersionLabel(label) {
|
||||
this.formVersionLabelValue = label
|
||||
this.showVersionLabelForm = false
|
||||
this.$emit('label-update', this.version, label)
|
||||
},
|
||||
|
||||
deleteVersion() {
|
||||
this.$emit('delete', this.version)
|
||||
},
|
||||
|
|
@ -337,28 +286,4 @@ export default {
|
|||
color: var(--color-text-light);
|
||||
}
|
||||
}
|
||||
|
||||
.version-label-modal {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
height: 250px;
|
||||
padding: 16px;
|
||||
|
||||
&__title {
|
||||
margin-bottom: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&__info {
|
||||
margin-top: 12px;
|
||||
color: var(--color-text-maxcontrast);
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 64px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
115
apps/files_versions/src/components/VersionLabelForm.vue
Normal file
115
apps/files_versions/src/components/VersionLabelForm.vue
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
<!--
|
||||
- @copyright Copyright (c) 2024 Louis Chemineau <louis@chmn.me>
|
||||
-
|
||||
- @author Louis Chemineau <louis@chmn.me>
|
||||
-
|
||||
- @license AGPL-3.0-or-later
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<template>
|
||||
<form class="version-label-modal"
|
||||
@submit.prevent="setVersionLabel(innerVersionLabel)">
|
||||
<label>
|
||||
<div class="version-label-modal__title">{{ t('files_versions', 'Version name') }}</div>
|
||||
<NcTextField ref="labelInput"
|
||||
:value.sync="innerVersionLabel"
|
||||
:placeholder="t('files_versions', 'Version name')"
|
||||
:label-outside="true" />
|
||||
</label>
|
||||
|
||||
<div class="version-label-modal__info">
|
||||
{{ t('files_versions', 'Named versions are persisted, and excluded from automatic cleanups when your storage quota is full.') }}
|
||||
</div>
|
||||
|
||||
<div class="version-label-modal__actions">
|
||||
<NcButton :disabled="innerVersionLabel.trim().length === 0" @click="setVersionLabel('')">
|
||||
{{ t('files_versions', 'Remove version name') }}
|
||||
</NcButton>
|
||||
<NcButton type="primary" native-type="submit">
|
||||
<template #icon>
|
||||
<Check />
|
||||
</template>
|
||||
{{ t('files_versions', 'Save version name') }}
|
||||
</NcButton>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Check from 'vue-material-design-icons/Check.vue'
|
||||
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
|
||||
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
|
||||
import { translate } from '@nextcloud/l10n'
|
||||
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'VersionLabelForm',
|
||||
components: {
|
||||
NcButton,
|
||||
NcTextField,
|
||||
Check,
|
||||
},
|
||||
props: {
|
||||
versionLabel: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
innerVersionLabel: this.versionLabel,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
(this.$refs.labelInput as Vue).$el.getElementsByTagName('input')[0].focus()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
setVersionLabel(label: string) {
|
||||
this.$emit('label-update', label)
|
||||
},
|
||||
|
||||
t: translate,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.version-label-modal {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
height: 250px;
|
||||
padding: 16px;
|
||||
|
||||
&__title {
|
||||
margin-bottom: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&__info {
|
||||
margin-top: 12px;
|
||||
color: var(--color-text-maxcontrast);
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 64px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable jsdoc/require-param */
|
||||
/* eslint-disable jsdoc/require-jsdoc */
|
||||
/**
|
||||
* @copyright 2022 Louis Chemineau <mlouis@chmn.me>
|
||||
*
|
||||
|
|
@ -29,39 +32,35 @@ import { encodeFilePath } from '../../../files/src/utils/fileUtils.ts'
|
|||
import client from '../utils/davClient.js'
|
||||
import davRequest from '../utils/davRequest.js'
|
||||
import logger from '../utils/logger.js'
|
||||
import type { FileStat, ResponseDataDetailed } from 'webdav'
|
||||
|
||||
/**
|
||||
* @typedef {object} Version
|
||||
* @property {string} fileId - The id of the file associated to the version.
|
||||
* @property {string} label - 'Current version' or ''
|
||||
* @property {string} filename - File name relative to the version DAV endpoint
|
||||
* @property {string} basename - A base name generated from the mtime
|
||||
* @property {string} mime - Empty for the current version, else the actual mime type of the version
|
||||
* @property {string} etag - Empty for the current version, else the actual mime type of the version
|
||||
* @property {string} size - Human readable size
|
||||
* @property {string} type - 'file'
|
||||
* @property {number} mtime - Version creation date as a timestamp
|
||||
* @property {string} permissions - Only readable: 'R'
|
||||
* @property {boolean} hasPreview - Whether the version has a preview
|
||||
* @property {string} previewUrl - Preview URL of the version
|
||||
* @property {string} url - Download URL of the version
|
||||
* @property {string} source - The WebDAV endpoint of the ressource
|
||||
* @property {string|null} fileVersion - The version id, null for the current version
|
||||
*/
|
||||
export interface Version {
|
||||
fileId: string, // The id of the file associated to the version.
|
||||
label: string, // 'Current version' or ''
|
||||
filename: string, // File name relative to the version DAV endpoint
|
||||
basename: string, // A base name generated from the mtime
|
||||
mime: string, // Empty for the current version, else the actual mime type of the version
|
||||
etag: string, // Empty for the current version, else the actual mime type of the version
|
||||
size: string, // Human readable size
|
||||
type: string, // 'file'
|
||||
mtime: number, // Version creation date as a timestamp
|
||||
permissions: string, // Only readable: 'R'
|
||||
hasPreview: boolean, // Whether the version has a preview
|
||||
previewUrl: string, // Preview URL of the version
|
||||
url: string, // Download URL of the version
|
||||
source: string, // The WebDAV endpoint of the ressource
|
||||
fileVersion: string|null, // The version id, null for the current version
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fileInfo
|
||||
* @return {Promise<Version[]>}
|
||||
*/
|
||||
export async function fetchVersions(fileInfo) {
|
||||
export async function fetchVersions(fileInfo: any): Promise<Version[]> {
|
||||
const path = `/versions/${getCurrentUser()?.uid}/versions/${fileInfo.id}`
|
||||
|
||||
try {
|
||||
/** @type {import('webdav').ResponseDataDetailed<import('webdav').FileStat[]>} */
|
||||
const response = await client.getDirectoryContents(path, {
|
||||
data: davRequest,
|
||||
details: true,
|
||||
})
|
||||
}) as ResponseDataDetailed<FileStat[]>
|
||||
|
||||
return response.data
|
||||
// Filter out root
|
||||
.filter(({ mime }) => mime !== '')
|
||||
|
|
@ -74,10 +73,8 @@ export async function fetchVersions(fileInfo) {
|
|||
|
||||
/**
|
||||
* Restore the given version
|
||||
*
|
||||
* @param {Version} version
|
||||
*/
|
||||
export async function restoreVersion(version) {
|
||||
export async function restoreVersion(version: Version) {
|
||||
try {
|
||||
logger.debug('Restoring version', { url: version.url })
|
||||
await client.moveFile(
|
||||
|
|
@ -92,12 +89,8 @@ export async function restoreVersion(version) {
|
|||
|
||||
/**
|
||||
* Format version
|
||||
*
|
||||
* @param {object} version - raw version received from the versions DAV endpoint
|
||||
* @param {object} fileInfo - file properties received from the files DAV endpoint
|
||||
* @return {Version}
|
||||
*/
|
||||
function formatVersion(version, fileInfo) {
|
||||
function formatVersion(version: any, fileInfo: any): Version {
|
||||
const mtime = moment(version.lastmod).unix() * 1000
|
||||
let previewUrl = ''
|
||||
|
||||
|
|
@ -132,11 +125,7 @@ function formatVersion(version, fileInfo) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Version} version
|
||||
* @param {string} newLabel
|
||||
*/
|
||||
export async function setVersionLabel(version, newLabel) {
|
||||
export async function setVersionLabel(version: Version, newLabel: string) {
|
||||
return await client.customRequest(
|
||||
version.filename,
|
||||
{
|
||||
|
|
@ -156,9 +145,6 @@ export async function setVersionLabel(version, newLabel) {
|
|||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Version} version
|
||||
*/
|
||||
export async function deleteVersion(version) {
|
||||
export async function deleteVersion(version: Version) {
|
||||
await client.deleteFile(version.filename)
|
||||
}
|
||||
|
|
@ -16,30 +16,37 @@
|
|||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<template>
|
||||
<VirtualScrolling :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="handleLabelUpdate"
|
||||
@delete="handleDelete" />
|
||||
</template>
|
||||
</ul>
|
||||
</template>
|
||||
<NcLoadingIcon v-if="loading" slot="loader" class="files-list-viewer__loader" />
|
||||
</VirtualScrolling>
|
||||
<div class="versions-tab__container">
|
||||
<VirtualScrolling :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>
|
||||
<NcLoadingIcon v-if="loading" slot="loader" class="files-list-viewer__loader" />
|
||||
</VirtualScrolling>
|
||||
<NcModal v-if="showVersionLabelForm"
|
||||
:title="t('files_versions', 'Name this version')"
|
||||
@close="showVersionLabelForm = false">
|
||||
<VersionLabelForm :version-label="editedVersion.label" @label-update="handleLabelUpdate" />
|
||||
</NcModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
@ -49,18 +56,22 @@ import { showError, showSuccess } from '@nextcloud/dialogs'
|
|||
import isMobile from '@nextcloud/vue/dist/Mixins/isMobile.js'
|
||||
import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
import { NcLoadingIcon } from '@nextcloud/vue'
|
||||
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
|
||||
import NcModal from '@nextcloud/vue/dist/Components/NcModal.js'
|
||||
|
||||
import { fetchVersions, deleteVersion, restoreVersion, setVersionLabel } from '../utils/versions.js'
|
||||
import { fetchVersions, deleteVersion, restoreVersion, setVersionLabel } from '../utils/versions.ts'
|
||||
import Version from '../components/Version.vue'
|
||||
import VirtualScrolling from '../components/VirtualScrolling.vue'
|
||||
import VersionLabelForm from '../components/VersionLabelForm.vue'
|
||||
|
||||
export default {
|
||||
name: 'VersionTab',
|
||||
components: {
|
||||
Version,
|
||||
VirtualScrolling,
|
||||
VersionLabelForm,
|
||||
NcLoadingIcon,
|
||||
NcModal,
|
||||
},
|
||||
mixins: [
|
||||
isMobile,
|
||||
|
|
@ -69,17 +80,12 @@ export default {
|
|||
return {
|
||||
fileInfo: null,
|
||||
isActive: false,
|
||||
/** @type {import('../utils/versions.js').Version[]} */
|
||||
/** @type {import('../utils/versions.ts').Version[]} */
|
||||
versions: [],
|
||||
loading: false,
|
||||
showVersionLabelForm: false,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
subscribe('files_versions:restore:restored', this.fetchVersions)
|
||||
},
|
||||
beforeUnmount() {
|
||||
unsubscribe('files_versions:restore:restored', this.fetchVersions)
|
||||
},
|
||||
computed: {
|
||||
sections() {
|
||||
const rows = this.orderedVersions.map(version => ({ key: version.mtime, height: 68, sectionKey: 'versions', items: [version] }))
|
||||
|
|
@ -90,7 +96,7 @@ export default {
|
|||
* Order versions by mtime.
|
||||
* Put the current version at the top.
|
||||
*
|
||||
* @return {import('../utils/versions.js').Version[]}
|
||||
* @return {import('../utils/versions.ts').Version[]}
|
||||
*/
|
||||
orderedVersions() {
|
||||
return [...this.versions].sort((a, b) => {
|
||||
|
|
@ -146,6 +152,12 @@ export default {
|
|||
return !this.isMobile
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
subscribe('files_versions:restore:restored', this.fetchVersions)
|
||||
},
|
||||
beforeUnmount() {
|
||||
unsubscribe('files_versions:restore:restored', this.fetchVersions)
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* Update current fileInfo and fetch new data
|
||||
|
|
@ -180,7 +192,7 @@ export default {
|
|||
/**
|
||||
* Handle restored event from Version.vue
|
||||
*
|
||||
* @param {import('../utils/versions.js').Version} version
|
||||
* @param {import('../utils/versions.ts').Version} version
|
||||
*/
|
||||
async handleRestore(version) {
|
||||
// Update local copy of fileInfo as rendering depends on it.
|
||||
|
|
@ -220,26 +232,36 @@ export default {
|
|||
|
||||
/**
|
||||
* Handle label-updated event from Version.vue
|
||||
*
|
||||
* @param {import('../utils/versions.js').Version} version
|
||||
* @param {string} newName
|
||||
* @param {import('../utils/versions.ts').Version} version
|
||||
*/
|
||||
async handleLabelUpdate(version, newName) {
|
||||
const oldLabel = version.label
|
||||
version.label = newName
|
||||
handleLabelUpdateRequest(version) {
|
||||
this.showVersionLabelForm = true
|
||||
this.editedVersion = version
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle label-updated event from Version.vue
|
||||
* @param {string} newLabel
|
||||
*/
|
||||
async handleLabelUpdate(newLabel) {
|
||||
const oldLabel = this.editedVersion.label
|
||||
this.editedVersion.label = newLabel
|
||||
this.showVersionLabelForm = false
|
||||
|
||||
try {
|
||||
await setVersionLabel(version, newName)
|
||||
await setVersionLabel(this.editedVersion, newLabel)
|
||||
this.editedVersion = null
|
||||
} catch (exception) {
|
||||
version.label = oldLabel
|
||||
showError(t('files_versions', 'Could not set version name'))
|
||||
this.editedVersion.label = oldLabel
|
||||
showError(this.t('files_versions', 'Could not set version label'))
|
||||
logger.error('Could not set version label', { exception })
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle deleted event from Version.vue
|
||||
*
|
||||
* @param {import('../utils/versions.js').Version} version
|
||||
* @param {import('../utils/versions.ts').Version} version
|
||||
* @param {string} newName
|
||||
*/
|
||||
async handleDelete(version) {
|
||||
|
|
@ -292,3 +314,8 @@ export default {
|
|||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.versions-tab__container {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in a new issue