file-tree-root.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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. const FileTreeRoot = React.memo(function FileTreeRoot({
  19. refProviders,
  20. reindexReferences,
  21. setRefProviderEnabled,
  22. setStartedFreeTrial,
  23. onSelect,
  24. onInit,
  25. isConnected,
  26. }) {
  27. const { _id: projectId } = useProjectContext(projectContextPropTypes)
  28. const { fileTreeData } = useFileTreeData()
  29. const isReady = projectId && fileTreeData
  30. useEffect(() => {
  31. if (isReady) onInit()
  32. }, [isReady, onInit])
  33. if (!isReady) return null
  34. return (
  35. <FileTreeContext
  36. refProviders={refProviders}
  37. setRefProviderEnabled={setRefProviderEnabled}
  38. setStartedFreeTrial={setStartedFreeTrial}
  39. reindexReferences={reindexReferences}
  40. onSelect={onSelect}
  41. >
  42. {isConnected ? null : <div className="disconnected-overlay" />}
  43. <FileTreeToolbar />
  44. <FileTreeContextMenu />
  45. <div className="file-tree-inner">
  46. <FileTreeRootFolder />
  47. </div>
  48. <FileTreeModalDelete />
  49. <FileTreeModalCreateFile />
  50. <FileTreeModalCreateFolder />
  51. <FileTreeModalError />
  52. </FileTreeContext>
  53. )
  54. })
  55. function FileTreeRootFolder() {
  56. useFileTreeSocketListener()
  57. const { fileTreeData } = useFileTreeData()
  58. const { isOver, dropRef } = useDroppable(fileTreeData._id)
  59. return (
  60. <>
  61. <FileTreeDraggablePreviewLayer isOver={isOver} />
  62. <FileTreeFolderList
  63. folders={fileTreeData.folders}
  64. docs={fileTreeData.docs}
  65. files={fileTreeData.fileRefs}
  66. classes={{ root: 'file-tree-list' }}
  67. dropRef={dropRef}
  68. isOver={isOver}
  69. >
  70. <li className="bottom-buffer" />
  71. </FileTreeFolderList>
  72. </>
  73. )
  74. }
  75. FileTreeRoot.propTypes = {
  76. onSelect: PropTypes.func.isRequired,
  77. onInit: PropTypes.func.isRequired,
  78. isConnected: PropTypes.bool.isRequired,
  79. setRefProviderEnabled: PropTypes.func.isRequired,
  80. setStartedFreeTrial: PropTypes.func.isRequired,
  81. reindexReferences: PropTypes.func.isRequired,
  82. refProviders: PropTypes.object.isRequired,
  83. }
  84. const projectContextPropTypes = {
  85. _id: PropTypes.string.isRequired,
  86. }
  87. export default withErrorBoundary(FileTreeRoot, FileTreeError)