1 line
67 KiB
XML
1 line
67 KiB
XML
{"version":3,"file":"files_versions-sidebar-tab.mjs","sources":["../node_modules/@mdi/svg/svg/backup-restore.svg?raw","../node_modules/vue-material-design-icons/BackupRestore.vue","../node_modules/vue-material-design-icons/FileCompare.vue","../node_modules/vue-material-design-icons/ImageOffOutline.vue","../node_modules/vue-material-design-icons/PencilOutline.vue","../build/frontend/apps/files_versions/src/components/VersionEntry.vue","../build/frontend/apps/files_versions/src/components/VersionLabelDialog.vue","../build/frontend/apps/files_versions/src/utils/logger.ts","../build/frontend/apps/files_versions/src/components/VirtualScrolling.vue","../build/frontend/apps/files_versions/src/utils/davClient.ts","../build/frontend/apps/files_versions/src/utils/davRequest.ts","../build/frontend/apps/files_versions/src/utils/versions.ts","../build/frontend/apps/files_versions/src/views/FilesVersionsSidebarTab.vue","../build/frontend/apps/files_versions/src/sidebar_tab.ts"],"sourcesContent":["export default \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" id=\\\"mdi-backup-restore\\\" viewBox=\\\"0 0 24 24\\\"><path d=\\\"M12,3A9,9 0 0,0 3,12H0L4,16L8,12H5A7,7 0 0,1 12,5A7,7 0 0,1 19,12A7,7 0 0,1 12,19C10.5,19 9.09,18.5 7.94,17.7L6.5,19.14C8.04,20.3 9.94,21 12,21A9,9 0 0,0 21,12A9,9 0 0,0 12,3M14,12A2,2 0 0,0 12,10A2,2 0 0,0 10,12A2,2 0 0,0 12,14A2,2 0 0,0 14,12Z\\\" /></svg>\"","<template>\n <span v-bind=\"$attrs\"\n :aria-hidden=\"title ? null : 'true'\"\n :aria-label=\"title\"\n class=\"material-design-icon backup-restore-icon\"\n role=\"img\"\n @click=\"$emit('click', $event)\">\n <svg :fill=\"fillColor\"\n class=\"material-design-icon__svg\"\n :width=\"size\"\n :height=\"size\"\n viewBox=\"0 0 24 24\">\n <path d=\"M12,3A9,9 0 0,0 3,12H0L4,16L8,12H5A7,7 0 0,1 12,5A7,7 0 0,1 19,12A7,7 0 0,1 12,19C10.5,19 9.09,18.5 7.94,17.7L6.5,19.14C8.04,20.3 9.94,21 12,21A9,9 0 0,0 21,12A9,9 0 0,0 12,3M14,12A2,2 0 0,0 12,10A2,2 0 0,0 10,12A2,2 0 0,0 12,14A2,2 0 0,0 14,12Z\">\n <title v-if=\"title\">{{ title }}</title>\n </path>\n </svg>\n </span>\n</template>\n\n<script>\nexport default {\n name: \"BackupRestoreIcon\",\n emits: ['click'],\n props: {\n title: {\n type: String,\n },\n fillColor: {\n type: String,\n default: \"currentColor\"\n },\n size: {\n type: Number,\n default: 24\n }\n }\n}\n</script>","<template>\n <span v-bind=\"$attrs\"\n :aria-hidden=\"title ? null : 'true'\"\n :aria-label=\"title\"\n class=\"material-design-icon file-compare-icon\"\n role=\"img\"\n @click=\"$emit('click', $event)\">\n <svg :fill=\"fillColor\"\n class=\"material-design-icon__svg\"\n :width=\"size\"\n :height=\"size\"\n viewBox=\"0 0 24 24\">\n <path d=\"M10,18H6V16H10V18M10,14H6V12H10V14M10,1V2H6C4.89,2 4,2.89 4,4V20A2,2 0 0,0 6,22H10V23H12V1H10M20,8V20C20,21.11 19.11,22 18,22H14V20H18V11H14V9H18.5L14,4.5V2L20,8M16,14H14V12H16V14M16,18H14V16H16V18Z\">\n <title v-if=\"title\">{{ title }}</title>\n </path>\n </svg>\n </span>\n</template>\n\n<script>\nexport default {\n name: \"FileCompareIcon\",\n emits: ['click'],\n props: {\n title: {\n type: String,\n },\n fillColor: {\n type: String,\n default: \"currentColor\"\n },\n size: {\n type: Number,\n default: 24\n }\n }\n}\n</script>","<template>\n <span v-bind=\"$attrs\"\n :aria-hidden=\"title ? null : 'true'\"\n :aria-label=\"title\"\n class=\"material-design-icon image-off-outline-icon\"\n role=\"img\"\n @click=\"$emit('click', $event)\">\n <svg :fill=\"fillColor\"\n class=\"material-design-icon__svg\"\n :width=\"size\"\n :height=\"size\"\n viewBox=\"0 0 24 24\">\n <path d=\"M22 20.7L3.3 2L2 3.3L3 4.3V19C3 20.1 3.9 21 5 21H19.7L20.7 22L22 20.7M5 19V6.3L12.6 13.9L11.1 15.8L9 13.1L6 17H15.7L17.7 19H5M8.8 5L6.8 3H19C20.1 3 21 3.9 21 5V17.2L19 15.2V5H8.8\">\n <title v-if=\"title\">{{ title }}</title>\n </path>\n </svg>\n </span>\n</template>\n\n<script>\nexport default {\n name: \"ImageOffOutlineIcon\",\n emits: ['click'],\n props: {\n title: {\n type: String,\n },\n fillColor: {\n type: String,\n default: \"currentColor\"\n },\n size: {\n type: Number,\n default: 24\n }\n }\n}\n</script>","<template>\n <span v-bind=\"$attrs\"\n :aria-hidden=\"title ? null : 'true'\"\n :aria-label=\"title\"\n class=\"material-design-icon pencil-outline-icon\"\n role=\"img\"\n @click=\"$emit('click', $event)\">\n <svg :fill=\"fillColor\"\n class=\"material-design-icon__svg\"\n :width=\"size\"\n :height=\"size\"\n viewBox=\"0 0 24 24\">\n <path d=\"M14.06,9L15,9.94L5.92,19H5V18.08L14.06,9M17.66,3C17.41,3 17.15,3.1 16.96,3.29L15.13,5.12L18.88,8.87L20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18.17,3.09 17.92,3 17.66,3M14.06,6.19L3,17.25V21H6.75L17.81,9.94L14.06,6.19Z\">\n <title v-if=\"title\">{{ title }}</title>\n </path>\n </svg>\n </span>\n</template>\n\n<script>\nexport default {\n name: \"PencilOutlineIcon\",\n emits: ['click'],\n props: {\n title: {\n type: String,\n },\n fillColor: {\n type: String,\n default: \"currentColor\"\n },\n size: {\n type: Number,\n default: 24\n }\n }\n}\n</script>","<!--\n - SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n-->\n<template>\n\t<NcListItem\n\t\tclass=\"version\"\n\t\t:force-display-actions=\"true\"\n\t\t:actions-aria-label=\"t('files_versions', 'Actions for version from {versionHumanExplicitDate}', { versionHumanExplicitDate })\"\n\t\t:data-files-versions-version=\"version.fileVersion\"\n\t\t@click=\"click\">\n\t\t<!-- Icon -->\n\t\t<template #icon>\n\t\t\t<div v-if=\"!(loadPreview || previewLoaded)\" class=\"version__image\" />\n\t\t\t<img\n\t\t\t\tv-else-if=\"version.previewUrl && !previewErrored\"\n\t\t\t\t:src=\"version.previewUrl\"\n\t\t\t\talt=\"\"\n\t\t\t\tdecoding=\"async\"\n\t\t\t\tfetchpriority=\"low\"\n\t\t\t\tloading=\"lazy\"\n\t\t\t\tclass=\"version__image\"\n\t\t\t\t@load=\"previewLoaded = true\"\n\t\t\t\t@error=\"previewErrored = true\">\n\t\t\t<div\n\t\t\t\tv-else\n\t\t\t\tclass=\"version__image\">\n\t\t\t\t<ImageOffOutline :size=\"20\" />\n\t\t\t</div>\n\t\t</template>\n\n\t\t<!-- author -->\n\t\t<template #name>\n\t\t\t<div class=\"version__info\">\n\t\t\t\t<div\n\t\t\t\t\tv-if=\"versionLabel\"\n\t\t\t\t\tclass=\"version__info__label\"\n\t\t\t\t\tdata-cy-files-version-label\n\t\t\t\t\t:title=\"versionLabel\">\n\t\t\t\t\t{{ versionLabel }}\n\t\t\t\t</div>\n\t\t\t\t<div\n\t\t\t\t\tv-if=\"versionAuthor\"\n\t\t\t\t\tclass=\"version__info\"\n\t\t\t\t\tdata-cy-files-version-author-name>\n\t\t\t\t\t<span v-if=\"versionLabel\">•</span>\n\t\t\t\t\t<NcAvatar\n\t\t\t\t\t\tclass=\"avatar\"\n\t\t\t\t\t\t:user=\"version.author ?? undefined\"\n\t\t\t\t\t\t:size=\"20\"\n\t\t\t\t\t\tdisable-menu\n\t\t\t\t\t\tdisable-tooltip\n\t\t\t\t\t\thide-status />\n\t\t\t\t\t<div\n\t\t\t\t\t\tclass=\"version__info__author_name\"\n\t\t\t\t\t\t:title=\"versionAuthor\">\n\t\t\t\t\t\t{{ versionAuthor }}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</template>\n\n\t\t<!-- Version file size as subline -->\n\t\t<template #subname>\n\t\t\t<div class=\"version__info version__info__subline\">\n\t\t\t\t<NcDateTime\n\t\t\t\t\tclass=\"version__info__date\"\n\t\t\t\t\trelative-time=\"short\"\n\t\t\t\t\t:timestamp=\"version.mtime\" />\n\t\t\t\t<!-- Separate dot to improve alignment -->\n\t\t\t\t<span>•</span>\n\t\t\t\t<span>{{ humanReadableSize }}</span>\n\t\t\t</div>\n\t\t</template>\n\n\t\t<!-- Actions -->\n\t\t<template #actions>\n\t\t\t<NcActionButton\n\t\t\t\tv-if=\"enableLabeling && hasUpdatePermissions\"\n\t\t\t\tdata-cy-files-versions-version-action=\"label\"\n\t\t\t\t:close-after-click=\"true\"\n\t\t\t\t@click=\"labelUpdate\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<Pencil :size=\"22\" />\n\t\t\t\t</template>\n\t\t\t\t{{ version.label === '' ? t('files_versions', 'Name this version') : t('files_versions', 'Edit version name') }}\n\t\t\t</NcActionButton>\n\t\t\t<NcActionButton\n\t\t\t\tv-if=\"!isCurrent && canView && canCompare\"\n\t\t\t\tdata-cy-files-versions-version-action=\"compare\"\n\t\t\t\t:close-after-click=\"true\"\n\t\t\t\t@click=\"compareVersion\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<FileCompare :size=\"22\" />\n\t\t\t\t</template>\n\t\t\t\t{{ t('files_versions', 'Compare to current version') }}\n\t\t\t</NcActionButton>\n\t\t\t<NcActionButton\n\t\t\t\tv-if=\"!isCurrent && hasUpdatePermissions\"\n\t\t\t\tdata-cy-files-versions-version-action=\"restore\"\n\t\t\t\t:close-after-click=\"true\"\n\t\t\t\t@click=\"restoreVersion\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<BackupRestore :size=\"22\" />\n\t\t\t\t</template>\n\t\t\t\t{{ t('files_versions', 'Restore version') }}\n\t\t\t</NcActionButton>\n\t\t\t<NcActionLink\n\t\t\t\tv-if=\"isDownloadable\"\n\t\t\t\tdata-cy-files-versions-version-action=\"download\"\n\t\t\t\t:href=\"downloadURL\"\n\t\t\t\t:close-after-click=\"true\"\n\t\t\t\t:download=\"downloadURL\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<Download :size=\"22\" />\n\t\t\t\t</template>\n\t\t\t\t{{ t('files_versions', 'Download version') }}\n\t\t\t</NcActionLink>\n\t\t\t<NcActionButton\n\t\t\t\tv-if=\"!isCurrent && enableDeletion && hasDeletePermissions\"\n\t\t\t\tdata-cy-files-versions-version-action=\"delete\"\n\t\t\t\t:close-after-click=\"true\"\n\t\t\t\t@click=\"deleteVersion\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<Delete :size=\"22\" />\n\t\t\t\t</template>\n\t\t\t\t{{ t('files_versions', 'Delete version') }}\n\t\t\t</NcActionButton>\n\t\t</template>\n\t</NcListItem>\n</template>\n\n<script lang=\"ts\" setup>\nimport type { PropType } from 'vue'\nimport type { LegacyFileInfo } from '../../../files/src/services/FileInfo.ts'\nimport type { Version } from '../utils/versions.ts'\n\nimport { getCurrentUser } from '@nextcloud/auth'\nimport { formatFileSize, Permission } from '@nextcloud/files'\nimport { loadState } from '@nextcloud/initial-state'\nimport { t } from '@nextcloud/l10n'\nimport moment from '@nextcloud/moment'\nimport { joinPaths } from '@nextcloud/paths'\nimport { getRootUrl } from '@nextcloud/router'\nimport { computed, nextTick, ref } from 'vue'\nimport NcActionButton from '@nextcloud/vue/components/NcActionButton'\nimport NcActionLink from '@nextcloud/vue/components/NcActionLink'\nimport NcAvatar from '@nextcloud/vue/components/NcAvatar'\nimport NcDateTime from '@nextcloud/vue/components/NcDateTime'\nimport NcListItem from '@nextcloud/vue/components/NcListItem'\nimport BackupRestore from 'vue-material-design-icons/BackupRestore.vue'\nimport FileCompare from 'vue-material-design-icons/FileCompare.vue'\nimport ImageOffOutline from 'vue-material-design-icons/ImageOffOutline.vue'\nimport Pencil from 'vue-material-design-icons/PencilOutline.vue'\nimport Delete from 'vue-material-design-icons/TrashCanOutline.vue'\nimport Download from 'vue-material-design-icons/TrayArrowDown.vue'\n\nconst props = defineProps({\n\tversion: {\n\t\ttype: Object as PropType<Version>,\n\t\trequired: true,\n\t},\n\n\tfileInfo: {\n\t\ttype: Object as PropType<LegacyFileInfo>,\n\t\trequired: true,\n\t},\n\n\tisCurrent: {\n\t\ttype: Boolean,\n\t\tdefault: false,\n\t},\n\n\tisFirstVersion: {\n\t\ttype: Boolean,\n\t\tdefault: false,\n\t},\n\n\tloadPreview: {\n\t\ttype: Boolean,\n\t\tdefault: false,\n\t},\n\n\tcanView: {\n\t\ttype: Boolean,\n\t\tdefault: false,\n\t},\n\n\tcanCompare: {\n\t\ttype: Boolean,\n\t\tdefault: false,\n\t},\n})\n\nconst emit = defineEmits(['click', 'compare', 'restore', 'delete', 'label-update-request'])\n\nconst hasPermission = (permissions: number, permission: number): boolean => (permissions & permission) !== 0\n\nconst previewLoaded = ref(false)\nconst previewErrored = ref(false)\nconst capabilities = ref(loadState('core', 'capabilities', { files: { version_labeling: false, version_deletion: false } }))\n\nconst humanReadableSize = computed(() => {\n\treturn formatFileSize(props.version.size)\n})\n\nconst versionLabel = computed(() => {\n\tconst label = props.version.label ?? ''\n\n\tif (props.isCurrent) {\n\t\tif (label === '') {\n\t\t\treturn t('files_versions', 'Current version')\n\t\t} else {\n\t\t\treturn `${label} (${t('files_versions', 'Current version')})`\n\t\t}\n\t}\n\n\tif (props.isFirstVersion && label === '') {\n\t\treturn t('files_versions', 'Initial version')\n\t}\n\n\treturn label\n})\n\nconst versionAuthor = computed(() => {\n\tif (!props.version.author || !props.version.authorName) {\n\t\treturn ''\n\t}\n\n\tif (props.version.author === getCurrentUser()?.uid) {\n\t\treturn t('files_versions', 'You')\n\t}\n\n\treturn props.version.authorName ?? props.version.author\n})\n\nconst versionHumanExplicitDate = computed(() => {\n\treturn moment(props.version.mtime).format('LLLL')\n})\n\nconst downloadURL = computed(() => {\n\tif (props.isCurrent) {\n\t\treturn getRootUrl() + joinPaths('/remote.php/webdav', props.fileInfo.path, props.fileInfo.name)\n\t} else {\n\t\treturn getRootUrl() + props.version.url\n\t}\n})\n\nconst enableLabeling = computed(() => {\n\treturn capabilities.value.files.version_labeling === true\n})\n\nconst enableDeletion = computed(() => {\n\treturn capabilities.value.files.version_deletion === true\n})\n\nconst hasDeletePermissions = computed(() => {\n\treturn hasPermission(props.fileInfo.permissions, Permission.DELETE)\n})\n\nconst hasUpdatePermissions = computed(() => {\n\treturn hasPermission(props.fileInfo.permissions, Permission.UPDATE)\n})\n\nconst isDownloadable = computed(() => {\n\tif ((props.fileInfo.permissions & Permission.READ) === 0) {\n\t\treturn false\n\t}\n\n\t// If the mount type is a share, ensure it got download permissions.\n\tif (props.fileInfo.mountType === 'shared') {\n\t\tconst downloadAttribute = props.fileInfo.shareAttributes\n\t\t\t.find((attribute) => attribute.scope === 'permissions' && attribute.key === 'download') || {}\n\t\t// If the download attribute is set to false, the file is not downloadable\n\t\tif (downloadAttribute?.value === false) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n})\n\n/**\n *\n */\nfunction labelUpdate() {\n\temit('label-update-request')\n}\n\n/**\n *\n */\nfunction restoreVersion() {\n\temit('restore', props.version)\n}\n\n/**\n *\n */\nasync function deleteVersion() {\n\t// Let @nc-vue properly remove the popover before we delete the version.\n\t// This prevents @nc-vue from throwing a error.\n\tawait nextTick()\n\tawait nextTick()\n\temit('delete', props.version)\n}\n\n/**\n *\n */\nfunction click() {\n\tif (!props.canView) {\n\t\twindow.location.href = downloadURL.value\n\t\treturn\n\t}\n\temit('click', { version: props.version })\n}\n\n/**\n *\n */\nfunction compareVersion() {\n\tif (!props.canView) {\n\t\tthrow new Error('Cannot compare version of this file')\n\t}\n\temit('compare', { version: props.version })\n}\n</script>\n\n<style scoped lang=\"scss\">\n.version {\n\tdisplay: flex;\n\tflex-direction: row;\n\n\t&__info {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\talign-items: center;\n\t\tgap: 0.5rem;\n\t\tcolor: var(--color-main-text);\n\t\tfont-weight: 500;\n\t\toverflow: hidden;\n\n\t\t&__label {\n\t\t\tfont-weight: 700;\n\t\t\t// Fix overflow on narrow screens\n\t\t\toverflow: hidden;\n\t\t\ttext-overflow: ellipsis;\n\t\t\tmin-width: 110px;\n\t\t}\n\n\t\t&__author_name {\n\t\t\toverflow: hidden;\n\t\t\ttext-overflow: ellipsis;\n\t\t}\n\n\t\t&__date {\n\t\t\t// Fix overflow on narrow screens\n\t\t\toverflow: hidden;\n\t\t\ttext-overflow: ellipsis;\n\t\t}\n\n\t\t&__subline {\n\t\t\tcolor: var(--color-text-maxcontrast)\n\t\t}\n\t}\n\n\t&__image {\n\t\twidth: 3rem;\n\t\theight: 3rem;\n\t\tborder: 1px solid var(--color-border);\n\t\tborder-radius: var(--border-radius-large);\n\n\t\t// Useful to display no preview icon.\n\t\tdisplay: flex;\n\t\tjustify-content: center;\n\t\tcolor: var(--color-main-text);\n\t}\n}\n</style>\n","<!--\n - SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n-->\n<template>\n\t<NcDialog\n\t\t:buttons=\"dialogButtons\"\n\t\tcontent-classes=\"version-label-modal\"\n\t\tis-form\n\t\t:open=\"open\"\n\t\tsize=\"normal\"\n\t\t:name=\"t('files_versions', 'Name this version')\"\n\t\t@update:open=\"$emit('update:open', $event)\"\n\t\t@submit=\"setVersionLabel(internalLabel)\">\n\t\t<NcTextField\n\t\t\tref=\"labelInput\"\n\t\t\tv-model=\"internalLabel\"\n\t\t\tclass=\"version-label-modal__input\"\n\t\t\t:label=\"t('files_versions', 'Version name')\"\n\t\t\t:placeholder=\"t('files_versions', 'Version name')\" />\n\n\t\t<p class=\"version-label-modal__info\">\n\t\t\t{{ t('files_versions', 'Named versions are persisted, and excluded from automatic cleanups when your storage quota is full.') }}\n\t\t</p>\n\t</NcDialog>\n</template>\n\n<script lang=\"ts\" setup>\nimport svgCheck from '@mdi/svg/svg/check.svg?raw'\nimport { t } from '@nextcloud/l10n'\nimport { computed, nextTick, ref, useTemplateRef, watchEffect } from 'vue'\nimport NcDialog from '@nextcloud/vue/components/NcDialog'\nimport NcTextField from '@nextcloud/vue/components/NcTextField'\n\nconst props = defineProps({\n\topen: {\n\t\ttype: Boolean,\n\t\tdefault: false,\n\t},\n\n\tlabel: {\n\t\ttype: String,\n\t\tdefault: '',\n\t},\n})\n\nconst emit = defineEmits(['update:open', 'update:label'])\n\nconst labelInput = useTemplateRef('labelInput')\n\nconst internalLabel = ref('')\n\nconst dialogButtons = computed(() => {\n\tconst buttons: unknown[] = []\n\tif (props.label.trim() === '') {\n\t\t// If there is no label just offer a cancel action that just closes the dialog\n\t\tbuttons.push({\n\t\t\tlabel: t('files_versions', 'Cancel'),\n\t\t})\n\t} else {\n\t\t// If there is already a label set, offer to remove the version label\n\t\tbuttons.push({\n\t\t\tlabel: t('files_versions', 'Remove version name'),\n\t\t\ttype: 'reset',\n\t\t\tvariant: 'error',\n\t\t\tcallback: () => { setVersionLabel('') },\n\t\t})\n\t}\n\treturn [\n\t\t...buttons,\n\t\t{\n\t\t\tlabel: t('files_versions', 'Save version name'),\n\t\t\ticon: svgCheck,\n\t\t\ttype: 'submit',\n\t\t\tvariant: 'primary',\n\t\t},\n\t]\n})\n\nwatchEffect(() => {\n\tinternalLabel.value = props.label ?? ''\n})\n\nwatchEffect(() => {\n\tif (props.open) {\n\t\tnextTick(() => labelInput.value?.focus())\n\t}\n\tinternalLabel.value = props.label\n})\n\n/**\n *\n * @param label - The new label\n */\nfunction setVersionLabel(label: string) {\n\temit('update:label', label)\n}\n</script>\n\n<style scoped lang=\"scss\">\n.version-label-modal {\n\t&__info {\n\t\tcolor: var(--color-text-maxcontrast);\n\t\tmargin-block: calc(3 * var(--default-grid-baseline));\n\t}\n\n\t&__input {\n\t\tmargin-block-start: calc(2 * var(--default-grid-baseline));\n\t}\n}\n</style>\n","/**\n * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport { getLoggerBuilder } from '@nextcloud/logger'\n\nexport default getLoggerBuilder()\n\t.setApp('files_version')\n\t.detectUser()\n\t.build()\n","<!--\n - SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n-->\n<template>\n\t<div v-if=\"!useWindow && containerElement === null\" ref=\"container\" class=\"vs-container\">\n\t\t<div\n\t\t\tref=\"rowsContainer\"\n\t\t\tclass=\"vs-rows-container\"\n\t\t\t:style=\"rowsContainerStyle\">\n\t\t\t<slot :visible-sections=\"visibleSections\" />\n\t\t\t<slot name=\"loader\" />\n\t\t</div>\n\t</div>\n\t<div\n\t\tv-else\n\t\tref=\"rowsContainer\"\n\t\tclass=\"vs-rows-container\"\n\t\t:style=\"rowsContainerStyle\">\n\t\t<slot :visible-sections=\"visibleSections\" />\n\t\t<slot name=\"loader\" />\n\t</div>\n</template>\n\n<script lang=\"ts\">\nimport {\n\ttype PropType,\n\n\tdefineComponent,\n} from 'vue'\nimport logger from '../utils/logger.ts'\n\nexport interface RowItem {\n\tid: string // Unique id for the item.\n\tkey?: string // Unique key for the item.\n}\n\nexport interface Row {\n\tkey: string // Unique key for the row.\n\theight: number // The height of the row.\n\tsectionKey: string // Unique key for the row.\n\titems: RowItem[] // List of items in the row.\n}\n\ninterface VisibleRow extends Row {\n\tdistance: number // The distance from the visible viewport\n}\n\ninterface Section {\n\tkey: string // Unique key for the section.\n\trows: Row[] // The height of the row.\n\theight: number // Height of the section, excluding the header.\n}\n\ninterface VisibleSection extends Section {\n\trows: VisibleRow[] // The height of the row.\n}\n\nexport default defineComponent({\n\tname: 'VirtualScrolling',\n\n\tprops: {\n\t\tsections: {\n\t\t\ttype: Array as PropType<Section[]>,\n\t\t\trequired: true,\n\t\t},\n\n\t\tcontainerElement: {\n\t\t\ttype: HTMLElement,\n\t\t\tdefault: null,\n\t\t},\n\n\t\tuseWindow: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\theaderHeight: {\n\t\t\ttype: Number,\n\t\t\tdefault: 75,\n\t\t},\n\n\t\trenderDistance: {\n\t\t\ttype: Number,\n\t\t\tdefault: 0.5,\n\t\t},\n\n\t\tbottomBufferRatio: {\n\t\t\ttype: Number,\n\t\t\tdefault: 2,\n\t\t},\n\n\t\tscrollToKey: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t},\n\n\temits: ['need-content'],\n\n\tdata() {\n\t\treturn {\n\t\t\tscrollPosition: 0,\n\t\t\tcontainerHeight: 0,\n\t\t\trowsContainerHeight: 0,\n\t\t\tresizeObserver: null as ResizeObserver | null,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\tvisibleSections(): VisibleSection[] {\n\t\t\tlogger.debug('[VirtualScrolling] Computing visible section', { sections: this.sections })\n\n\t\t\t// Optimization: get those computed properties once to not go through vue's internal every time we need them.\n\t\t\tconst containerHeight = this.containerHeight\n\t\t\tconst containerTop = this.scrollPosition\n\t\t\tconst containerBottom = containerTop + containerHeight\n\n\t\t\tlet currentRowTop = 0\n\t\t\tlet currentRowBottom = 0\n\n\t\t\t// Compute whether a row should be included in the DOM (shouldRender)\n\t\t\t// And how visible the row is.\n\t\t\tconst visibleSections = this.sections\n\t\t\t\t.map((section) => {\n\t\t\t\t\tcurrentRowBottom += this.headerHeight\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...section,\n\t\t\t\t\t\trows: section.rows.reduce((visibleRows, row) => {\n\t\t\t\t\t\t\tcurrentRowTop = currentRowBottom\n\t\t\t\t\t\t\tcurrentRowBottom += row.height\n\n\t\t\t\t\t\t\tlet distance = 0\n\n\t\t\t\t\t\t\tif (currentRowBottom < containerTop) {\n\t\t\t\t\t\t\t\tdistance = (containerTop - currentRowBottom) / containerHeight\n\t\t\t\t\t\t\t} else if (currentRowTop > containerBottom) {\n\t\t\t\t\t\t\t\tdistance = (currentRowTop - containerBottom) / containerHeight\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (distance > this.renderDistance) {\n\t\t\t\t\t\t\t\treturn visibleRows\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\t\t...visibleRows,\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t...row,\n\t\t\t\t\t\t\t\t\tdistance,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}, [] as VisibleRow[]),\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.filter((section) => section.rows.length > 0)\n\n\t\t\t// To allow vue to recycle the DOM elements instead of adding and deleting new ones,\n\t\t\t// we assign a random key to each items. When a item removed, we recycle its key for new items,\n\t\t\t// so vue can replace the content of removed DOM elements with the content of new items, but keep the other DOM elements untouched.\n\t\t\tconst visibleItems = visibleSections\n\t\t\t\t.flatMap(({ rows }) => rows)\n\t\t\t\t.flatMap(({ items }) => items)\n\n\t\t\tconst rowIdToKeyMap = this._rowIdToKeyMap as { [key: string]: string }\n\n\t\t\tvisibleItems.forEach((item) => (item.key = rowIdToKeyMap[item.id]))\n\n\t\t\tconst usedTokens = visibleItems\n\t\t\t\t.map(({ key }) => key)\n\t\t\t\t.filter((key) => key !== undefined)\n\n\t\t\tconst unusedTokens = Object.values(rowIdToKeyMap).filter((key) => !usedTokens.includes(key))\n\n\t\t\tvisibleItems\n\t\t\t\t.filter(({ key }) => key === undefined)\n\t\t\t\t.forEach((item) => (item.key = unusedTokens.pop() ?? Math.random().toString(36).substr(2)))\n\n\t\t\t// this._rowIdToKeyMap is created in the beforeCreate hook, so value changes are not tracked.\n\t\t\t// Therefore, we wont trigger the computation of visibleSections again if we alter the value of this._rowIdToKeyMap.\n\t\t\t// eslint-disable-next-line vue/no-side-effects-in-computed-properties\n\t\t\tthis._rowIdToKeyMap = visibleItems.reduce((finalMapping, { id, key }) => ({ ...finalMapping, [`${id}`]: key }), {})\n\n\t\t\treturn visibleSections\n\t\t},\n\n\t\t/**\n\t\t * Total height of all the rows + some room for the loader.\n\t\t */\n\t\ttotalHeight(): number {\n\t\t\tconst loaderHeight = 0\n\n\t\t\treturn this.sections\n\t\t\t\t.map((section) => this.headerHeight + section.height)\n\t\t\t\t.reduce((totalHeight, sectionHeight) => totalHeight + sectionHeight, 0) + loaderHeight\n\t\t},\n\n\t\tpaddingTop(): number {\n\t\t\tif (this.visibleSections.length === 0) {\n\t\t\t\treturn 0\n\t\t\t}\n\n\t\t\tlet paddingTop = 0\n\n\t\t\tfor (const section of this.sections) {\n\t\t\t\tif (section.key !== this.visibleSections[0].rows[0].sectionKey) {\n\t\t\t\t\tpaddingTop += this.headerHeight + section.height\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tfor (const row of section.rows) {\n\t\t\t\t\tif (row.key === this.visibleSections[0].rows[0].key) {\n\t\t\t\t\t\treturn paddingTop\n\t\t\t\t\t}\n\n\t\t\t\t\tpaddingTop += row.height\n\t\t\t\t}\n\n\t\t\t\tpaddingTop += this.headerHeight\n\t\t\t}\n\n\t\t\treturn paddingTop\n\t\t},\n\n\t\t/**\n\t\t * padding-top is used to replace not included item in the container.\n\t\t */\n\t\trowsContainerStyle(): { height: string, paddingTop: string } {\n\t\t\treturn {\n\t\t\t\theight: `${this.totalHeight}px`,\n\t\t\t\tpaddingTop: `${this.paddingTop}px`,\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Whether the user is near the bottom.\n\t\t * If true, then the need-content event will be emitted.\n\t\t */\n\t\tisNearBottom(): boolean {\n\t\t\tconst buffer = this.containerHeight * this.bottomBufferRatio\n\t\t\treturn this.scrollPosition + this.containerHeight >= this.totalHeight - buffer\n\t\t},\n\n\t\tcontainer() {\n\t\t\tlogger.debug('[VirtualScrolling] Computing container')\n\t\t\tif (this.containerElement !== null) {\n\t\t\t\treturn this.containerElement\n\t\t\t} else if (this.useWindow) {\n\t\t\t\treturn window\n\t\t\t} else {\n\t\t\t\treturn this.$refs.container as Element\n\t\t\t}\n\t\t},\n\t},\n\n\twatch: {\n\t\tisNearBottom(value) {\n\t\t\tlogger.debug('[VirtualScrolling] isNearBottom changed', { value })\n\t\t\tif (value) {\n\t\t\t\tthis.$emit('need-content')\n\t\t\t}\n\t\t},\n\n\t\tvisibleSections() {\n\t\t\t// Re-emit need-content when rows is updated and isNearBottom is still true.\n\t\t\t// If the height of added rows is under `bottomBufferRatio`, `isNearBottom` will still be true so we need more content.\n\t\t\tif (this.isNearBottom) {\n\t\t\t\tthis.$emit('need-content')\n\t\t\t}\n\t\t},\n\n\t\tscrollToKey(key) {\n\t\t\tlet currentRowTopDistanceFromTop = 0\n\n\t\t\tfor (const section of this.sections) {\n\t\t\t\tif (section.key !== key) {\n\t\t\t\t\tcurrentRowTopDistanceFromTop += this.headerHeight + section.height\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tlogger.debug('[VirtualScrolling] Scrolling to', { currentRowTopDistanceFromTop })\n\t\t\tthis.container.scrollTo({ top: currentRowTopDistanceFromTop, behavior: 'smooth' })\n\t\t},\n\t},\n\n\tbeforeCreate() {\n\t\tthis._rowIdToKeyMap = {}\n\t},\n\n\tmounted() {\n\t\tthis.resizeObserver = new ResizeObserver((entries) => {\n\t\t\tfor (const entry of entries) {\n\t\t\t\tconst cr = entry.contentRect\n\t\t\t\tif (entry.target === this.container) {\n\t\t\t\t\tthis.containerHeight = cr.height\n\t\t\t\t}\n\t\t\t\tif (entry.target.classList.contains('vs-rows-container')) {\n\t\t\t\t\tthis.rowsContainerHeight = cr.height\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\tif (this.useWindow) {\n\t\t\twindow.addEventListener('resize', this.updateContainerSize, { passive: true })\n\t\t\tthis.containerHeight = window.innerHeight\n\t\t} else {\n\t\t\tthis.resizeObserver.observe(this.container as HTMLElement | Element)\n\t\t}\n\n\t\tthis.resizeObserver.observe(this.$refs.rowsContainer as Element)\n\t\tthis.container.addEventListener('scroll', this.updateScrollPosition, { passive: true })\n\t},\n\n\tbeforeUnmount() {\n\t\tif (this.useWindow) {\n\t\t\twindow.removeEventListener('resize', this.updateContainerSize)\n\t\t}\n\n\t\tthis.resizeObserver?.disconnect()\n\t\tthis.container.removeEventListener('scroll', this.updateScrollPosition)\n\t},\n\n\tmethods: {\n\t\tupdateScrollPosition() {\n\t\t\tthis._onScrollHandle ??= requestAnimationFrame(() => {\n\t\t\t\tthis._onScrollHandle = null\n\t\t\t\tif (this.useWindow) {\n\t\t\t\t\tthis.scrollPosition = (this.container as Window).scrollY\n\t\t\t\t} else {\n\t\t\t\t\tthis.scrollPosition = (this.container as HTMLElement | Element).scrollTop\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\n\t\tupdateContainerSize() {\n\t\t\tthis.containerHeight = window.innerHeight\n\t\t},\n\t},\n})\n</script>\n\n<style scoped lang=\"scss\">\n.vs-container {\n\toverflow-y: scroll;\n\theight: 100%;\n}\n\n.vs-rows-container {\n\tbox-sizing: border-box;\n\twill-change: scroll-position, padding;\n\tcontain: layout paint style;\n}\n</style>\n","/**\n * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport { getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'\nimport { generateRemoteUrl } from '@nextcloud/router'\nimport { createClient } from 'webdav'\n\n// init webdav client\nconst rootPath = 'dav'\nconst remote = generateRemoteUrl(rootPath)\nconst client = createClient(remote)\n\n/**\n * set CSRF token header\n *\n * @param token - CSRF token\n */\nfunction setHeaders(token) {\n\tclient.setHeaders({\n\t\t// Add this so the server knows it is an request from the browser\n\t\t'X-Requested-With': 'XMLHttpRequest',\n\t\t// Inject user auth\n\t\trequesttoken: token ?? '',\n\t})\n}\n\n// refresh headers when request token changes\nonRequestTokenUpdate(setHeaders)\nsetHeaders(getRequestToken())\n\nexport default client\n","/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nexport default `<?xml version=\"1.0\"?>\n<d:propfind xmlns:d=\"DAV:\"\n\txmlns:oc=\"http://owncloud.org/ns\"\n\txmlns:nc=\"http://nextcloud.org/ns\"\n\txmlns:ocs=\"http://open-collaboration-services.org/ns\">\n\t<d:prop>\n\t\t<d:getcontentlength />\n\t\t<d:getcontenttype />\n\t\t<d:getlastmodified />\n\t\t<d:getetag />\n\t\t<nc:version-label />\n\t\t<nc:version-author />\n\t\t<nc:has-preview />\n\t</d:prop>\n</d:propfind>`\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable jsdoc/require-param */\n/* eslint-disable jsdoc/require-jsdoc */\n/**\n * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport type { FileStat, ResponseDataDetailed } from 'webdav'\n\nimport { getCurrentUser } from '@nextcloud/auth'\nimport axios from '@nextcloud/axios'\nimport moment from '@nextcloud/moment'\nimport { encodePath, joinPaths } from '@nextcloud/paths'\nimport { generateRemoteUrl, generateUrl } from '@nextcloud/router'\nimport client from '../utils/davClient.ts'\nimport davRequest from '../utils/davRequest.ts'\nimport logger from '../utils/logger.ts'\n\nexport interface Version {\n\tfileId: string // The id of the file associated to the version.\n\tlabel: string // 'Current version' or ''\n\tauthor: string | null // UID for the author of the version\n\tauthorName: string | null // Display name of the author\n\tfilename: string // File name relative to the version DAV endpoint\n\tbasename: string // A base name generated from the mtime\n\tmime: string // Empty for the current version, else the actual mime type of the version\n\tetag: string // Empty for the current version, else the actual mime type of the version\n\tsize: string // Human readable size\n\ttype: string // 'file'\n\tmtime: number // Version creation date as a timestamp\n\tpermissions: string // Only readable: 'R'\n\tpreviewUrl: string // Preview URL of the version\n\turl: string // Download URL of the version\n\tsource: string // The WebDAV endpoint of the resource\n\tfileVersion: string | null // The version id, null for the current version\n}\n\nexport async function fetchVersions(fileInfo: any): Promise<Version[]> {\n\tconst path = `/versions/${getCurrentUser()?.uid}/versions/${fileInfo.id}`\n\n\ttry {\n\t\tconst response = await client.getDirectoryContents(path, {\n\t\t\tdata: davRequest,\n\t\t\tdetails: true,\n\t\t}) as ResponseDataDetailed<FileStat[]>\n\n\t\tconst versions = response.data\n\t\t\t// Filter out root\n\t\t\t.filter(({ mime }) => mime !== '')\n\t\t\t.map((version) => formatVersion(version, fileInfo))\n\n\t\tconst authorIds = new Set(versions.map((version) => String(version.author)))\n\t\tconst authors = await axios.post(generateUrl('/displaynames'), { users: [...authorIds] })\n\n\t\tfor (const version of versions) {\n\t\t\tconst author = authors.data.users[version.author ?? '']\n\t\t\tif (author) {\n\t\t\t\tversion.authorName = author\n\t\t\t}\n\t\t}\n\n\t\treturn versions\n\t} catch (exception) {\n\t\tlogger.error('Could not fetch version', { exception })\n\t\tthrow exception\n\t}\n}\n\n/**\n * Restore the given version\n */\nexport async function restoreVersion(version: Version) {\n\ttry {\n\t\tlogger.debug('Restoring version', { url: version.url })\n\t\tawait client.moveFile(\n\t\t\t`/versions/${getCurrentUser()?.uid}/versions/${version.fileId}/${version.fileVersion}`,\n\t\t\t`/versions/${getCurrentUser()?.uid}/restore/target`,\n\t\t)\n\t} catch (exception) {\n\t\tlogger.error('Could not restore version', { exception })\n\t\tthrow exception\n\t}\n}\n\n/**\n * Format version\n */\nfunction formatVersion(version: any, fileInfo: any): Version {\n\tconst mtime = moment(version.lastmod).unix() * 1000\n\tlet previewUrl = ''\n\n\tif (mtime === fileInfo.mtime) { // Version is the current one\n\t\tpreviewUrl = generateUrl('/core/preview?fileId={fileId}&c={fileEtag}&x=250&y=250&forceIcon=0&a=0&forceIcon=1&mimeFallback=1', {\n\t\t\tfileId: fileInfo.id,\n\t\t\tfileEtag: fileInfo.etag,\n\t\t})\n\t} else {\n\t\tpreviewUrl = generateUrl('/apps/files_versions/preview?file={file}&version={fileVersion}&mimeFallback=1', {\n\t\t\tfile: joinPaths(fileInfo.path, fileInfo.name),\n\t\t\tfileVersion: version.basename,\n\t\t})\n\t}\n\n\treturn {\n\t\tfileId: fileInfo.id,\n\t\t// If version-label is defined make sure it is a string (prevent issue if the label is a number an PHP returns a number then)\n\t\tlabel: version.props['version-label'] ? String(version.props['version-label']) : '',\n\t\tauthor: version.props['version-author'] ? String(version.props['version-author']) : null,\n\t\tauthorName: null,\n\t\tfilename: version.filename,\n\t\tbasename: moment(mtime).format('LLL'),\n\t\tmime: version.mime,\n\t\tetag: `${version.props.getetag}`,\n\t\tsize: version.size,\n\t\ttype: version.type,\n\t\tmtime,\n\t\tpermissions: 'R',\n\t\tpreviewUrl,\n\t\turl: joinPaths('/remote.php/dav', version.filename),\n\t\tsource: generateRemoteUrl('dav') + encodePath(version.filename),\n\t\tfileVersion: version.basename,\n\t}\n}\n\nexport async function setVersionLabel(version: Version, newLabel: string) {\n\treturn await client.customRequest(\n\t\tversion.filename,\n\t\t{\n\t\t\tmethod: 'PROPPATCH',\n\t\t\tdata: `<?xml version=\"1.0\"?>\n\t\t\t\t\t<d:propertyupdate xmlns:d=\"DAV:\"\n\t\t\t\t\t\txmlns:oc=\"http://owncloud.org/ns\"\n\t\t\t\t\t\txmlns:nc=\"http://nextcloud.org/ns\"\n\t\t\t\t\t\txmlns:ocs=\"http://open-collaboration-services.org/ns\">\n\t\t\t\t\t<d:set>\n\t\t\t\t\t\t<d:prop>\n\t\t\t\t\t\t\t<nc:version-label>${newLabel}</nc:version-label>\n\t\t\t\t\t\t</d:prop>\n\t\t\t\t\t</d:set>\n\t\t\t\t\t</d:propertyupdate>`,\n\t\t},\n\t)\n}\n\nexport async function deleteVersion(version: Version) {\n\tawait client.deleteFile(version.filename)\n}\n","<!--\n - SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n-->\n<template>\n\t<div v-if=\"fileInfo !== null\" class=\"versions-tab__container\">\n\t\t<VirtualScrolling\n\t\t\t:sections=\"sections\"\n\t\t\t:header-height=\"0\">\n\t\t\t<template #default=\"{ visibleSections }\">\n\t\t\t\t<ul :aria-label=\"t('files_versions', 'File versions')\" data-files-versions-versions-list>\n\t\t\t\t\t<template v-if=\"visibleSections.length === 1\">\n\t\t\t\t\t\t<VersionEntry\n\t\t\t\t\t\t\tv-for=\"(row) of visibleSections[0].rows\"\n\t\t\t\t\t\t\t:key=\"row.items[0].version.mtime\"\n\t\t\t\t\t\t\t:can-view=\"canView\"\n\t\t\t\t\t\t\t:can-compare=\"canCompare\"\n\t\t\t\t\t\t\t:load-preview=\"isActive\"\n\t\t\t\t\t\t\t:version=\"row.items[0].version\"\n\t\t\t\t\t\t\t:file-info=\"fileInfo\"\n\t\t\t\t\t\t\t:is-current=\"row.items[0].version.mtime === fileInfo.mtime\"\n\t\t\t\t\t\t\t:is-first-version=\"row.items[0].version.mtime === initialVersionMtime\"\n\t\t\t\t\t\t\t@click=\"openVersion\"\n\t\t\t\t\t\t\t@compare=\"compareVersion\"\n\t\t\t\t\t\t\t@restore=\"handleRestore\"\n\t\t\t\t\t\t\t@label-update-request=\"handleLabelUpdateRequest(row.items[0].version)\"\n\t\t\t\t\t\t\t@delete=\"handleDelete\" />\n\t\t\t\t\t</template>\n\t\t\t\t</ul>\n\t\t\t</template>\n\t\t\t<template #loader>\n\t\t\t\t<NcLoadingIcon v-if=\"loading\" class=\"files-list-viewer__loader\" />\n\t\t\t</template>\n\t\t</VirtualScrolling>\n\t\t<VersionLabelDialog\n\t\t\tv-if=\"editedVersion\"\n\t\t\tv-model:open=\"showVersionLabelForm\"\n\t\t\t:label=\"editedVersion.label\"\n\t\t\t@update:label=\"handleLabelUpdate\" />\n\t</div>\n</template>\n\n<script lang=\"ts\" setup>\nimport type { LegacyFileInfo } from '../../../files/src/services/FileInfo.ts'\nimport type { Version } from '../utils/versions.ts'\n\nimport { getCurrentUser } from '@nextcloud/auth'\nimport { showError, showSuccess } from '@nextcloud/dialogs'\nimport { emit, subscribe, unsubscribe } from '@nextcloud/event-bus'\nimport { t } from '@nextcloud/l10n'\nimport { useIsMobile } from '@nextcloud/vue/composables/useIsMobile'\nimport path from 'path'\nimport { computed, onBeforeUnmount, onMounted, ref } from 'vue'\nimport NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'\nimport VersionEntry from '../components/VersionEntry.vue'\nimport VersionLabelDialog from '../components/VersionLabelDialog.vue'\nimport VirtualScrolling from '../components/VirtualScrolling.vue'\nimport logger from '../utils/logger.ts'\nimport { deleteVersion, fetchVersions, restoreVersion, setVersionLabel } from '../utils/versions.ts'\n\nconst isMobile = useIsMobile()\n\nconst fileInfo = ref<LegacyFileInfo | null>(null)\nconst isActive = ref<boolean>(false)\nconst versions = ref<Version[]>([])\nconst loading = ref(false)\nconst showVersionLabelForm = ref(false)\nconst editedVersion = ref<Version | null>(null)\n\n/**\n * Order versions by mtime.\n * Put the current version at the top.\n */\nconst orderedVersions = computed(() => {\n\treturn [...versions.value].sort((a, b) => {\n\t\tif (fileInfo.value === null) {\n\t\t\treturn 0\n\t\t}\n\n\t\tif (a.mtime === fileInfo.value.mtime) {\n\t\t\treturn -1\n\t\t} else if (b.mtime === fileInfo.value.mtime) {\n\t\t\treturn 1\n\t\t} else {\n\t\t\treturn b.mtime - a.mtime\n\t\t}\n\t})\n})\n\nconst sections = computed(() => {\n\tconst rows = orderedVersions.value.map((version) => ({ key: version.mtime.toString(), height: 68, sectionKey: 'versions', items: [{ id: version.mtime.toString(), version }] }))\n\treturn [{ key: 'versions', rows, height: 68 * orderedVersions.value.length }]\n})\n\n/**\n * Return the mtime of the first version to display \"Initial version\" label\n */\nconst initialVersionMtime = computed(() => {\n\treturn versions.value\n\t\t.map((version) => version.mtime)\n\t\t.reduce((a, b) => Math.min(a, b))\n})\n\nconst viewerFileInfo = computed(() => {\n\tif (fileInfo.value === null) {\n\t\treturn null\n\t}\n\n\t// We need to remap bitmask to dav permissions as the file info we have is converted through client.js\n\tlet davPermissions = ''\n\tif (fileInfo.value.permissions & 1) {\n\t\tdavPermissions += 'R'\n\t}\n\tif (fileInfo.value.permissions & 2) {\n\t\tdavPermissions += 'W'\n\t}\n\tif (fileInfo.value.permissions & 8) {\n\t\tdavPermissions += 'D'\n\t}\n\treturn {\n\t\t...fileInfo.value,\n\t\tmime: fileInfo.value.mimetype,\n\t\tbasename: fileInfo.value.name,\n\t\tfilename: fileInfo.value.path + '/' + fileInfo.value.name,\n\t\tpermissions: davPermissions,\n\t\tfileid: fileInfo.value.id,\n\t}\n})\n\nconst canView = computed(() => {\n\tif (fileInfo.value === null) {\n\t\treturn false\n\t}\n\n\treturn window.OCA.Viewer?.mimetypesCompare?.includes(fileInfo.value.mimetype)\n})\n\nconst canCompare = computed(() => {\n\treturn !isMobile.value\n})\n\nonMounted(() => {\n\tsubscribe('files_versions:restore:restored', fetchVersions)\n})\n\nonBeforeUnmount(() => {\n\tunsubscribe('files_versions:restore:restored', fetchVersions)\n})\n\ndefineExpose({\n\t/**\n\t * Update current fileInfo and fetch new data\n\t *\n\t * @param _fileInfo the current file FileInfo\n\t */\n\tasync update(_fileInfo: LegacyFileInfo) {\n\t\tfileInfo.value = _fileInfo\n\t\tresetState()\n\t\tinternalFetchVersions()\n\t},\n\n\t/**\n\t * @param _isActive whether the tab is active\n\t */\n\tasync setIsActive(_isActive: boolean) {\n\t\tisActive.value = _isActive\n\t},\n})\n\n/**\n * Get the existing versions infos\n */\nasync function internalFetchVersions() {\n\ttry {\n\t\tloading.value = true\n\t\tversions.value = await fetchVersions(fileInfo.value)\n\t} finally {\n\t\tloading.value = false\n\t}\n}\n\n/**\n * Handle restored event from Version.vue\n *\n * @param version The version to restore\n */\nasync function handleRestore(version: Version) {\n\t// Update local copy of fileInfo as rendering depends on it.\n\tconst oldFileInfo = fileInfo.value\n\tfileInfo.value = {\n\t\t...fileInfo.value,\n\t\tsize: version.size,\n\t\tmtime: version.mtime,\n\t}\n\n\tconst restoreStartedEventState = {\n\t\tpreventDefault: false,\n\t\tfileInfo: fileInfo.value,\n\t\tversion,\n\t}\n\temit('files_versions:restore:requested', restoreStartedEventState)\n\tif (restoreStartedEventState.preventDefault) {\n\t\treturn\n\t}\n\n\ttry {\n\t\tawait restoreVersion(version)\n\t\tif (version.label) {\n\t\t\tshowSuccess(t('files_versions', `${version.label} restored`))\n\t\t} else if (version.mtime === initialVersionMtime.value) {\n\t\t\tshowSuccess(t('files_versions', 'Initial version restored'))\n\t\t} else {\n\t\t\tshowSuccess(t('files_versions', 'Version restored'))\n\t\t}\n\t\temit('files_versions:restore:restored', version)\n\t} catch {\n\t\tfileInfo.value = oldFileInfo\n\t\tshowError(t('files_versions', 'Could not restore version'))\n\t\temit('files_versions:restore:failed', version)\n\t}\n}\n\n/**\n * Handle label-updated event from Version.vue\n *\n * @param version The version to update\n */\nfunction handleLabelUpdateRequest(version: Version) {\n\tshowVersionLabelForm.value = true\n\teditedVersion.value = version\n}\n\n/**\n * Handle label-updated event from Version.vue\n *\n * @param newLabel The new label\n */\nasync function handleLabelUpdate(newLabel: string) {\n\tif (editedVersion.value === null) {\n\t\tthrow new Error('editedVersion should be set at that point')\n\t}\n\n\tconst oldLabel = editedVersion.value.label\n\teditedVersion.value.label = newLabel\n\tshowVersionLabelForm.value = false\n\n\ttry {\n\t\tawait setVersionLabel(editedVersion.value, newLabel)\n\t\teditedVersion.value = null\n\t} catch (exception) {\n\t\teditedVersion.value!.label = oldLabel\n\t\tshowError(t('files_versions', 'Could not set version label'))\n\t\tlogger.error('Could not set version label', { exception })\n\t}\n}\n\n/**\n * Handle deleted event from Version.vue\n *\n * @param version The version to delete\n */\nasync function handleDelete(version: Version) {\n\tconst index = versions.value.indexOf(version)\n\tversions.value.splice(index, 1)\n\n\ttry {\n\t\tawait deleteVersion(version)\n\t} catch {\n\t\tversions.value.push(version)\n\t\tshowError(t('files_versions', 'Could not delete version'))\n\t}\n}\n\n/**\n * Reset the current view to its default state\n */\nfunction resetState() {\n\tversions.value = []\n}\n\n/**\n * @param payload - The event payload\n * @param payload.version - The version to open\n */\nfunction openVersion({ version }: { version: Version }) {\n\tif (fileInfo.value === null) {\n\t\treturn\n\t}\n\n\t// Open current file view instead of read only\n\tif (version.mtime === fileInfo.value.mtime) {\n\t\twindow.OCA.Viewer.open({ fileInfo: viewerFileInfo.value })\n\t\treturn\n\t}\n\n\twindow.OCA.Viewer.open({\n\t\tfileInfo: {\n\t\t\t...version,\n\t\t\t// Versions previews are too small for our use case, so we override previewUrl\n\t\t\t// to either point to the original file or original version.\n\t\t\tfilename: version.mtime === fileInfo.value.mtime ? path.join('files', getCurrentUser()?.uid ?? '', fileInfo.value.path, fileInfo.value.name) : version.filename,\n\t\t\tpreviewUrl: undefined,\n\t\t},\n\t\tenableSidebar: false,\n\t})\n}\n\n/**\n * @param payload - The event payload\n * @param payload.version - The version to compare\n */\nfunction compareVersion({ version }: { version: Version }) {\n\tconst _versions = versions.value.map((version) => ({ ...version, previewUrl: undefined }))\n\n\twindow.OCA.Viewer.compare(viewerFileInfo.value, _versions.find((v) => v.source === version.source))\n}\n</script>\n\n<style lang=\"scss\">\n.versions-tab__container {\n\theight: 100%;\n}\n</style>\n","/**\n * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport type { App, ComponentPublicInstance } from 'vue'\n\nimport BackupRestore from '@mdi/svg/svg/backup-restore.svg?raw'\nimport { t } from '@nextcloud/l10n'\nimport { createApp } from 'vue'\nimport FilesVersionsSidebarTab from './views/FilesVersionsSidebarTab.vue'\n\n// Init FilesVersions tab component\nlet filesVersionsTabApp: App<Element> | null = null\nlet filesVersionsTabInstance: ComponentPublicInstance<typeof FilesVersionsSidebarTab> | null = null\n\nwindow.addEventListener('DOMContentLoaded', function() {\n\tif (window.OCA.Files?.Sidebar === undefined) {\n\t\treturn\n\t}\n\n\twindow.OCA.Files.Sidebar.registerTab(new window.OCA.Files.Sidebar.Tab({\n\t\tid: 'files_versions',\n\t\tname: t('files_versions', 'Versions'),\n\t\ticonSvg: BackupRestore,\n\n\t\tasync mount(el, fileInfo) {\n\t\t\t// destroy previous instance if available\n\t\t\tif (filesVersionsTabApp) {\n\t\t\t\tfilesVersionsTabApp.unmount()\n\t\t\t}\n\t\t\tfilesVersionsTabApp = createApp(FilesVersionsSidebarTab)\n\t\t\tfilesVersionsTabInstance = filesVersionsTabApp.mount(el)\n\t\t\tfilesVersionsTabInstance.update(fileInfo)\n\t\t},\n\t\tupdate(fileInfo) {\n\t\t\tfilesVersionsTabInstance!.update(fileInfo)\n\t\t},\n\t\tsetIsActive(isActive) {\n\t\t\tfilesVersionsTabInstance?.setIsActive(isActive)\n\t\t},\n\t\tdestroy() {\n\t\t\tfilesVersionsTabApp?.unmount()\n\t\t\tfilesVersionsTabApp = null\n\t\t},\n\t\tenabled(fileInfo) {\n\t\t\treturn !(fileInfo?.isDirectory() ?? true)\n\t\t},\n\t}))\n})\n"],"names":["BackupRestore$1","_sfc_main","_hoisted_3","_createElementBlock","_mergeProps","_ctx","$props","_cache","$event","_createElementVNode","_openBlock","props","__props","emit","__emit","hasPermission","permissions","permission","previewLoaded","ref","previewErrored","capabilities","loadState","humanReadableSize","computed","formatFileSize","versionLabel","label","t","versionAuthor","getCurrentUser","versionHumanExplicitDate","moment","downloadURL","getRootUrl","joinPaths","enableLabeling","enableDeletion","hasDeletePermissions","Permission","hasUpdatePermissions","isDownloadable","attribute","labelUpdate","restoreVersion","deleteVersion","nextTick","click","compareVersion","_createBlock","_unref","NcListItem","_createVNode","ImageOffOutline","_hoisted_1","_hoisted_4","_hoisted_5","_hoisted_6","NcAvatar","_hoisted_8","_hoisted_9","NcDateTime","NcActionButton","Pencil","_createTextVNode","FileCompare","BackupRestore","NcActionLink","Download","Delete","labelInput","useTemplateRef","internalLabel","dialogButtons","buttons","setVersionLabel","svgCheck","watchEffect","NcDialog","$emit","NcTextField","_toDisplayString","logger","getLoggerBuilder","_sfc_main$1","defineComponent","containerHeight","containerTop","containerBottom","currentRowTop","currentRowBottom","visibleSections","section","visibleRows","row","distance","visibleItems","rows","items","rowIdToKeyMap","item","usedTokens","key","unusedTokens","finalMapping","id","totalHeight","sectionHeight","paddingTop","buffer","value","currentRowTopDistanceFromTop","entries","entry","cr","_normalizeStyle","_renderSlot","rootPath","remote","generateRemoteUrl","client","createClient","setHeaders","token","onRequestTokenUpdate","getRequestToken","davRequest","fetchVersions","fileInfo","path","versions","mime","version","formatVersion","authorIds","authors","axios","generateUrl","author","exception","mtime","previewUrl","encodePath","newLabel","isMobile","useIsMobile","isActive","loading","showVersionLabelForm","editedVersion","orderedVersions","a","b","sections","initialVersionMtime","viewerFileInfo","davPermissions","canView","canCompare","onMounted","subscribe","onBeforeUnmount","unsubscribe","__expose","_fileInfo","resetState","internalFetchVersions","_isActive","handleRestore","oldFileInfo","restoreStartedEventState","showSuccess","showError","handleLabelUpdateRequest","handleLabelUpdate","oldLabel","handleDelete","index","openVersion","_versions","v","VirtualScrolling","_withCtx","_Fragment","_renderList","VersionEntry","NcLoadingIcon","VersionLabelDialog","filesVersionsTabApp","filesVersionsTabInstance","el","createApp","FilesVersionsSidebarTab"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4]} |