Преглед изворни кода

Allow any single file to be uploaded (#17215)

GitOrigin-RevId: 9eecc9e044ec1a489b42ccf697806fecfbe5dfc8
Alf Eaton пре 2 година
родитељ
комит
bef2e4fbce

+ 9 - 5
services/web/frontend/js/features/file-tree/components/file-tree-create/modes/file-tree-upload-doc.tsx

@@ -96,7 +96,7 @@ export default function FileTreeUploadDoc() {
     const endpoint = buildEndpoint(projectId, parentFolderId)
 
     return (
-      new Uppy({
+      new Uppy<{ relativePath?: string; targetFolderId: string }>({
         // logger: Uppy.debugLogger,
         allowMultipleUploadBatches: false,
         restrictions: {
@@ -104,7 +104,12 @@ export default function FileTreeUploadDoc() {
           maxFileSize: maxFileSize || null,
         },
         onBeforeFileAdded(file) {
-          if (!isAcceptableFile(file)) {
+          if (
+            !isAcceptableFile(
+              file.name,
+              file.meta.relativePath as string | undefined
+            )
+          ) {
             return false
           }
         },
@@ -180,15 +185,14 @@ export default function FileTreeUploadDoc() {
           source: 'Local',
           isRemote: false,
           meta: {
-            relativePath: file.relativePath,
+            relativePath: (file as any).relativePath,
             targetFolderId: droppedFiles.targetFolderId,
           },
         })
         const uppyFile = uppy.getFile(fileId)
         uppy.setFileState(fileId, {
           xhrUpload: {
-            // @ts-ignore
-            ...uppyFile.xhrUpload,
+            ...(uppyFile as any).xhrUpload,
             endpoint: buildEndpoint(projectId, droppedFiles.targetFolderId),
           },
         })

+ 12 - 3
services/web/frontend/js/features/file-tree/contexts/file-tree-actionable.tsx

@@ -34,6 +34,15 @@ import {
 } from '../errors'
 import { Folder } from '../../../../../types/folder'
 
+type DroppedFile = File & {
+  relativePath?: string
+}
+
+type DroppedFiles = {
+  files: DroppedFile[]
+  targetFolderId: string
+}
+
 const FileTreeActionableContext = createContext<
   | {
       isDeleting: boolean
@@ -63,8 +72,8 @@ const FileTreeActionableContext = createContext<
       finishCreatingDoc: any
       finishCreatingLinkedFile: any
       cancel: () => void
-      droppedFiles: { files: any; targetFolderId: string } | null
-      setDroppedFiles: (files: any) => void
+      droppedFiles: { files: File[]; targetFolderId: string } | null
+      setDroppedFiles: (value: DroppedFiles | null) => void
       downloadPath?: string
     }
   | undefined
@@ -222,7 +231,7 @@ export const FileTreeActionableProvider: FC<{
   const { fileTreeData, dispatchRename, dispatchMove } = useFileTreeData()
   const { selectedEntityIds, isRootFolderSelected } = useFileTreeSelectable()
 
-  const [droppedFiles, setDroppedFiles] = useState(null)
+  const [droppedFiles, setDroppedFiles] = useState<DroppedFiles | null>(null)
 
   const startRenaming = useCallback(() => {
     dispatch({ type: ACTION_TYPES.START_RENAME })

+ 6 - 1
services/web/frontend/js/features/file-tree/contexts/file-tree-draggable.tsx

@@ -122,7 +122,12 @@ export function useDroppable(targetEntityId: string) {
 
       // native file(s) dragged in from outside
       getDroppedFiles(item as unknown as DataTransfer)
-        .then(files => files.filter(isAcceptableFile))
+        .then(files =>
+          files.filter(file =>
+            // note: getDroppedFiles normalises webkitRelativePath to relativePath
+            isAcceptableFile(file.name, (file as any).relativePath)
+          )
+        )
         .then(files => {
           setDroppedFiles({ files, targetFolderId: targetEntityId })
           startUploadingDocOrFile()

+ 14 - 2
services/web/frontend/js/features/file-tree/util/is-acceptable-file.ts

@@ -5,5 +5,17 @@ const fileIgnoreMatcher = new Minimatch(
   { nocase: true, dot: true }
 )
 
-export const isAcceptableFile = (file: { name: string }) =>
-  !fileIgnoreMatcher.match(file.name)
+export const isAcceptableFile = (name?: string, relativePath?: string) => {
+  if (!name) {
+    // the file must have a name, of course
+    return false
+  }
+
+  if (!relativePath) {
+    // uploading an individual file, so allow anything
+    return true
+  }
+
+  // uploading a file in a folder, so exclude unwanted file paths
+  return !fileIgnoreMatcher.match(relativePath + '/' + name)
+}