file-tree-root.js 2.7 KB

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