overleaf/services/web/frontend/js/features/file-tree/util/mutate-in-tree.js
Timothée Alby 420aa4a657 Merge pull request #3232 from overleaf/ta-file-tree-react
React File Tree

GitOrigin-RevId: fb3141ba8cd9ca0d68e87edb74764a360144c8fe
2020-11-27 03:05:05 +00:00

74 lines
2.1 KiB
JavaScript

import { findInTreeOrThrow } from './find-in-tree'
export function renameInTree(tree, id, { newName }) {
return mutateInTree(tree, id, (parent, entity, index) => {
const newParent = Object.assign([], parent)
const newEntity = {
...entity,
name: newName
}
newParent[index] = newEntity
return newParent
})
}
export function deleteInTree(tree, id) {
return mutateInTree(tree, id, (parent, entity, index) => {
return [...parent.slice(0, index), ...parent.slice(index + 1)]
})
}
export function moveInTree(tree, entityId, toFolderId) {
const found = findInTreeOrThrow(tree, entityId)
if (found.parentFolderId === toFolderId) {
// nothing to do (the entity was probably already moved)
return tree
}
const newFileTreeData = deleteInTree(tree, entityId)
return createEntityInTree(newFileTreeData, toFolderId, {
...found.entity,
type: found.type
})
}
export function createEntityInTree(tree, parentFolderId, newEntityData) {
const { type, ...newEntity } = newEntityData
if (!type) throw new Error('Entity has no type')
const entityType = `${type}s`
return mutateInTree(tree, parentFolderId, (parent, folder, index) => {
parent[index] = {
...folder,
[entityType]: [...folder[entityType], newEntity]
}
return parent
})
}
function mutateInTree(tree, id, mutationFunction) {
if (tree._id === id) {
// covers the root folder case: it has no parent so in order to use
// mutationFunction we pass an empty array as the parent and return the
// mutated tree directly
const [newTree] = mutationFunction([], tree, 0)
return newTree
}
for (const entityType of ['docs', 'fileRefs', 'folders']) {
for (let index = 0; index < tree[entityType].length; index++) {
const entity = tree[entityType][index]
if (entity._id === id) {
return {
...tree,
[entityType]: mutationFunction(tree[entityType], entity, index)
}
}
}
}
const newFolders = tree.folders.map(folder =>
mutateInTree(folder, id, mutationFunction)
)
return { ...tree, folders: newFolders }
}