| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- import React, {
- createContext,
- useCallback,
- useReducer,
- useContext
- } from 'react'
- import PropTypes from 'prop-types'
- import {
- renameInTree,
- deleteInTree,
- moveInTree,
- createEntityInTree
- } from '../util/mutate-in-tree'
- const FileTreeMutableContext = createContext()
- const ACTION_TYPES = {
- RENAME: 'RENAME',
- DELETE: 'DELETE',
- MOVE: 'MOVE',
- CREATE_ENTITY: 'CREATE_ENTITY'
- }
- function fileTreeMutableReducer({ fileTreeData }, action) {
- switch (action.type) {
- case ACTION_TYPES.RENAME: {
- const newFileTreeData = renameInTree(fileTreeData, action.id, {
- newName: action.newName
- })
- return {
- fileTreeData: newFileTreeData,
- fileCount: countFiles(newFileTreeData)
- }
- }
- case ACTION_TYPES.DELETE: {
- const newFileTreeData = deleteInTree(fileTreeData, action.id)
- return {
- fileTreeData: newFileTreeData,
- fileCount: countFiles(newFileTreeData)
- }
- }
- case ACTION_TYPES.MOVE: {
- const newFileTreeData = moveInTree(
- fileTreeData,
- action.entityId,
- action.toFolderId
- )
- return {
- fileTreeData: newFileTreeData,
- fileCount: countFiles(newFileTreeData)
- }
- }
- case ACTION_TYPES.CREATE_ENTITY: {
- const newFileTreeData = createEntityInTree(
- fileTreeData,
- action.parentFolderId,
- action.entity
- )
- return {
- fileTreeData: newFileTreeData,
- fileCount: countFiles(newFileTreeData)
- }
- }
- default: {
- throw new Error(`Unknown mutable file tree action type: ${action.type}`)
- }
- }
- }
- export const FileTreeMutableProvider = function({ rootFolder, children }) {
- const [{ fileTreeData, fileCount }, dispatch] = useReducer(
- fileTreeMutableReducer,
- {
- fileTreeData: rootFolder[0],
- fileCount: countFiles(rootFolder[0])
- }
- )
- return (
- <FileTreeMutableContext.Provider
- value={{ fileTreeData, fileCount, dispatch }}
- >
- {children}
- </FileTreeMutableContext.Provider>
- )
- }
- FileTreeMutableProvider.propTypes = {
- rootFolder: PropTypes.array.isRequired,
- children: PropTypes.oneOfType([
- PropTypes.arrayOf(PropTypes.node),
- PropTypes.node
- ]).isRequired
- }
- export function useFileTreeMutable() {
- const { fileTreeData, fileCount, dispatch } = useContext(
- FileTreeMutableContext
- )
- const dispatchCreateFolder = useCallback(
- (parentFolderId, entity) => {
- entity.type = 'folder'
- dispatch({
- type: ACTION_TYPES.CREATE_ENTITY,
- parentFolderId,
- entity
- })
- },
- [dispatch]
- )
- const dispatchCreateDoc = useCallback(
- (parentFolderId, entity) => {
- entity.type = 'doc'
- dispatch({
- type: ACTION_TYPES.CREATE_ENTITY,
- parentFolderId,
- entity
- })
- },
- [dispatch]
- )
- const dispatchCreateFile = useCallback(
- (parentFolderId, entity) => {
- entity.type = 'fileRef'
- dispatch({
- type: ACTION_TYPES.CREATE_ENTITY,
- parentFolderId,
- entity
- })
- },
- [dispatch]
- )
- const dispatchRename = useCallback(
- (id, newName) => {
- dispatch({
- type: ACTION_TYPES.RENAME,
- newName,
- id
- })
- },
- [dispatch]
- )
- const dispatchDelete = useCallback(
- id => {
- dispatch({ type: ACTION_TYPES.DELETE, id })
- },
- [dispatch]
- )
- const dispatchMove = useCallback(
- (entityId, toFolderId) => {
- dispatch({ type: ACTION_TYPES.MOVE, entityId, toFolderId })
- },
- [dispatch]
- )
- return {
- fileTreeData,
- fileCount,
- dispatchRename,
- dispatchDelete,
- dispatchMove,
- dispatchCreateFolder,
- dispatchCreateDoc,
- dispatchCreateFile
- }
- }
- function filesInFolder({ docs, folders, fileRefs }) {
- const files = [...docs, ...fileRefs]
- for (const folder of folders) {
- files.push(...filesInFolder(folder))
- }
- return files
- }
- function countFiles(fileTreeData) {
- const files = filesInFolder(fileTreeData)
- // count all the non-deleted entities
- const value = files.filter(item => !item.deleted).length
- const limit = window.ExposedSettings.maxEntitiesPerProject
- const status = fileCountStatus(value, limit, Math.ceil(limit / 20))
- return { value, status, limit }
- }
- function fileCountStatus(value, limit, range) {
- if (value >= limit) {
- return 'error'
- }
- if (value >= limit - range) {
- return 'warning'
- }
- return 'success'
- }
|