file-tree-root.jsx 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import React, { useEffect } from 'react'
  2. import PropTypes from 'prop-types'
  3. import withErrorBoundary from '../../../infrastructure/error-boundary'
  4. import { useProjectContext } from '../../../shared/context/project-context'
  5. import { useFileTreeData } from '../../../shared/context/file-tree-data-context'
  6. import FileTreeContext from './file-tree-context'
  7. import FileTreeDraggablePreviewLayer from './file-tree-draggable-preview-layer'
  8. import FileTreeFolderList from './file-tree-folder-list'
  9. import FileTreeToolbar from './file-tree-toolbar'
  10. import FileTreeModalDelete from './modals/file-tree-modal-delete'
  11. import FileTreeModalCreateFolder from './modals/file-tree-modal-create-folder'
  12. import FileTreeModalError from './modals/file-tree-modal-error'
  13. import FileTreeContextMenu from './file-tree-context-menu'
  14. import FileTreeError from './file-tree-error'
  15. import { useDroppable } from '../contexts/file-tree-draggable'
  16. import { useFileTreeSocketListener } from '../hooks/file-tree-socket-listener'
  17. import FileTreeModalCreateFile from './modals/file-tree-modal-create-file'
  18. import FileTreeInner from './file-tree-inner'
  19. const FileTreeRoot = React.memo(function FileTreeRoot({
  20. refProviders,
  21. reindexReferences,
  22. setRefProviderEnabled,
  23. setStartedFreeTrial,
  24. onSelect,
  25. onInit,
  26. isConnected,
  27. }) {
  28. const { _id: projectId } = useProjectContext(projectContextPropTypes)
  29. const { fileTreeData } = useFileTreeData()
  30. const isReady = projectId && fileTreeData
  31. useEffect(() => {
  32. if (isReady) onInit()
  33. }, [isReady, onInit])
  34. if (!isReady) return null
  35. return (
  36. <FileTreeContext
  37. refProviders={refProviders}
  38. setRefProviderEnabled={setRefProviderEnabled}
  39. setStartedFreeTrial={setStartedFreeTrial}
  40. reindexReferences={reindexReferences}
  41. onSelect={onSelect}
  42. >
  43. {isConnected ? null : <div className="disconnected-overlay" />}
  44. <FileTreeToolbar />
  45. <FileTreeContextMenu />
  46. <FileTreeInner>
  47. <FileTreeRootFolder />
  48. </FileTreeInner>
  49. <FileTreeModalDelete />
  50. <FileTreeModalCreateFile />
  51. <FileTreeModalCreateFolder />
  52. <FileTreeModalError />
  53. </FileTreeContext>
  54. )
  55. })
  56. function FileTreeRootFolder() {
  57. useFileTreeSocketListener()
  58. const { fileTreeData } = useFileTreeData()
  59. const { isOver, dropRef } = useDroppable(fileTreeData._id)
  60. return (
  61. <>
  62. <FileTreeDraggablePreviewLayer isOver={isOver} />
  63. <FileTreeFolderList
  64. folders={fileTreeData.folders}
  65. docs={fileTreeData.docs}
  66. files={fileTreeData.fileRefs}
  67. classes={{ root: 'file-tree-list' }}
  68. dropRef={dropRef}
  69. dataTestId="file-tree-list-root"
  70. />
  71. </>
  72. )
  73. }
  74. FileTreeRoot.propTypes = {
  75. onSelect: PropTypes.func.isRequired,
  76. onInit: PropTypes.func.isRequired,
  77. isConnected: PropTypes.bool.isRequired,
  78. setRefProviderEnabled: PropTypes.func.isRequired,
  79. setStartedFreeTrial: PropTypes.func.isRequired,
  80. reindexReferences: PropTypes.func.isRequired,
  81. refProviders: PropTypes.object.isRequired,
  82. }
  83. const projectContextPropTypes = {
  84. _id: PropTypes.string.isRequired,
  85. }
  86. export default withErrorBoundary(FileTreeRoot, FileTreeError)