Просмотр исходного кода

Merge pull request #4023 from overleaf/ae-reset-file-tree-state

Reset file tree component state when rootFolder prop changes

GitOrigin-RevId: acf23ce7c7a8f175c4e12b367bfa9e48d2f946c8
Alf Eaton 5 лет назад
Родитель
Сommit
fb9579c2b7

+ 8 - 2
services/web/frontend/js/features/file-tree/contexts/file-tree-actionable.js

@@ -15,7 +15,7 @@ import {
   syncMove,
   syncCreateEntity,
 } from '../util/sync-mutation'
-import { findInTreeOrThrow } from '../util/find-in-tree'
+import { findInTree, findInTreeOrThrow } from '../util/find-in-tree'
 import { isNameUniqueInFolder } from '../util/is-name-unique-in-folder'
 import { isBlockedFilename, isCleanFilename } from '../util/safe-path'
 
@@ -380,7 +380,13 @@ function getSelectedParentFolderId(fileTreeData, selectedEntityIds) {
     return fileTreeData._id
   }
 
-  const found = findInTreeOrThrow(fileTreeData, selectedEntityId)
+  const found = findInTree(fileTreeData, selectedEntityId)
+
+  if (!found) {
+    // if the entity isn't in the tree, return the root folder id.
+    return fileTreeData._id
+  }
+
   return found.type === 'folder' ? found.entity._id : found.parentFolderId
 }
 

+ 25 - 4
services/web/frontend/js/features/file-tree/contexts/file-tree-mutable.js

@@ -3,6 +3,7 @@ import React, {
   useCallback,
   useReducer,
   useContext,
+  useEffect,
 } from 'react'
 import PropTypes from 'prop-types'
 
@@ -17,6 +18,7 @@ const FileTreeMutableContext = createContext()
 
 const ACTION_TYPES = {
   RENAME: 'RENAME',
+  RESET: 'RESET',
   DELETE: 'DELETE',
   MOVE: 'MOVE',
   CREATE_ENTITY: 'CREATE_ENTITY',
@@ -24,6 +26,15 @@ const ACTION_TYPES = {
 
 function fileTreeMutableReducer({ fileTreeData }, action) {
   switch (action.type) {
+    case ACTION_TYPES.RESET: {
+      const newFileTreeData = action.fileTreeData
+
+      return {
+        fileTreeData: newFileTreeData,
+        fileCount: countFiles(newFileTreeData),
+      }
+    }
+
     case ACTION_TYPES.RENAME: {
       const newFileTreeData = renameInTree(fileTreeData, action.id, {
         newName: action.newName,
@@ -76,15 +87,25 @@ function fileTreeMutableReducer({ fileTreeData }, action) {
   }
 }
 
+const initialState = rootFolder => ({
+  fileTreeData: rootFolder[0],
+  fileCount: countFiles(rootFolder[0]),
+})
+
 export const FileTreeMutableProvider = function ({ rootFolder, children }) {
   const [{ fileTreeData, fileCount }, dispatch] = useReducer(
     fileTreeMutableReducer,
-    {
-      fileTreeData: rootFolder[0],
-      fileCount: countFiles(rootFolder[0]),
-    }
+    rootFolder,
+    initialState
   )
 
+  useEffect(() => {
+    dispatch({
+      type: ACTION_TYPES.RESET,
+      fileTreeData: rootFolder[0],
+    })
+  }, [rootFolder])
+
   const dispatchCreateFolder = useCallback((parentFolderId, entity) => {
     entity.type = 'folder'
     dispatch({

+ 3 - 3
services/web/frontend/js/features/file-tree/contexts/file-tree-selectable.js

@@ -123,9 +123,9 @@ export function FileTreeSelectableProvider({
 
   // calls `onSelect` on entities selection
   useEffect(() => {
-    const selectedEntities = Array.from(selectedEntityIds).map(id =>
-      findInTree(fileTreeData, id)
-    )
+    const selectedEntities = Array.from(selectedEntityIds)
+      .map(id => findInTree(fileTreeData, id))
+      .filter(Boolean)
     onSelect(selectedEntities)
   }, [fileTreeData, selectedEntityIds, onSelect])