editor-navigation-toolbar-root.jsx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import React, { useCallback } from 'react'
  2. import PropTypes from 'prop-types'
  3. import ToolbarHeader from './toolbar-header'
  4. import { useEditorContext } from '../../../shared/context/editor-context'
  5. import { useChatContext } from '../../chat/context/chat-context'
  6. import { useLayoutContext } from '../../../shared/context/layout-context'
  7. import { useProjectContext } from '../../../shared/context/project-context'
  8. import * as eventTracking from '../../../infrastructure/event-tracking'
  9. const projectContextPropTypes = {
  10. name: PropTypes.string.isRequired,
  11. features: PropTypes.shape({
  12. trackChangesVisible: PropTypes.bool,
  13. }).isRequired,
  14. }
  15. const editorContextPropTypes = {
  16. cobranding: PropTypes.object,
  17. loading: PropTypes.bool,
  18. isRestrictedTokenMember: PropTypes.bool,
  19. renameProject: PropTypes.func.isRequired,
  20. isProjectOwner: PropTypes.bool,
  21. permissionsLevel: PropTypes.string,
  22. }
  23. const chatContextPropTypes = {
  24. markMessagesAsRead: PropTypes.func.isRequired,
  25. unreadMessageCount: PropTypes.number.isRequired,
  26. }
  27. function isOpentoString(open) {
  28. return open ? 'open' : 'close'
  29. }
  30. const EditorNavigationToolbarRoot = React.memo(
  31. function EditorNavigationToolbarRoot({
  32. onlineUsersArray,
  33. openDoc,
  34. openShareProjectModal,
  35. }) {
  36. const {
  37. name: projectName,
  38. features: { trackChangesVisible },
  39. } = useProjectContext(projectContextPropTypes)
  40. const {
  41. cobranding,
  42. loading,
  43. isRestrictedTokenMember,
  44. renameProject,
  45. permissionsLevel,
  46. } = useEditorContext(editorContextPropTypes)
  47. const {
  48. chatIsOpen,
  49. setChatIsOpen,
  50. reviewPanelOpen,
  51. setReviewPanelOpen,
  52. view,
  53. setView,
  54. setLeftMenuShown,
  55. } = useLayoutContext()
  56. const { markMessagesAsRead, unreadMessageCount } =
  57. useChatContext(chatContextPropTypes)
  58. const toggleChatOpen = useCallback(() => {
  59. if (!chatIsOpen) {
  60. markMessagesAsRead()
  61. }
  62. eventTracking.sendMB('navigation-clicked-chat', {
  63. action: isOpentoString(!chatIsOpen),
  64. })
  65. setChatIsOpen(!chatIsOpen)
  66. }, [chatIsOpen, setChatIsOpen, markMessagesAsRead])
  67. const toggleReviewPanelOpen = useCallback(
  68. event => {
  69. event.preventDefault()
  70. eventTracking.sendMB('navigation-clicked-review', {
  71. action: isOpentoString(!reviewPanelOpen),
  72. })
  73. setReviewPanelOpen(value => !value)
  74. },
  75. [reviewPanelOpen, setReviewPanelOpen]
  76. )
  77. const toggleHistoryOpen = useCallback(() => {
  78. const action = view === 'history' ? 'close' : 'open'
  79. eventTracking.sendMB('navigation-clicked-history', { action })
  80. setView(view === 'history' ? 'editor' : 'history')
  81. }, [view, setView])
  82. const openShareModal = useCallback(() => {
  83. eventTracking.sendMB('navigation-clicked-share')
  84. openShareProjectModal()
  85. }, [openShareProjectModal])
  86. const onShowLeftMenuClick = useCallback(() => {
  87. eventTracking.sendMB('navigation-clicked-menu')
  88. setLeftMenuShown(value => !value)
  89. }, [setLeftMenuShown])
  90. const goToUser = useCallback(
  91. user => {
  92. if (user.doc && typeof user.row === 'number') {
  93. openDoc(user.doc, { gotoLine: user.row + 1 })
  94. }
  95. },
  96. [openDoc]
  97. )
  98. // using {display: 'none'} as 1:1 migration from Angular's ng-hide. Using
  99. // `loading ? null : <ToolbarHeader/>` causes UI glitches
  100. return (
  101. <ToolbarHeader
  102. style={loading ? { display: 'none' } : {}}
  103. cobranding={cobranding}
  104. onShowLeftMenuClick={onShowLeftMenuClick}
  105. chatIsOpen={chatIsOpen}
  106. unreadMessageCount={unreadMessageCount}
  107. toggleChatOpen={toggleChatOpen}
  108. reviewPanelOpen={reviewPanelOpen}
  109. toggleReviewPanelOpen={toggleReviewPanelOpen}
  110. historyIsOpen={view === 'history'}
  111. toggleHistoryOpen={toggleHistoryOpen}
  112. onlineUsers={onlineUsersArray}
  113. goToUser={goToUser}
  114. isRestrictedTokenMember={isRestrictedTokenMember}
  115. hasPublishPermissions={
  116. permissionsLevel === 'owner' || permissionsLevel === 'readAndWrite'
  117. }
  118. projectName={projectName}
  119. renameProject={renameProject}
  120. hasRenamePermissions={permissionsLevel === 'owner'}
  121. openShareModal={openShareModal}
  122. trackChangesVisible={trackChangesVisible}
  123. />
  124. )
  125. }
  126. )
  127. EditorNavigationToolbarRoot.propTypes = {
  128. onlineUsersArray: PropTypes.array.isRequired,
  129. openDoc: PropTypes.func.isRequired,
  130. openShareProjectModal: PropTypes.func.isRequired,
  131. }
  132. export default EditorNavigationToolbarRoot