mirror of
https://github.com/overleaf/overleaf.git
synced 2024-09-16 02:52:31 -04:00
Merge pull request #6210 from overleaf/ta-file-tree-data-in-context
Remove rootFolder from EditorContext GitOrigin-RevId: 827b046046265ad2418eb91d5a69eae02aa8b5a4
This commit is contained in:
parent
392410390e
commit
24bd557485
26 changed files with 202 additions and 179 deletions
|
@ -2,7 +2,6 @@ import PropTypes from 'prop-types'
|
|||
|
||||
import { FileTreeMainProvider } from '../contexts/file-tree-main'
|
||||
import { FileTreeActionableProvider } from '../contexts/file-tree-actionable'
|
||||
import { FileTreeMutableProvider } from '../contexts/file-tree-mutable'
|
||||
import { FileTreeSelectableProvider } from '../contexts/file-tree-selectable'
|
||||
import { FileTreeDraggableProvider } from '../contexts/file-tree-draggable'
|
||||
|
||||
|
@ -26,13 +25,11 @@ function FileTreeContext({
|
|||
setStartedFreeTrial={setStartedFreeTrial}
|
||||
reindexReferences={reindexReferences}
|
||||
>
|
||||
<FileTreeMutableProvider>
|
||||
<FileTreeSelectableProvider onSelect={onSelect}>
|
||||
<FileTreeActionableProvider>
|
||||
<FileTreeDraggableProvider>{children}</FileTreeDraggableProvider>
|
||||
</FileTreeActionableProvider>
|
||||
</FileTreeSelectableProvider>
|
||||
</FileTreeMutableProvider>
|
||||
<FileTreeSelectableProvider onSelect={onSelect}>
|
||||
<FileTreeActionableProvider>
|
||||
<FileTreeDraggableProvider>{children}</FileTreeDraggableProvider>
|
||||
</FileTreeActionableProvider>
|
||||
</FileTreeSelectableProvider>
|
||||
</FileTreeMainProvider>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import FileTreeUploadDoc from './modes/file-tree-upload-doc'
|
|||
import FileTreeModalCreateFileMode from './file-tree-modal-create-file-mode'
|
||||
import FileTreeCreateNameProvider from '../../contexts/file-tree-create-name'
|
||||
import { useFileTreeActionable } from '../../contexts/file-tree-actionable'
|
||||
import { useFileTreeMutable } from '../../contexts/file-tree-mutable'
|
||||
import { useFileTreeData } from '../../../../shared/context/file-tree-data-context'
|
||||
|
||||
import importOverleafModules from '../../../../../macros/import-overleaf-module.macro'
|
||||
|
||||
|
@ -16,7 +16,7 @@ export default function FileTreeModalCreateFileBody() {
|
|||
const { t } = useTranslation()
|
||||
|
||||
const { newFileCreateMode } = useFileTreeActionable()
|
||||
const { fileCount } = useFileTreeMutable()
|
||||
const { fileCount } = useFileTreeData()
|
||||
|
||||
if (!fileCount || fileCount.status === 'error') {
|
||||
return null
|
||||
|
|
|
@ -2,13 +2,13 @@ import { useTranslation } from 'react-i18next'
|
|||
import { Alert, Button } from 'react-bootstrap'
|
||||
import { useFileTreeCreateForm } from '../../contexts/file-tree-create-form'
|
||||
import { useFileTreeActionable } from '../../contexts/file-tree-actionable'
|
||||
import { useFileTreeMutable } from '../../contexts/file-tree-mutable'
|
||||
import { useFileTreeData } from '../../../../shared/context/file-tree-data-context'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
export default function FileTreeModalCreateFileFooter() {
|
||||
const { valid } = useFileTreeCreateForm()
|
||||
const { newFileCreateMode, inFlight, cancel } = useFileTreeActionable()
|
||||
const { fileCount } = useFileTreeMutable()
|
||||
const { fileCount } = useFileTreeData()
|
||||
|
||||
return (
|
||||
<FileTreeModalCreateFileFooterContent
|
||||
|
|
|
@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
|
|||
|
||||
import withErrorBoundary from '../../../infrastructure/error-boundary'
|
||||
import { useProjectContext } from '../../../shared/context/project-context'
|
||||
import { useFileTreeData } from '../../../shared/context/file-tree-data-context'
|
||||
import FileTreeContext from './file-tree-context'
|
||||
import FileTreeDraggablePreviewLayer from './file-tree-draggable-preview-layer'
|
||||
import FileTreeFolderList from './file-tree-folder-list'
|
||||
|
@ -13,7 +14,6 @@ import FileTreeModalError from './modals/file-tree-modal-error'
|
|||
import FileTreeContextMenu from './file-tree-context-menu'
|
||||
import FileTreeError from './file-tree-error'
|
||||
|
||||
import { useFileTreeMutable } from '../contexts/file-tree-mutable'
|
||||
import { useDroppable } from '../contexts/file-tree-draggable'
|
||||
|
||||
import { useFileTreeSocketListener } from '../hooks/file-tree-socket-listener'
|
||||
|
@ -28,10 +28,9 @@ const FileTreeRoot = React.memo(function FileTreeRoot({
|
|||
onInit,
|
||||
isConnected,
|
||||
}) {
|
||||
const { _id: projectId, rootFolder } = useProjectContext(
|
||||
projectContextPropTypes
|
||||
)
|
||||
const isReady = projectId && rootFolder
|
||||
const { _id: projectId } = useProjectContext(projectContextPropTypes)
|
||||
const { fileTreeData } = useFileTreeData()
|
||||
const isReady = projectId && fileTreeData
|
||||
|
||||
useEffect(() => {
|
||||
if (isReady) onInit()
|
||||
|
@ -62,7 +61,7 @@ const FileTreeRoot = React.memo(function FileTreeRoot({
|
|||
|
||||
function FileTreeRootFolder() {
|
||||
useFileTreeSocketListener()
|
||||
const { fileTreeData } = useFileTreeMutable()
|
||||
const { fileTreeData } = useFileTreeData()
|
||||
|
||||
const { isOver, dropRef } = useDroppable(fileTreeData._id)
|
||||
|
||||
|
@ -95,7 +94,6 @@ FileTreeRoot.propTypes = {
|
|||
|
||||
const projectContextPropTypes = {
|
||||
_id: PropTypes.string.isRequired,
|
||||
rootFolder: PropTypes.array.isRequired,
|
||||
}
|
||||
|
||||
export default withErrorBoundary(FileTreeRoot, FileTreeError)
|
||||
|
|
|
@ -22,7 +22,7 @@ import { isBlockedFilename, isCleanFilename } from '../util/safe-path'
|
|||
|
||||
import { useProjectContext } from '../../../shared/context/project-context'
|
||||
import { useEditorContext } from '../../../shared/context/editor-context'
|
||||
import { useFileTreeMutable } from './file-tree-mutable'
|
||||
import { useFileTreeData } from '../../../shared/context/file-tree-data-context'
|
||||
import { useFileTreeSelectable } from './file-tree-selectable'
|
||||
|
||||
import {
|
||||
|
@ -129,7 +129,7 @@ export function FileTreeActionableProvider({ children }) {
|
|||
defaultState
|
||||
)
|
||||
|
||||
const { fileTreeData, dispatchRename, dispatchMove } = useFileTreeMutable()
|
||||
const { fileTreeData, dispatchRename, dispatchMove } = useFileTreeData()
|
||||
const { selectedEntityIds } = useFileTreeSelectable()
|
||||
|
||||
const startRenaming = useCallback(() => {
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
} from '../util/find-in-tree'
|
||||
|
||||
import { useFileTreeActionable } from './file-tree-actionable'
|
||||
import { useFileTreeMutable } from './file-tree-mutable'
|
||||
import { useFileTreeData } from '../../../shared/context/file-tree-data-context'
|
||||
import { useFileTreeSelectable } from '../contexts/file-tree-selectable'
|
||||
import { useEditorContext } from '../../../shared/context/editor-context'
|
||||
|
||||
|
@ -77,7 +77,7 @@ export function useDraggable(draggedEntityId) {
|
|||
const { t } = useTranslation()
|
||||
|
||||
const { permissionsLevel } = useEditorContext(editorContextPropTypes)
|
||||
const { fileTreeData } = useFileTreeMutable()
|
||||
const { fileTreeData } = useFileTreeData()
|
||||
const { selectedEntityIds } = useFileTreeSelectable()
|
||||
|
||||
const [isDraggable, setIsDraggable] = useState(true)
|
||||
|
|
|
@ -12,7 +12,7 @@ import classNames from 'classnames'
|
|||
import _ from 'lodash'
|
||||
|
||||
import { findInTree } from '../util/find-in-tree'
|
||||
import { useFileTreeMutable } from './file-tree-mutable'
|
||||
import { useFileTreeData } from '../../../shared/context/file-tree-data-context'
|
||||
import { useProjectContext } from '../../../shared/context/project-context'
|
||||
import { useEditorContext } from '../../../shared/context/editor-context'
|
||||
import usePersistedState from '../../../shared/hooks/use-persisted-state'
|
||||
|
@ -85,7 +85,7 @@ export function FileTreeSelectableProvider({ onSelect, children }) {
|
|||
rootDocId
|
||||
)
|
||||
|
||||
const { fileTreeData } = useFileTreeMutable()
|
||||
const { fileTreeData } = useFileTreeData()
|
||||
|
||||
const [selectedEntityIds, dispatch] = useReducer(
|
||||
permissionsLevel === 'readOnly'
|
||||
|
|
|
@ -2,7 +2,7 @@ import { useCallback, useEffect } from 'react'
|
|||
import PropTypes from 'prop-types'
|
||||
|
||||
import { useUserContext } from '../../../shared/context/user-context'
|
||||
import { useFileTreeMutable } from '../contexts/file-tree-mutable'
|
||||
import { useFileTreeData } from '../../../shared/context/file-tree-data-context'
|
||||
import { useFileTreeSelectable } from '../contexts/file-tree-selectable'
|
||||
import { findInTreeOrThrow } from '../util/find-in-tree'
|
||||
|
||||
|
@ -18,7 +18,7 @@ export function useFileTreeSocketListener() {
|
|||
dispatchCreateDoc,
|
||||
dispatchCreateFile,
|
||||
fileTreeData,
|
||||
} = useFileTreeMutable()
|
||||
} = useFileTreeData()
|
||||
const { selectedEntityIds, selectedEntityParentIds, select, unselect } =
|
||||
useFileTreeSelectable()
|
||||
const socket = window._ide && window._ide.socket
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
export function countFiles(fileTreeData) {
|
||||
if (!fileTreeData) {
|
||||
return 0
|
||||
}
|
||||
|
||||
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 filesInFolder({ docs, folders, fileRefs }) {
|
||||
const files = [...docs, ...fileRefs]
|
||||
|
||||
for (const folder of folders) {
|
||||
files.push(...filesInFolder(folder))
|
||||
}
|
||||
|
||||
return files
|
||||
}
|
||||
|
||||
function fileCountStatus(value, limit, range) {
|
||||
if (value >= limit) {
|
||||
return 'error'
|
||||
}
|
||||
|
||||
if (value >= limit - range) {
|
||||
return 'warning'
|
||||
}
|
||||
|
||||
return 'success'
|
||||
}
|
|
@ -34,9 +34,6 @@ EditorContext.Provider.propTypes = {
|
|||
insertSymbol: PropTypes.func,
|
||||
isProjectOwner: PropTypes.bool,
|
||||
isRestrictedTokenMember: PropTypes.bool,
|
||||
rootFolder: PropTypes.shape({
|
||||
children: PropTypes.arrayOf(PropTypes.shape({ type: PropTypes.string })),
|
||||
}),
|
||||
permissionsLevel: PropTypes.oneOf(['readOnly', 'readAndWrite', 'owner']),
|
||||
}),
|
||||
}
|
||||
|
@ -73,7 +70,6 @@ export function EditorProvider({ children, settings }) {
|
|||
|
||||
const [loading] = useScopeValue('state.loading')
|
||||
const [projectName, setProjectName] = useScopeValue('project.name')
|
||||
const [rootFolder] = useScopeValue('rootFolder', true)
|
||||
const [permissionsLevel] = useScopeValue('permissionsLevel')
|
||||
const [showSymbolPalette] = useScopeValue('editor.showSymbolPalette')
|
||||
const [toggleSymbolPalette] = useScopeValue('editor.toggleSymbolPalette')
|
||||
|
@ -135,7 +131,6 @@ export function EditorProvider({ children, settings }) {
|
|||
permissionsLevel,
|
||||
isProjectOwner: owner?._id === window.user.id,
|
||||
isRestrictedTokenMember: window.isRestrictedTokenMember,
|
||||
rootFolder,
|
||||
showSymbolPalette,
|
||||
toggleSymbolPalette,
|
||||
insertSymbol,
|
||||
|
@ -147,7 +142,6 @@ export function EditorProvider({ children, settings }) {
|
|||
renameProject,
|
||||
permissionsLevel,
|
||||
owner?._id,
|
||||
rootFolder,
|
||||
showSymbolPalette,
|
||||
toggleSymbolPalette,
|
||||
insertSymbol,
|
||||
|
|
|
@ -4,18 +4,36 @@ import {
|
|||
useReducer,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
} from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import useScopeValue from '../hooks/use-scope-value'
|
||||
import {
|
||||
renameInTree,
|
||||
deleteInTree,
|
||||
moveInTree,
|
||||
createEntityInTree,
|
||||
} from '../util/mutate-in-tree'
|
||||
import { useProjectContext } from '../../../shared/context/project-context'
|
||||
} from '../../features/file-tree/util/mutate-in-tree'
|
||||
import { countFiles } from '../../features/file-tree/util/count-in-tree'
|
||||
|
||||
const FileTreeMutableContext = createContext()
|
||||
const FileTreeDataContext = createContext()
|
||||
|
||||
const fileTreeDataPropType = PropTypes.shape({
|
||||
_id: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
docs: PropTypes.array.isRequired,
|
||||
fileRefs: PropTypes.array.isRequired,
|
||||
folders: PropTypes.array.isRequired,
|
||||
})
|
||||
|
||||
FileTreeDataContext.Provider.propTypes = {
|
||||
value: PropTypes.shape({
|
||||
// fileTreeData is the up-to-date representation of the files list, updated
|
||||
// by the file tree
|
||||
fileTreeData: fileTreeDataPropType,
|
||||
hasFolders: PropTypes.bool,
|
||||
}),
|
||||
}
|
||||
|
||||
const ACTION_TYPES = {
|
||||
RENAME: 'RENAME',
|
||||
|
@ -88,13 +106,37 @@ function fileTreeMutableReducer({ fileTreeData }, action) {
|
|||
}
|
||||
}
|
||||
|
||||
const initialState = rootFolder => ({
|
||||
fileTreeData: rootFolder[0],
|
||||
fileCount: countFiles(rootFolder[0]),
|
||||
})
|
||||
const initialState = rootFolder => {
|
||||
const fileTreeData = rootFolder?.[0]
|
||||
return {
|
||||
fileTreeData,
|
||||
fileCount: countFiles(fileTreeData),
|
||||
}
|
||||
}
|
||||
|
||||
export const FileTreeMutableProvider = function ({ children }) {
|
||||
const { rootFolder } = useProjectContext(projectContextPropTypes)
|
||||
export function useFileTreeData(propTypes) {
|
||||
const context = useContext(FileTreeDataContext)
|
||||
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
'useFileTreeData is only available inside FileTreeDataProvider'
|
||||
)
|
||||
}
|
||||
|
||||
PropTypes.checkPropTypes(
|
||||
propTypes,
|
||||
context,
|
||||
'data',
|
||||
'FileTreeDataContext.Provider'
|
||||
)
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
export function FileTreeDataProvider({ children }) {
|
||||
const [project] = useScopeValue('project', true)
|
||||
|
||||
const { rootFolder } = project || {}
|
||||
|
||||
const [{ fileTreeData, fileCount }, dispatch] = useReducer(
|
||||
fileTreeMutableReducer,
|
||||
|
@ -105,7 +147,7 @@ export const FileTreeMutableProvider = function ({ children }) {
|
|||
useEffect(() => {
|
||||
dispatch({
|
||||
type: ACTION_TYPES.RESET,
|
||||
fileTreeData: rootFolder[0],
|
||||
fileTreeData: rootFolder?.[0],
|
||||
})
|
||||
}, [rootFolder])
|
||||
|
||||
|
@ -152,7 +194,19 @@ export const FileTreeMutableProvider = function ({ children }) {
|
|||
dispatch({ type: ACTION_TYPES.MOVE, entityId, toFolderId })
|
||||
}, [])
|
||||
|
||||
const value = {
|
||||
const value = useMemo(() => {
|
||||
return {
|
||||
dispatchCreateDoc,
|
||||
dispatchCreateFile,
|
||||
dispatchCreateFolder,
|
||||
dispatchDelete,
|
||||
dispatchMove,
|
||||
dispatchRename,
|
||||
fileCount,
|
||||
fileTreeData,
|
||||
hasFolders: fileTreeData?.folders.length > 0,
|
||||
}
|
||||
}, [
|
||||
dispatchCreateDoc,
|
||||
dispatchCreateFile,
|
||||
dispatchCreateFolder,
|
||||
|
@ -161,76 +215,15 @@ export const FileTreeMutableProvider = function ({ children }) {
|
|||
dispatchRename,
|
||||
fileCount,
|
||||
fileTreeData,
|
||||
}
|
||||
])
|
||||
|
||||
return (
|
||||
<FileTreeMutableContext.Provider value={value}>
|
||||
<FileTreeDataContext.Provider value={value}>
|
||||
{children}
|
||||
</FileTreeMutableContext.Provider>
|
||||
</FileTreeDataContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
FileTreeMutableProvider.propTypes = {
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node,
|
||||
]).isRequired,
|
||||
}
|
||||
|
||||
const projectContextPropTypes = {
|
||||
rootFolder: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
_id: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
docs: PropTypes.array.isRequired,
|
||||
fileRefs: PropTypes.array.isRequired,
|
||||
folders: PropTypes.array.isRequired,
|
||||
})
|
||||
),
|
||||
}
|
||||
|
||||
export function useFileTreeMutable() {
|
||||
const context = useContext(FileTreeMutableContext)
|
||||
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
'useFileTreeMutable is only available in FileTreeMutableProvider'
|
||||
)
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
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'
|
||||
FileTreeDataProvider.propTypes = {
|
||||
children: PropTypes.any,
|
||||
}
|
|
@ -1,17 +1,9 @@
|
|||
import { createContext, useContext } from 'react'
|
||||
import { createContext, useContext, useMemo } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import useScopeValue from '../hooks/use-scope-value'
|
||||
|
||||
const ProjectContext = createContext()
|
||||
|
||||
const fileTreeDataPropType = PropTypes.shape({
|
||||
_id: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
docs: PropTypes.array.isRequired,
|
||||
fileRefs: PropTypes.array.isRequired,
|
||||
folders: PropTypes.array.isRequired,
|
||||
})
|
||||
|
||||
ProjectContext.Provider.propTypes = {
|
||||
value: PropTypes.shape({
|
||||
_id: PropTypes.string.isRequired,
|
||||
|
@ -44,7 +36,6 @@ ProjectContext.Provider.propTypes = {
|
|||
_id: PropTypes.string.isRequired,
|
||||
email: PropTypes.string.isRequired,
|
||||
}),
|
||||
rootFolder: PropTypes.arrayOf(fileTreeDataPropType),
|
||||
}),
|
||||
}
|
||||
|
||||
|
@ -67,13 +58,24 @@ export function useProjectContext(propTypes) {
|
|||
return context
|
||||
}
|
||||
|
||||
// when the provider is created the project is still not added to the Angular
|
||||
// scope. A few props are populated to prevent errors in existing React
|
||||
// components
|
||||
const projectFallback = {
|
||||
_id: window.project_id,
|
||||
name: '',
|
||||
features: {},
|
||||
}
|
||||
|
||||
export function ProjectProvider({ children }) {
|
||||
const [project] = useScopeValue('project', true)
|
||||
|
||||
// when the provider is created the project is still not added to the Angular scope.
|
||||
// Name is also populated to prevent errors in existing React components
|
||||
const value = project || { _id: window.project_id, name: '', features: {} }
|
||||
|
||||
const value = useMemo(() => {
|
||||
return {
|
||||
...projectFallback,
|
||||
...project,
|
||||
}
|
||||
}, [project])
|
||||
return (
|
||||
<ProjectContext.Provider value={value}>{children}</ProjectContext.Provider>
|
||||
)
|
||||
|
|
|
@ -10,6 +10,7 @@ import { DetachProvider } from './detach-context'
|
|||
import { ChatProvider } from '../../features/chat/context/chat-context'
|
||||
import { ProjectProvider } from './project-context'
|
||||
import { SplitTestProvider } from './split-test-context'
|
||||
import { FileTreeDataProvider } from './file-tree-data-context'
|
||||
|
||||
export function ContextRoot({ children, ide, settings }) {
|
||||
return (
|
||||
|
@ -17,15 +18,17 @@ export function ContextRoot({ children, ide, settings }) {
|
|||
<IdeProvider ide={ide}>
|
||||
<UserProvider>
|
||||
<ProjectProvider>
|
||||
<EditorProvider settings={settings}>
|
||||
<DetachProvider>
|
||||
<LayoutProvider>
|
||||
<CompileProvider>
|
||||
<ChatProvider>{children}</ChatProvider>
|
||||
</CompileProvider>
|
||||
</LayoutProvider>
|
||||
</DetachProvider>
|
||||
</EditorProvider>
|
||||
<FileTreeDataProvider>
|
||||
<EditorProvider settings={settings}>
|
||||
<DetachProvider>
|
||||
<LayoutProvider>
|
||||
<CompileProvider>
|
||||
<ChatProvider>{children}</ChatProvider>
|
||||
</CompileProvider>
|
||||
</LayoutProvider>
|
||||
</DetachProvider>
|
||||
</EditorProvider>
|
||||
</FileTreeDataProvider>
|
||||
</ProjectProvider>
|
||||
</UserProvider>
|
||||
</IdeProvider>
|
||||
|
|
|
@ -8,7 +8,7 @@ import PropTypes from 'prop-types'
|
|||
import renderWithContext from '../../helpers/render-with-context'
|
||||
import FileTreeModalCreateFile from '../../../../../../frontend/js/features/file-tree/components/modals/file-tree-modal-create-file'
|
||||
import { useFileTreeActionable } from '../../../../../../frontend/js/features/file-tree/contexts/file-tree-actionable'
|
||||
import { useFileTreeMutable } from '../../../../../../frontend/js/features/file-tree/contexts/file-tree-mutable'
|
||||
import { useFileTreeData } from '../../../../../../frontend/js/shared/context/file-tree-data-context'
|
||||
|
||||
describe('<FileTreeModalCreateFile/>', function () {
|
||||
beforeEach(function () {
|
||||
|
@ -65,7 +65,7 @@ describe('<FileTreeModalCreateFile/>', function () {
|
|||
]
|
||||
|
||||
renderWithContext(<OpenWithMode mode="doc" />, {
|
||||
contextProps: { projectRootFolder: rootFolder },
|
||||
contextProps: { rootFolder },
|
||||
})
|
||||
|
||||
screen.getByRole(
|
||||
|
@ -89,7 +89,7 @@ describe('<FileTreeModalCreateFile/>', function () {
|
|||
]
|
||||
|
||||
renderWithContext(<OpenWithMode mode="doc" />, {
|
||||
contextProps: { projectRootFolder: rootFolder },
|
||||
contextProps: { rootFolder },
|
||||
})
|
||||
|
||||
screen.getByText(/This project is approaching the file limit \(\d+\/\d+\)/)
|
||||
|
@ -127,7 +127,7 @@ describe('<FileTreeModalCreateFile/>', function () {
|
|||
]
|
||||
|
||||
renderWithContext(<OpenWithMode mode="doc" />, {
|
||||
contextProps: { projectRootFolder: rootFolder },
|
||||
contextProps: { rootFolder },
|
||||
})
|
||||
|
||||
screen.getByText(/This project is approaching the file limit \(\d+\/\d+\)/)
|
||||
|
@ -458,7 +458,7 @@ describe('<FileTreeModalCreateFile/>', function () {
|
|||
function OpenWithMode({ mode }) {
|
||||
const { newFileCreateMode, startCreatingFile } = useFileTreeActionable()
|
||||
|
||||
const { fileCount } = useFileTreeMutable()
|
||||
const { fileCount } = useFileTreeData()
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
useEffect(() => startCreatingFile(mode), [])
|
||||
|
|
|
@ -19,7 +19,7 @@ describe('<FileTreeDoc/>', function () {
|
|||
<FileTreeDoc name="foo.tex" id="123abc" isLinkedFile={false} />,
|
||||
{
|
||||
contextProps: {
|
||||
projectRootFolder: [
|
||||
rootFolder: [
|
||||
{
|
||||
_id: 'root-folder-id',
|
||||
name: 'rootFolder',
|
||||
|
@ -50,7 +50,7 @@ describe('<FileTreeDoc/>', function () {
|
|||
it('selects', function () {
|
||||
renderWithContext(<FileTreeDoc name="foo.tex" id="123abc" expanded />, {
|
||||
contextProps: {
|
||||
projectRootFolder: [
|
||||
rootFolder: [
|
||||
{
|
||||
_id: 'root-folder-id',
|
||||
name: 'rootFolder',
|
||||
|
@ -71,7 +71,7 @@ describe('<FileTreeDoc/>', function () {
|
|||
it('multi-selects', function () {
|
||||
renderWithContext(<FileTreeDoc name="foo.tex" id="123abc" expanded />, {
|
||||
contextProps: {
|
||||
projectRootFolder: [
|
||||
rootFolder: [
|
||||
{
|
||||
_id: 'root-folder-id',
|
||||
name: 'rootFolder',
|
||||
|
|
|
@ -43,7 +43,7 @@ describe('<FileTreeFolderList/>', function () {
|
|||
{
|
||||
contextProps: {
|
||||
permissionsLevel: 'readOnly',
|
||||
projectRootFolder: [
|
||||
rootFolder: [
|
||||
{
|
||||
_id: 'root-folder-id',
|
||||
name: 'rootFolder',
|
||||
|
@ -80,7 +80,7 @@ describe('<FileTreeFolderList/>', function () {
|
|||
<FileTreeFolderList folders={[]} docs={docs} files={[]} />,
|
||||
{
|
||||
contextProps: {
|
||||
projectRootFolder: [
|
||||
rootFolder: [
|
||||
{
|
||||
_id: 'root-folder-id',
|
||||
name: 'rootFolder',
|
||||
|
|
|
@ -35,7 +35,7 @@ describe('<FileTreeFolder/>', function () {
|
|||
/>,
|
||||
{
|
||||
contextProps: {
|
||||
projectRootFolder: [
|
||||
rootFolder: [
|
||||
{
|
||||
_id: 'root-folder-id',
|
||||
name: 'rootFolder',
|
||||
|
@ -66,7 +66,7 @@ describe('<FileTreeFolder/>', function () {
|
|||
/>,
|
||||
{
|
||||
contextProps: {
|
||||
projectRootFolder: [
|
||||
rootFolder: [
|
||||
{
|
||||
_id: 'root-folder-id',
|
||||
name: 'rootFolder',
|
||||
|
@ -97,7 +97,7 @@ describe('<FileTreeFolder/>', function () {
|
|||
/>,
|
||||
{
|
||||
contextProps: {
|
||||
projectRootFolder: [
|
||||
rootFolder: [
|
||||
{
|
||||
_id: 'root-folder-id',
|
||||
name: 'rootFolder',
|
||||
|
|
|
@ -86,7 +86,7 @@ describe('<FileTreeitemInner />', function () {
|
|||
{
|
||||
contextProps: {
|
||||
rootDocId: '123abc',
|
||||
projectRootFolder: [
|
||||
rootFolder: [
|
||||
{
|
||||
_id: 'root-folder-id',
|
||||
name: 'rootFolder',
|
||||
|
|
|
@ -47,7 +47,7 @@ describe('<FileTreeRoot/>', function () {
|
|||
isConnected
|
||||
/>,
|
||||
{
|
||||
projectRootFolder: rootFolder,
|
||||
rootFolder,
|
||||
projectId: '123abc',
|
||||
rootDocId: '456def',
|
||||
features: {},
|
||||
|
@ -86,7 +86,7 @@ describe('<FileTreeRoot/>', function () {
|
|||
isConnected
|
||||
/>,
|
||||
{
|
||||
projectRootFolder: rootFolder,
|
||||
rootFolder,
|
||||
projectId: '123abc',
|
||||
rootDocId: '456def',
|
||||
features: {},
|
||||
|
@ -128,7 +128,7 @@ describe('<FileTreeRoot/>', function () {
|
|||
setStartedFreeTrial={() => null}
|
||||
/>,
|
||||
{
|
||||
projectRootFolder: rootFolder,
|
||||
rootFolder,
|
||||
projectId: '123abc',
|
||||
rootDocId: '456def',
|
||||
features: {},
|
||||
|
@ -163,7 +163,7 @@ describe('<FileTreeRoot/>', function () {
|
|||
isConnected
|
||||
/>,
|
||||
{
|
||||
projectRootFolder: rootFolder,
|
||||
rootFolder,
|
||||
projectId: '123abc',
|
||||
rootDocId: '456def',
|
||||
features: {},
|
||||
|
@ -219,7 +219,7 @@ describe('<FileTreeRoot/>', function () {
|
|||
isConnected
|
||||
/>,
|
||||
{
|
||||
projectRootFolder: rootFolder,
|
||||
rootFolder,
|
||||
projectId: '123abc',
|
||||
rootDocId: '456def',
|
||||
features: {},
|
||||
|
@ -266,7 +266,7 @@ describe('<FileTreeRoot/>', function () {
|
|||
isConnected
|
||||
/>,
|
||||
{
|
||||
projectRootFolder: rootFolder,
|
||||
rootFolder,
|
||||
projectId: '123abc',
|
||||
rootDocId: '456def',
|
||||
features: {},
|
||||
|
|
|
@ -31,7 +31,7 @@ describe('<FileTreeToolbar/>', function () {
|
|||
renderWithContext(<FileTreeToolbar />, {
|
||||
contextProps: {
|
||||
rootDocId: '456def',
|
||||
projectRootFolder: [
|
||||
rootFolder: [
|
||||
{
|
||||
_id: 'root-folder-id',
|
||||
name: 'rootFolder',
|
||||
|
|
|
@ -39,7 +39,7 @@ describe('FileTree Context Menu Flow', function () {
|
|||
isConnected
|
||||
/>,
|
||||
{
|
||||
projectRootFolder: rootFolder,
|
||||
rootFolder,
|
||||
projectId: '123abc',
|
||||
rootDocId: '456def',
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ describe('FileTree Context Menu Flow', function () {
|
|||
isConnected
|
||||
/>,
|
||||
{
|
||||
projectRootFolder: rootFolder,
|
||||
rootFolder,
|
||||
projectId: '123abc',
|
||||
rootDocId: '456def',
|
||||
permissionsLevel: 'readOnly',
|
||||
|
|
|
@ -48,7 +48,7 @@ describe('FileTree Create Folder Flow', function () {
|
|||
/>,
|
||||
{
|
||||
socket: new MockedSocket(),
|
||||
projectRootFolder: rootFolder,
|
||||
rootFolder,
|
||||
projectId: '123abc',
|
||||
}
|
||||
)
|
||||
|
@ -110,7 +110,7 @@ describe('FileTree Create Folder Flow', function () {
|
|||
/>,
|
||||
{
|
||||
socket: new MockedSocket(),
|
||||
projectRootFolder: rootFolder,
|
||||
rootFolder,
|
||||
projectId: '123abc',
|
||||
rootDocId: '789ghi',
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ describe('FileTree Create Folder Flow', function () {
|
|||
/>,
|
||||
{
|
||||
socket: new MockedSocket(),
|
||||
projectRootFolder: rootFolder,
|
||||
rootFolder,
|
||||
projectId: '123abc',
|
||||
rootDocId: '456def',
|
||||
}
|
||||
|
@ -243,7 +243,7 @@ describe('FileTree Create Folder Flow', function () {
|
|||
/>,
|
||||
{
|
||||
socket: new MockedSocket(),
|
||||
projectRootFolder: rootFolder,
|
||||
rootFolder,
|
||||
projectId: '123abc',
|
||||
rootDocId: '456def',
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ describe('FileTree Delete Entity Flow', function () {
|
|||
/>,
|
||||
{
|
||||
socket: new MockedSocket(),
|
||||
projectRootFolder: rootFolder,
|
||||
rootFolder,
|
||||
projectId: '123abc',
|
||||
}
|
||||
)
|
||||
|
@ -164,7 +164,7 @@ describe('FileTree Delete Entity Flow', function () {
|
|||
/>,
|
||||
{
|
||||
socket: new MockedSocket(),
|
||||
projectRootFolder: rootFolder,
|
||||
rootFolder,
|
||||
projectId: '123abc',
|
||||
}
|
||||
)
|
||||
|
@ -223,7 +223,7 @@ describe('FileTree Delete Entity Flow', function () {
|
|||
/>,
|
||||
{
|
||||
socket: new MockedSocket(),
|
||||
projectRootFolder: rootFolder,
|
||||
rootFolder,
|
||||
projectId: '123abc',
|
||||
}
|
||||
)
|
||||
|
|
|
@ -59,7 +59,7 @@ describe('FileTree Rename Entity Flow', function () {
|
|||
/>,
|
||||
{
|
||||
socket: new MockedSocket(),
|
||||
projectRootFolder: rootFolder,
|
||||
rootFolder,
|
||||
projectId: '123abc',
|
||||
}
|
||||
)
|
||||
|
|
|
@ -5,7 +5,7 @@ export default (children, options = {}) => {
|
|||
let { contextProps = {}, ...renderOptions } = options
|
||||
contextProps = {
|
||||
projectId: '123abc',
|
||||
projectRootFolder: [
|
||||
rootFolder: [
|
||||
{
|
||||
_id: 'root-folder-id',
|
||||
name: 'rootFolder',
|
||||
|
|
|
@ -14,6 +14,7 @@ import { get } from 'lodash'
|
|||
import { ProjectProvider } from '../../../frontend/js/shared/context/project-context'
|
||||
import { SplitTestProvider } from '../../../frontend/js/shared/context/split-test-context'
|
||||
import { CompileProvider } from '../../../frontend/js/shared/context/compile-context'
|
||||
import { FileTreeDataProvider } from '../../../frontend/js/shared/context/file-tree-data-context'
|
||||
|
||||
// these constants can be imported in tests instead of
|
||||
// using magic strings
|
||||
|
@ -36,8 +37,7 @@ export function EditorProviders({
|
|||
},
|
||||
permissionsLevel = 'owner',
|
||||
children,
|
||||
rootFolder,
|
||||
projectRootFolder = [
|
||||
rootFolder = [
|
||||
{
|
||||
_id: 'root-folder-id',
|
||||
name: 'rootFolder',
|
||||
|
@ -75,10 +75,7 @@ export function EditorProviders({
|
|||
},
|
||||
features,
|
||||
rootDoc_id: rootDocId,
|
||||
rootFolder: projectRootFolder,
|
||||
},
|
||||
rootFolder: rootFolder || {
|
||||
children: [],
|
||||
rootFolder,
|
||||
},
|
||||
ui,
|
||||
$watch: (path, callback) => {
|
||||
|
@ -113,13 +110,15 @@ export function EditorProviders({
|
|||
<IdeProvider ide={window._ide}>
|
||||
<UserProvider>
|
||||
<ProjectProvider>
|
||||
<EditorProvider settings={{}}>
|
||||
<DetachProvider>
|
||||
<LayoutProvider>
|
||||
<CompileProvider>{children}</CompileProvider>
|
||||
</LayoutProvider>
|
||||
</DetachProvider>
|
||||
</EditorProvider>
|
||||
<FileTreeDataProvider>
|
||||
<EditorProvider settings={{}}>
|
||||
<DetachProvider>
|
||||
<LayoutProvider>
|
||||
<CompileProvider>{children}</CompileProvider>
|
||||
</LayoutProvider>
|
||||
</DetachProvider>
|
||||
</EditorProvider>
|
||||
</FileTreeDataProvider>
|
||||
</ProjectProvider>
|
||||
</UserProvider>
|
||||
</IdeProvider>
|
||||
|
|
Loading…
Reference in a new issue