aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorJohn Molakvoæ <skjnldsv@users.noreply.github.com>2023-12-20 17:42:11 +0100
committerGitHub <noreply@github.com>2023-12-20 17:42:11 +0100
commitaae99606e04f716fe9bebcac064a7dc8ef0f71e4 (patch)
treeadecd0376b1f80b6cac7f0a02be49cd22e7182d1 /apps
parent4f7ed475de1d71d3b0481b1681b8d08bb1920a6c (diff)
parentdc82c2798a072c9054c60a14136dd7e2ab78dad7 (diff)
downloadnextcloud-server-aae99606e04f716fe9bebcac064a7dc8ef0f71e4.tar.gz
nextcloud-server-aae99606e04f716fe9bebcac064a7dc8ef0f71e4.zip
Merge pull request #42366 from nextcloud/fix/dragdrop-join
Diffstat (limited to 'apps')
-rw-r--r--apps/files/src/components/DragAndDropNotice.vue79
-rw-r--r--apps/files/src/components/FilesListVirtual.vue4
-rw-r--r--apps/files/src/services/DropService.ts14
3 files changed, 82 insertions, 15 deletions
diff --git a/apps/files/src/components/DragAndDropNotice.vue b/apps/files/src/components/DragAndDropNotice.vue
index 66cddcaff97..df03713601d 100644
--- a/apps/files/src/components/DragAndDropNotice.vue
+++ b/apps/files/src/components/DragAndDropNotice.vue
@@ -25,23 +25,33 @@
class="files-list__drag-drop-notice"
@drop="onDrop">
<div class="files-list__drag-drop-notice-wrapper">
- <TrayArrowDownIcon :size="48" />
- <h3 class="files-list-drag-drop-notice__title">
- {{ t('files', 'Drag and drop files here to upload') }}
- </h3>
+ <template v-if="canUpload && !isQuotaExceeded">
+ <TrayArrowDownIcon :size="48" />
+ <h3 class="files-list-drag-drop-notice__title">
+ {{ t('files', 'Drag and drop files here to upload') }}
+ </h3>
+ </template>
+
+ <!-- Not permitted to drop files here -->
+ <template v-else>
+ <h3 class="files-list-drag-drop-notice__title">
+ {{ cantUploadLabel }}
+ </h3>
+ </template>
</div>
</div>
</template>
<script lang="ts">
-import { translate as t } from '@nextcloud/l10n'
import { defineComponent } from 'vue'
+import { Folder, Permission } from '@nextcloud/files'
+import { showError, showSuccess } from '@nextcloud/dialogs'
+import { translate as t } from '@nextcloud/l10n'
import TrayArrowDownIcon from 'vue-material-design-icons/TrayArrowDown.vue'
import logger from '../logger.js'
import { handleDrop } from '../services/DropService'
-import { showSuccess } from '@nextcloud/dialogs'
export default defineComponent({
name: 'DragAndDropNotice',
@@ -52,7 +62,7 @@ export default defineComponent({
props: {
currentFolder: {
- type: Object,
+ type: Folder,
required: true,
},
},
@@ -63,35 +73,86 @@ export default defineComponent({
}
},
+ computed: {
+ /**
+ * Check if the current folder has create permissions
+ */
+ canUpload() {
+ return this.currentFolder && (this.currentFolder.permissions & Permission.CREATE) !== 0
+ },
+ isQuotaExceeded() {
+ return this.currentFolder?.attributes?.['quota-available-bytes'] === 0
+ },
+
+ cantUploadLabel() {
+ if (this.isQuotaExceeded) {
+ return this.t('files', 'Your have used your space quota and cannot upload files anymore')
+ } else if (!this.canUpload) {
+ return this.t('files', 'You don’t have permission to upload or create files here')
+ }
+ return null
+ },
+ },
+
mounted() {
// Add events on parent to cover both the table and DragAndDrop notice
const mainContent = window.document.querySelector('main.app-content') as HTMLElement
mainContent.addEventListener('dragover', this.onDragOver)
mainContent.addEventListener('dragleave', this.onDragLeave)
+ mainContent.addEventListener('drop', this.onContentDrop)
},
beforeDestroy() {
const mainContent = window.document.querySelector('main.app-content') as HTMLElement
mainContent.removeEventListener('dragover', this.onDragOver)
mainContent.removeEventListener('dragleave', this.onDragLeave)
+ mainContent.removeEventListener('drop', this.onContentDrop)
},
methods: {
onDragOver(event: DragEvent) {
+ // Needed to keep the drag/drop events chain working
+ event.preventDefault()
+
const isForeignFile = event.dataTransfer?.types.includes('Files')
+
+ logger.debug('Drag over DragAndDropNotice', { isForeignFile, event })
if (isForeignFile) {
- // Only handle uploading
+ // Only handle uploading of outside files (not Nextcloud files)
this.dragover = true
}
},
- onDragLeave(/* event: DragEvent */) {
+ onDragLeave(event: DragEvent) {
+ // Counter bubbling, make sure we're ending the drag
+ // only when we're leaving the current element
+ // Avoid flickering
+ const currentTarget = event.currentTarget as HTMLElement
+ if (currentTarget?.contains(event.relatedTarget as HTMLElement)) {
+ return
+ }
+
+ if (this.dragover) {
+ this.dragover = false
+ }
+ },
+
+ onContentDrop(event: DragEvent) {
+ logger.debug('Drag and drop cancelled, dropped on empty space', { event })
+ event.preventDefault()
if (this.dragover) {
this.dragover = false
}
},
onDrop(event: DragEvent) {
+ logger.debug('Dropped on DragAndDropNotice', { event, error: this.cantUploadLabel })
+
+ if (!this.canUpload || this.isQuotaExceeded) {
+ showError(this.cantUploadLabel)
+ return
+ }
+
if (this.$el.querySelector('tbody')?.contains(event.target as Node)) {
return
}
diff --git a/apps/files/src/components/FilesListVirtual.vue b/apps/files/src/components/FilesListVirtual.vue
index e0f2c50b87f..88bb7e2076a 100644
--- a/apps/files/src/components/FilesListVirtual.vue
+++ b/apps/files/src/components/FilesListVirtual.vue
@@ -128,7 +128,6 @@ export default defineComponent({
FileEntryGrid,
headers: getFileListHeaders(),
scrollToIndex: 0,
- dndNoticeHeight: 0,
}
},
@@ -259,7 +258,10 @@ export default defineComponent({
onDragOver(event: DragEvent) {
// Detect if we're only dragging existing files or not
const isForeignFile = event.dataTransfer?.types.includes('Files')
+
if (isForeignFile) {
+ // Only handle uploading of existing Nextcloud files
+ // See DragAndDropNotice for handling of foreign files
return
}
diff --git a/apps/files/src/services/DropService.ts b/apps/files/src/services/DropService.ts
index 4b4f98a01d6..372b849bcc4 100644
--- a/apps/files/src/services/DropService.ts
+++ b/apps/files/src/services/DropService.ts
@@ -23,11 +23,13 @@
import type { Upload } from '@nextcloud/upload'
import type { FileStat, ResponseDataDetailed } from 'webdav'
-import { showError } from '@nextcloud/dialogs'
-import { emit } from '@nextcloud/event-bus'
import { davGetClient, davGetDefaultPropfind, davResultToNode, davRootPath } from '@nextcloud/files'
-import { translate as t } from '@nextcloud/l10n'
+import { emit } from '@nextcloud/event-bus'
import { getUploader } from '@nextcloud/upload'
+import { joinPaths } from '@nextcloud/paths'
+import { showError } from '@nextcloud/dialogs'
+import { translate as t } from '@nextcloud/l10n'
+
import logger from '../logger.js'
export const handleDrop = async (data: DataTransfer) => {
@@ -85,10 +87,12 @@ const handleRecursiveUpload = async (entry: FileSystemEntry, path: string = ''):
]
} else {
const directory = entry as FileSystemDirectoryEntry
- logger.debug('Handle directory recursivly', { name: directory.name })
// TODO: Implement this on `@nextcloud/upload`
- const absolutPath = `${davRootPath}${getUploader().destination.path}${path}${directory.name}`
+ const absolutPath = joinPaths(davRootPath, getUploader().destination.path, path, directory.name)
+
+ logger.debug('Handle directory recursively', { name: directory.name, absolutPath })
+
const davClient = davGetClient()
const dirExists = await davClient.exists(absolutPath)
if (!dirExists) {