Upload files dropped onto the file tree (#8064)

GitOrigin-RevId: 97043661e344b72ff742326c9dc2809e46d0bb9c
This commit is contained in:
Alf Eaton
2022-07-21 09:32:34 +01:00
committed by Copybot
parent 9d55859419
commit 44b241b5ca
6 changed files with 93 additions and 14 deletions

18
package-lock.json generated
View File

@@ -34542,6 +34542,7 @@
"@uppy/core": "^1.15.0",
"@uppy/dashboard": "^1.11.0",
"@uppy/react": "^1.11.0",
"@uppy/utils": "^4.0.7",
"@uppy/xhr-upload": "^1.6.8",
"abort-controller": "^3.0.0",
"accepts": "^1.3.7",
@@ -34819,6 +34820,14 @@
"lodash": "^4.17.15"
}
},
"services/web/node_modules/@uppy/utils": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/@uppy/utils/-/utils-4.0.7.tgz",
"integrity": "sha512-nKViMT8XchKy+NWpb3DtVKuzZBmW7au26LrMq89EsvTwIOT6UR9+7bmz/+zr3+lc7UC7vMgNChIC6G+/Ya9wWQ==",
"dependencies": {
"lodash.throttle": "^4.1.1"
}
},
"services/web/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@@ -42084,6 +42093,7 @@
"@uppy/core": "^1.15.0",
"@uppy/dashboard": "^1.11.0",
"@uppy/react": "^1.11.0",
"@uppy/utils": "^4.0.7",
"@uppy/xhr-upload": "^1.6.8",
"abort-controller": "^3.0.0",
"accepts": "^1.3.7",
@@ -42330,6 +42340,14 @@
"lodash": "^4.17.15"
}
},
"@uppy/utils": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/@uppy/utils/-/utils-4.0.7.tgz",
"integrity": "sha512-nKViMT8XchKy+NWpb3DtVKuzZBmW7au26LrMq89EsvTwIOT6UR9+7bmz/+zr3+lc7UC7vMgNChIC6G+/Ya9wWQ==",
"requires": {
"lodash.throttle": "^4.1.1"
}
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",

View File

@@ -1,6 +1,6 @@
import { Trans } from 'react-i18next'
import { Alert, Button } from 'react-bootstrap'
import { useCallback, useState } from 'react'
import { useCallback, useEffect, useState } from 'react'
import PropTypes from 'prop-types'
import Uppy from '@uppy/core'
import XHRUpload from '@uppy/xhr-upload'
@@ -14,7 +14,8 @@ import { refreshProjectMetadata } from '../../../util/api'
import ErrorMessage from '../error-message'
export default function FileTreeUploadDoc() {
const { parentFolderId, cancel, isDuplicate } = useFileTreeActionable()
const { parentFolderId, cancel, isDuplicate, droppedFiles, setDroppedFiles } =
useFileTreeActionable()
const { _id: projectId } = useProjectContext(projectContextPropTypes)
const [error, setError] = useState()
@@ -28,16 +29,22 @@ export default function FileTreeUploadDoc() {
// calculate conflicts
const buildConflicts = files =>
Object.values(files).filter(file =>
isDuplicate(parentFolderId, file.meta.name)
isDuplicate(file.meta.targetFolderId ?? parentFolderId, file.meta.name)
)
const buildEndpoint = (projectId, targetFolderId) => {
let endpoint = `/project/${projectId}/upload`
if (targetFolderId) {
endpoint += `?folder_id=${targetFolderId}`
}
return endpoint
}
// initialise the Uppy object
const uppy = useUppy(() => {
let endpoint = `/project/${projectId}/upload`
if (parentFolderId) {
endpoint += `?folder_id=${parentFolderId}`
}
const endpoint = buildEndpoint(projectId, parentFolderId)
return (
new Uppy({
@@ -113,6 +120,37 @@ export default function FileTreeUploadDoc() {
)
})
useEffect(() => {
if (uppy && droppedFiles) {
uppy.setOptions({
autoProceed: false,
})
for (const file of droppedFiles.files) {
const fileId = uppy.addFile({
name: file.name,
type: file.type,
data: file,
source: 'Local',
isRemote: false,
meta: {
targetFolderId: droppedFiles.targetFolderId,
},
})
const uppyFile = uppy.getFile(fileId)
uppy.setFileState(fileId, {
xhrUpload: {
...uppyFile.xhrUpload,
endpoint: buildEndpoint(projectId, droppedFiles.targetFolderId),
},
})
}
}
return () => {
setDroppedFiles(null)
}
}, [uppy, droppedFiles, setDroppedFiles, projectId])
// handle forced overwriting of conflicting files
const handleOverwrite = useCallback(() => {
setOverwrite(true)

View File

@@ -20,7 +20,7 @@ function FileTreeDraggablePreviewLayer({ isOver }) {
? ref.current.getBoundingClientRect()
: null
if (!isDragging) {
if (!isDragging || !item.title) {
return null
}

View File

@@ -5,6 +5,7 @@ import {
useReducer,
useContext,
useEffect,
useState,
} from 'react'
import PropTypes from 'prop-types'
@@ -132,6 +133,8 @@ export function FileTreeActionableProvider({ children }) {
const { fileTreeData, dispatchRename, dispatchMove } = useFileTreeData()
const { selectedEntityIds } = useFileTreeSelectable()
const [droppedFiles, setDroppedFiles] = useState(null)
const startRenaming = useCallback(() => {
dispatch({ type: ACTION_TYPES.START_RENAME })
}, [])
@@ -363,6 +366,8 @@ export function FileTreeActionableProvider({ children }) {
finishCreatingDoc,
finishCreatingLinkedFile,
cancel,
droppedFiles,
setDroppedFiles,
}
return (

View File

@@ -1,9 +1,14 @@
import { useRef, useEffect, useState } from 'react'
import PropTypes from 'prop-types'
import { useTranslation } from 'react-i18next'
import getDroppedFiles from '@uppy/utils/lib/getDroppedFiles'
import { DndProvider, createDndContext, useDrag, useDrop } from 'react-dnd'
import { HTML5Backend, getEmptyImage } from 'react-dnd-html5-backend'
import {
HTML5Backend,
getEmptyImage,
NativeTypes,
} from 'react-dnd-html5-backend'
import {
findAllInTreeOrThrow,
@@ -119,20 +124,32 @@ const editorContextPropTypes = {
}
export function useDroppable(droppedEntityId) {
const { finishMoving } = useFileTreeActionable()
const { finishMoving, setDroppedFiles, startUploadingDocOrFile } =
useFileTreeActionable()
const [{ isOver }, dropRef] = useDrop({
accept: DRAGGABLE_TYPE,
accept: [DRAGGABLE_TYPE, NativeTypes.FILE],
canDrop: (item, monitor) => {
const isOver = monitor.isOver({ shallow: true })
if (!isOver) return false
if (item.forbiddenFolderIds.has(droppedEntityId)) return false
if (
item.type === DRAGGABLE_TYPE &&
item.forbiddenFolderIds.has(droppedEntityId)
)
return false
return true
},
drop: (item, monitor) => {
const didDropInChild = monitor.didDrop()
if (didDropInChild) return
finishMoving(droppedEntityId, item.draggedEntityIds)
if (item.type === DRAGGABLE_TYPE) {
finishMoving(droppedEntityId, item.draggedEntityIds)
} else {
getDroppedFiles(item).then(files => {
setDroppedFiles({ files, targetFolderId: droppedEntityId })
startUploadingDocOrFile()
})
}
},
collect: monitor => ({
isOver: monitor.canDrop(),

View File

@@ -76,6 +76,7 @@
"@uppy/core": "^1.15.0",
"@uppy/dashboard": "^1.11.0",
"@uppy/react": "^1.11.0",
"@uppy/utils": "^4.0.7",
"@uppy/xhr-upload": "^1.6.8",
"abort-controller": "^3.0.0",
"accepts": "^1.3.7",